Loading nixos/modules/services/misc/sourcehut/default.nix +68 −90 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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"; Loading Loading @@ -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 '' Loading Loading @@ -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; Loading Loading @@ -784,6 +777,7 @@ in extraConfig = '' PermitUserEnvironment SRHT_* ''; startWhenNeeded = false; }; environment.etc."ssh/sourcehut/config.ini".source = settingsFormat.generate "sourcehut-dispatch-config.ini" Loading @@ -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. Loading @@ -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" Loading @@ -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" Loading @@ -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, Loading @@ -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" ]; }; Loading Loading @@ -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 = { Loading Loading @@ -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; }; Loading Loading @@ -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); Loading @@ -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 Loading @@ -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; Loading Loading @@ -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; }; Loading Loading @@ -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; Loading nixos/modules/services/misc/sourcehut/service.nix +32 −4 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -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 ]; }; Loading @@ -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}"; Loading Loading @@ -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: Loading nixos/tests/sourcehut.nix +1 −5 Original line number Diff line number Diff line Loading @@ -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} Loading @@ -134,11 +135,6 @@ in services.sourcehut = { enable = true; services = [ "builds" "git" "meta" ]; nginx.enable = true; nginx.virtualHost = { forceSSL = true; Loading pkgs/applications/version-management/sourcehut/builds.nix +8 −5 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -50,7 +51,9 @@ buildPythonPackage rec { celery pyyaml markdown # Unofficial dependencies ansi2html lxml ]; preBuild = '' Loading pkgs/applications/version-management/sourcehut/core.nix +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 Loading
nixos/modules/services/misc/sourcehut/default.nix +68 −90 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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"; Loading Loading @@ -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 '' Loading Loading @@ -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; Loading Loading @@ -784,6 +777,7 @@ in extraConfig = '' PermitUserEnvironment SRHT_* ''; startWhenNeeded = false; }; environment.etc."ssh/sourcehut/config.ini".source = settingsFormat.generate "sourcehut-dispatch-config.ini" Loading @@ -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. Loading @@ -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" Loading @@ -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" Loading @@ -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, Loading @@ -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" ]; }; Loading Loading @@ -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 = { Loading Loading @@ -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; }; Loading Loading @@ -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); Loading @@ -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 Loading @@ -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; Loading Loading @@ -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; }; Loading Loading @@ -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; Loading
nixos/modules/services/misc/sourcehut/service.nix +32 −4 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -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 ]; }; Loading @@ -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}"; Loading Loading @@ -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: Loading
nixos/tests/sourcehut.nix +1 −5 Original line number Diff line number Diff line Loading @@ -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} Loading @@ -134,11 +135,6 @@ in services.sourcehut = { enable = true; services = [ "builds" "git" "meta" ]; nginx.enable = true; nginx.virtualHost = { forceSSL = true; Loading
pkgs/applications/version-management/sourcehut/builds.nix +8 −5 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -50,7 +51,9 @@ buildPythonPackage rec { celery pyyaml markdown # Unofficial dependencies ansi2html lxml ]; preBuild = '' Loading
pkgs/applications/version-management/sourcehut/core.nix +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