about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--docs/gerrit.org79
-rw-r--r--hosts/tahoe/secrets/buildkite/agent.agebin450 -> 0 bytes
-rw-r--r--hosts/tahoe/secrets/buildkite/graphql.age9
-rw-r--r--hosts/tahoe/secrets/gerrit/hooks.age13
-rw-r--r--hosts/tahoe/secrets/gerrit/secure-config.agebin717 -> 0 bytes
-rw-r--r--hosts/tahoe/secrets/secrets.nix30
-rw-r--r--modules/services/buildkite/default.nix63
-rw-r--r--modules/services/cgit/default.nix131
-rw-r--r--modules/services/default.nix3
-rw-r--r--modules/services/gerrit/default.nix151
-rw-r--r--ops/buildkite/.gitignore3
-rw-r--r--ops/buildkite/README.org7
-rw-r--r--ops/buildkite/buildkite.tf51
-rw-r--r--ops/buildkite/default.nix23
-rw-r--r--ops/buildkite/steps.yml6
-rw-r--r--ops/ci/README.org3
-rw-r--r--ops/ci/pipeline.yml25
-rw-r--r--ops/default.nix1
-rw-r--r--tools/default.nix1
-rw-r--r--tools/gerrit-hook/README.org12
-rw-r--r--tools/gerrit-hook/buildkite.go139
-rw-r--r--tools/gerrit-hook/default.nix16
-rw-r--r--tools/gerrit-hook/gerrit.go149
-rw-r--r--tools/gerrit-hook/go.mod3
-rw-r--r--tools/gerrit-hook/main.go68
25 files changed, 0 insertions, 986 deletions
diff --git a/docs/gerrit.org b/docs/gerrit.org
deleted file mode 100644
index 28ab95f..0000000
--- a/docs/gerrit.org
+++ /dev/null
@@ -1,79 +0,0 @@
-#+TITLE: Configuration of gerrit
-
-A gerrit instance is running at [[https://cl.fcuny.net][cl.fcuny.net]].
-
-* Permissions
-- branches other than main can be pushed to the server
-- the main branch can only be modified by gerrit
-* Secure configuration
-The file =/var/lib/gerrit/etc/secure.config= is managed by nix and is encrypted with age. The file contains the following settings:
-#+begin_src ini
-[auth]
-  registerEmailPrivateKey = <redacted>
-[sendemail]
-  smtpUser = <fastmail user>
-  smtpPass = <fastmail SMTP password>
-[plugin "gerrit-oauth-provider-google-oauth"]
-  client-secret = <google oauth secret>
-#+end_src
-
-From the directory =hosts/tahoe/secrets= you can run =nix run github:ryantm/agenix -- -e gerrit/secure-config.age= to edit the secrets.
-* Notes
-The [[https://gerrit.googlesource.com/plugins/reviewnotes/][review notes]] plugin is enabled. The plugin stores into the notes the information about the reviews.
-
-When cloning the repo, run the following:
-#+begin_src sh
-git config --add remote.origin.fetch refs/notes/review:refs/notes/review
-git fetch
-#+end_src
-
-Then running =git log --show-notes=review= will show these notes.
-
-More information can be found at [[https://cl.fcuny.net/plugins/reviewnotes/Documentation/refs-notes-review.md][this URL]].
-* Repositories configuration
-Gerrit stores information about repositories in a git repository. To get the configuration, run:
-#+begin_src sh
-git clone "https://fcuny@cl.fcuny.net/a/All-Projects" && (cd "All-Projects" && mkdir -p .git/hooks && cu
-https://fcuny@cl.fcuny.net/tools/hooks/commit-msg; chmod +x `git rev-parse --git-dir`/hooks/commit-msg)
-cd All-Projects
-git fetch origin refs/meta/config:refs/remotes/origin/meta/config
-git checkout meta/config
-#+end_src
-
-Then the file =project.config= can be edited.
-* Labels
-** Verified
-The label verified is typically used for CI. Relevant diffs to add the label:
-#+begin_src diff
-diff --git a/project.config b/project.config
-index eb13426..9d504c7 100644
---- a/project.config
-+++ b/project.config
-@@ -63,6 +63,11 @@
-        value = 0 No score
-        value = +1 Looks good to me, but someone else must approve
-        value = +2 Looks good to me, approved
-+[label "Verified"]
-+       function = MaxWithBlock
-+       value = -1 Fails
-+       value =  0 No score
-+       value = +1 Verified
- [capability]
-        administrateServer = group Administrators
-        priority = batch group Service Users
-#+end_src
-
-#+begin_src diff
-diff --git a/project.config b/project.config
-index 9d504c7..5f9352d 100644
---- a/project.config
-+++ b/project.config
-@@ -26,6 +26,7 @@
-        label-Code-Review = -2..+2 group Administrators
-        label-Code-Review = -2..+2 group Project Owners
-        label-Code-Review = -1..+1 group Registered Users
-+        label-Verified = -1..+1 group Service Users
-        push = group Administrators
-        push = group Project Owners
-        read = group Anonymous Users
-#+end_src
diff --git a/hosts/tahoe/secrets/buildkite/agent.age b/hosts/tahoe/secrets/buildkite/agent.age
deleted file mode 100644
index 5f2f551..0000000
--- a/hosts/tahoe/secrets/buildkite/agent.age
+++ /dev/null
Binary files differdiff --git a/hosts/tahoe/secrets/buildkite/graphql.age b/hosts/tahoe/secrets/buildkite/graphql.age
deleted file mode 100644
index b2b355f..0000000
--- a/hosts/tahoe/secrets/buildkite/graphql.age
+++ /dev/null
@@ -1,9 +0,0 @@
-age-encryption.org/v1
--> ssh-ed25519 dtgBNg 9wM6u3f8tfdhUSmWKZy2aW15Q9NLEt+Q+2r9Zp3c2B8
-rnuasAgCi0UJW28Pjb9BqkwNk0WuHThwvCTNd+tFGkU
--> ssh-ed25519 wtownA Xw4G1YaRMwJ1bwNmjHwFyo6vcI5P8fPg+LKcn29jgVw
-1EQrgeDwGjzPpy7oEdnSteyib03CUksd1zGMeZ5DK9o
--> 5zXn-grease %CU]+%WC
-gboFw7YNFbVbmAcwdg
---- wcsDAcM1XS+GqGZuaVyK/DmzlInUAXrhflWbfqOFyfk
-;M1|0aҬ+u]?JJQV*Zxӣ.
T_hܲ
\ No newline at end of file
diff --git a/hosts/tahoe/secrets/gerrit/hooks.age b/hosts/tahoe/secrets/gerrit/hooks.age
deleted file mode 100644
index f4d258c..0000000
--- a/hosts/tahoe/secrets/gerrit/hooks.age
+++ /dev/null
@@ -1,13 +0,0 @@
-age-encryption.org/v1
--> ssh-ed25519 dtgBNg B3koVcKCOfBNaM7JXTlT51CMtFEwLSaKT6YCsSlv2Ss
-6HXVu2wgeH/sD4DglvfImV4bu7RRG0pV6vt5d59n4k0
--> ssh-ed25519 wtownA FXfgex5qjGhm6OVvsuCekeKFqwfvZvq1Ib2uJOkvQDw
-TC/SA31VaQWxHt29flbLhUqNMrmF4IVUex46BxqXqmo
--> )l%.-grease h)/EOR@ yI=$sZN I!{z
-F0/wLuqmuTl4V6DHniGs7E6+RQLPlo0QsdkqfneLgckOHCFJXnGUJBPmNBE0Bk+t
-wwqXE0o0XpVmpNeaCY7KVNkC/vIhoqYbNU5jL6Hj9BU
---- wIBxjXQeKIxVy1spYCpsAZNQPYMRIhlhQXbCCs+8IBI
-d=cgL-
-gRy1K5ars%!c.-E-4}i*;jU5+
l-={4R.hJ'*;?ZtOќmH
-1j1Lm*`
BPn ȇO ʺ:4%qG`IG/*!$B?u3?RrKW=R,.;Ln<xrp^_
-
\ No newline at end of file
diff --git a/hosts/tahoe/secrets/gerrit/secure-config.age b/hosts/tahoe/secrets/gerrit/secure-config.age
deleted file mode 100644
index 45d0c42..0000000
--- a/hosts/tahoe/secrets/gerrit/secure-config.age
+++ /dev/null
Binary files differdiff --git a/hosts/tahoe/secrets/secrets.nix b/hosts/tahoe/secrets/secrets.nix
index 7b9500f..fb55bd8 100644
--- a/hosts/tahoe/secrets/secrets.nix
+++ b/hosts/tahoe/secrets/secrets.nix
@@ -14,41 +14,11 @@ in
     owner = "acme";
   };
 
-  # see https://buildkite.com/docs/agent/v3/tokens
-  "buildkite/agent.age" = {
-    publicKeys = all;
-    owner = "buildkite-agent-builder-1";
-    group = "buildkite-agents";
-    mode = "0440";
-  };
-
   "drone/secrets.age" = {
     publicKeys = all;
     owner = "drone";
   };
 
-  "buildkite/graphql.age" = {
-    publicKeys = all;
-    owner = "buildkite-agent-builder-1";
-    group = "buildkite-agents";
-    mode = "0440";
-  };
-
-  # the owner is gerrit, but we also want the builders to access this
-  # configuration.
-  "gerrit/hooks.age" = {
-    publicKeys = all;
-    owner = "git";
-    group = "buildkite-agents";
-    mode = "0440";
-  };
-
-  "gerrit/secure-config.age" = {
-    publicKeys = all;
-    owner = "git";
-    path = "/var/lib/gerrit/etc/secure.config";
-  };
-
   "syncthing/key.age" = {
     publicKeys = all;
     owner = "fcuny";
diff --git a/modules/services/buildkite/default.nix b/modules/services/buildkite/default.nix
deleted file mode 100644
index 90253bf..0000000
--- a/modules/services/buildkite/default.nix
+++ /dev/null
@@ -1,63 +0,0 @@
-{ config, pkgs, lib, ... }:
-let
-  cfg = config.my.services.buildkite;
-  agents = lib.range 1 5;
-  secrets = config.age.secrets;
-
-  my-gerrit-hook = name:
-    pkgs.writeShellScript "gerrit-buildkite-hook" ''
-      exec -a ${name} ${pkgs.tools.gerrit-hook}/bin/gerrit-hook "$@"
-    '';
-
-  buildkiteHooks = pkgs.runCommandNoCC "buildkite-hooks" { } ''
-    mkdir -p $out/bin
-    ln -s ${my-gerrit-hook "post-command"} $out/bin/post-command
-  '';
-
-in
-{
-  options.my.services.buildkite = with lib; {
-    enable = mkEnableOption "buildkite agent";
-  };
-
-  config = lib.mkIf cfg.enable {
-    # see https://buildkite.com/docs/agent/v3
-    # and https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/continuous-integration/buildkite-agents.nix
-    services.buildkite-agents = lib.listToAttrs (map
-      (n: rec {
-        name = "builder-${toString n}";
-        value = {
-          inherit name;
-          enable = true;
-          tokenPath = secrets."buildkite/agent".path;
-          hooks.post-command = "${buildkiteHooks}/bin/post-command";
-          runtimePackages = with pkgs; [
-            bash
-            coreutils
-            curl
-            git
-            gnutar
-            gzip
-            jq
-            nix
-          ];
-        };
-      })
-      agents);
-
-    # Set up a group for all Buildkite agent users
-    users = {
-      groups.buildkite-agents = { };
-      users = builtins.listToAttrs (map
-        (n: rec {
-          name = "buildkite-agent-builder-${toString n}";
-          value = {
-            isSystemUser = true;
-            group = lib.mkForce "buildkite-agents";
-            extraGroups = [ name "docker" ];
-          };
-        })
-        agents);
-    };
-  };
-}
diff --git a/modules/services/cgit/default.nix b/modules/services/cgit/default.nix
deleted file mode 100644
index 2c4802f..0000000
--- a/modules/services/cgit/default.nix
+++ /dev/null
@@ -1,131 +0,0 @@
-{ config, pkgs, lib, ... }:
-let
-  cfg = config.my.services.cgit;
-  # there's no need for web crawlers on that site
-  robots-deny = pkgs.writeText "robots.txt" ''
-    User-agent: *
-    Disallow: /
-  '';
-  cgitrc = ''
-    # Global configuration
-    virtual-root=/
-
-    # clone will be handled by gerrit
-    enable-http-clone=0
-    clone-url=https://cl.fcuny.net/$CGIT_REPO_URL
-
-    # I've fewer than 150 repos, all should be able to be listed on
-    # the main page
-    max-repo-count=150
-
-    # limit to year for the stats
-    max-stats=year
-
-    snapshots=tar.gz
-
-    source-filter=${pkgs.cgit}/lib/cgit/filters/syntax-highlighting.py
-    about-filter=${pkgs.cgit}/lib/cgit/filters/about-formatting.sh
-
-    enable-git-config=1
-    enable-index-owner=0
-
-    remove-suffix=1
-
-    # sort repositories by section and branches by date
-    repository-sort=age
-    branch-sort=age
-
-    readme=:README.md
-    readme=:README.org
-    readme=:readme.org
-
-    # print the number of modified files
-    enable-log-filecount=1
-    # print the number of modified lines
-    enable-log-linecount=1
-    enable-follow-links=1
-    enable-blame=1
-
-    root-title="Franck git repositories"
-    root-desc="source code of my various projects"
-
-    # don't index or follow
-    robots="noindex, nofollow"
-
-    project-list=/var/lib/cgit/cache/projects.list
-    scan-path=/var/lib/gerrit/git
-  '';
-in
-{
-  options.my.services.cgit = with lib; {
-    enable = mkEnableOption "git web viewer";
-  };
-
-  config = lib.mkIf cfg.enable {
-    services.fcgiwrap = {
-      enable = true;
-      user = "git";
-      group = "git";
-    };
-
-    systemd = {
-      timers.sync-cgit-repo = {
-        description = "synchronize the list of repositories from gerrit";
-        wantedBy = [ "timers.target" ];
-        partOf = [ "sync-cgit-repo.service" ];
-        timerConfig.OnCalendar = "*:0/10";
-      };
-      services.sync-cgit-repo = {
-        description = "synchronize the list of repositories from gerrit";
-        serviceConfig.Type = "oneshot";
-        script = ''
-          mkdir -p /var/lib/cgit/cache
-          tmplist=$(mktemp)
-
-          # as per https://gerrit-review.googlesource.com/Documentation/rest-api.html#output we need to remove `)]}' from the response
-          repos=$(${pkgs.curl}/bin/curl -s -H "Content-Type: application/json" "https://cl.fcuny.net/projects/?state=ACTIVE"|sed "s/^)]}'//"|${pkgs.jq}/bin/jq -r 'to_entries | .[] | .value | .id')
-
-          # list of repositories that I still want to be active in gerrit but I don't want to list here
-          exclude_repos="password-store|All-Projects|All-Users|homelab"
-
-          for repo in ''${repos}; do
-            if [[ ! $exclude_repos =~ $repo ]]; then
-              echo "''${repo}.git" >> $tmplist
-            fi
-          done
-          mv $tmplist /var/lib/cgit/cache/projects.list
-          # TODO(fcuny): this should run as the git user
-          chown git:git /var/lib/cgit/cache/projects.list
-        '';
-      };
-    };
-
-    services.nginx.virtualHosts."git.fcuny.net" = {
-      # make cgit the default site: if a request goes through nginx
-      # without a host header, this will be the default site we serve
-      # for that request.
-      default = true;
-      forceSSL = true;
-      enableACME = true;
-      locations = {
-        "~* ^.+.(css|png|ico)$" = { root = "${pkgs.cgit}/cgit"; };
-        # as per https://github.com/yandex/gixy/blob/master/docs/en/plugins/aliastraversal.md
-        # if you want to map a single file make sure the location starts with a =, e.g =/i.gif instead of /i.gif.
-        "=/robots.txt".alias = robots-deny;
-        "/".extraConfig = ''
-          include ${pkgs.nginx}/conf/fastcgi_params;
-          fastcgi_param CGIT_CONFIG ${pkgs.writeText "cgitrc" cgitrc};
-          fastcgi_param SCRIPT_FILENAME ${pkgs.cgit}/cgit/cgit.cgi;
-          fastcgi_split_path_info ^(/?)(.+)$;
-          fastcgi_param PATH_INFO $fastcgi_path_info;
-          fastcgi_param HTTP_HOST $server_name;
-          fastcgi_param QUERY_STRING $args;
-          fastcgi_pass unix:${config.services.fcgiwrap.socketAddress};
-          if ($http_user_agent ~* "(Blackbox Exporter)" ) {
-            access_log off;
-          }
-        '';
-      };
-    };
-  };
-}
diff --git a/modules/services/default.nix b/modules/services/default.nix
index 73e2e6d..538e564 100644
--- a/modules/services/default.nix
+++ b/modules/services/default.nix
@@ -4,11 +4,8 @@
   imports = [
     ./avahi
     ./backup
-    ./buildkite
-    ./cgit
     ./drone
     ./fwupd
-    ./gerrit
     ./gitea
     ./gnome
     ./grafana
diff --git a/modules/services/gerrit/default.nix b/modules/services/gerrit/default.nix
deleted file mode 100644
index 1592839..0000000
--- a/modules/services/gerrit/default.nix
+++ /dev/null
@@ -1,151 +0,0 @@
-{ config, pkgs, lib, ... }:
-let
-  cfg = config.my.services.gerrit;
-  secrets = config.age.secrets;
-
-  my-gerrit-hook = name:
-    pkgs.writeShellScript "my-gerrit-hook" ''
-      exec -a ${name} ${pkgs.tools.gerrit-hook}/bin/gerrit-hook "$@"
-    '';
-
-  gerritHooks = pkgs.runCommandNoCC "gerrit-hooks" { } ''
-    mkdir -p $out
-    ln -s ${my-gerrit-hook "patchset-created"} $out/patchset-created
-  '';
-
-  oauth = pkgs.fetchurl {
-    url =
-      "https://github.com/davido/gerrit-oauth-provider/releases/download/v3.5.1/gerrit-oauth-provider.jar";
-    sha256 = "312dc494c454ac15f89a289f95ea4c11344add26804aaa6a3b79d49fd92adc69";
-  };
-in
-{
-  options.my.services.gerrit = with lib; {
-    enable = mkEnableOption "gerrit git server";
-    vhostName = mkOption {
-      type = types.str;
-      example = "cl.fcuny.net";
-      description = "Name for the virtual host";
-    };
-  };
-
-  config = lib.mkIf cfg.enable {
-    users.users.git = {
-      description = "git";
-      home = "/var/lib/gerrit";
-      useDefaultShell = true;
-      group = "git";
-      isSystemUser = true;
-    };
-    users.groups.git = { };
-
-    services.gerrit = {
-      enable = true;
-      listenAddress = "[::]:4778";
-      serverId = "36bc0ffe-8f33-4045-bf8b-de5f88815fc0";
-      builtinPlugins = [
-        # commands to download changes
-        "download-commands"
-        # to run custom hooks
-        "hooks"
-        # stores review information for Gerrit changes in the
-        # refs/notes/review branch.
-        "reviewnotes"
-        # delete projects via the command line
-        "delete-project"
-      ];
-      jvmHeapLimit = "4g";
-
-      plugins = [ oauth ];
-
-      # The default JDK is incompatible with gerrit.
-      jvmPackage = pkgs.openjdk11_headless;
-
-      settings = {
-        core.packedGitLimit = "100m";
-        log.jsonLogging = true;
-        log.textLogging = false;
-        sshd.advertisedAddress = "git.fcuny.net:29418";
-        hooks.path = "${gerritHooks}";
-        cache.web_sessions.maxAge = "3 months";
-        plugins.allowRemoteAdmin = false;
-        change.enableAttentionSet = true;
-        change.enableAssignee = false;
-
-        gerrit = {
-          canonicalWebUrl = "https://${cfg.vhostName}";
-          docUrl = "/Documentation";
-        };
-
-        httpd.listenUrl = "proxy-https://localhost:4778";
-
-        download.command = [ "checkout" "cherry_pick" "format_patch" "pull" ];
-
-        # Configure for cgit.
-        gitweb = {
-          type = "custom";
-          url = "https://git.fcuny.net";
-          project = "/\${project}";
-          revision = "/commit/?id=\${commit}";
-          branch = "/log/?h=\${branch}";
-          tag = "/tag/?h=\${tag}";
-          roottree = "/tree/?h=\${commit}";
-          file = "/tree/\${file}?h=\${commit}";
-          filehistory = "/log/\${file}?h=\${branch}";
-          linkname = "cgit";
-        };
-
-        auth.type = "OAUTH";
-
-        # users can change their emails
-        oauth.allowRegisterNewEmail = true;
-
-        plugin.gerrit-oauth-provider-google-oauth = {
-          client-id =
-            "966881439540-5k20bis59lqs2bsi3rukfbveu8r0ta8q.apps.googleusercontent.com";
-        };
-
-        # use gerrit HTTP password
-        auth.gitBasicAuthPolicy = "HTTP";
-
-        # Receiving email is not currently supported.
-        sendemail = {
-          enable = true;
-          html = false;
-          connectTimeout = "10sec";
-          from = "gerrit <gerrit@fcuny.net>";
-          includeDiff = true;
-          smtpEncryption = "tls";
-          smtpServer = "smtp.fastmail.com";
-          smtpServerPort = 587;
-        };
-      };
-    };
-
-    systemd.services.gerrit = {
-      serviceConfig = {
-        # Using DynamicUser fails to generate correctly the ssh keys
-        # needed for the ssh server that is managed by gerrit.
-        # Instead, let's re-use the git user.
-        DynamicUser = lib.mkForce false;
-        User = "git";
-        Group = "git";
-      };
-    };
-
-    my.services.backup = {
-      paths = [ "/var/lib/gerrit" ];
-      exclude = [
-        "/var/lib/gerrit/tmp"
-        "/var/lib/gerrit/logs"
-        "/var/lib/gerrit/cache"
-      ];
-    };
-
-    services.nginx.virtualHosts."${cfg.vhostName}" = {
-      forceSSL = true;
-      enableACME = true;
-      locations."/" = { proxyPass = "http://127.0.0.1:4778"; };
-    };
-  };
-}
diff --git a/ops/buildkite/.gitignore b/ops/buildkite/.gitignore
deleted file mode 100644
index 112bb96..0000000
--- a/ops/buildkite/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-# ignore the various terraform files that are generate. The state is
-# stored in a GCS bucket.
-.terraform*
diff --git a/ops/buildkite/README.org b/ops/buildkite/README.org
deleted file mode 100644
index c28acbd..0000000
--- a/ops/buildkite/README.org
+++ /dev/null
@@ -1,7 +0,0 @@
-This is to configure the pipelines in buildkite.
-
-To upload them, run =nix run .#ops.buildkite.upload=.
-
-The state is stored in a GCS bucket (and it needs to be created before we run this).
-
-The service account =terraform= needs to exist first, running =gcloud iam service-accounts list= will list them and we can verify it is defined. I might need to run =gcloud auth application-default login= in order to authenticate first.
diff --git a/ops/buildkite/buildkite.tf b/ops/buildkite/buildkite.tf
deleted file mode 100644
index cd74785..0000000
--- a/ops/buildkite/buildkite.tf
+++ /dev/null
@@ -1,51 +0,0 @@
-locals {
-  terraform_service_account = "terraform@fcuny-homelab.iam.gserviceaccount.com"
-}
-
-provider "google" {
-  alias = "impersonation"
-  scopes = [
-    "https://www.googleapis.com/auth/cloud-platform",
-    "https://www.googleapis.com/auth/userinfo.email",
-  ]
-}
-
-data "google_service_account_access_token" "default" {
-  provider               = google.impersonation
-  target_service_account = local.terraform_service_account
-  scopes                 = ["userinfo-email", "cloud-platform"]
-  lifetime               = "1200s"
-}
-
-provider "google" {
-  project         = "fcuny-homelab"
-  region          = "us-west1"
-  zone            = "us-west1-c"
-  access_token    = data.google_service_account_access_token.default.access_token
-  request_timeout = "60s"
-}
-
-terraform {
-  required_providers {
-    buildkite = {
-      source = "buildkite/buildkite"
-    }
-  }
-
-  backend "gcs" {
-    bucket                      = "world-tf-state"
-    prefix                      = "buildkite/state"
-    impersonate_service_account = "terraform@fcuny-homelab.iam.gserviceaccount.com"
-  }
-}
-
-provider "buildkite" {
-  organization = "fcuny-dot-xyz"
-}
-
-resource "buildkite_pipeline" "world" {
-  name        = "world"
-  description = "CI pipeline for the world repository."
-  repository  = "https://cl.fcuny.net/world"
-  steps       = file("./steps.yml")
-}
diff --git a/ops/buildkite/default.nix b/ops/buildkite/default.nix
deleted file mode 100644
index 8e7c05c..0000000
--- a/ops/buildkite/default.nix
+++ /dev/null
@@ -1,23 +0,0 @@
-{ pkgs }:
-let
-  terraform = pkgs.terraform.withPlugins (p: [
-    p.buildkite
-    p.google
-  ]);
-in
-pkgs.stdenv.mkDerivation rec {
-  name = "tf-buildkite";
-  src = ./.;
-
-  upload = pkgs.writeShellScriptBin "tf-buildkite-upload" ''
-    set -ueo pipefail
-
-    cd $(git rev-parse --show-toplevel)/ops/buildkite
-
-    export BUILDKITE_API_TOKEN=$(pass api/buildkite-terraform-token)
-
-    ${terraform}/bin/terraform init
-    ${terraform}/bin/terraform plan
-    ${terraform}/bin/terraform apply
-  '';
-}
diff --git a/ops/buildkite/steps.yml b/ops/buildkite/steps.yml
deleted file mode 100644
index 9f30b8a..0000000
--- a/ops/buildkite/steps.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-steps:
-  - label: ":buildkite:"
-    key: ":init:"
-    command: |
-      buildkite-agent pipeline upload ops/ci/pipeline.yml
diff --git a/ops/ci/README.org b/ops/ci/README.org
deleted file mode 100644
index 0754937..0000000
--- a/ops/ci/README.org
+++ /dev/null
@@ -1,3 +0,0 @@
-The default pipeline is managed by [[file:~/workspace/world/ops/buildkite/][ops/buildkite]]. When a new build starts, the buildkite agent uploads the pipeline defined in this directory.
-
-The configuration for the repository is managed with [[file+emacs:pipeline.yml][pipeline.yml]]. All the steps are executed in parallel except for the last one, which wait on the completion of all the previous steps. If one of the previous steps has failed, the build is marked as failed, otherwise we consider it to pass.
diff --git a/ops/ci/pipeline.yml b/ops/ci/pipeline.yml
deleted file mode 100644
index 4308f6a..0000000
--- a/ops/ci/pipeline.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-env:
-  BUILDKITE_TOKEN_PATH: /run/agenix/buildkite/graphql
-steps:
-  - label: ":shell:"
-    command: "nix develop -c pre-commit run --all-files"
-
-  # wait for all previous steps to complete.
-  - wait: null
-    continue_on_failure: true
-
-  - label: ":hammer:"
-    command: |
-      set -ueo pipefail
-
-      readonly FAILED_JOBS=$(curl 'https://graphql.buildkite.com/v1' \
-        --silent \
-        -H "Authorization: Bearer $(cat ${BUILDKITE_TOKEN_PATH})" \
-        -d "{\"query\": \"query BuildStatusQuery { build(uuid: \\\"$BUILDKITE_BUILD_ID\\\") { jobs(passed: false) { count } } }\"}" | \
-        jq -r '.data.build.jobs.count')
-
-      echo "$$FAILED_JOBS build jobs failed."
-
-      if (( $$FAILED_JOBS > 0 )); then
-        exit 1
-      fi
diff --git a/ops/default.nix b/ops/default.nix
index 194252c..64a3d68 100644
--- a/ops/default.nix
+++ b/ops/default.nix
@@ -1,7 +1,6 @@
 { pkgs }:
 
 pkgs.lib.makeScope pkgs.newScope (pkgs: {
-  buildkite = pkgs.callPackage ./buildkite { };
   gcp-backups = pkgs.callPackage ./gcp-backups { };
   github = pkgs.callPackage ./github { };
 })
diff --git a/tools/default.nix b/tools/default.nix
index 93bc84e..96a59be 100644
--- a/tools/default.nix
+++ b/tools/default.nix
@@ -2,7 +2,6 @@
 
 pkgs.lib.makeScope pkgs.newScope (pkgs: {
   dnsupdate = pkgs.callPackage ./dnsupdate { };
-  gerrit-hook = pkgs.callPackage ./gerrit-hook { };
   ipconverter = pkgs.callPackage ./ipconverter { };
   seqstat = pkgs.callPackage ./seqstat { };
   gha-billing = pkgs.callPackage ./gha-billing { };
diff --git a/tools/gerrit-hook/README.org b/tools/gerrit-hook/README.org
deleted file mode 100644
index d7146d8..0000000
--- a/tools/gerrit-hook/README.org
+++ /dev/null
@@ -1,12 +0,0 @@
-#+TITLE: gerrit-hook
-
-A hook for gerrit.
-
-* Configuring the gerrit user
-First create the account with =rgerrit create-account CI=.
-
-Next we need to generate the HTTP password for the user, this can be done with =gerrit set-account CI --generate-http-password=.
-
-Store the password in the file [[file:~/workspace/world/hosts/tahoe/secrets/gerrit/hooks.age][gerrit/hook.age]]
-* Configuring the buildKite API key
-You can obtain API token by going to this [[https://buildkite.com/user/api-access-tokens][page]]. Store the API token in the same file as the gerrit user.
diff --git a/tools/gerrit-hook/buildkite.go b/tools/gerrit-hook/buildkite.go
deleted file mode 100644
index 07d2cfd..0000000
--- a/tools/gerrit-hook/buildkite.go
+++ /dev/null
@@ -1,139 +0,0 @@
-package main
-
-import (
-	"bytes"
-	"context"
-	"encoding/json"
-	"fmt"
-	"io/ioutil"
-	"log/syslog"
-	"net/http"
-	"os"
-	"strings"
-	"time"
-)
-
-// https://buildkite.com/docs/apis/rest-api/builds#create-a-Build
-type Build struct {
-	Commit string            `json:"commit"`
-	Branch string            `json:"branch"`
-	Env    map[string]string `json:"env"`
-}
-
-type buildResponse struct {
-	WebUrl string `json:"web_url"`
-}
-
-func triggerBuild(cfg *config, log *syslog.Writer, trigger *buildTrigger) error {
-	env := make(map[string]string)
-	branch := trigger.ref
-
-	if trigger.changeId != "" && trigger.patchset != "" {
-		env["GERRIT_CHANGE_ID"] = trigger.changeId
-		env["GERRIT_CHANGE_URL"] = trigger.changeUrl
-		env["GERRIT_PATCHSET"] = trigger.patchset
-
-		branch = fmt.Sprintf("cl/%v", strings.Split(trigger.ref, "/")[3])
-	}
-
-	b := Build{
-		Commit: trigger.commit,
-		Branch: branch,
-		Env:    env,
-	}
-
-	body, _ := json.Marshal(b)
-	reader := ioutil.NopCloser(bytes.NewReader(body))
-
-	bkUrl := fmt.Sprintf("https://api.buildkite.com/v2/organizations/%s/pipelines/%s/builds", cfg.BuildKiteOrganization, trigger.project)
-	req, err := http.NewRequest("POST", bkUrl, reader)
-	if err != nil {
-		return fmt.Errorf("failed to create an HTTP request: %v", err)
-	}
-
-	req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", cfg.BuildKiteToken))
-	req.Header.Add("Content-Type", "application/json")
-
-	// Let's budget this to 10 seconds maximum, this should be more
-	// than enough, as we're only triggering the build, we're not
-	// waiting on the status of the build
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	defer cancel()
-
-	resp, err := http.DefaultClient.Do(req.WithContext(ctx))
-	if err != nil {
-		return fmt.Errorf("failed to send buildKite request: %v", err)
-	}
-	defer resp.Body.Close()
-
-	respBody, err := ioutil.ReadAll(resp.Body)
-	if err != nil {
-		return fmt.Errorf("failed to parse buildKite response: %v", err)
-	}
-
-	if resp.StatusCode != http.StatusCreated {
-		return fmt.Errorf("received a non-success response from buildKite: %s (%v)", respBody, resp.Status)
-	}
-
-	var buildResp buildResponse
-	err = json.Unmarshal(respBody, &buildResp)
-	if err != nil {
-		return fmt.Errorf("failed to unmarshal build response: %v", err)
-	}
-
-	// Report the status back to the Gerrit CL so that users can click
-	// through to the running build.
-	msg := fmt.Sprintf("started build for patchset #%s on: %s", trigger.patchset, buildResp.WebUrl)
-	review := reviewInput{
-		Message:                        msg,
-		OmitDuplicateComments:          true,
-		Tag:                            "autogenerated:buildkite~trigger",
-		IgnoreDefaultAttentionSetRules: true,
-		Notify:                         "NONE",
-	}
-	updateGerrit(cfg, review, trigger.changeId, trigger.patchset)
-	return nil
-}
-
-func postCommand(cfg *config) {
-	changeId := os.Getenv("GERRIT_CHANGE_ID")
-	patchSet := os.Getenv("GERRIT_PATCHSET")
-
-	if changeId == "" || patchSet == "" {
-		fmt.Println("nothing to do")
-		return
-	}
-
-	// our build stage has the label :hammer:
-	if os.Getenv("BUILDKITE_LABEL") != ":hammer:" {
-		return
-	}
-
-	var vote int
-	var verb string
-	var notify string
-
-	if os.Getenv("BUILDKITE_COMMAND_EXIT_STATUS") == "0" {
-		vote = 1
-		verb = "passed"
-		notify = "NONE"
-	} else {
-		vote = -1
-		verb = "failed"
-		notify = "OWNER"
-	}
-
-	msg := fmt.Sprintf("Build of patchset %s %s: %s", patchSet, verb, os.Getenv("BUILDKITE_BUILD_URL"))
-	review := reviewInput{
-		Message:                        msg,
-		OmitDuplicateComments:          true,
-		IgnoreDefaultAttentionSetRules: vote == 1,
-		Tag:                            "autogenerated:buildkite~result",
-		Notify:                         notify,
-		Labels: map[string]int{
-			"Verified": vote,
-		},
-	}
-
-	updateGerrit(cfg, review, changeId, patchSet)
-}
diff --git a/tools/gerrit-hook/default.nix b/tools/gerrit-hook/default.nix
deleted file mode 100644
index c0667ae..0000000
--- a/tools/gerrit-hook/default.nix
+++ /dev/null
@@ -1,16 +0,0 @@
-{ pkgs, ... }:
-
-pkgs.buildGoModule rec {
-  name = "gerrit-hook";
-  src = ./.;
-  subPackages = [ "." ];
-  vendorSha256 = null;
-
-  meta = with pkgs.lib; {
-    description = "hooks for gerrit";
-    homepage = "https://golang.fcuny.net";
-    license = licenses.mit;
-    platforms = platforms.linux;
-    maintainers = [ ];
-  };
-}
diff --git a/tools/gerrit-hook/gerrit.go b/tools/gerrit-hook/gerrit.go
deleted file mode 100644
index 4854427..0000000
--- a/tools/gerrit-hook/gerrit.go
+++ /dev/null
@@ -1,149 +0,0 @@
-package main
-
-import (
-	"bytes"
-	"context"
-	"encoding/json"
-	"flag"
-	"fmt"
-	"io/ioutil"
-	"log"
-	"log/syslog"
-	"net/http"
-	"os"
-	"regexp"
-	"strconv"
-	"strings"
-	"time"
-)
-
-// Regular expression to extract change ID out of a URL
-var changeIdRegexp = regexp.MustCompile(`^.*/(\d+)$`)
-
-func gerritHookMain(cfg *config, log *syslog.Writer, trigger *buildTrigger) {
-	if trigger == nil {
-		os.Exit(0)
-	}
-
-	err := triggerBuild(cfg, log, trigger)
-	if err != nil {
-		log.Err(fmt.Sprintf("failed to trigger Buildkite build: %s", err))
-		os.Exit(1)
-	}
-}
-
-type reviewInput struct {
-	Message                        string         `json:"message"`
-	Labels                         map[string]int `json:"labels,omitempty"`
-	OmitDuplicateComments          bool           `json:"omit_duplicate_comments"`
-	IgnoreDefaultAttentionSetRules bool           `json:"ignore_default_attention_set_rules"`
-	Tag                            string         `json:"tag"`
-	Notify                         string         `json:"notify,omitempty"`
-}
-
-type buildTrigger struct {
-	project             string
-	change              string
-	kind                string
-	changeUrl           string
-	changeOwner         string
-	changeOwnerUserName string
-	branch              string
-	topic               string
-	uploader            string
-	uploaderUserName    string
-	commit              string
-	patchset            string
-	changeId            string
-	ref                 string
-}
-
-// https://gerrit.googlesource.com/plugins/hooks/+/HEAD/src/main/resources/Documentation/hooks.md#patchset_created
-func triggerForPatchsetCreated() (*buildTrigger, error) {
-	var trigger buildTrigger
-
-	flag.StringVar(&trigger.project, "project", "", "Gerrit project")
-	flag.StringVar(&trigger.change, "change", "", "Gerrit change")
-	flag.StringVar(&trigger.kind, "kind", "", "Gerrit kind")
-	flag.StringVar(&trigger.changeUrl, "change-url", "", "Gerrit URL for the change")
-	flag.StringVar(&trigger.changeOwner, "change-owner", "", "Gerrit owner")
-	flag.StringVar(&trigger.changeOwnerUserName, "change-owner-username", "", "Gerrit username")
-	flag.StringVar(&trigger.branch, "branch", "", "name of the branch")
-	flag.StringVar(&trigger.topic, "topic", "", "name of the topic")
-	flag.StringVar(&trigger.uploader, "uploader", "", "name ofthe uploader")
-	flag.StringVar(&trigger.uploaderUserName, "uploader-username", "", "")
-	flag.StringVar(&trigger.commit, "commit", "", "")
-	flag.StringVar(&trigger.patchset, "patchset", "", "")
-
-	flag.Parse()
-
-	// if the name of the repository has  dot in it's name,  we
-	// replace it with the string `-dot-'.
-	trigger.project = strings.Replace(trigger.project, ".", "-dot-", -1)
-
-	// if the name of the targetted branch is not `main', we don't
-	// care about running the tests.
-	if trigger.branch != "main" {
-		return nil, nil
-	}
-
-	// We only care about patchset that are actually modifying the
-	// code. See
-	// https://gerrit-review.googlesource.com/Documentation/config-labels.html
-	if trigger.kind == "NO_CODE_CHANGE" || trigger.kind == "NO_CHANGE" {
-		return nil, nil
-	}
-
-	// extract the changeId from the URL
-	matches := changeIdRegexp.FindStringSubmatch(trigger.changeUrl)
-	trigger.changeId = matches[1]
-
-	// build the ref
-	changeId, _ := strconv.Atoi(trigger.changeId)
-	trigger.ref = fmt.Sprintf(
-		"refs/changes/%02d/%s/%s",
-		changeId%100, trigger.changeId, trigger.patchset,
-	)
-
-	return &trigger, nil
-}
-
-// after triggering a build with buildKite, we update gerrit to add a
-// comment that links to the build.
-func updateGerrit(cfg *config, review reviewInput, changeId string, patchSet string) {
-	body, err := json.Marshal(review)
-	if err != nil {
-		log.Fatal(fmt.Sprintf("failed to marshal gerrit update: %v", err))
-		os.Exit(1)
-	}
-
-	reader := ioutil.NopCloser(bytes.NewReader(body))
-	url := fmt.Sprintf("%s/a/changes/%s/revisions/%s/review", cfg.GerritUrl, changeId, patchSet)
-	req, err := http.NewRequest("POST", url, reader)
-	if err != nil {
-		fmt.Fprintf(os.Stderr, "failed to create an HTTP request: %v", err)
-		os.Exit(1)
-	}
-
-	req.SetBasicAuth(cfg.GerritUser, cfg.GerritPassword)
-	req.Header.Add("Content-Type", "application/json")
-
-	// Let's budget this to 10 seconds maximum, this should be more
-	// than enough to add a comment to gerrit.
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	defer cancel()
-
-	resp, err := http.DefaultClient.Do(req.WithContext(ctx))
-	if err != nil {
-		fmt.Fprintf(os.Stderr, "failed to send gerrit request: %v", err)
-		os.Exit(1)
-	}
-	defer resp.Body.Close()
-
-	if resp.StatusCode != http.StatusOK {
-		respBody, _ := ioutil.ReadAll(resp.Body)
-		fmt.Fprintf(os.Stderr, "failed to update gerrit: %s: %s ", respBody, resp.Status)
-	} else {
-		fmt.Printf("added link to CI build to %s", patchSet)
-	}
-}
diff --git a/tools/gerrit-hook/go.mod b/tools/gerrit-hook/go.mod
deleted file mode 100644
index 98968da..0000000
--- a/tools/gerrit-hook/go.mod
+++ /dev/null
@@ -1,3 +0,0 @@
-module golang.fcuny.net/gerrit-hook
-
-go 1.16
diff --git a/tools/gerrit-hook/main.go b/tools/gerrit-hook/main.go
deleted file mode 100644
index ccd2ad6..0000000
--- a/tools/gerrit-hook/main.go
+++ /dev/null
@@ -1,68 +0,0 @@
-package main
-
-import (
-	"encoding/json"
-	"fmt"
-	"io/ioutil"
-	"log/syslog"
-	"os"
-	"path"
-)
-
-// config represents the configuration for the gerrit hook
-type config struct {
-	GerritUrl             string `json:"gerritUrl"`
-	GerritUser            string `json:"gerritUser"`
-	GerritPassword        string `json:"gerritPassword"`
-	BuildKiteToken        string `json:"buildKiteToken"`
-	BuildKiteOrganization string `json:"buildKiteOrganization"`
-}
-
-func loadConfig() (*config, error) {
-	configPath := "/var/run/agenix/gerrit/hooks"
-
-	configJson, err := ioutil.ReadFile(configPath)
-	if err != nil {
-		return nil, fmt.Errorf("failed to read configuration file %s: %v", configPath, err)
-	}
-
-	var cfg config
-	err = json.Unmarshal(configJson, &cfg)
-	if err != nil {
-		return nil, fmt.Errorf("failed to unmarshall configuration: %v", err)
-	}
-
-	return &cfg, nil
-}
-
-func main() {
-	log, err := syslog.New(syslog.LOG_INFO|syslog.LOG_USER, "gerrit-hook")
-	if err != nil {
-		fmt.Fprintf(os.Stderr, "failed to open syslog: %s\n", err)
-		os.Exit(1)
-	}
-
-	log.Info(fmt.Sprintf("`gerrit-hook' called with arguments: %v\n", os.Args))
-
-	cmd := path.Base(os.Args[0])
-
-	cfg, err := loadConfig()
-	if err != nil {
-		os.Exit(1)
-	}
-
-	switch cmd {
-	case "patchset-created":
-		trigger, err := triggerForPatchsetCreated()
-		if err != nil {
-			log.Crit(fmt.Sprintf("failed to create a trigger: %s", err))
-			os.Exit(1)
-		}
-		gerritHookMain(cfg, log, trigger)
-	case "post-command":
-		postCommand(cfg)
-	default:
-		log.Info(fmt.Sprintf("`%s' is not a supported command", cmd))
-		os.Exit(1)
-	}
-}