Unverified Commit 7859adb9 authored by tomberek's avatar tomberek Committed by GitHub
Browse files

Merge pull request #245394 from christoph-heiss/pkgs/sourcehut

sourcehut: update all component; lots of fixes
parents 0e890294 88a3d2a0
Loading
Loading
Loading
Loading
+68 −90
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ let
      || head srvMatch == srv # Include sections for the service being configured
      then v
      # Enable Web links and integrations between services.
      else if tail srvMatch == [ null ] && elem (head srvMatch) cfg.services
      else if tail srvMatch == [ null ] && cfg.${head srvMatch}.enable
      then {
        inherit (v) origin;
        # mansrht crashes without it
@@ -38,9 +38,9 @@ let
      # for services needing access to them.
      "builds.sr.ht::worker".buildlogs = "/var/log/sourcehut/buildsrht-worker";
      "git.sr.ht".post-update-script = "/usr/bin/gitsrht-update-hook";
      "git.sr.ht".repos = "/var/lib/sourcehut/gitsrht/repos";
      "git.sr.ht".repos = cfg.settings."git.sr.ht".repos;
      "hg.sr.ht".changegroup-script = "/usr/bin/hgsrht-hook-changegroup";
      "hg.sr.ht".repos = "/var/lib/sourcehut/hgsrht/repos";
      "hg.sr.ht".repos = cfg.settings."hg.sr.ht".repos;
      # Making this a per service option despite being in a global section,
      # so that it uses the redis-server used by the service.
      "sr.ht".redis-host = cfg.${srv}.redis.host;
@@ -77,6 +77,14 @@ let
      type = types.path;
      apply = s: "<" + toString s;
    };
    api-origin = mkOption {
      description = lib.mdDoc "Origin URL for the API";
      type = types.str;
      default = "http://${cfg.listenAddress}:${toString (cfg.${srv}.port + 100)}";
      defaultText = lib.literalMD ''
        `"http://''${`[](#opt-services.sourcehut.listenAddress)`}:''${toString (`[](#opt-services.sourcehut.${srv}.port)` + 100)}"`
      '';
    };
  };

  # Specialized python containing all the modules
@@ -112,15 +120,6 @@ in
      and account management services
    '');

    services = mkOption {
      type = with types; listOf (enum
        [ "builds" "git" "hg" "hub" "lists" "man" "meta" "pages" "paste" "todo" ]);
      defaultText = "locally enabled services";
      description = lib.mdDoc ''
        Services that may be displayed as links in the title bar of the Web interface.
      '';
    };

    listenAddress = mkOption {
      type = types.str;
      default = "localhost";
@@ -400,8 +399,8 @@ in
              This setting is propagated to newer and existing repositories.
            '';
            type = types.str;
            default = "${cfg.python}/bin/hgsrht-hook-changegroup";
            defaultText = "\${cfg.python}/bin/hgsrht-hook-changegroup";
            default = "${pkgs.sourcehut.hgsrht}/bin/hgsrht-hook-changegroup";
            defaultText = "\${pkgs.sourcehut.hgsrht}/bin/hgsrht-hook-changegroup";
          };
          repos = mkOption {
            description = lib.mdDoc ''
@@ -501,12 +500,6 @@ in
        options."meta.sr.ht" =
          removeAttrs (commonServiceSettings "meta")
            ["oauth-client-id" "oauth-client-secret"] // {
          api-origin = mkOption {
            description = lib.mdDoc "Origin URL for API, 100 more than web.";
            type = types.str;
            default = "http://${cfg.listenAddress}:${toString (cfg.meta.port + 100)}";
            defaultText = lib.literalMD ''`"http://''${`[](#opt-services.sourcehut.listenAddress)`}:''${toString (`[](#opt-services.sourcehut.meta.port)` + 100)}"`'';
          };
          webhooks = mkOption {
            description = lib.mdDoc "The Redis connection used for the webhooks worker.";
            type = types.str;
@@ -784,6 +777,7 @@ in
        extraConfig = ''
          PermitUserEnvironment SRHT_*
        '';
        startWhenNeeded = false;
      };
      environment.etc."ssh/sourcehut/config.ini".source =
        settingsFormat.generate "sourcehut-dispatch-config.ini"
@@ -792,15 +786,28 @@ in
      environment.etc."ssh/sourcehut/subdir/srht-dispatch" = {
        # sshd_config(5): The program must be owned by root, not writable by group or others
        mode = "0755";
        source = pkgs.writeShellScript "srht-dispatch" ''
        source = pkgs.writeShellScript "srht-dispatch-wrapper" ''
          set -e
          set -x
          cd /etc/ssh/sourcehut/subdir
          ${cfg.python}/bin/gitsrht-dispatch "$@"
          ${pkgs.sourcehut.gitsrht}/bin/gitsrht-dispatch "$@"
        '';
      };
      systemd.tmpfiles.settings."10-sourcehut-gitsrht" = mkIf cfg.git.enable (
        builtins.listToAttrs (map (name: {
          name = "/var/log/sourcehut/gitsrht-${name}";
          value.f = {
            inherit (cfg.git) user group;
            mode = "0644";
          };
        }) [ "keys" "shell" "update-hook" ])
      );
      systemd.services.sshd = {
        #path = optional cfg.git.enable [ cfg.git.package ];
        preStart = mkIf cfg.hg.enable ''
          chown ${cfg.hg.user}:${cfg.hg.group} /var/log/sourcehut/hgsrht-keys
        '';
        serviceConfig = {
          LogsDirectory = "sourcehut";
          BindReadOnlyPaths =
            # Note that those /usr/bin/* paths are hardcoded in multiple places in *.sr.ht,
            # for instance to get the user from the [git.sr.ht::dispatch] settings.
@@ -813,7 +820,6 @@ in
              "${pkgs.writeShellScript "buildsrht-keys-wrapper" ''
                set -e
                cd /run/sourcehut/buildsrht/subdir
                set -x
                exec -a "$0" ${pkgs.sourcehut.buildsrht}/bin/buildsrht-keys "$@"
              ''}:/usr/bin/buildsrht-keys"
              "${pkgs.sourcehut.buildsrht}/bin/master-shell:/usr/bin/master-shell"
@@ -825,31 +831,26 @@ in
              "${pkgs.writeShellScript "gitsrht-keys-wrapper" ''
                set -e
                cd /run/sourcehut/gitsrht/subdir
                set -x
                exec -a "$0" ${pkgs.sourcehut.gitsrht}/bin/gitsrht-keys "$@"
              ''}:/usr/bin/gitsrht-keys"
              "${pkgs.writeShellScript "gitsrht-shell-wrapper" ''
                set -e
                cd /run/sourcehut/gitsrht/subdir
                set -x
                export PATH="${cfg.git.package}/bin:$PATH"
                export SRHT_CONFIG=/run/sourcehut/gitsrht/config.ini
                exec -a "$0" ${pkgs.sourcehut.gitsrht}/bin/gitsrht-shell "$@"
              ''}:/usr/bin/gitsrht-shell"
              "${pkgs.writeShellScript "gitsrht-update-hook" ''
                set -e
                test -e "''${PWD%/*}"/config.ini ||
                # Git hooks are run relative to their repository's directory,
                # but gitsrht-update-hook looks up ../config.ini
                ln -s /run/sourcehut/gitsrht/config.ini "''${PWD%/*}"/config.ini
                export SRHT_CONFIG=/run/sourcehut/gitsrht/config.ini
                # hooks/post-update calls /usr/bin/gitsrht-update-hook as hooks/stage-3
                # but this wrapper being a bash script, it overrides $0 with /usr/bin/gitsrht-update-hook
                # hence this hack to put hooks/stage-3 back into gitsrht-update-hook's $0
                if test "''${STAGE3:+set}"
                then
                  set -x
                  exec -a hooks/stage-3 ${pkgs.sourcehut.gitsrht}/bin/gitsrht-update-hook "$@"
                else
                  export STAGE3=set
                  set -x
                  exec -a "$0" ${pkgs.sourcehut.gitsrht}/bin/gitsrht-update-hook "$@"
                fi
              ''}:/usr/bin/gitsrht-update-hook"
@@ -860,13 +861,11 @@ in
              "${pkgs.writeShellScript "hgsrht-keys-wrapper" ''
                set -e
                cd /run/sourcehut/hgsrht/subdir
                set -x
                exec -a "$0" ${pkgs.sourcehut.hgsrht}/bin/hgsrht-keys "$@"
              ''}:/usr/bin/hgsrht-keys"
              "${pkgs.writeShellScript "hgsrht-shell-wrapper" ''
                set -e
                cd /run/sourcehut/hgsrht/subdir
                set -x
                exec -a "$0" ${pkgs.sourcehut.hgsrht}/bin/hgsrht-shell "$@"
              ''}:/usr/bin/hgsrht-shell"
              # Mercurial's changegroup hooks are run relative to their repository's directory,
@@ -875,8 +874,7 @@ in
                set -e
                test -e "''$PWD"/config.ini ||
                ln -s /run/sourcehut/hgsrht/config.ini "''$PWD"/config.ini
                set -x
                exec -a "$0" ${cfg.python}/bin/hgsrht-hook-changegroup "$@"
                exec -a "$0" ${pkgs.sourcehut.hgsrht}/bin/hgsrht-hook-changegroup "$@"
              ''}:/usr/bin/hgsrht-hook-changegroup"
            ];
        };
@@ -1066,10 +1064,11 @@ in
          };
        })
      ];
      extraServices.gitsrht-api = {
        serviceConfig.Restart = "always";
        serviceConfig.RestartSec = "5s";
        serviceConfig.ExecStart = "${pkgs.sourcehut.gitsrht}/bin/gitsrht-api -b ${cfg.listenAddress}:${toString (cfg.git.port + 100)}";
      extraServices.gitsrht-api.serviceConfig = {
        Restart = "always";
        RestartSec = "5s";
        ExecStart = "${pkgs.sourcehut.gitsrht}/bin/gitsrht-api -b ${cfg.listenAddress}:${toString (cfg.git.port + 100)}";
        BindPaths = [ "${cfg.settings."git.sr.ht".repos}:/var/lib/sourcehut/gitsrht/repos" ];
      };
      extraServices.gitsrht-fcgiwrap = mkIf cfg.nginx.enable {
        serviceConfig = {
@@ -1188,7 +1187,7 @@ in
      extraServices.listssrht-lmtp = {
        wants = [ "postfix.service" ];
        unitConfig.JoinsNamespaceOf = optional cfg.postfix.enable "postfix.service";
        serviceConfig.ExecStart = "${cfg.python}/bin/listssrht-lmtp";
        serviceConfig.ExecStart = "${pkgs.sourcehut.listssrht}/bin/listssrht-lmtp";
        # Avoid crashing: os.chown(sock, os.getuid(), sock_gid)
        serviceConfig.PrivateUsers = mkForce false;
      };
@@ -1252,8 +1251,7 @@ in
          ) cfg.settings));
        serviceConfig.ExecStart = "${pkgs.sourcehut.metasrht}/bin/metasrht-api -b ${cfg.listenAddress}:${toString (cfg.meta.port + 100)}";
      };
      extraConfig = mkMerge [
        {
      extraConfig = {
        assertions = [
          { assertion = let s = cfg.settings."meta.sr.ht::billing"; in
                        s.enabled == "yes" -> (s.stripe-public-key != null && s.stripe-secret-key != null);
@@ -1268,7 +1266,7 @@ in
            else
              # In order to load config.ini
              if cd /run/sourcehut/metasrht
                then exec ${cfg.python}/bin/metasrht-manageuser "$@"
              then exec ${pkgs.sourcehut.metasrht}/bin/metasrht-manageuser "$@"
              else cat <<EOF
                Please run: sudo systemctl start metasrht
            EOF
@@ -1276,32 +1274,8 @@ in
              fi
            fi
          '');
        }
        (mkIf cfg.nginx.enable {
          services.nginx.virtualHosts."meta.${domain}" = {
            locations."/query" = {
              proxyPass = cfg.settings."meta.sr.ht".api-origin;
              extraConfig = ''
                if ($request_method = 'OPTIONS') {
                  add_header 'Access-Control-Allow-Origin' '*';
                  add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
                  add_header 'Access-Control-Allow-Headers' 'User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
                  add_header 'Access-Control-Max-Age' 1728000;
                  add_header 'Content-Type' 'text/plain; charset=utf-8';
                  add_header 'Content-Length' 0;
                  return 204;
                }

                add_header 'Access-Control-Allow-Origin' '*';
                add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
                add_header 'Access-Control-Allow-Headers' 'User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
                add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
              '';
            };
      };
    })
      ];
    })

    (import ./service.nix "pages" {
      inherit configIniOfService;
@@ -1356,7 +1330,7 @@ in
      extraServices.todosrht-lmtp = {
        wants = [ "postfix.service" ];
        unitConfig.JoinsNamespaceOf = optional cfg.postfix.enable "postfix.service";
        serviceConfig.ExecStart = "${cfg.python}/bin/todosrht-lmtp";
        serviceConfig.ExecStart = "${pkgs.sourcehut.todosrht}/bin/todosrht-lmtp";
        # Avoid crashing: os.chown(sock, os.getuid(), sock_gid)
        serviceConfig.PrivateUsers = mkForce false;
      };
@@ -1388,6 +1362,10 @@ in
        dispatch is deprecated. See https://sourcehut.org/blog/2022-08-01-dispatch-deprecation-plans/
        for more information.
    '')

    (mkRemovedOptionModule [ "services" "sourcehut" "services"] ''
        This option was removed in favor of individual <service>.enable flags.
    '')
  ];

  meta.doc = ./default.md;
+32 −4
Original line number Diff line number Diff line
@@ -108,7 +108,7 @@ let
      #SocketBindDeny = "any";
      SystemCallFilter = [
        "@system-service"
        "~@aio" "~@keyring" "~@memlock" "~@privileged" "~@resources" "~@timer"
        "~@aio" "~@keyring" "~@memlock" "~@privileged" "~@timer"
        "@chown" "@setuid"
      ];
      SystemCallArchitectures = "native";
@@ -222,6 +222,23 @@ in
            expires 30d;
          '';
        };
        locations."/query" = mkIf (cfg.settings.${iniKey} ? api-origin) {
          proxyPass = cfg.settings.${iniKey}.api-origin;
          extraConfig = ''
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';

            if ($request_method = 'OPTIONS') {
              add_header 'Access-Control-Max-Age' 1728000;
              add_header 'Content-Type' 'text/plain; charset=utf-8';
              add_header 'Content-Length' 0;
              return 204;
            }

            add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
          '';
        };
      } cfg.nginx.virtualHost ];
    };

@@ -236,9 +253,6 @@ in
        }) [srvCfg.user];
    };

    services.sourcehut.services = mkDefault (filter (s: cfg.${s}.enable)
      [ "builds" "dispatch" "git" "hg" "hub" "lists" "man" "meta" "pages" "paste" "todo" ]);

    services.sourcehut.settings = mkMerge [
      {
        "${srv}.sr.ht".origin = mkDefault "https://${srv}.${cfg.settings."sr.ht".global-domain}";
@@ -363,6 +377,20 @@ in
        }
        extraService
      ])) extraServices)

      # Work around 'pq: permission denied for schema public' with postgres v15, until a
      # solution for `services.postgresql.ensureUsers` is found.
      # See https://github.com/NixOS/nixpkgs/issues/216989
      # Workaround taken from nixos/forgejo: https://github.com/NixOS/nixpkgs/pull/262741
      (lib.mkIf (
          cfg.postgresql.enable
          && lib.strings.versionAtLeast config.services.postgresql.package.version "15.0"
        ) {
          postgresql.postStart = (lib.mkAfter ''
            $PSQL -tAc 'ALTER DATABASE "${srvCfg.postgresql.database}" OWNER TO "${srvCfg.user}";'
          '');
        }
      )
    ];

    systemd.timers = mapAttrs (timerName: timer:
+1 −5
Original line number Diff line number Diff line
@@ -126,6 +126,7 @@ in
    virtualisation.diskSize = 4 * 1024;
    virtualisation.memorySize = 2 * 1024;
    networking.domain = domain;
    networking.enableIPv6 = false;
    networking.extraHosts = ''
      ${config.networking.primaryIPAddress} builds.${domain}
      ${config.networking.primaryIPAddress} git.${domain}
@@ -134,11 +135,6 @@ in

    services.sourcehut = {
      enable = true;
      services = [
        "builds"
        "git"
        "meta"
      ];
      nginx.enable = true;
      nginx.virtualHost = {
        forceSSL = true;
+8 −5
Original line number Diff line number Diff line
@@ -8,31 +8,32 @@
, pyyaml
, markdown
, ansi2html
, lxml
, python
, unzip
}:
let
  version = "0.83.0";
  version = "0.86.10";

  src = fetchFromSourcehut {
    owner = "~sircmpwn";
    repo = "builds.sr.ht";
    rev = version;
    hash = "sha256-u/y+sYu/09LypWI/ngghbge5SvkuLQpray10j0SjlOo=";
    hash = "sha256-frwJgwJst2/NWd8VR0KbsVwm8JfWuekkY2oIIAdh3Fw=";
  };

  buildsrht-api = buildGoModule ({
    inherit src version;
    pname = "buildsrht-api";
    modRoot = "api";
    vendorHash = "sha256-DfVWr/4J4ZrhHpy9CXPaAQcbag/9FmDgiexcNo0lEsk=";
  } // import ./fix-gqlgen-trimpath.nix { inherit unzip; gqlgenVersion= "0.17.20"; });
    vendorHash = "sha256-2khk7j22KON4MsuvFUNKSUpouJtVIOxE0hkh63iaxZ4=";
  } // import ./fix-gqlgen-trimpath.nix { inherit unzip; gqlgenVersion = "0.17.29"; });

  buildsrht-worker = buildGoModule {
    inherit src version;
    sourceRoot = "${src.name}/worker";
    pname = "buildsrht-worker";
    vendorHash = "sha256-y5RFPbtaGmgPpiV2Q3njeWORGZF1TJRjAbY6VgC1hek=";
    vendorHash = "sha256-obdaeRwMhuiCV2kVwDo1c+rU/hmsbiL1IgAf7AcIpoc=";
  };
in
buildPythonPackage rec {
@@ -50,7 +51,9 @@ buildPythonPackage rec {
    celery
    pyyaml
    markdown
    # Unofficial dependencies
    ansi2html
    lxml
  ];

  preBuild = ''
+29 −45
Original line number Diff line number Diff line
{ lib
, fetchFromSourcehut
, fetchNodeModules
, buildPythonPackage
, pgpy
, flask
, bleach
, misaka
, humanize
, html5lib
, markdown
, sqlalchemy
, sqlalchemy-utils
, psycopg2
, pygments
, markdown
, mistletoe
, bleach
, requests
, sqlalchemy
, cryptography
, beautifulsoup4
, sqlalchemy-utils
, pygments
, cryptography
, prometheus-client
, celery
, alembic
, redis
, celery
, html5lib
, importlib-metadata
, mistletoe
, minio
, tinycss2
, sassc
, nodejs
, redis
, minify
}:

buildPythonPackage rec {
  pname = "srht";
  version = "0.69.0";
  version = "0.69.15";

  src = fetchFromSourcehut {
    owner = "~sircmpwn";
    repo = "core.sr.ht";
    rev = version;
    sha256 = "sha256-s/I0wxtPggjTkkTZnhm77PxdQjiT0Vq2MIk7JMvdupc=";
    sha256 = "sha256-T9yewweqnWL3IW5PHGyAcsIWCGn1ayK2rwrHVukYpgE=";
    fetchSubmodules = true;
  };

  node_modules = fetchNodeModules {
    src = "${src}/srht";
    nodejs = nodejs;
    sha256 = "sha256-IWKahdWv3qJ5DNyb1GB9JWYkZxghn6wzZe68clYXij8=";
  };

  patches = [
    # Disable check for npm
    ./disable-npm-install.patch
    # Fix Unix socket support in RedisQueueCollector
    patches/redis-socket/core/0001-Fix-Unix-socket-support-in-RedisQueueCollector.patch
  ];

  propagatedNativeBuildInputs = [
    sassc
    nodejs
    minify
  ];

  propagatedBuildInputs = [
    pgpy
    flask
    bleach
    misaka
    humanize
    html5lib
    markdown
    sqlalchemy
    sqlalchemy-utils
    psycopg2
    pygments
    requests
    markdown
    mistletoe
    sqlalchemy
    cryptography
    bleach
    requests
    beautifulsoup4
    sqlalchemy-utils
    pygments
    cryptography
    prometheus-client

    # Unofficial runtime dependencies?
    celery
    alembic
    importlib-metadata
    minio
    redis
    celery
    # Used transitively through beautifulsoup4
    html5lib
    # Used transitively trough bleach.css_sanitizer
    tinycss2
    # Used by srht.debug
    importlib-metadata
  ];

  PKGVER = version;

  preBuild = ''
    cp -r ${node_modules} srht/node_modules
  '';

  dontUseSetuptoolsCheck = true;
  pythonImportsCheck = [ "srht" ];

Loading