From dc190c7635d187d3ad1276fb9f9e0b47eddcd914 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Sun, 10 Sep 2023 08:53:04 +0000 Subject: [PATCH] improve master module --- buildbot_nix/master.py | 5 +- nix/master.nix | 217 +++++++++++++++++++++++++---------------- 2 files changed, 135 insertions(+), 87 deletions(-) diff --git a/buildbot_nix/master.py b/buildbot_nix/master.py index ecd6b20..926ebb2 100644 --- a/buildbot_nix/master.py +++ b/buildbot_nix/master.py @@ -33,6 +33,7 @@ def read_secret_file(secret_name: str) -> str: GITHUB_OAUTH_ID = os.environ.get("GITHUB_OAUTH_ID") GITHUB_OAUTH_SECRET = read_secret_file("github-oauth-secret") +GITHUB_ADMINS = os.environ.get("GITHUB_ADMINS", "").split(" ") GITHUB_TOKEN_SECRET_NAME = "github-token" GITHUB_TOKEN = read_secret_file(GITHUB_TOKEN_SECRET_NAME) GITHUB_WEBHOOK_SECRET = read_secret_file("github-webhook-secret") @@ -199,15 +200,13 @@ def build_config() -> dict[str, Any]: systemd_secrets = secrets.SecretInAFile(dirname=credentials) c["secretsProviders"] = [systemd_secrets] - github_admins = os.environ.get("GITHUB_ADMINS", "").split(",") - c["www"] = { "avatar_methods": [util.AvatarGitHub()], "port": int(os.environ.get("PORT", "1810")), "auth": util.GitHubAuth(GITHUB_OAUTH_ID, GITHUB_OAUTH_SECRET), "authz": util.Authz( roleMatchers=[ - util.RolesFromUsername(roles=["admin"], usernames=github_admins) + util.RolesFromUsername(roles=["admin"], usernames=GITHUB_ADMINS) ], allowRules=[ util.AnyEndpointMatcher(role="admin", defaultDeny=False), diff --git a/nix/master.nix b/nix/master.nix index 7e83c50..969aab2 100644 --- a/nix/master.nix +++ b/nix/master.nix @@ -1,98 +1,147 @@ { config , pkgs +, lib , ... }: let - # TODO: make this an option - # https://github.com/organizations/numtide/settings/applications - # Application name: BuildBot - # Homepage URL: https://buildbot.numtide.com - # Authorization callback URL: https://buildbot.numtide.com/auth/login - # oauth_token: 2516248ec6289e4d9818122cce0cbde39e4b788d - buildbotDomain = "buildbot.thalheim.io"; - githubOauthId = "d1b24258af1abc157934"; + cfg = config.services.buildbot-nix.master; in { - services.buildbot-master = { - enable = true; - masterCfg = "${./.}/master.py"; - dbUrl = "postgresql://@/buildbot"; - pythonPackages = ps: [ - ps.requests - ps.treq - ps.psycopg2 - (ps.toPythonModule pkgs.buildbot-worker) - pkgs.buildbot-plugins.www - pkgs.buildbot-plugins.www-react - ]; - }; - - systemd.services.buildbot-master = { - environment = { - PORT = "1810"; - DB_URL = config.services.buildbot-master.dbUrl; - # Github app used for the login button - GITHUB_OAUTH_ID = githubOauthId; - - # XXX replace this with renovate - REPO_FOR_FLAKE_UPDATE = "Mic92/dotfiles/main"; - - BUILDBOT_URL = "https://${buildbotDomain}/"; - BUILDBOT_GITHUB_USER = "mic92-buildbot"; - # comma seperated list of users that are allowed to login to buildbot and do stuff - GITHUB_ADMINS = "Mic92"; - NIX_SUPPORTED_SYSTEMS = builtins.toString [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; - NIX_EVAL_MAX_MEMORY_SIZE = "2048"; + options = { + services.buildbot-nix.master = { + port = lib.mkOption { + type = lib.types.int; + default = 1810; + description = "Port on which buildbot-master is listening"; + }; + dbUrl = lib.mkOption { + type = lib.types.str; + default = "postgresql://@/buildbot"; + description = "Postgresql database url"; + }; + github = { + tokenFile = lib.mkOption { + type = lib.types.path; + description = "Github token file"; + }; + webhookSecretFile = lib.mkOption { + type = lib.types.path; + description = "Github webhook secret file"; + }; + oauthSecretFile = lib.mkOption { + type = lib.types.path; + description = "Github oauth secret file"; + }; + # TODO: make this an option + # https://github.com/organizations/numtide/settings/applications + # Application name: BuildBot + # Homepage URL: https://buildbot.numtide.com + # Authorization callback URL: https://buildbot.numtide.com/auth/login + # oauth_token: 2516248ec6289e4d9818122cce0cbde39e4b788d + oauthId = lib.mkOption { + type = lib.types.str; + description = "Github oauth id. Used for the login button"; + }; + # Most likely you want to use the same user as for the buildbot + githubUser = lib.mkOption { + type = lib.types.str; + description = "Github user that is used for the buildbot"; + }; + githubAdmins = lib.mkOption { + type = lib.types.listOf lib.types.str; + description = "Users that are allowed to login to buildbot and do stuff"; + }; + }; + workersFile = lib.mkOption { + type = lib.types.path; + description = "File containing a list of nix workers"; + }; + buildSystems = lib.mkOption { + type = lib.types.listOf lib.types.str; + description = "Systems that we will be build"; + }; + evalMaxMemorySize = lib.mkOption { + type = lib.types.str; + description = '' + Maximum memory size for nix-eval-jobs (in MiB) per + worker. After the limit is reached, the worker is + restarted. + ''; + }; + url = lib.mkOption { + type = lib.types.str; + description = "Buildbot url"; + }; }; - serviceConfig = { - # in master.py we read secrets from $CREDENTIALS_DIRECTORY - LoadCredential = [ - "github-token:${config.sops.secrets.buildbot-github-token.path}" - "github-webhook-secret:${config.sops.secrets.buildbot-github-webhook-secret.path}" - "github-oauth-secret:${config.sops.secrets.buildbot-github-oauth-secret.path}" - "buildbot-nix-workers:${config.sops.secrets.buildbot-nix-workers.path}" + }; + config = { + services.buildbot-master = { + enable = true; + masterCfg = "${../buildbot_nix/master.py}"; + dbUrl = config.services.buildbot-nix.master.dbUrl; + pythonPackages = ps: [ + ps.requests + ps.treq + ps.psycopg2 + (ps.toPythonModule pkgs.buildbot-worker) + pkgs.buildbot-plugins.www + pkgs.buildbot-plugins.www-react ]; }; - }; - sops.secrets = { - buildbot-github-token = { }; - buildbot-github-webhook-secret = { }; - buildbot-github-oauth-secret = { }; - buildbot-nix-workers = { }; - }; - services.postgresql = { - ensureDatabases = [ "buildbot" ]; - ensureUsers = [ - { - name = "buildbot"; - ensurePermissions."DATABASE buildbot" = "ALL PRIVILEGES"; - } + systemd.services.buildbot-master = { + environment = { + PORT = builtins.toString cfg.port; + DB_URL = cfg.dbUrl; + GITHUB_OAUTH_ID = cfg.github.oauthId; + BUILDBOT_URL = cfg.url; + BUILDBOT_GITHUB_USER = cfg.github.githubUser; + GITHUB_ADMINS = builtins.toString cfg.github.githubAdmins; + NIX_SUPPORTED_SYSTEMS = builtins.toString cfg.buildSystems; + NIX_EVAL_MAX_MEMORY_SIZE = builtins.toString cfg.evalMaxMemorySize; + }; + serviceConfig = { + # in master.py we read secrets from $CREDENTIALS_DIRECTORY + LoadCredential = [ + "github-token:${cfg.github.tokenFile}" + "github-webhook-secret:${cfg.github.webhookSecretFile}" + "github-oauth-secret:${cfg.github.oauthSecretFile}" + "buildbot-nix-workers:${cfg.workersFile}" + ]; + }; + }; + + services.postgresql = { + ensureDatabases = [ "buildbot" ]; + ensureUsers = [ + { + name = "buildbot"; + ensurePermissions."DATABASE buildbot" = "ALL PRIVILEGES"; + } + ]; + }; + + services.nginx.virtualHosts.${cfg.url} = { + locations."/".proxyPass = "http://127.0.0.1:${cfg.port}/"; + locations."/sse" = { + proxyPass = "http://127.0.0.1:${cfg.port}/sse"; + # proxy buffering will prevent sse to work + extraConfig = "proxy_buffering off;"; + }; + locations."/ws" = { + proxyPass = "http://127.0.0.1:${cfg.port}/ws"; + proxyWebsockets = true; + # raise the proxy timeout for the websocket + extraConfig = "proxy_read_timeout 6000s;"; + }; + + # In this directory we store the lastest build store paths for nix attributes + locations."/nix-outputs".root = "/var/www/buildbot/"; + }; + + # Allow buildbot-master to write to this directory + systemd.tmpfiles.rules = [ + "d /var/www/buildbot/nix-outputs 0755 buildbot buildbot - -" ]; }; - - services.nginx.virtualHosts.${buildbotDomain} = { - forceSSL = true; - useACMEHost = "thalheim.io"; - locations."/".proxyPass = "http://127.0.0.1:1810/"; - locations."/sse" = { - proxyPass = "http://127.0.0.1:1810/sse/"; - # proxy buffering will prevent sse to work - extraConfig = "proxy_buffering off;"; - }; - locations."/ws" = { - proxyPass = "http://127.0.0.1:1810/ws"; - proxyWebsockets = true; - # raise the proxy timeout for the websocket - extraConfig = "proxy_read_timeout 6000s;"; - }; - - # In this directory we store the lastest build store paths for nix attributes - locations."/nix-outputs".root = "/var/www/buildbot/"; - }; - - # Allow buildbot-master to write to this directory - systemd.tmpfiles.rules = [ - "d /var/www/buildbot/nix-outputs 0755 buildbot buildbot - -" - ]; }