Created
July 5, 2022 18:07
-
-
Save corpix/3b82218f340855b03b06757f6efd6c4d to your computer and use it in GitHub Desktop.
AgolaCI Nix integration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ pkgs ? import <nixpkgs> {} }: | |
pkgs.buildGoModule { | |
name = "agola"; | |
src = pkgs.fetchFromGitHub { | |
owner = "agola-io"; | |
repo = "agola"; | |
rev = "v0.7.0"; | |
sha256 = "sha256-AiD7mVogWk/TOYy7Ed1aT31h1kbrRwseue5qc3wLOCI="; | |
}; | |
doCheck = false; | |
vendorSha256 = "sha256-Y3ck7Qdo9uq3YuLzZUe+RZkKQqWpSko3q+f4bfkSz6g="; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ config, lib, pkgs, ... }: let | |
inherit (builtins) | |
toString | |
toJSON | |
; | |
inherit (pkgs) | |
writeText | |
; | |
inherit (lib) | |
mkIf | |
mkOption | |
mkDefault | |
types | |
concatStringsSep | |
optional | |
optionals | |
optionalAttrs | |
; | |
cfg = config.services.agola; | |
in { | |
options.services.agola = { | |
enable = mkOption { | |
description = "Whether to enable agola"; | |
type = types.bool; | |
default = false; | |
}; | |
dataDir = mkOption { | |
description = "Agola data directory"; | |
type = types.path; | |
default = "/var/lib/agola"; | |
}; | |
components = mkOption { | |
description = "List of components to activate for this instance"; | |
type = types.listOf (types.enum [ | |
"all-base" | |
"gateway" | |
"scheduler" | |
"notification" | |
"runservice" | |
"executor" | |
"configstore" | |
"gitserver" | |
]); | |
default = ["all-base" "executor"]; | |
}; | |
etcd = mkOption { | |
type = types.str; | |
}; | |
web = mkOption { | |
type = types.submodule ({ config, ... }: { | |
options = { | |
api = mkOption { | |
type = types.submodule { | |
options = { | |
url = mkOption { | |
type = types.str; | |
default = config.url; | |
}; | |
}; | |
}; | |
default = {}; | |
}; | |
listen = mkOption { | |
description = "Address for server to bind to"; | |
type = types.str; | |
default = "127.0.0.1"; | |
}; | |
port = mkOption { | |
type = types.ints.unsigned; | |
default = 8080; | |
}; | |
url = mkOption { | |
type = types.str; | |
}; | |
}; | |
}); | |
default = {}; | |
}; | |
runservice = mkOption { | |
type = types.submodule ({ config, ... }: { | |
options = { | |
listen = mkOption { | |
description = "Address for server to bind to"; | |
type = types.str; | |
default = "127.0.0.1"; | |
}; | |
port = mkOption { | |
type = types.ints.unsigned; | |
default = 4000; | |
}; | |
url = mkOption { | |
type = types.str; | |
default = "http://127.0.0.1:${toString config.port}"; | |
}; | |
}; | |
}); | |
default = {}; | |
}; | |
executor = mkOption { | |
type = types.submodule ({ config, ... }: { | |
options = { | |
listen = mkOption { | |
description = "Address for server to bind to"; | |
type = types.str; | |
default = "127.0.0.1"; | |
}; | |
port = mkOption { | |
type = types.ints.unsigned; | |
default = 4001; | |
}; | |
url = mkOption { | |
type = types.str; | |
default = "http://127.0.0.1:${toString config.port}"; | |
}; | |
driver = mkOption { | |
description = "Executor driver settings describes the job execution environment"; | |
type = types.submodule { | |
options = { | |
type = mkOption { | |
description = "Executor driver type"; | |
type = types.enum ["docker" "kubernetes"]; | |
default = "docker"; | |
}; | |
}; | |
}; | |
default = {}; | |
}; | |
}; | |
}); | |
default = {}; | |
}; | |
configstore = mkOption { | |
type = types.submodule ({ config, ... }: { | |
options = { | |
listen = mkOption { | |
description = "Address for server to bind to"; | |
type = types.str; | |
default = "127.0.0.1"; | |
}; | |
port = mkOption { | |
type = types.ints.unsigned; | |
default = 4002; | |
}; | |
url = mkOption { | |
type = types.str; | |
default = "http://127.0.0.1:${toString config.port}"; | |
}; | |
}; | |
}); | |
default = {}; | |
}; | |
gitserver = mkOption { | |
type = types.submodule ({ config, ... }: { | |
options = { | |
listen = mkOption { | |
description = "Address for server to bind to"; | |
type = types.str; | |
default = "127.0.0.1"; | |
}; | |
port = mkOption { | |
type = types.ints.unsigned; | |
default = 4003; | |
}; | |
url = mkOption { | |
type = types.str; | |
default = "http://127.0.0.1:${toString config.port}"; | |
}; | |
}; | |
}); | |
default = {}; | |
}; | |
# FIXME: secrets are FUCKED | |
adminToken = mkOption { | |
description = "Password for web"; | |
type = types.str; | |
default = "root"; | |
}; | |
hmacKey = mkOption { | |
description = "Password for hmac"; | |
type = types.str; | |
default = "supersecretsigningkey"; | |
}; | |
}; | |
config = mkIf cfg.enable { | |
virtualisation.docker.enable = cfg.executor.driver.type == "docker"; | |
systemd.tmpfiles.rules = ["d '${cfg.dataDir}' 0700 agola - - -"]; | |
systemd.services.agola = let | |
configFile = writeText "config-agola.yml" (toJSON { | |
gateway = { | |
webExposedURL = "${cfg.web.url}"; | |
apiExposedURL = "${cfg.web.api.url}"; | |
runserviceURL = "${cfg.runservice.url}"; | |
configstoreURL = "${cfg.configstore.url}"; | |
gitserverURL = "${cfg.gitserver.url}"; | |
web = { | |
listenAddress = "${cfg.web.listen}:${toString cfg.web.port}"; | |
tls = false; | |
}; | |
# FIXME: those are FUCKED | |
tokenSigning = { | |
method = "hmac"; | |
key = cfg.hmacKey; | |
}; | |
adminToken = cfg.adminToken; | |
}; | |
scheduler.runserviceURL = cfg.runservice.url; | |
notification = { | |
webExposedURL = "${cfg.web.url}"; | |
runserviceURL = "${cfg.runservice.url}"; | |
configstoreURL = "${cfg.configstore.url}"; | |
etcd.endpoints = cfg.etcd; | |
}; | |
executor = { | |
dataDir = "${cfg.dataDir}/executor"; | |
toolboxPath = "${pkgs.agola}/bin"; | |
activeTasksLimit = 2; | |
driver.type = cfg.executor.driver.type; | |
allowPrivilegedContainers = false; | |
runserviceURL = cfg.runservice.url; | |
web.listenAddress = "${cfg.executor.listen}:${toString cfg.executor.port}"; | |
}; | |
configstore = { | |
dataDir = "${cfg.dataDir}/configstore"; | |
objectStorage = { | |
type = "posix"; | |
path = "${cfg.dataDir}/configstore/ost"; | |
}; | |
web.listenAddress = "${cfg.configstore.listen}:${toString cfg.configstore.port}"; | |
etcd.endpoints = cfg.etcd; | |
}; | |
gitserver = { | |
dataDir = "${cfg.dataDir}/gitserver"; | |
gatewayURL = cfg.web.url; | |
web.listenAddress = "${cfg.gitserver.listen}:${toString cfg.gitserver.port}"; | |
}; | |
runservice = { | |
dataDir = "${cfg.dataDir}/runservice"; | |
objectStorage = { | |
type = "posix"; | |
path = "${cfg.dataDir}/runservice/ost"; | |
}; | |
web.listenAddress = "${cfg.runservice.listen}:${toString cfg.runservice.port}"; | |
etcd.endpoints = cfg.etcd; | |
}; | |
}); | |
in { | |
description = "Simple build server"; | |
wantedBy = ["multi-user.target"]; | |
after = ["network.target"]; | |
unitConfig = { | |
Documentation = "https://github.com/agola-io/agola"; | |
}; | |
serviceConfig = { | |
Type = "simple"; | |
ExecStart = concatStringsSep " " [ | |
"${pkgs.agola}/bin/agola serve" | |
"--config ${configFile}" | |
"--components ${concatStringsSep "," cfg.components}" | |
]; | |
User = "agola"; | |
LimitNOFILE = mkDefault 40000; | |
}; | |
}; | |
environment.systemPackages = [pkgs.agola]; | |
users.groups.agola = {}; | |
users.users.agola = { | |
description = "Agola daemon user"; | |
home = cfg.dataDir; | |
createHome = true; | |
isSystemUser = true; | |
group = "agola"; | |
extraGroups = (optional (cfg.executor.driver.type == "docker") "docker"); | |
}; | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment