diff --git a/lib/maintainers.nix b/lib/maintainers.nix index ad83f9ee4fb0..1684b02d888b 100644 --- a/lib/maintainers.nix +++ b/lib/maintainers.nix @@ -376,6 +376,7 @@ SShrike = "Severen Redwood "; stephenmw = "Stephen Weinberg "; steveej = "Stefan Junker "; + swarren83 = "Shawn Warren "; swistak35 = "Rafał Łasocha "; szczyp = "Szczyp "; sztupi = "Attila Sztupak "; diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index 7f387b25a208..3ba279f597da 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -271,6 +271,8 @@ squeezelite = 248; turnserver = 249; smokeping = 250; + gocd-agent = 251; + gocd-server = 252; # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! @@ -512,6 +514,8 @@ #squeezelite = 248; #unused turnserver = 249; smokeping = 250; + gocd-agent = 251; + gocd-server = 252; # When adding a gid, make sure it doesn't match an existing # uid. Users and groups with the same name should have equal diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 3e3d7c492807..5d04140dad50 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -130,6 +130,8 @@ ./services/computing/slurm/slurm.nix ./services/continuous-integration/buildkite-agent.nix ./services/continuous-integration/hydra/default.nix + ./services/continuous-integration/gocd-agent/default.nix + ./services/continuous-integration/gocd-server/default.nix ./services/continuous-integration/jenkins/default.nix ./services/continuous-integration/jenkins/job-builder.nix ./services/continuous-integration/jenkins/slave.nix diff --git a/nixos/modules/services/continuous-integration/gocd-agent/default.nix b/nixos/modules/services/continuous-integration/gocd-agent/default.nix new file mode 100644 index 000000000000..36f6527ee47b --- /dev/null +++ b/nixos/modules/services/continuous-integration/gocd-agent/default.nix @@ -0,0 +1,212 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.gocd-agent; +in { + options = { + services.gocd-agent = { + enable = mkEnableOption "gocd-agent"; + + user = mkOption { + default = "gocd-agent"; + type = types.str; + description = '' + User the Go.CD agent should execute under. + ''; + }; + + group = mkOption { + default = "gocd-agent"; + type = types.str; + description = '' + If the default user "gocd-agent" is configured then this is the primary + group of that user. + ''; + }; + + extraGroups = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "wheel" "docker" ]; + description = '' + List of extra groups that the "gocd-agent" user should be a part of. + ''; + }; + + packages = mkOption { + default = [ pkgs.stdenv pkgs.jre config.programs.ssh.package pkgs.nix ]; + type = types.listOf types.package; + description = '' + Packages to add to PATH for the Go.CD agent process. + ''; + }; + + agentConfig = mkOption { + default = ""; + type = types.str; + example = '' + agent.auto.register.resources=ant,java + agent.auto.register.environments=QA,Performance + agent.auto.register.hostname=Agent01 + ''; + description = '' + Agent registration configuration. + ''; + }; + + goServer = mkOption { + default = "127.0.0.1"; + type = types.str; + description = '' + Address of GoCD Server to attach the Go.CD Agent to. + ''; + }; + + goServerPort = mkOption { + default = 8153; + type = types.int; + description = '' + Port that Go.CD Server is Listening on. + ''; + }; + + workDir = mkOption { + default = "/var/lib/go-agent"; + type = types.str; + description = '' + Specifies the working directory in which the Go.CD agent java archive resides. + ''; + }; + + heapSize = mkOption { + default = "128m"; + type = types.str; + description = '' + Specifies the java heap memory size for the Go.CD agent java process. + ''; + }; + + maxMemory = mkOption { + default = "256m"; + type = types.str; + description = '' + Specifies the java maximum memory size for the Go.CD agent java process. + ''; + }; + + startupOptions = mkOption { + default = [ + "-Xms${cfg.heapSize}" + "-Xmx${cfg.maxMemory}" + "-Djava.io.tmpdir=/tmp" + "-Dcruise.console.publish.interval=10" + "-Djava.security.egd=file:/dev/./urandom" + ]; + description = '' + Specifies startup command line arguments to pass to Go.CD agent + java process. Example contains debug and gcLog arguments. + ''; + }; + + extraOptions = mkOption { + default = [ ]; + example = [ + "-X debug" + "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5006" + "-verbose:gc" + "-Xloggc:go-agent-gc.log" + "-XX:+PrintGCTimeStamps" + "-XX:+PrintTenuringDistribution" + "-XX:+PrintGCDetails" + "-XX:+PrintGC" + ]; + description = '' + Specifies additional command line arguments to pass to Go.CD agent + java process. Example contains debug and gcLog arguments. + ''; + }; + + environment = mkOption { + default = { }; + type = with types; attrsOf str; + description = '' + Additional environment variables to be passed to the Go.CD agent process. + As a base environment, Go.CD agent receives NIX_PATH from + , NIX_REMOTE is set to + "daemon". + ''; + }; + }; + }; + + config = mkIf cfg.enable { + users.extraGroups = optional (cfg.group == "gocd-agent") { + name = "gocd-agent"; + gid = config.ids.gids.gocd-agent; + }; + + users.extraUsers = optional (cfg.user == "gocd-agent") { + name = "gocd-agent"; + description = "gocd-agent user"; + createHome = true; + home = cfg.workDir; + group = cfg.group; + extraGroups = cfg.extraGroups; + useDefaultShell = true; + uid = config.ids.uids.gocd-agent; + }; + + systemd.services.gocd-agent = { + description = "GoCD Agent"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + environment = + let + selectedSessionVars = + lib.filterAttrs (n: v: builtins.elem n [ "NIX_PATH" ]) + config.environment.sessionVariables; + in + selectedSessionVars // + { + NIX_REMOTE = "daemon"; + AGENT_WORK_DIR = cfg.workDir; + AGENT_STARTUP_ARGS = ''${concatStringsSep " " cfg.startupOptions}''; + LOG_DIR = cfg.workDir; + LOG_FILE = "${cfg.workDir}/go-agent-start.log"; + } // + cfg.environment; + + path = cfg.packages; + + script = '' + MPATH="''${PATH}"; + source /etc/profile + export PATH="''${MPATH}:''${PATH}"; + + if ! test -f ~/.nixpkgs/config.nix; then + mkdir -p ~/.nixpkgs/ + echo "{ allowUnfree = true; }" > ~/.nixpkgs/config.nix + fi + + mkdir -p config + rm -f config/autoregister.properties + ln -s "${pkgs.writeText "autoregister.properties" cfg.agentConfig}" config/autoregister.properties + + ${pkgs.git}/bin/git config --global --add http.sslCAinfo /etc/ssl/certs/ca-certificates.crt + ${pkgs.jre}/bin/java ${concatStringsSep " " cfg.startupOptions} \ + ${concatStringsSep " " cfg.extraOptions} \ + -jar ${pkgs.gocd-agent}/go-agent/agent-bootstrapper.jar \ + ${cfg.goServer} \ + ${toString cfg.goServerPort} + ''; + + serviceConfig = { + User = cfg.user; + WorkingDirectory = cfg.workDir; + }; + }; + }; +} diff --git a/nixos/modules/services/continuous-integration/gocd-server/default.nix b/nixos/modules/services/continuous-integration/gocd-server/default.nix new file mode 100644 index 000000000000..f0d9d6f53c83 --- /dev/null +++ b/nixos/modules/services/continuous-integration/gocd-server/default.nix @@ -0,0 +1,183 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.gocd-server; +in { + options = { + services.gocd-server = { + enable = mkEnableOption "gocd-server"; + + user = mkOption { + default = "gocd-server"; + type = types.str; + description = '' + User the Go.CD server should execute under. + ''; + }; + + group = mkOption { + default = "gocd-server"; + type = types.str; + description = '' + If the default user "gocd-server" is configured then this is the primary group of that user. + ''; + }; + + extraGroups = mkOption { + default = [ ]; + example = [ "wheel" "docker" ]; + description = '' + List of extra groups that the "gocd-server" user should be a part of. + ''; + }; + + listenAddress = mkOption { + default = "0.0.0.0"; + example = "localhost"; + type = types.str; + description = '' + Specifies the bind address on which the Go.CD server HTTP interface listens. + ''; + }; + + port = mkOption { + default = 8153; + type = types.int; + description = '' + Specifies port number on which the Go.CD server HTTP interface listens. + ''; + }; + + sslPort = mkOption { + default = 8154; + type = types.int; + description = '' + Specifies port number on which the Go.CD server HTTPS interface listens. + ''; + }; + + workDir = mkOption { + default = "/var/lib/go-server"; + type = types.str; + description = '' + Specifies the working directory in which the Go.CD server java archive resides. + ''; + }; + + packages = mkOption { + default = [ pkgs.stdenv pkgs.jre config.programs.ssh.package pkgs.nix ]; + type = types.listOf types.package; + description = '' + Packages to add to PATH for the Go.CD server's process. + ''; + }; + + heapSize = mkOption { + default = "512m"; + type = types.str; + description = '' + Specifies the java heap memory size for the Go.CD server's java process. + ''; + }; + + maxMemory = mkOption { + default = "1024m"; + type = types.str; + description = '' + Specifies the java maximum memory size for the Go.CD server's java process. + ''; + }; + + extraOptions = mkOption { + default = [ + "-Xms${cfg.heapSize}" + "-Xmx${cfg.maxMemory}" + "-Dcruise.listen.host=${cfg.listenAddress}" + "-Duser.language=en" + "-Djruby.rack.request.size.threshold.bytes=30000000" + "-Duser.country=US" + "-Dcruise.config.dir=${cfg.workDir}/conf" + "-Dcruise.config.file=${cfg.workDir}/conf/cruise-config.xml" + "-Dcruise.server.port=${toString cfg.port}" + "-Dcruise.server.ssl.port=${toString cfg.sslPort}" + ]; + example = [ + "-X debug" + "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005" + "-verbose:gc" + "-Xloggc:go-server-gc.log" + "-XX:+PrintGCTimeStamps" + "-XX:+PrintTenuringDistribution" + "-XX:+PrintGCDetails" + "-XX:+PrintGC" + ]; + description = '' + Specifies additional command line arguments to pass to Go.CD server's + java process. Example contains debug and gcLog arguments. + ''; + }; + + environment = mkOption { + default = { }; + type = with types; attrsOf str; + description = '' + Additional environment variables to be passed to the gocd-server process. + As a base environment, gocd-server receives NIX_PATH from + , NIX_REMOTE is set to + "daemon". + ''; + }; + }; + }; + + config = mkIf cfg.enable { + users.extraGroups = optional (cfg.group == "gocd-server") { + name = "gocd-server"; + gid = config.ids.gids.gocd-server; + }; + + users.extraUsers = optional (cfg.user == "gocd-server") { + name = "gocd-server"; + description = "gocd-server user"; + createHome = true; + home = cfg.workDir; + group = cfg.group; + extraGroups = cfg.extraGroups; + useDefaultShell = true; + uid = config.ids.uids.gocd-server; + }; + + systemd.services.gocd-server = { + description = "GoCD Server"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + environment = + let + selectedSessionVars = + lib.filterAttrs (n: v: builtins.elem n [ "NIX_PATH" ]) + config.environment.sessionVariables; + in + selectedSessionVars // + { NIX_REMOTE = "daemon"; + } // + cfg.environment; + + path = cfg.packages; + + script = '' + ${pkgs.git}/bin/git config --global --add http.sslCAinfo /etc/ssl/certs/ca-certificates.crt + ${pkgs.jre}/bin/java -server ${concatStringsSep " " cfg.extraOptions} \ + -jar ${pkgs.gocd-server}/go-server/go.jar + ''; + + serviceConfig = { + User = cfg.user; + Group = cfg.group; + WorkingDirectory = cfg.workDir; + }; + }; + }; +} diff --git a/nixos/release.nix b/nixos/release.nix index 966dee1aff03..273c3e21a10d 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -228,6 +228,8 @@ in rec { tests.firewall = callTest tests/firewall.nix {}; tests.fleet = hydraJob (import tests/fleet.nix { system = "x86_64-linux"; }); #tests.gitlab = callTest tests/gitlab.nix {}; + tests.gocd-agent = callTest tests/gocd-agent.nix {}; + tests.gocd-server = callTest tests/gocd-server.nix {}; tests.gnome3 = callTest tests/gnome3.nix {}; tests.gnome3-gdm = callTest tests/gnome3-gdm.nix {}; tests.grsecurity = callTest tests/grsecurity.nix {}; diff --git a/nixos/tests/gocd-agent.nix b/nixos/tests/gocd-agent.nix new file mode 100644 index 000000000000..d5ed0f65ab01 --- /dev/null +++ b/nixos/tests/gocd-agent.nix @@ -0,0 +1,34 @@ +# verifies: +# 1. GoCD agent starts +# 2. GoCD agent responds +# 3. GoCD agent is available on GoCD server using GoCD API +# 3.1. https://api.go.cd/current/#get-all-agents + +import ./make-test.nix ({ pkgs, ...} : { + name = "gocd-agent"; + meta = with pkgs.stdenv.lib.maintainers; { + maintainers = [ swarren83 ]; + }; + +nodes = { + gocd_agent = + { config, pkgs, ... }: + { + virtualisation.memorySize = 2048; + services.gocd-agent = { + enable = true; + }; + services.gocd-server = { + enable = true; + }; + }; +}; + + testScript = '' + startAll; + $gocd_agent->waitForUnit("gocd-server"); + $gocd_agent->waitForOpenPort("8153"); + $gocd_agent->waitForUnit("gocd-agent"); + $gocd_agent->waitUntilSucceeds("curl -s -f localhost:8153/go/api/agents -H 'Accept: application/vnd.go.cd.v2+json'"); + ''; +}) diff --git a/nixos/tests/gocd-server.nix b/nixos/tests/gocd-server.nix new file mode 100644 index 000000000000..6ec5bfb4dbb9 --- /dev/null +++ b/nixos/tests/gocd-server.nix @@ -0,0 +1,28 @@ +# verifies: +# 1. GoCD server starts +# 2. GoCD server responds + +import ./make-test.nix ({ pkgs, ...} : + +{ + name = "gocd-server"; + meta = with pkgs.stdenv.lib.maintainers; { + maintainers = [ swarren83 ]; + }; + +nodes = { + gocd_server = + { config, pkgs, ... }: + { + virtualisation.memorySize = 2048; + services.gocd-server.enable = true; + }; +}; + + testScript = '' + $gocd_server->start; + $gocd_server->waitForUnit("gocd-server"); + $gocd_server->waitForOpenPort("8153"); + $gocd_server->waitUntilSucceeds("curl -s -f localhost:8153/go"); + ''; +}) diff --git a/pkgs/development/tools/continuous-integration/gocd-agent/default.nix b/pkgs/development/tools/continuous-integration/gocd-agent/default.nix new file mode 100644 index 000000000000..170f07ca5c3d --- /dev/null +++ b/pkgs/development/tools/continuous-integration/gocd-agent/default.nix @@ -0,0 +1,26 @@ +{ stdenv, fetchurl, unzip }: + +stdenv.mkDerivation rec { + name = "gocd-agent-${version}-${rev}"; + version = "16.5.0"; + rev = "3305"; + + src = fetchurl { + url = "https://download.go.cd/binaries/${version}-${rev}/generic/go-agent-${version}-${rev}.zip"; + sha256 = "2cb988d36ec747b2917f3be040b430f2a8289c07353a6b6bdc95bf741fa1ed97"; + }; + meta = with stdenv.lib; { + description = "A continuous delivery server specializing in advanced workflow modeling and visualization"; + homepage = http://www.go.cd; + license = licenses.asl20; + platforms = platforms.all; + maintainers = with maintainers; [ swarren83 ]; + }; + + buildInputs = [ unzip ]; + + buildCommand = " + unzip $src -d $out + mv $out/go-agent-${version} $out/go-agent + "; +} diff --git a/pkgs/development/tools/continuous-integration/gocd-server/default.nix b/pkgs/development/tools/continuous-integration/gocd-server/default.nix new file mode 100644 index 000000000000..0b9794fd6d7f --- /dev/null +++ b/pkgs/development/tools/continuous-integration/gocd-server/default.nix @@ -0,0 +1,28 @@ +{ stdenv, fetchurl, unzip }: + +stdenv.mkDerivation rec { + name = "gocd-server-${version}-${rev}"; + version = "16.5.0"; + rev = "3305"; + + src = fetchurl { + url = "https://download.go.cd/binaries/${version}-${rev}/generic/go-server-${version}-${rev}.zip"; + sha256 = "41139051f419dc340a5c05c76e5de06eeef3516526341f377ac77532511bfa2c"; + }; + + meta = with stdenv.lib; { + description = "A continuous delivery server specializing in advanced workflow modeling and visualization"; + homepage = http://www.go.cd; + license = licenses.asl20; + platforms = platforms.all; + maintainers = with maintainers; [ swarren83 ]; + }; + + buildInputs = [ unzip ]; + + buildCommand = " + unzip $src -d $out + mv $out/go-server-${version} $out/go-server + mkdir -p $out/go-server/conf + "; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 4b73c32ac0e5..4c411ca71f78 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -6374,6 +6374,10 @@ in gob2 = callPackage ../development/tools/misc/gob2 { }; + gocd-agent = callPackage ../development/tools/continuous-integration/gocd-agent { }; + + gocd-server = callPackage ../development/tools/continuous-integration/gocd-server { }; + gotty = callPackage ../servers/gotty { }; gradleGen = callPackage ../development/tools/build-managers/gradle { };