diff options
38 files changed, 435 insertions, 965 deletions
diff --git a/krebs/1systems/hotdog/config.nix b/krebs/1systems/hotdog/config.nix index 9f1ac9134..84eaeaa19 100644 --- a/krebs/1systems/hotdog/config.nix +++ b/krebs/1systems/hotdog/config.nix @@ -10,6 +10,7 @@ <stockholm/krebs/2configs/ircd.nix> <stockholm/krebs/2configs/reaktor2.nix> <stockholm/krebs/2configs/wiki.nix> + <stockholm/krebs/2configs/acme.nix> ## shackie irc bot <stockholm/krebs/2configs/shack/reaktor.nix> diff --git a/krebs/2configs/acme.nix b/krebs/2configs/acme.nix new file mode 100644 index 000000000..056aa7ae4 --- /dev/null +++ b/krebs/2configs/acme.nix @@ -0,0 +1,67 @@ +# generate intermediate certificate with generate-krebs-intermediate-ca +{ config, lib, pkgs, ... }: let + domain = "ca.r"; +in { + security.acme = { + acceptTerms = true; # kinda pointless since we never use upstream + email = "spam@krebsco.de"; + certs.${domain}.server = "https://${domain}:1443/acme/acme/directory"; # use 1443 here cause bootstrapping loop + }; + networking.firewall.allowedTCPPorts = [ 80 443 ]; + services.nginx = { + enable = true; + recommendedProxySettings = true; + virtualHosts.${domain} = { + addSSL = true; + enableACME = true; + locations."/" = { + proxyPass = "https://localhost:1443"; + }; + locations."= /ca.crt".alias = ../6assets/krebsAcmeCA.crt; + }; + }; + krebs.secret.files.krebsAcme = { + path = "/var/lib/step-ca/intermediate_ca.key"; + owner.name = "root"; + mode = "1444"; + source-path = builtins.toString <secrets> + "/acme_ca.key"; + }; + services.step-ca = { + enable = true; + intermediatePasswordFile = "/dev/null"; + address = "0.0.0.0"; + port = 1443; + settings = { + root = pkgs.writeText "root.crt" config.krebs.ssl.rootCA; + crt = pkgs.writeText "intermediate.crt" config.krebs.ssl.intermediateCA; + key = "/var/lib/step-ca/intermediate_ca.key"; + dnsNames = [ domain ]; + logger.format = "text"; + db = { + type = "badger"; + dataSource = "/var/lib/step-ca/db"; + }; + authority = { + provisioners = [{ + type = "ACME"; + name = "acme"; + forceCN = true; + }]; + claims = { + maxTLSCertDuration = "2160h"; + defaultTLSCertDuration = "2160h"; + }; + backdate = "1m0s"; + }; + tls = { + cipherSuites = [ + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" + ]; + minVersion = 1.2; + maxVersion = 1.3; + renegotiation = false; + }; + }; + }; +} diff --git a/krebs/2configs/buildbot-stockholm.nix b/krebs/2configs/buildbot-stockholm.nix index 43a38a9f8..9fc6a79e5 100644 --- a/krebs/2configs/buildbot-stockholm.nix +++ b/krebs/2configs/buildbot-stockholm.nix @@ -6,11 +6,13 @@ enable = true; virtualHosts.build = { serverAliases = [ "build.r" "build.${config.networking.hostName}.r" ]; - locations."/".extraConfig = '' - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_pass http://127.0.0.1:${toString config.krebs.buildbot.master.web.port}; - ''; + locations."/" = { + proxyPass = "http://127.0.0.1:${toString config.services.buildbot-master.port}"; + proxyWebsockets = true; + extraConfig = '' + proxy_read_timeout 3600s; + ''; + }; }; }; krebs.ci = { @@ -18,25 +20,20 @@ repos = { disko.urls = [ "http://cgit.gum.r/disko" - "http://cgit.hotdog.r/disko" "http://cgit.ni.r/disko" "http://cgit.prism.r/disko" ]; krops.urls = [ - "http://cgit.hotdog.r/krops" "http://cgit.ni.r/krops" "http://cgit.prism.r/krops" "https://github.com/krebs/krops.git" ]; nix_writers.urls = [ - "http://cgit.hotdog.r/nix-writers" "http://cgit.ni.r/nix-writers" "http://cgit.prism.r/nix-writers" ]; stockholm.urls = [ - "http://cgit.enklave.r/stockholm" "http://cgit.gum.r/stockholm" - "http://cgit.hotdog.r/stockholm" "http://cgit.ni.r/stockholm" "http://cgit.prism.r/stockholm" ]; diff --git a/krebs/2configs/default.nix b/krebs/2configs/default.nix index 8a84d4465..9200d41fe 100644 --- a/krebs/2configs/default.nix +++ b/krebs/2configs/default.nix @@ -4,18 +4,14 @@ with import <stockholm/lib>; { imports = [ ./backup.nix - (let ca-bundle = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; in { - environment.variables = { - CURL_CA_BUNDLE = ca-bundle; - GIT_SSL_CAINFO = ca-bundle; - SSL_CERT_FILE = ca-bundle; - }; - }) ]; krebs.announce-activation.enable = true; krebs.enable = true; krebs.tinc.retiolum.enable = mkDefault true; + # trust krebs ACME CA + krebs.ssl.trustIntermediate = true; + krebs.build.user = mkDefault config.krebs.users.krebs; networking.hostName = config.krebs.build.host.name; diff --git a/krebs/2configs/shack/ssh-keys.nix b/krebs/2configs/shack/ssh-keys.nix index 50bb93809..80957f3a5 100644 --- a/krebs/2configs/shack/ssh-keys.nix +++ b/krebs/2configs/shack/ssh-keys.nix @@ -7,6 +7,7 @@ config.krebs.users.raute.pubkey config.krebs.users.ulrich.pubkey config.krebs.users.xq.pubkey + config.krebs.users.xkey.pubkey "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAEAQDb9NPa2Hf51afcG1H13UPbE5E02J8aC9a1sGCRls592wAVlQbmojYR1jWDPA2m32Bsyv0ztqi81zDyndWWZPQVJVBk00VjYBcgk6D5ifqoAuWLzfuHJPWZGOvBf/U74/LNFNUkj1ywjneK7HYTRPXrRBBfBSQNmQzkvue7s599L2vdueZKyjNsMpx2m6nm2SchaMuDskSQut/168JgU1l4M8BeT68Bo4WdelhBYnhSI1a59FGkgdu2SCjyighLQRy2sOH3ksnkHWENPkA+wwQOlKl7R3DsEybrNd4NU9FSwFDyDmdhfv5gJp8UGSFdjAwx43+8zM5t5ruZ25J0LnVb0PuTuRA00UsW83MkLxFpDQLrQV08tlsY6iGrqxP67C3VJ6t4v6oTp7/vaRLhEFc1PhOLh+sZ18o8MLO+e2rGmHGHQnSKfBOLUvDMGa4jb01XBGjdnIXLOkVo79YR5jZn7jJb2gTZ95OD6bWSDADoURSuwuLa7kh4ti1ItAKuhkIvbuky3rRVvQEc92kJ6aNUswIUXJa0K2ibbIY6ycKAA3Ljksl3Mm9KzOn6yc/i/lSF+SOrTGhabPJigKkIoqKIwnV5IU3gkfsxPQJOBMPqHDGAOeYQe3WpWedEPYuhQEczw4exMb9TkNE96F71PzuQPJDl5sPAWyPLeMKpy5XbfRiF2by4nxN3ZIQvjtoyVkjNV+qM0q0yKBzLxuRAEQOZ2yCEaBudZQkQiwHD97H2vu4SRQ/2aOie1XiOnmdbQRDZSO3BsoDK569K1w+gDfSnqY7zVUMj6tw+uKx6Gstck5lbvYMtdWKsfPv/pDM8eyIVFLL93dKTX+ertcQj6xDwLfOiNubE5ayFXhYkjwImV6NgfBuq+3hLK0URP2rPlOZbbZTQ0WlKD6CCRZPMSZCU9oD2zYfqpvRArBUcdkAwGePezORkfJQLE6mYEJp6pdFkJ/IeFLbO6M0lZVlfnpzAC9kjjkMCRofZUETcFSppyTImCbgo3+ok59/PkNU5oavBXyW80ue2tWHr08HX/QALNte3UITmIIlU6SFMCPMWJqadK1eDPWfJ4H4iDXRNn3D5wqN++iMloKvpaj0wieqXLY4+YfvNTNr177OU48GEWW8DnoEkbpwsCbjPxznGDQhdDqdYyMY/fDgRQReKITvKYGHRzesGysw5cKsp9LEfXD0R6WE2TeiiENla5AWzTgXJB0AyZEcOiIfqOgT9Nr9S8q5gc/BdA7P+jhGGJgEHhV3dVlfIZ7pmZc27Yu7UTQ0lbAKWqcMSTOdne+QL6ILzbvLrQwdvax4tQdm5opfU16SrOox1AMwAbkdq84z6uJqYVx3cUXfMJgTyDNrVv3or root@plattenschwein" # for backup "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC1Lx5MKtVjB/Ef6LpEiIAgVwY5xKQFdHuLQR+odQO4cAgxj1QaIXGN0moixY52DebVQhAtiCNiFZ83uJyOj8kmu30yuXwtSOQeqziA859qMJKZ4ZcYdKvbXwnf2Chm5Ck/0FvtpjTWHIZAogwP1wQto/lcqHOjrTAnZeJfQuHTswYUSnmUU5zdsEZ9HidDPUc2Gv0wkBNd+KMQyOZl0HkaxHWvn0h4KK4hYZisOpeTfXJxD87bo+Eg4LL2vvnHW6dF6Ygrbd/0XRMsRRI8OAReVBUoJn7IE1wwAl/FpblNmhaF9hlL7g7hR1ADvaWMMw0e8SSzW6Y+oIa8qFQL6wR1 gitlab-builder" # for being deployed by gitlab ci ]; diff --git a/krebs/2configs/wiki.nix b/krebs/2configs/wiki.nix index 9a18b8dff..40d946f7d 100644 --- a/krebs/2configs/wiki.nix +++ b/krebs/2configs/wiki.nix @@ -29,6 +29,7 @@ in { services.gollum = { enable = true; + address = "::1"; extraConfig = '' Gollum::Hook.register(:post_commit, :hook_id) do |committer, sha1| system('${pushCgit}') @@ -38,16 +39,20 @@ in systemd.services.gollum.environment.LC_ALL = "en_US.UTF-8"; - networking.firewall.allowedTCPPorts = [ 80 ]; + networking.firewall.allowedTCPPorts = [ 80 443 ]; + security.acme.certs."wiki.r".server = config.krebs.ssl.acmeURL; services.nginx = { enable = true; - virtualHosts.wiki = { - serverAliases = [ "wiki.r" "wiki.${config.networking.hostName}.r" ]; - locations."/".extraConfig = '' - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_pass http://127.0.0.1:${toString config.services.gollum.port}; - ''; + virtualHosts."wiki.r" = { + enableACME = true; + addSSL = true; + locations."/" = { + proxyPass = "http://[::1]:${toString config.services.gollum.port}"; + proxyWebsockets = true; + extraConfig = '' + proxy_set_header Host $host; + ''; + }; }; }; diff --git a/krebs/3modules/buildbot/master.nix b/krebs/3modules/buildbot/master.nix deleted file mode 100644 index c30f31e31..000000000 --- a/krebs/3modules/buildbot/master.nix +++ /dev/null @@ -1,382 +0,0 @@ -{ config, pkgs, lib, ... }: - -with import <stockholm/lib>; -let - buildbot-master-config = pkgs.writeText "buildbot-master.cfg" '' - # -*- python -*- - from buildbot.plugins import * - import re - import json - c = BuildmasterConfig = {} - - c['slaves'] = [] - slaves = json.loads('${builtins.toJSON cfg.slaves}') - slavenames = [ s for s in slaves ] - for k,v in slaves.items(): - c['slaves'].append(buildslave.BuildSlave(k, v)) - - # TODO: configure protocols? - c['protocols'] = {'pb': {'port': 9989}} - - ####### Build Inputs - c['change_source'] = cs = [] - - ${ concatStringsSep "\n" - (mapAttrsToList (n: v: '' - #### Change_Source: Begin of ${n} - ${v} - #### Change_Source: End of ${n} - '') cfg.change_source )} - - ####### Build Scheduler - c['schedulers'] = sched = [] - - ${ concatStringsSep "\n" - (mapAttrsToList (n: v: '' - #### Schedulers: Begin of ${n} - ${v} - #### Schedulers: End of ${n} - '') cfg.scheduler )} - - ###### Builder - c['builders'] = bu = [] - - # Builder Pre: Begin - ${cfg.builder_pre} - # Builder Pre: End - - ${ concatStringsSep "\n" - (mapAttrsToList (n: v: '' - #### Builder: Begin of ${n} - ${v} - #### Builder: End of ${n} - '') cfg.builder )} - - - ####### Status - c['status'] = st = [] - - # If you want to configure this url, override with extraConfig - c['buildbotURL'] = "http://${config.networking.hostName}:${toString cfg.web.port}/" - - ${optionalString (cfg.web.enable) '' - from buildbot.status import html - from buildbot.status.web import authz, auth - authz_cfg=authz.Authz( - auth=auth.BasicAuth([ ("${cfg.web.username}","${cfg.web.password}") ]), - # TODO: configure harder - gracefulShutdown = False, - forceBuild = 'auth', - forceAllBuilds = 'auth', - pingBuilder = False, - stopBuild = 'auth', - stopAllBuilds = 'auth', - cancelPendingBuild = 'auth' - ) - # TODO: configure krebs.nginx - st.append(html.WebStatus(http_port=${toString cfg.web.port}, authz=authz_cfg)) - ''} - - ${optionalString (cfg.irc.enable) '' - from buildbot.status import words - irc = words.IRC("${cfg.irc.server}", "${cfg.irc.nick}", - channels=${builtins.toJSON cfg.irc.channels}, - notify_events={ - 'started': 1, - 'success': 1, - 'failure': 1, - 'exception': 1, - 'successToFailure': 1, - 'failureToSuccess': 1, - }${optionalString cfg.irc.allowForce ",allowForce=True"}) - c['status'].append(irc) - ''} - - ${ concatStringsSep "\n" - (mapAttrsToList (n: v: '' - #### Status: Begin of ${n} - ${v} - #### Status: End of ${n} - '') cfg.status )} - - ####### PROJECT IDENTITY - c['title'] = "${cfg.title}" - c['titleURL'] = "http://krebsco.de" - - - ####### DB URL - # TODO: configure - c['db'] = { - 'db_url' : "sqlite:///state.sqlite", - } - ${cfg.extraConfig} - ''; - - cfg = config.krebs.buildbot.master; - - api = { - enable = mkEnableOption "Buildbot Master"; - title = mkOption { - default = "Buildbot CI"; - type = types.str; - description = '' - Title of the Buildbot Installation - ''; - }; - workDir = mkOption { - default = "/var/lib/buildbot/master"; - type = types.str; - description = '' - Path to build bot master directory. - Will be created on startup. - ''; - }; - - secrets = mkOption { - default = []; - type = types.listOf types.str; - example = [ "cac.json" ]; - description = '' - List of all the secrets in ‹secrets› which should be copied into the - buildbot master directory. - ''; - }; - - slaves = mkOption { - default = {}; - type = types.attrsOf types.str; - description = '' - Attrset of slavenames with their passwords - slavename = slavepassword - ''; - }; - - change_source = mkOption { - default = {}; - type = types.attrsOf types.str; - example = { - stockholm = '' - cs.append(changes.GitPoller( - 'http://cgit.gum/stockholm', - workdir='stockholm-poller', branch='master', - project='stockholm', - pollinterval=120)) - ''; - }; - description = '' - Attrset of all the change_sources which should be configured. - It will be directly included into the master configuration. - - At the end an change object should be appended to <literal>cs</literal> - ''; - }; - - scheduler = mkOption { - default = {}; - type = types.attrsOf types.str; - example = { - force-scheduler = '' - sched.append(schedulers.ForceScheduler( - name="force", - builderNames=["full-tests"])) - ''; - }; - description = '' - Attrset of all the schedulers which should be configured. - It will be directly included into the master configuration. - - At the end an change object should be appended to <literal>sched</literal> - ''; - }; - - builder_pre = mkOption { - default = ""; - type = types.lines; - example = '' - grab_repo = steps.Git(repourl=stockholm_repo, mode='incremental') - ''; - description = '' - some code before the builders are being assembled. - can be used to define functions used by multiple builders - ''; - }; - - builder = mkOption { - default = {}; - type = types.attrsOf types.str; - example = { - fast-test = '' - ''; - }; - description = '' - Attrset of all the builder which should be configured. - It will be directly included into the master configuration. - - At the end an change object should be appended to <literal>bu</literal> - ''; - }; - - status = mkOption { - default = {}; - type = types.attrsOf types.str; - description = '' - Attrset of all the extra status which should be configured. - It will be directly included into the master configuration. - - At the end an change object should be appended to <literal>st</literal> - - Right now IRC and Web status can be configured by setting - <literal>buildbot.master.irc.enable</literal> and - <literal>buildbot.master.web.enable</literal> - ''; - }; - - # Configurable Stati - web = mkOption { - default = {}; - type = types.submodule ({ config2, ... }: { - options = { - enable = mkEnableOption "Buildbot Master Web Status"; - username = mkOption { - default = "krebs"; - type = types.str; - description = '' - username for web authentication - ''; - }; - hostname = mkOption { - default = config.networking.hostName; - type = types.str; - description = '' - web interface Hostname - ''; - }; - password = mkOption { - default = "bob"; - type = types.str; - description = '' - password for web authentication - ''; - }; - port = mkOption { - default = 8010; - type = types.int; - description = '' - port for buildbot web status - ''; - }; - }; - }); - }; - - irc = mkOption { - default = {}; - type = types.submodule ({ config, ... }: { - options = { - enable = mkEnableOption "Buildbot Master IRC Status"; - channels = mkOption { - default = [ "nix-buildbot-meetup" ]; - type = with types; listOf str; - description = '' - irc channels the bot should connect to - ''; - }; - allowForce = mkOption { - default = false; - type = types.bool; - description = '' - Determines if builds can be forced via IRC - ''; - }; - nick = mkOption { - default = "nix-buildbot"; - type = types.str; - description = '' - nickname for IRC - ''; - }; - server = mkOption { - default = "irc.freenode.net"; - type = types.str; - description = '' - Buildbot Status IRC Server to connect to - ''; - }; - }; - }); - }; - - extraConfig = mkOption { - default = ""; - type = types.lines; - description = '' - extra config appended to the generated master.cfg - ''; - }; - }; - - imp = { - - users.extraUsers.buildbotMaster = { - uid = genid "buildbotMaster"; - group = "buildbotMaster"; - description = "Buildbot Master"; - home = cfg.workDir; - createHome = false; - isSystemUser = true; - }; - - users.extraGroups.buildbotMaster = { - gid = 672626386; - }; - - systemd.services.buildbotMaster = { - description = "Buildbot Master"; - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; - # TODO: add extra dependencies to master like svn and cvs - path = [ pkgs.git ]; - environment = { - SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; - }; - serviceConfig = let - workdir = shell.escape cfg.workDir; - secretsdir = shell.escape (toString <secrets>); - in { - PermissionsStartOnly = true; - # TODO: maybe also prepare buildbot.tac? - ExecStartPre = pkgs.writeDash "buildbot-master-init" '' - set -efux - if [ ! -e ${workdir} ];then - mkdir -p ${workdir} - ${pkgs.buildbot-classic}/bin/buildbot create-master -r -l 10 -f ${workdir} - fi - # always override the master.cfg - cp ${buildbot-master-config} ${workdir}/master.cfg - - # copy secrets - ${ concatMapStringsSep "\n" - (f: "cp ${secretsdir}/${f} ${workdir}/${f}" ) cfg.secrets } - # sanity - ${pkgs.buildbot-classic}/bin/buildbot checkconfig ${workdir} - - # TODO: maybe upgrade? not sure about this - # normally we should write buildbot.tac by our own - # ${pkgs.buildbot-classic}/bin/buildbot upgrade-master ${workdir} - - chmod 700 ${workdir} - chown buildbotMaster:buildbotMaster -R ${workdir} - ''; - ExecStart = "${pkgs.buildbot-classic}/bin/buildbot start --nodaemon ${workdir}"; - PrivateTmp = "true"; - User = "buildbotMaster"; - Restart = "always"; - RestartSec = "10"; - }; - }; - }; -in -{ - options.krebs.buildbot.master = api; - config = lib.mkIf cfg.enable imp; -} diff --git a/krebs/3modules/buildbot/slave.nix b/krebs/3modules/buildbot/slave.nix deleted file mode 100644 index f97b50def..000000000 --- a/krebs/3modules/buildbot/slave.nix +++ /dev/null @@ -1,186 +0,0 @@ -{ config, pkgs, lib, ... }: - -with import <stockholm/lib>; -let - buildbot-slave-init = pkgs.writeText "buildbot-slave.tac" '' - import os - - from buildslave.bot import BuildSlave - from twisted.application import service - - basedir = '${cfg.workDir}' - rotateLength = 10000000 - maxRotatedFiles = 10 - - application = service.Application('buildslave') - - from twisted.python.logfile import LogFile - from twisted.python.log import ILogObserver, FileLogObserver - logfile = LogFile.fromFullPath(os.path.join(basedir, "twistd.log"), rotateLength=rotateLength, - maxRotatedFiles=maxRotatedFiles) - application.setComponent(ILogObserver, FileLogObserver(logfile).emit) - - buildmaster_host = '${cfg.masterhost}' - # TODO: masterport? - port = 9989 - slavename = '${cfg.username}' - passwd = '${cfg.password}' - keepalive = 600 - usepty = 0 - umask = None - maxdelay = 300 - allow_shutdown = None - - ${cfg.extraConfig} - - s = BuildSlave(buildmaster_host, port, slavename, passwd, basedir, - keepalive, usepty, umask=umask, maxdelay=maxdelay, - allow_shutdown=allow_shutdown) - s.setServiceParent(application) - ''; - default-packages = [ pkgs.git pkgs.bash ]; - cfg = config.krebs.buildbot.slave; - - api = { - enable = mkEnableOption "Buildbot Slave"; - - workDir = mkOption { - default = "/var/lib/buildbot/slave"; - type = types.str; - description = '' - Path to build bot slave directory. - Will be created on startup. - ''; - }; - - masterhost = mkOption { - default = "localhost"; - type = types.str; - description = '' - Hostname/IP of the buildbot master - ''; - }; - - username = mkOption { - type = types.str; - description = '' - slavename used to authenticate with master - ''; - }; - - password = mkOption { - type = types.str; - description = '' - slave password used to authenticate with master - ''; - }; - - contact = mkOption { - default = "nix slave <buildslave@${config.networking.hostName}>"; - type = types.str; - description = '' - contact to be announced by buildslave - ''; - }; - - description = mkOption { - default = "Nix Generated BuildSlave"; - type = types.str; - description = '' - description for hostto be announced by buildslave - ''; - }; - - packages = mkOption { - default = [ pkgs.git ]; - type = with types; listOf package; - description = '' - packages which should be in path for buildslave - ''; - }; - - extraEnviron = mkOption { - default = {}; - example = { - NIX_PATH = "nixpkgs=/path/to/my/nixpkgs"; - }; - type = types.attrsOf types.str; - description = '' - extra environment variables to be provided to the buildslave service - if you need nixpkgs, e.g. for running nix-shell you can set NIX_PATH here. - ''; - }; - - extraConfig = mkOption { - default = ""; - type = types.lines; - example = '' - port = 443 - keepalive = 600 - ''; - description = '' - extra config evaluated before calling BuildSlave init in .tac file - ''; - }; - }; - - imp = { - - users.extraUsers.buildbotSlave = { - uid = genid "buildbotSlave"; - group = "buildbotSlave"; - description = "Buildbot Slave"; - home = cfg.workDir; - createHome = false; - isSystemUser = true; - }; - - users.extraGroups.buildbotSlave = { - gid = 1408105834; - }; - - systemd.services."buildbotSlave-${cfg.username}-${cfg.masterhost}" = { - description = "Buildbot Slave for ${cfg.username}@${cfg.masterhost}"; - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; - path = default-packages ++ cfg.packages; - - environment = { - SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; - NIX_REMOTE="daemon"; - } // cfg.extraEnviron; - - serviceConfig = let - workdir = shell.escape cfg.workDir; - contact = shell.escape cfg.contact; - description = shell.escape cfg.description; - # TODO:make this - in { - PermissionsStartOnly = true; - Type = "forking"; - PIDFile = "${workdir}/twistd.pid"; - # TODO: maybe also prepare buildbot.tac? - ExecStar |