mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-23 14:11:36 +00:00
nixos/hercules-ci-agent: init
This commit is contained in:
parent
0149bdac53
commit
346a1b0ec6
|
@ -175,6 +175,11 @@ GRANT ALL PRIVILEGES ON *.* TO 'mysql'@'localhost' WITH GRANT OPTION;
|
|||
<para>
|
||||
There is a new <xref linkend="opt-security.doas.enable"/> module that provides <command>doas</command>, a lighter alternative to <command>sudo</command> with many of the same features.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<link xlink:href="https://hercules-ci.com">Hercules CI</link> Agent is a specialized build agent for projects built with Nix. See the <link xlink:href="https://nixos.org/nixos/options.html#services.hercules-ci-agent">options</link> and <link xlink:href="https://docs.hercules-ci.com/hercules-ci/getting-started/#deploy-agent">setup</link>.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
|
|
|
@ -263,6 +263,7 @@
|
|||
./services/continuous-integration/buildbot/worker.nix
|
||||
./services/continuous-integration/buildkite-agents.nix
|
||||
./services/continuous-integration/hail.nix
|
||||
./services/continuous-integration/hercules-ci-agent/default.nix
|
||||
./services/continuous-integration/hydra/default.nix
|
||||
./services/continuous-integration/gitlab-runner.nix
|
||||
./services/continuous-integration/gocd-agent/default.nix
|
||||
|
|
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
|
||||
This file is for options that NixOS and nix-darwin have in common.
|
||||
|
||||
Platform-specific code is in the respective default.nix files.
|
||||
|
||||
*/
|
||||
|
||||
{ config, lib, options, pkgs, ... }:
|
||||
|
||||
let
|
||||
inherit (lib) mkOption mkIf types filterAttrs literalExample mkRenamedOptionModule;
|
||||
|
||||
cfg =
|
||||
config.services.hercules-ci-agent;
|
||||
|
||||
format = pkgs.formats.toml {};
|
||||
|
||||
settingsModule = { config, ... }: {
|
||||
freeformType = format.type;
|
||||
options = {
|
||||
baseDirectory = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/hercules-ci-agent";
|
||||
description = ''
|
||||
State directory (secrets, work directory, etc) for agent
|
||||
'';
|
||||
};
|
||||
concurrentTasks = mkOption {
|
||||
description = ''
|
||||
Number of tasks to perform simultaneously, such as evaluations, derivations.
|
||||
|
||||
You must have a total capacity across agents of at least 2 concurrent tasks on <literal>x86_64-linux</literal>
|
||||
to allow for import from derivation.
|
||||
'';
|
||||
type = types.int;
|
||||
default = 4;
|
||||
};
|
||||
workDirectory = mkOption {
|
||||
description = ''
|
||||
The directory in which temporary subdirectories are created for task state. This includes sources for Nix evaluation.
|
||||
'';
|
||||
type = types.path;
|
||||
default = config.baseDirectory + "/work";
|
||||
defaultText = literalExample ''baseDirectory + "/work"'';
|
||||
};
|
||||
staticSecretsDirectory = mkOption {
|
||||
description = ''
|
||||
This is the default directory to look for statically configured secrets like <literal>cluster-join-token.key</literal>.
|
||||
'';
|
||||
type = types.path;
|
||||
default = config.baseDirectory + "/secrets";
|
||||
defaultText = literalExample ''baseDirectory + "/secrets"'';
|
||||
};
|
||||
clusterJoinTokenPath = mkOption {
|
||||
description = ''
|
||||
Location of the cluster-join-token.key file.
|
||||
'';
|
||||
type = types.path;
|
||||
default = config.staticSecretsDirectory + "/cluster-join-token.key";
|
||||
defaultText = literalExample ''staticSecretsDirectory + "/cluster-join-token.key"'';
|
||||
# internal: It's a bit too detailed to show by default in the docs,
|
||||
# but useful to define explicitly to allow reuse by other modules.
|
||||
internal = true;
|
||||
};
|
||||
binaryCachesPath = mkOption {
|
||||
description = ''
|
||||
Location of the binary-caches.json file.
|
||||
'';
|
||||
type = types.path;
|
||||
default = config.staticSecretsDirectory + "/binary-caches.json";
|
||||
defaultText = literalExample ''staticSecretsDirectory + "/binary-caches.json"'';
|
||||
# internal: It's a bit too detailed to show by default in the docs,
|
||||
# but useful to define explicitly to allow reuse by other modules.
|
||||
internal = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
checkNix =
|
||||
if !cfg.checkNix
|
||||
then ""
|
||||
else if lib.versionAtLeast config.nix.package.version "2.4.0"
|
||||
then ""
|
||||
else pkgs.stdenv.mkDerivation {
|
||||
name = "hercules-ci-check-system-nix-src";
|
||||
inherit (config.nix.package) src patches;
|
||||
configurePhase = ":";
|
||||
buildPhase = ''
|
||||
echo "Checking in-memory pathInfoCache expiry"
|
||||
if ! grep 'struct PathInfoCacheValue' src/libstore/store-api.hh >/dev/null; then
|
||||
cat 1>&2 <<EOF
|
||||
|
||||
You are deploying Hercules CI Agent on a system with an incompatible
|
||||
nix-daemon. Please
|
||||
- either upgrade Nix to version 2.4.0 (when released),
|
||||
- or set option services.hercules-ci-agent.patchNix = true;
|
||||
- or set option nix.package to a build of Nix 2.3 with this patch applied:
|
||||
https://github.com/NixOS/nix/pull/3405
|
||||
|
||||
The patch is required for Nix-daemon clients that expect a change in binary
|
||||
cache contents while running, like the agent's evaluator. Without it, import
|
||||
from derivation will fail if your cluster has more than one machine.
|
||||
We are conservative with changes to the overall system, which is why we
|
||||
keep changes to a minimum and why we ask for confirmation in the form of
|
||||
services.hercules-ci-agent.patchNix = true before applying.
|
||||
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
'';
|
||||
installPhase = "touch $out";
|
||||
};
|
||||
|
||||
patchedNix = lib.mkIf (!lib.versionAtLeast pkgs.nix.version "2.4.0") (
|
||||
if lib.versionAtLeast pkgs.nix.version "2.4pre"
|
||||
then lib.warn "Hercules CI Agent module will not patch 2.4 pre-release. Make sure it includes (equivalently) PR #3043, commit d048577909 or is no older than 2020-03-13." pkgs.nix
|
||||
else pkgs.nix.overrideAttrs (
|
||||
o: {
|
||||
patches = (o.patches or []) ++ [ backportNix3398 ];
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
backportNix3398 = pkgs.fetchurl {
|
||||
url = "https://raw.githubusercontent.com/hercules-ci/hercules-ci-agent/hercules-ci-agent-0.7.3/for-upstream/issue-3398-path-info-cache-ttls-backport-2.3.patch";
|
||||
sha256 = "0jfckqjir9il2il7904yc1qyadw366y7xqzg81sp9sl3f1pw70ib";
|
||||
};
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(mkRenamedOptionModule ["services" "hercules-ci-agent" "extraOptions"] ["services" "hercules-ci-agent" "settings"])
|
||||
(mkRenamedOptionModule ["services" "hercules-ci-agent" "baseDirectory"] ["services" "hercules-ci-agent" "settings" "baseDirectory"])
|
||||
(mkRenamedOptionModule ["services" "hercules-ci-agent" "concurrentTasks"] ["services" "hercules-ci-agent" "settings" "concurrentTasks"])
|
||||
];
|
||||
|
||||
options.services.hercules-ci-agent = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Enable to run Hercules CI Agent as a system service.
|
||||
|
||||
<link xlink:href="https://hercules-ci.com">Hercules CI</link> is a
|
||||
continuous integation service that is centered around Nix.
|
||||
|
||||
Support is available at <link xlink:href="mailto:help@hercules-ci.com">help@hercules-ci.com</link>.
|
||||
'';
|
||||
};
|
||||
patchNix = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Fix Nix 2.3 cache path metadata caching behavior. Has the effect of <literal>nix.package = patch pkgs.nix;</literal>
|
||||
|
||||
This option will be removed when Hercules CI Agent moves to Nix 2.4 (upcoming Nix release).
|
||||
'';
|
||||
};
|
||||
checkNix = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to make sure that the system's Nix (nix-daemon) is compatible.
|
||||
|
||||
If you set this to false, please keep up with the change log.
|
||||
'';
|
||||
};
|
||||
package = mkOption {
|
||||
description = ''
|
||||
Package containing the bin/hercules-ci-agent executable.
|
||||
'';
|
||||
type = types.package;
|
||||
default = pkgs.hercules-ci-agent;
|
||||
defaultText = literalExample "pkgs.hercules-ci-agent";
|
||||
};
|
||||
settings = mkOption {
|
||||
description = ''
|
||||
These settings are written to the <literal>agent.toml</literal> file.
|
||||
|
||||
Not all settings are listed as options, can be set nonetheless.
|
||||
|
||||
For the exhaustive list of settings, see <link xlink:href="https://docs.hercules-ci.com/hercules-ci/reference/agent-config/"/>.
|
||||
'';
|
||||
type = types.submoduleWith { modules = [ settingsModule ]; };
|
||||
};
|
||||
|
||||
/*
|
||||
Internal and/or computed values.
|
||||
|
||||
These are written as options instead of let binding to allow sharing with
|
||||
default.nix on both NixOS and nix-darwin.
|
||||
*/
|
||||
tomlFile = mkOption {
|
||||
type = types.path;
|
||||
internal = true;
|
||||
defaultText = "generated hercules-ci-agent.toml";
|
||||
description = ''
|
||||
The fully assembled config file.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
nix.extraOptions = lib.addContextFrom checkNix ''
|
||||
# A store path that was missing at first may well have finished building,
|
||||
# even shortly after the previous lookup. This *also* applies to the daemon.
|
||||
narinfo-cache-negative-ttl = 0
|
||||
'';
|
||||
nix.package = mkIf cfg.patchNix patchedNix;
|
||||
services.hercules-ci-agent.tomlFile =
|
||||
format.generate "hercules-ci-agent.toml" cfg.settings;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
|
||||
This file is for NixOS-specific options and configs.
|
||||
|
||||
Code that is shared with nix-darwin goes in common.nix.
|
||||
|
||||
*/
|
||||
|
||||
{ pkgs, config, lib, ... }:
|
||||
|
||||
let
|
||||
|
||||
inherit (lib) mkIf mkDefault;
|
||||
|
||||
cfg = config.services.hercules-ci-agent;
|
||||
|
||||
command = "${cfg.package}/bin/hercules-ci-agent --config ${cfg.tomlFile}";
|
||||
testCommand = "${command} --test-configuration";
|
||||
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./common.nix
|
||||
(lib.mkRenamedOptionModule ["services" "hercules-ci-agent" "user"] ["systemd" "services" "hercules-ci-agent" "serviceConfig" "User"])
|
||||
];
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
systemd.services.hercules-ci-agent = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
path = [ config.nix.package ];
|
||||
serviceConfig = {
|
||||
User = "hercules-ci-agent";
|
||||
ExecStart = command;
|
||||
ExecStartPre = testCommand;
|
||||
Restart = "on-failure";
|
||||
RestartSec = 120;
|
||||
StartLimitBurst = 30 * 1000000; # practically infinite
|
||||
};
|
||||
};
|
||||
|
||||
# Changes in the secrets do not affect the unit in any way that would cause
|
||||
# a restart, which is currently necessary to reload the secrets.
|
||||
systemd.paths.hercules-ci-agent-restart-files = {
|
||||
wantedBy = [ "hercules-ci-agent.service" ];
|
||||
pathConfig = {
|
||||
Unit = "hercules-ci-agent-restarter.service";
|
||||
PathChanged = [ cfg.settings.clusterJoinTokenPath cfg.settings.binaryCachesPath ];
|
||||
};
|
||||
};
|
||||
systemd.services.hercules-ci-agent-restarter = {
|
||||
serviceConfig.Type = "oneshot";
|
||||
script = ''
|
||||
# Wait a bit, with the effect of bundling up file changes into a single
|
||||
# run of this script and hopefully a single restart.
|
||||
sleep 10
|
||||
if systemctl is-active --quiet hercules-ci-agent.service; then
|
||||
if ${testCommand}; then
|
||||
systemctl restart hercules-ci-agent.service
|
||||
else
|
||||
echo 1>&2 "WARNING: Not restarting agent because config is not valid at this time."
|
||||
fi
|
||||
else
|
||||
echo 1>&2 "Not restarting hercules-ci-agent despite config file update, because it is not already active."
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
# Trusted user allows simplified configuration and better performance
|
||||
# when operating in a cluster.
|
||||
nix.trustedUsers = [ config.systemd.services.hercules-ci-agent.serviceConfig.User ];
|
||||
services.hercules-ci-agent.settings.nixUserIsTrusted = true;
|
||||
|
||||
users.users.hercules-ci-agent = {
|
||||
home = cfg.settings.baseDirectory;
|
||||
createHome = true;
|
||||
group = "hercules-ci-agent";
|
||||
description = "Hercules CI Agent system user";
|
||||
isSystemUser = true;
|
||||
};
|
||||
|
||||
users.groups.hercules-ci-agent = {};
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue