Unverified Commit 5fccfa89 authored by nixpkgs-ci[bot]'s avatar nixpkgs-ci[bot] Committed by GitHub
Browse files

Merge master into staging-next

parents 4efa28f3 01ac1583
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -60,6 +60,10 @@

- [go-httpbin](https://github.com/mccutchen/go-httpbin), a reasonably complete and well-tested golang port of httpbin, with zero dependencies outside the go stdlib. Available as [services.go-httpbin](#opt-services.go-httpbin.enable).

- [radicle-ci-broker](https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:zwTxygwuz5LDGBq255RA2CbNGrz8), runs CI for repositories in the local [Radicle](https://radicle.xyz/) node. Available as [services.radicle.ci.broker.enable](#opt-services.radicle.ci.broker.enable).

- [radicle-native-ci](https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:z3qg5TKmN83afz2fj9z3fQjU8vaYE), an adapter for the [Radicle CI broker](https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:zwTxygwuz5LDGBq255RA2CbNGrz8), for performing CI runs locally. Available as [services.radicle.ci.adapters.native](#opt-services.radicle.ci.adapters.native.instances).

- [llama-swap](https://github.com/mostlygeek/llama-swap), a light weight transparent proxy server that provides automatic model swapping to llama.cpp's server (or any server with an OpenAI compatible endpoint). Available as [](#opt-services.llama-swap.enable).

- [tuwunel](https://matrix-construct.github.io/tuwunel/), a federated chat server implementing the Matrix protocol, forked from Conduwuit. Available as [services.matrix-tuwunel](#opt-services.matrix-tuwunel.enable).
+2 −0
Original line number Diff line number Diff line
@@ -506,6 +506,8 @@
  ./services/continuous-integration/jenkins/default.nix
  ./services/continuous-integration/jenkins/job-builder.nix
  ./services/continuous-integration/jenkins/slave.nix
  ./services/continuous-integration/radicle/adapters/native.nix
  ./services/continuous-integration/radicle/ci-broker.nix
  ./services/continuous-integration/woodpecker/agents.nix
  ./services/continuous-integration/woodpecker/server.nix
  ./services/databases/aerospike.nix
+141 −0
Original line number Diff line number Diff line
{
  config,
  lib,
  pkgs,
  ...
}:

let
  cfg = config.services.radicle.ci.adapters.native;
  brokerCfg = config.services.radicle.ci.broker;

  settingsFormat = pkgs.formats.yaml { };

  enabledInstances = lib.filter (instance: instance.enable) (lib.attrValues cfg.instances);
in

{
  meta.maintainers = with lib.maintainers; [ defelo ];

  options.services.radicle.ci.adapters.native = {
    instances = lib.mkOption {
      type = lib.types.attrsOf (
        lib.types.submodule (
          { config, name, ... }:
          {
            options = {
              enable = lib.mkEnableOption "this radicle-native-ci instance" // {
                default = true;
                example = false;
              };

              name = lib.mkOption {
                type = lib.types.str;
                description = ''
                  Adapter name that is used in the radicle-ci-broker configuration.
                  Defaults to the attribute name.
                '';
              };

              package = lib.mkPackageOption pkgs "radicle-native-ci" { };

              runtimePackages = lib.mkOption {
                type = lib.types.listOf lib.types.package;
                description = "Packages added to the adapter's {env}`PATH`.";
                defaultText = lib.literalExpression ''
                  with pkgs; [
                    bash
                    coreutils
                    curl
                    gawk
                    gitMinimal
                    gnused
                    wget
                  ]
                '';
              };

              settings = lib.mkOption {
                type = lib.types.submodule {
                  freeformType = settingsFormat.type;

                  options = {
                    state = lib.mkOption {
                      type = lib.types.path;
                      description = "Directory where per-run directories are stored.";
                      defaultText = lib.literalExpression ''"''${config.services.radicle.ci.broker.stateDir}/adapters/native/${config.name}"'';
                    };

                    log = lib.mkOption {
                      type = lib.types.path;
                      description = "File where radicle-native-ci should write the run log.";
                      defaultText = lib.literalExpression ''"''${config.services.radicle.ci.broker.logDir}/adapters/native/${config.name}.log"'';
                    };

                    base_url = lib.mkOption {
                      type = lib.types.nullOr lib.types.str;
                      description = "Base URL for build logs (mandatory for access from CI broker page).";
                      default = null;
                    };
                  };
                };
                description = ''
                  Configuration of radicle-native-ci.
                  See <https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:z3qg5TKmN83afz2fj9z3fQjU8vaYE#configuration> for more information.
                '';
                default = { };
              };
            };

            config = {
              name = lib.mkDefault name;

              runtimePackages = with pkgs; [
                bash
                coreutils
                curl
                gawk
                gitMinimal
                gnused
                wget
              ];

              settings = {
                state = lib.mkDefault "${brokerCfg.stateDir}/adapters/native/${config.name}";
                log = lib.mkDefault "${brokerCfg.logDir}/adapters/native/${config.name}.log";
              };
            };
          }
        )
      );
      description = "radicle-native-ci adapter instances.";
      default = { };
    };
  };

  config = lib.mkIf (enabledInstances != [ ]) {
    services.radicle.ci.broker.settings.adapters = lib.listToAttrs (
      map (
        instance:
        lib.nameValuePair instance.name {
          command = lib.getExe instance.package;
          config = instance.settings;
          config_env = "RADICLE_NATIVE_CI";
          env.PATH = lib.makeBinPath instance.runtimePackages;
        }
      ) enabledInstances
    );

    systemd.tmpfiles.settings.radicle-native-ci = lib.listToAttrs (
      map (
        instance:
        lib.nameValuePair (builtins.dirOf instance.settings.log) {
          d = {
            user = config.users.users.radicle.name;
            group = config.users.groups.radicle.name;
          };
        }
      ) enabledInstances
    );
  };
}
+256 −0
Original line number Diff line number Diff line
{
  config,
  lib,
  pkgs,
  ...
}:

let
  cfg = config.services.radicle.ci.broker;

  settingsFormat = pkgs.formats.json { };
  configFile = pkgs.runCommand "ci-broker.json" { } (
    ''
      cp ${settingsFormat.generate "ci-broker.json" cfg.settings} $out
    ''
    + lib.optionalString cfg.checkConfig ''
      ${lib.getExe' cfg.package "cib"} --config $out config
    ''
  );

  RAD_HOME = "/var/lib/radicle";

  # Convenient wrapper to run `cibtool` in the namespaces of `radicle-ci-broker.service`
  cibtool-system = pkgs.writeShellScriptBin "cibtool-system" ''
    set -o allexport
    ${lib.toShellVars {
      inherit RAD_HOME;
      HOME = RAD_HOME;
    }}
    # Note that --env is not used to preserve host's envvars like $TERM
    exec ${lib.getExe' pkgs.util-linux "nsenter"} -a \
      -t "$(${lib.getExe' config.systemd.package "systemctl"} show -P MainPID radicle-ci-broker.service)" \
      -S "$(${lib.getExe' config.systemd.package "systemctl"} show -P UID radicle-ci-broker.service)" \
      -G "$(${lib.getExe' config.systemd.package "systemctl"} show -P GID radicle-ci-broker.service)" \
      ${lib.getExe' cfg.package "cibtool"} --db ${lib.escapeShellArg cfg.settings.db} "$@"
  '';
in

{
  meta.maintainers = with lib.maintainers; [ defelo ];

  options.services.radicle.ci.broker = {
    enable = lib.mkEnableOption "radicle-ci-broker";

    package = lib.mkPackageOption pkgs "radicle-ci-broker" { };

    stateDir = lib.mkOption {
      type = lib.types.path;
      description = "State directory of radicle-ci-broker.";
      default = "/var/lib/radicle-ci";
    };

    logDir = lib.mkOption {
      type = lib.types.path;
      description = "Log directory of radicle-ci-broker.";
      default = "/var/log/radicle-ci";
    };

    enableHardening = lib.mkEnableOption "systemd hardening" // {
      default = true;
      example = false;
    };

    checkConfig =
      lib.mkEnableOption "checking the {file}`ci-broker.yaml` file resulting from [](#opt-services.radicle.ci.broker.settings)"
      // {
        default = true;
        example = false;
      };

    settings = lib.mkOption {
      type = lib.types.submodule {
        freeformType = settingsFormat.type;

        options = {
          db = lib.mkOption {
            type = lib.types.path;
            description = "Database file path.";
            defaultText = lib.literalExpression ''"''${config.services.radicle.ci.broker.stateDir}/ci-broker.db"'';
          };

          report_dir = lib.mkOption {
            type = lib.types.nullOr lib.types.path;
            description = "Directory where HTML and JSON report pages are written.";
            defaultText = lib.literalExpression ''"''${config.services.radicle.ci.broker.stateDir}/reports"'';
          };

          adapters = lib.mkOption {
            type = lib.types.attrsOf (
              lib.types.submodule {
                freeformType = settingsFormat.type;

                options = {
                  command = lib.mkOption {
                    type = lib.types.str;
                    description = "Adapter command to run.";
                  };
                  env = lib.mkOption {
                    type = lib.types.attrsOf settingsFormat.type;
                    description = "Environment variables to add when running the adapter.";
                    default = { };
                  };
                };
              }
            );
            description = ''
              CI adapters.
              See also the options under [services.radicle.ci.adapters](#opt-services.radicle.ci.adapters.native.instances).
            '';
            default = { };
          };

          triggers = lib.mkOption {
            type = lib.types.listOf (
              lib.types.submodule {
                freeformType = settingsFormat.type;

                options = {
                  adapter = lib.mkOption {
                    type = lib.types.str;
                    description = "Adapter name.";
                  };

                  filters = lib.mkOption {
                    type = lib.types.listOf settingsFormat.type;
                    description = "Trigger filter.";
                  };
                };
              }
            );
            description = "CI triggers.";
            default = [ ];
          };
        };
      };
      description = ''
        Configuration of radicle-ci-broker.
        See <https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:zwTxygwuz5LDGBq255RA2CbNGrz8/tree/doc/userguide.md#configuration> for more information.
      '';
      default = { };
      example = lib.literalExpression ''
        {
          adapters.native = {
            command = lib.getExe pkgs.radicle-native-ci;
            config = { };
            config_env = "RADICLE_NATIVE_CI";
            env.PATH = lib.makeBinPath (with pkgs; [ bash coreutils ]);
          };

          triggers = [
            {
              adapter = "native";
              filters = [
                {
                  And = [
                    { HasFile = ".radicle/native.yaml"; }
                    { Node = "z6MkgEMYod7Hxfy9qCvDv5hYHkZ4ciWmLFgfvm3Wn1b2w2FV"; }
                    {
                      Or = [
                        "DefaultBranch"
                        "PatchCreated"
                        "PatchUpdated"
                      ];
                    }
                  ];
                }
              ];
            }
          ];
        }
      '';
    };
  };

  config = lib.mkIf cfg.enable {
    assertions = [
      {
        assertion = config.services.radicle.enable;
        message = "radicle-ci-broker requires a local radicle node to be running.";
      }
    ];

    services.radicle.ci.broker.settings = {
      db = lib.mkDefault "${cfg.stateDir}/ci-broker.db";
      report_dir = lib.mkDefault "${cfg.stateDir}/reports";
    };

    systemd.services.radicle-ci-broker = {
      wantedBy = [ "multi-user.target" ];

      bindsTo = [ "radicle-node.service" ];
      after = [ "radicle-node.service" ];

      environment = { inherit RAD_HOME; };

      serviceConfig = lib.mkMerge [
        {
          User = config.users.users.radicle.name;
          Group = config.users.groups.radicle.name;
          Restart = "always";

          StateDirectory = lib.mkIf (cfg.stateDir == "/var/lib/radicle-ci") "radicle-ci";
          LogsDirectory = lib.mkIf (cfg.logDir == "/var/log/radicle-ci") "radicle-ci";
          RuntimeDirectory = "radicle-ci-broker";
          WorkingDirectory = "/run/radicle-ci-broker";

          BindReadOnlyPaths = config.systemd.services.radicle-node.serviceConfig.BindReadOnlyPaths;
          ReadWritePaths = [ RAD_HOME ];

          ExecStart = "${lib.getExe' cfg.package "cib"} --config ${configFile} process-events";
        }

        (lib.mkIf cfg.enableHardening {
          AmbientCapabilities = "";
          CapabilityBoundingSet = [ "" ];
          DevicePolicy = "closed";
          LockPersonality = true;
          MemoryDenyWriteExecute = true;
          NoNewPrivileges = true;
          PrivateDevices = true;
          PrivateTmp = true;
          PrivateUsers = true;
          ProcSubset = "pid";
          ProtectClock = true;
          ProtectControlGroups = true;
          ProtectHome = true;
          ProtectHostname = true;
          ProtectKernelLogs = true;
          ProtectKernelModules = true;
          ProtectKernelTunables = true;
          ProtectProc = "invisible";
          ProtectSystem = "strict";
          RemoveIPC = true;
          RestrictAddressFamilies = [ "AF_INET AF_INET6 AF_UNIX" ];
          RestrictNamespaces = true;
          RestrictRealtime = true;
          RestrictSUIDSGID = true;
          SystemCallArchitectures = "native";
          SystemCallFilter = [
            "@system-service"
            "~@privileged"
            "~@resources"
          ];
          UMask = "0066";
        })
      ];
    };

    systemd.tmpfiles.settings.radicle-ci-broker.${cfg.settings.report_dir}.d = {
      user = config.users.users.radicle.name;
      group = config.users.groups.radicle.name;
    };

    environment.systemPackages = [ cibtool-system ];
  };
}
+1 −0
Original line number Diff line number Diff line
@@ -1277,6 +1277,7 @@ in
  radarr = runTest ./radarr.nix;
  radicale = runTest ./radicale.nix;
  radicle = runTest ./radicle.nix;
  radicle-ci-broker = runTest ./radicle-ci-broker.nix;
  ragnarwm = runTestOn [ "x86_64-linux" "aarch64-linux" ] ./ragnarwm.nix;
  rasdaemon = runTest ./rasdaemon.nix;
  rathole = runTest ./rathole.nix;
Loading