flake reorg

This commit is contained in:
Robin Appelman 2024-01-12 23:30:09 +01:00
commit f552f9c6cf
5 changed files with 268 additions and 232 deletions

31
flake.lock generated
View file

@ -7,32 +7,31 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1685804727, "lastModified": 1698420672,
"narHash": "sha256-9kd2ac4MmTRLDX2MnXGIzJM9eDvWocQrXhWWkWj/0zI=", "narHash": "sha256-/TdeHMPRjjdJub7p7+w55vyABrsJlt5QkznPYy55vKA=",
"owner": "icewind1991", "owner": "nix-community",
"repo": "naersk", "repo": "naersk",
"rev": "21b870efb320d44ec1c2f661f6e6e8deca9bb239", "rev": "aeb58d5e8faead8980a807c840232697982d47b9",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "icewind1991", "owner": "nix-community",
"repo": "naersk", "repo": "naersk",
"rev": "21b870efb320d44ec1c2f661f6e6e8deca9bb239",
"type": "github" "type": "github"
} }
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1685789966, "lastModified": 1705095711,
"narHash": "sha256-pyqctu5Cq1jwymO3Os0/RNj5Nm3q5kmRCT24p7gtG70=", "narHash": "sha256-//p6ObTf4udW43XmPevAvb7+SrcmFxNtYQv1rmM/3bE=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "4eaa9e3eb36386de0c6a268ba5da72cafc959619", "rev": "2932c4c3af0d213b318c25ec6b4e28db68657086",
"type": "github" "type": "github"
}, },
"original": { "original": {
"id": "nixpkgs", "id": "nixpkgs",
"ref": "release-23.05", "ref": "release-23.11",
"type": "indirect" "type": "indirect"
} }
}, },
@ -54,11 +53,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1685759304, "lastModified": 1705025860,
"narHash": "sha256-I3YBH6MS3G5kGzNuc1G0f9uYfTcNY9NYoRc3QsykLk4=", "narHash": "sha256-9vcqo5CJLOHU63S7pVlP0u4OhgJxrXebQR4vqMPXLRg=",
"owner": "oxalica", "owner": "oxalica",
"repo": "rust-overlay", "repo": "rust-overlay",
"rev": "c535b4f3327910c96dcf21851bbdd074d0760290", "rev": "d458975da373a37422577886566fce8201bc1254",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -87,11 +86,11 @@
"systems": "systems" "systems": "systems"
}, },
"locked": { "locked": {
"lastModified": 1685518550, "lastModified": 1701680307,
"narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", "rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
"type": "github" "type": "github"
}, },
"original": { "original": {

230
flake.nix
View file

@ -1,9 +1,9 @@
{ {
inputs = { inputs = {
utils.url = "github:numtide/flake-utils"; utils.url = "github:numtide/flake-utils";
naersk.url = "github:icewind1991/naersk?rev=21b870efb320d44ec1c2f661f6e6e8deca9bb239"; naersk.url = "github:nix-community/naersk";
naersk.inputs.nixpkgs.follows = "nixpkgs"; naersk.inputs.nixpkgs.follows = "nixpkgs";
nixpkgs.url = "nixpkgs/release-23.05"; nixpkgs.url = "nixpkgs/release-23.11";
rust-overlay.url = "github:oxalica/rust-overlay"; rust-overlay.url = "github:oxalica/rust-overlay";
rust-overlay.inputs.nixpkgs.follows = "nixpkgs"; rust-overlay.inputs.nixpkgs.follows = "nixpkgs";
rust-overlay.inputs.flake-utils.follows = "utils"; rust-overlay.inputs.flake-utils.follows = "utils";
@ -18,15 +18,19 @@
}: }:
utils.lib.eachDefaultSystem (system: let utils.lib.eachDefaultSystem (system: let
lib = nixpkgs.lib; lib = nixpkgs.lib;
overlays = [ (import rust-overlay) ]; overlays = [
(import rust-overlay)
(import ./overlay.nix)
];
pkgs = (import nixpkgs) { pkgs = (import nixpkgs) {
inherit system overlays; inherit system overlays;
}; };
hostTarget = pkgs.hostPlatform.config; hostTarget = pkgs.hostPlatform.config;
targets = ["x86_64-unknown-linux-musl" hostTarget]; targets = ["x86_64-unknown-linux-musl" hostTarget];
naerskForTarget = target: let naerskForTarget = target: let
toolchain = pkgs.rust-bin.stable.latest.default.override { targets = [target]; }; toolchain = pkgs.rust-bin.stable.latest.default.override {targets = [target];};
in pkgs.callPackage naersk { in
pkgs.callPackage naersk {
cargo = toolchain; cargo = toolchain;
rustc = toolchain; rustc = toolchain;
}; };
@ -37,17 +41,19 @@
root = src; root = src;
}; };
in rec { in rec {
packages = (lib.attrsets.genAttrs targets (target: (naerskForTarget target).buildPackage nearskOpt)) // rec { packages =
dispenser = hostNaersk.buildPackage nearskOpt; (lib.attrsets.genAttrs targets (target: (naerskForTarget target).buildPackage nearskOpt))
check = hostNaersk.buildPackage (nearskOpt // { checkOnly = true; }); // rec {
test = hostNaersk.buildPackage (nearskOpt // { testOnly = true; }); dispenser = pkgs.dispenser;
clippy = hostNaersk.buildPackage (nearskOpt // { clippyOnly = true; }); check = hostNaersk.buildPackage (nearskOpt // {checkOnly = true;});
test = hostNaersk.buildPackage (nearskOpt // {testOnly = true;});
clippy = hostNaersk.buildPackage (nearskOpt // {clippyOnly = true;});
dockerImage = pkgs.dockerTools.buildImage { dockerImage = pkgs.dockerTools.buildImage {
name = "spiretf/dispenser"; name = "spiretf/dispenser";
tag = "latest"; tag = "latest";
copyToRoot = [dispenser]; copyToRoot = [dispenser];
config = { config = {
Cmd = [ "${dispenser}/bin/dispenser" "/config.toml"]; Cmd = ["${dispenser}/bin/dispenser" "/config.toml"];
}; };
}; };
default = dispenser; default = dispenser;
@ -58,203 +64,17 @@
}; };
}) })
// { // {
nixosModule = { overlays.default = import ./overlay.nix;
nixosModules.default = {
pkgs,
config, config,
lib, lib,
pkgs,
... ...
}: }: {
with lib; let imports = [./module.nix];
cfg = config.services.dispenser; config = lib.mkIf config.services.dispenser.enable {
format = pkgs.formats.toml {}; nixpkgs.overlays = [self.overlays.default];
configFile = format.generate "dispenser.toml" (filterAttrs (n: v: v != null) { services.dispenser.package = lib.mkDefault pkgs.dispenser;
inherit (cfg) server vultr dyndns schedule;
digital_ocean = cfg.digitalocean;
});
in {
options.services.dispenser = {
enable = mkEnableOption "Enables the dispenser service";
server = mkOption {
type = types.submodule {
options = {
rcon = mkOption {
type = types.str;
description = "Rcon password for created server";
};
password = mkOption {
type = types.str;
description = "Server password for created server";
};
demostf_key = mkOption {
type = types.str;
description = "Api key for demos.tf";
};
logstf_key = mkOption {
type = types.str;
description = "Api key for logs.tf";
};
config_league = mkOption {
type = types.str;
default = "etf2l";
description = "League of the config to load on startup";
};
config_mode = mkOption {
type = types.str;
default = "6v6";
description = "Gamemode of the config to load on startup";
};
name = mkOption {
type = types.str;
default = "Spire";
description = "Server name for the created server";
};
tv_name = mkOption {
type = types.str;
default = "SpireTV";
description = "STV name for the created server";
};
image = mkOption {
type = types.str;
default = "spiretf/docker-spire-server";
description = "Docker image to use for the server";
};
ssh_keys = mkOption {
type = types.listOf types.str;
description = "ssh keys to allow on the server";
};
manage_existing = mkOption {
type = types.bool;
description = "Take control of existing server";
};
};
};
};
vultr = mkOption {
type = types.nullOr (types.submodule {
options = {
api_key = mkOption {
type = types.str;
description = "Vultr api key";
};
region = mkOption {
type = types.str;
default = "ams";
description = "Vultr region to deploy the server in";
};
plan = mkOption {
type = types.str;
default = "vc2-1c-2gb";
description = "Vultr plan to deploy";
};
};
});
default = null;
};
digitalocean = mkOption {
type = types.nullOr (types.submodule {
options = {
api_key = mkOption {
type = types.str;
description = "DO api key";
};
region = mkOption {
type = types.str;
default = "ams3";
description = "DO region to deploy the server in";
};
plan = mkOption {
type = types.str;
default = "s-1vcpu-2gb";
description = "DO plan to deploy";
};
};
});
default = null;
};
dyndns = mkOption {
type = types.nullOr (types.submodule {
options = {
update_url = mkOption {
type = types.str;
description = "dyndns update url";
};
hostname = mkOption {
type = types.str;
description = "hostname to update";
};
username = mkOption {
type = types.str;
description = "username for the update";
};
password = mkOption {
type = types.str;
description = "password for the update";
};
};
});
default = null;
};
schedule = mkOption {
type = types.submodule {
options = {
start = mkOption {
type = types.str;
description = "start schedule in cron format";
};
stop = mkOption {
type = types.str;
description = "start schedule in cron format";
};
};
};
};
docker = mkOption rec {
type = types.bool;
default = false;
example = true;
description = "enable docker integration";
};
};
config = mkIf cfg.enable {
systemd.services.dispenser = let
pkg = self.packages.${pkgs.system}.dispenser;
in {
wantedBy = ["multi-user.target"];
script = "${pkg}/bin/dispenser ${configFile}";
serviceConfig = {
Restart = "on-failure";
DynamicUser = true;
PrivateTmp = true;
ProtectSystem = "strict";
ProtectHome = true;
NoNewPrivileges = true;
PrivateDevices = true;
ProtectClock = true;
CapabilityBoundingSet = true;
ProtectKernelLogs = true;
ProtectControlGroups = true;
SystemCallArchitectures = "native";
ProtectKernelModules = true;
RestrictNamespaces = true;
MemoryDenyWriteExecute = true;
ProtectHostname = true;
LockPersonality = true;
ProtectKernelTunables = true;
RestrictAddressFamilies = "AF_INET AF_INET6";
RestrictRealtime = true;
ProtectProc = "noaccess";
SystemCallFilter = ["@system-service" "~@resources" "~@privileged"];
IPAddressDeny = "localhost link-local multicast";
};
};
}; };
}; };
}; };

196
module.nix Normal file
View file

@ -0,0 +1,196 @@
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.services.dispenser;
format = pkgs.formats.toml {};
configFile = format.generate "dispenser.toml" (filterAttrs (n: v: v != null) {
inherit (cfg) server vultr dyndns schedule;
digital_ocean = cfg.digitalocean;
});
in {
options.services.dispenser = {
enable = mkEnableOption "Enables the dispenser service";
server = mkOption {
type = types.submodule {
options = {
rcon = mkOption {
type = types.str;
description = "Rcon password for created server";
};
password = mkOption {
type = types.str;
description = "Server password for created server";
};
demostf_key = mkOption {
type = types.str;
description = "Api key for demos.tf";
};
logstf_key = mkOption {
type = types.str;
description = "Api key for logs.tf";
};
config_league = mkOption {
type = types.str;
default = "etf2l";
description = "League of the config to load on startup";
};
config_mode = mkOption {
type = types.str;
default = "6v6";
description = "Gamemode of the config to load on startup";
};
name = mkOption {
type = types.str;
default = "Spire";
description = "Server name for the created server";
};
tv_name = mkOption {
type = types.str;
default = "SpireTV";
description = "STV name for the created server";
};
image = mkOption {
type = types.str;
default = "spiretf/docker-spire-server";
description = "Docker image to use for the server";
};
ssh_keys = mkOption {
type = types.listOf types.str;
description = "ssh keys to allow on the server";
};
manage_existing = mkOption {
type = types.bool;
description = "Take control of existing server";
};
};
};
};
vultr = mkOption {
type = types.nullOr (types.submodule {
options = {
api_key = mkOption {
type = types.str;
description = "Vultr api key";
};
region = mkOption {
type = types.str;
default = "ams";
description = "Vultr region to deploy the server in";
};
plan = mkOption {
type = types.str;
default = "vc2-1c-2gb";
description = "Vultr plan to deploy";
};
};
});
default = null;
};
digitalocean = mkOption {
type = types.nullOr (types.submodule {
options = {
api_key = mkOption {
type = types.str;
description = "DO api key";
};
region = mkOption {
type = types.str;
default = "ams3";
description = "DO region to deploy the server in";
};
plan = mkOption {
type = types.str;
default = "s-1vcpu-2gb";
description = "DO plan to deploy";
};
};
});
default = null;
};
dyndns = mkOption {
type = types.nullOr (types.submodule {
options = {
update_url = mkOption {
type = types.str;
description = "dyndns update url";
};
hostname = mkOption {
type = types.str;
description = "hostname to update";
};
username = mkOption {
type = types.str;
description = "username for the update";
};
password = mkOption {
type = types.str;
description = "password for the update";
};
};
});
default = null;
};
schedule = mkOption {
type = types.submodule {
options = {
start = mkOption {
type = types.str;
description = "start schedule in cron format";
};
stop = mkOption {
type = types.str;
description = "start schedule in cron format";
};
};
};
};
package = mkOption {
type = types.package;
defaultText = literalExpression "pkgs.dispenser";
description = "package to use";
};
};
config = mkIf cfg.enable {
systemd.services.dispenser = {
wantedBy = ["multi-user.target"];
script = "${cfg.package}/bin/dispenser ${configFile}";
serviceConfig = {
Restart = "on-failure";
DynamicUser = true;
PrivateTmp = true;
ProtectSystem = "strict";
ProtectHome = true;
NoNewPrivileges = true;
PrivateDevices = true;
ProtectClock = true;
CapabilityBoundingSet = true;
ProtectKernelLogs = true;
ProtectControlGroups = true;
SystemCallArchitectures = "native";
ProtectKernelModules = true;
RestrictNamespaces = true;
MemoryDenyWriteExecute = true;
ProtectHostname = true;
LockPersonality = true;
ProtectKernelTunables = true;
RestrictAddressFamilies = "AF_INET AF_INET6";
RestrictRealtime = true;
ProtectProc = "noaccess";
SystemCallFilter = ["@system-service" "~@resources" "~@privileged"];
IPAddressDeny = "localhost link-local multicast";
};
};
};
}

3
overlay.nix Normal file
View file

@ -0,0 +1,3 @@
final: prev: {
dispenser = final.callPackage ./package.nix {};
}

18
package.nix Normal file
View file

@ -0,0 +1,18 @@
{
stdenv,
rustPlatform,
lib,
}: let
inherit (lib.sources) sourceByRegex;
src = sourceByRegex ./. ["Cargo.*" "(src)(/.*)?"];
in
rustPlatform.buildRustPackage rec {
name = "dispenser";
version = "0.1.0";
inherit src;
cargoLock = {
lockFile = ./Cargo.lock;
};
}