diff --git a/modules/services/drone/default.nix b/modules/services/drone/default.nix index 7a9b668..3e84ddd 100644 --- a/modules/services/drone/default.nix +++ b/modules/services/drone/default.nix @@ -3,16 +3,13 @@ # Inspired by [1] # [1]: https://github.com/Mic92/dotfiles/blob/master/nixos/eve/modules/drone.nix { config, lib, pkgs, ... }: -let - cfg = config.my.services.drone; - - hasRunner = (name: builtins.elem name cfg.runners); - - execPkg = pkgs.drone-runner-exec; - - dockerPkg = pkgs.drone-runner-docker; -in { + imports = [ + ./runner-docker + ./runner-exec + ./server + ]; + options.my.services.drone = with lib; { enable = mkEnableOption "Drone CI"; runners = mkOption { @@ -44,151 +41,4 @@ in description = "Shared RPC secret to inject into server and runners"; }; }; - - config = lib.mkIf cfg.enable { - systemd.services.drone-server = { - wantedBy = [ "multi-user.target" ]; - after = [ "postgresql.service" ]; - serviceConfig = { - EnvironmentFile = [ - cfg.secretFile - cfg.sharedSecretFile - ]; - Environment = [ - "DRONE_DATABASE_DATASOURCE=postgres:///drone?host=/run/postgresql" - "DRONE_SERVER_HOST=drone.${config.networking.domain}" - "DRONE_SERVER_PROTO=https" - "DRONE_DATABASE_DRIVER=postgres" - "DRONE_SERVER_PORT=:${toString cfg.port}" - "DRONE_USER_CREATE=username:${cfg.admin},admin:true" - "DRONE_JSONNET_ENABLED=true" - "DRONE_STARLARK_ENABLED=true" - ]; - ExecStart = "${pkgs.drone}/bin/drone-server"; - User = "drone"; - Group = "drone"; - }; - }; - - users.users.drone = { - isSystemUser = true; - createHome = true; - group = "drone"; - }; - users.groups.drone = { }; - - services.postgresql = { - enable = true; - ensureDatabases = [ "drone" ]; - ensureUsers = [{ - name = "drone"; - ensurePermissions = { - "DATABASE drone" = "ALL PRIVILEGES"; - }; - }]; - }; - - my.services.nginx.virtualHosts = [ - { - subdomain = "drone"; - inherit (cfg) port; - } - ]; - - # Docker runner - systemd.services.drone-runner-docker = lib.mkIf (hasRunner "docker") { - wantedBy = [ "multi-user.target" ]; - after = [ "docker.socket" ]; # Needs the socket to be available - # might break deployment - restartIfChanged = false; - confinement.enable = true; - serviceConfig = { - Environment = [ - "DRONE_SERVER_HOST=drone.${config.networking.domain}" - "DRONE_SERVER_PROTO=https" - "DRONE_RUNNER_CAPACITY=10" - "CLIENT_DRONE_RPC_HOST=127.0.0.1:${toString cfg.port}" - ]; - BindPaths = [ - "/var/run/docker.sock" - ]; - EnvironmentFile = [ - cfg.sharedSecretFile - ]; - ExecStart = "${dockerPkg}/bin/drone-runner-docker"; - User = "drone-runner-docker"; - Group = "drone-runner-docker"; - }; - }; - - # Make sure it is activated in that case - virtualisation.docker.enable = lib.mkIf (hasRunner "docker") true; - - users.users.drone-runner-docker = lib.mkIf (hasRunner "docker") { - isSystemUser = true; - group = "drone-runner-docker"; - extraGroups = [ "docker" ]; # Give access to the daemon - }; - users.groups.drone-runner-docker = lib.mkIf (hasRunner "docker") { }; - - # Exec runner - systemd.services.drone-runner-exec = lib.mkIf (hasRunner "exec") { - wantedBy = [ "multi-user.target" ]; - # might break deployment - restartIfChanged = false; - confinement.enable = true; - confinement.packages = with pkgs; [ - git - gnutar - bash - nixUnstable - gzip - ]; - path = with pkgs; [ - git - gnutar - bash - nixUnstable - gzip - ]; - serviceConfig = { - Environment = [ - "DRONE_SERVER_HOST=drone.${config.networking.domain}" - "DRONE_SERVER_PROTO=https" - "DRONE_RUNNER_CAPACITY=10" - "CLIENT_DRONE_RPC_HOST=127.0.0.1:${toString cfg.port}" - "NIX_REMOTE=daemon" - "PAGER=cat" - ]; - BindPaths = [ - "/nix/var/nix/daemon-socket/socket" - "/run/nscd/socket" - ]; - BindReadOnlyPaths = [ - "/etc/resolv.conf:/etc/resolv.conf" - "/etc/resolvconf.conf:/etc/resolvconf.conf" - "/etc/passwd:/etc/passwd" - "/etc/group:/etc/group" - "/nix/var/nix/profiles/system/etc/nix:/etc/nix" - "${config.environment.etc."ssl/certs/ca-certificates.crt".source}:/etc/ssl/certs/ca-certificates.crt" - "${config.environment.etc."ssh/ssh_known_hosts".source}:/etc/ssh/ssh_known_hosts" - "/etc/machine-id" - # channels are dynamic paths in the nix store, therefore we need to bind mount the whole thing - "/nix/" - ]; - EnvironmentFile = [ - cfg.sharedSecretFile - ]; - ExecStart = "${execPkg}/bin/drone-runner-exec"; - User = "drone-runner-exec"; - Group = "drone-runner-exec"; - }; - }; - - users.users.drone-runner-exec = lib.mkIf (hasRunner "exec") { - isSystemUser = true; - group = "drone-runner-exec"; - }; - users.groups.drone-runner-exec = lib.mkIf (hasRunner "exec") { }; - }; } diff --git a/modules/services/drone/runner-docker/default.nix b/modules/services/drone/runner-docker/default.nix new file mode 100644 index 0000000..0f2e3b3 --- /dev/null +++ b/modules/services/drone/runner-docker/default.nix @@ -0,0 +1,44 @@ +{ config, lib, pkgs, ... }: +let + cfg = config.my.services.drone; + hasRunner = (name: builtins.elem name cfg.runners); + dockerPkg = pkgs.drone-runner-docker; +in +{ + config = lib.mkIf (cfg.enable && hasRunner "docker") { + systemd.services.drone-runner-docker = { + wantedBy = [ "multi-user.target" ]; + after = [ "docker.socket" ]; # Needs the socket to be available + # might break deployment + restartIfChanged = false; + confinement.enable = true; + serviceConfig = { + Environment = [ + "DRONE_SERVER_HOST=drone.${config.networking.domain}" + "DRONE_SERVER_PROTO=https" + "DRONE_RUNNER_CAPACITY=10" + "CLIENT_DRONE_RPC_HOST=127.0.0.1:${toString cfg.port}" + ]; + BindPaths = [ + "/var/run/docker.sock" + ]; + EnvironmentFile = [ + cfg.sharedSecretFile + ]; + ExecStart = "${dockerPkg}/bin/drone-runner-docker"; + User = "drone-runner-docker"; + Group = "drone-runner-docker"; + }; + }; + + # Make sure it is activated in that case + virtualisation.docker.enable = true; + + users.users.drone-runner-docker = { + isSystemUser = true; + group = "drone-runner-docker"; + extraGroups = [ "docker" ]; # Give access to the daemon + }; + users.groups.drone-runner-docker = { }; + }; +} diff --git a/modules/services/drone/runner-exec/default.nix b/modules/services/drone/runner-exec/default.nix new file mode 100644 index 0000000..6c776b4 --- /dev/null +++ b/modules/services/drone/runner-exec/default.nix @@ -0,0 +1,68 @@ +{ config, lib, pkgs, ... }: +let + cfg = config.my.services.drone; + hasRunner = (name: builtins.elem name cfg.runners); + execPkg = pkgs.drone-runner-exec; +in +{ + config = lib.mkIf (cfg.enable && hasRunner "exec") { + systemd.services.drone-runner-exec = { + wantedBy = [ "multi-user.target" ]; + # might break deployment + restartIfChanged = false; + confinement.enable = true; + confinement.packages = with pkgs; [ + git + gnutar + bash + nixUnstable + gzip + ]; + path = with pkgs; [ + git + gnutar + bash + nixUnstable + gzip + ]; + serviceConfig = { + Environment = [ + "DRONE_SERVER_HOST=drone.${config.networking.domain}" + "DRONE_SERVER_PROTO=https" + "DRONE_RUNNER_CAPACITY=10" + "CLIENT_DRONE_RPC_HOST=127.0.0.1:${toString cfg.port}" + "NIX_REMOTE=daemon" + "PAGER=cat" + ]; + BindPaths = [ + "/nix/var/nix/daemon-socket/socket" + "/run/nscd/socket" + ]; + BindReadOnlyPaths = [ + "/etc/resolv.conf:/etc/resolv.conf" + "/etc/resolvconf.conf:/etc/resolvconf.conf" + "/etc/passwd:/etc/passwd" + "/etc/group:/etc/group" + "/nix/var/nix/profiles/system/etc/nix:/etc/nix" + "${config.environment.etc."ssl/certs/ca-certificates.crt".source}:/etc/ssl/certs/ca-certificates.crt" + "${config.environment.etc."ssh/ssh_known_hosts".source}:/etc/ssh/ssh_known_hosts" + "/etc/machine-id" + # channels are dynamic paths in the nix store, therefore we need to bind mount the whole thing + "/nix/" + ]; + EnvironmentFile = [ + cfg.sharedSecretFile + ]; + ExecStart = "${execPkg}/bin/drone-runner-exec"; + User = "drone-runner-exec"; + Group = "drone-runner-exec"; + }; + }; + + users.users.drone-runner-exec = { + isSystemUser = true; + group = "drone-runner-exec"; + }; + users.groups.drone-runner-exec = { }; + }; +} diff --git a/modules/services/drone/server/default.nix b/modules/services/drone/server/default.nix new file mode 100644 index 0000000..1202010 --- /dev/null +++ b/modules/services/drone/server/default.nix @@ -0,0 +1,56 @@ +{ config, lib, pkgs, ... }: +let + cfg = config.my.services.drone; +in +{ + config = lib.mkIf cfg.enable { + systemd.services.drone-server = { + wantedBy = [ "multi-user.target" ]; + after = [ "postgresql.service" ]; + serviceConfig = { + EnvironmentFile = [ + cfg.secretFile + cfg.sharedSecretFile + ]; + Environment = [ + "DRONE_DATABASE_DATASOURCE=postgres:///drone?host=/run/postgresql" + "DRONE_SERVER_HOST=drone.${config.networking.domain}" + "DRONE_SERVER_PROTO=https" + "DRONE_DATABASE_DRIVER=postgres" + "DRONE_SERVER_PORT=:${toString cfg.port}" + "DRONE_USER_CREATE=username:${cfg.admin},admin:true" + "DRONE_JSONNET_ENABLED=true" + "DRONE_STARLARK_ENABLED=true" + ]; + ExecStart = "${pkgs.drone}/bin/drone-server"; + User = "drone"; + Group = "drone"; + }; + }; + + users.users.drone = { + isSystemUser = true; + createHome = true; + group = "drone"; + }; + users.groups.drone = { }; + + services.postgresql = { + enable = true; + ensureDatabases = [ "drone" ]; + ensureUsers = [{ + name = "drone"; + ensurePermissions = { + "DATABASE drone" = "ALL PRIVILEGES"; + }; + }]; + }; + + my.services.nginx.virtualHosts = [ + { + subdomain = "drone"; + inherit (cfg) port; + } + ]; + }; +}