This is a combination of 129 commits: Initial Server Configuration Add Caddy Add Jelly Bucket to Minio Remove Podman DNS Initialize Server Configuration Directory Also replace Minio Pod w/ Nix Derivation Remove Neko/WatchThingz User Configuration (Broken, See Issue) Disable WatchThingz Add cockpit TODO: Add Cockpit Plugins TODO: Add Performance Metrics https://github.com/performancecopilot/pcp Start adding Gitea TODO: Gitea specific postgres config, determine global postgres Add Second Mass Storage Drive Add Gitea in Full Mount Both Data Dirs for Minio Add CUDA to Nvidia Add OCI Based Servers TODO: Organize into server arcitecture Add Secrets Add some nice to have packages Massive Server Upgrade Jelly s3fs mount Stats for things like Minio Usage, Logs etc. VirtualHost & Pod Cleanup Move pod import inot oci services that use them Have services define what virtualhost of caddy they belong to Migrade homeassitant and jellyfin to new dir structure Headscale and static files Directory Reorganization New Module Structure Headscale is public facing Headscale User Generation Module Finish HeadScale PreAuth Module TODO: Activation Script sketch: (Tailscale & Container) Headscale integration Add Local DNS Resolver & Local Domains Add Path to Output of ensureUsers Fix Path Setting Add Services Dir Local Join to Tailnet w/ Auth Gen Togers Uses .tv ... Move networking config Add networking to configuration.nix Update to Brdiged Networking Requirement for nspawn Fix unit definitions Cleanup defs for container support Add Minio Containers to tailnet Disable PostGresql, seems to break things Migrate to LVM Disk Fix not Using Headscale Containers Re-add Nextcloud Re Auth Prometheus for Minio Pretty Graphs Init: pre-office servers Init: pre Pterodactyl server Fix Jelly VPN Disable Grafana for Now Add VaultWarden Add Anki Add GC and Store Optimization Correct Gitea's connection to postgresql Add Vaultwarden, Remove Anki Cleanup User Depsfor Recognize Pterodactyl: Add Nspawn Service Change to Flake System Fix flake path pugs Add Hydra Add Build Machine Wings: Migrate to Nix Directly... or do tun tap. Might do latter Try to get Anki to Work It passes args properly now, but not environment variables Add NAT Passthrough on Ports Disable for now, interferes b/c of NAT Tried to enable actions Nix Serve Cache Hydra DynRun Increase port range Stop Using Pod Patch Hydra Video Group & Patches libnvidia-container ldconfig patch More patching nvidia-podman fix && jellyfin nvidia Nix cache domain Update Flake Container Deployment User & Script Add Handy Helper Deploy-scheme Forgetten Flake Update 2023-03-12 -> 2023-03-21 Update Flake Update Nextcloud 25 -> 26 Update Flake & Nvidia-Podman Update of flake broke nvidia podman, this fixes it, hopefully Latest working version Update Time! Use new Gitea Config Use new Gitea Config, properly Currently borked, need to wait, or go back to earlier working version Working now Updates Change Hydra Port Whoops, Keyboard bad Convert to String Update Time NodeJS InSecure for Now OpenSSL1.1.1t InSecure Disable Hydra Tests More insecure Update and Ethan Basic AudioBookshelf impl Add AudioBookShelf Fix Group Test Env Var Environment Wrong Location Remove TMP Env Config Dir SystemDir: Audiobookshelf Audiobook: getopt ExecStart Args for Env Correct Port Add Domain: AudioBooks Git LFS Hauk Location Tracking TODO: Change domain to whereis.chris.crompton.cc Enable Hauk Correct Hauk Port Flake Update Docker-compat Disable Recognize Setup Nextcloud 26 -> 27 Disable Podman-Nvidia Environment is clouded for some reason™️ (nvidia-container-tools makes a "docker" command visible) OctoPrint & Prusa Samba server Reorganize for Config Merge Move Nvidia Fix to File Migrate to sops-nix servers -> server Remove Old Key Things for Agenix
204 lines
6.7 KiB
Nix
204 lines
6.7 KiB
Nix
{ config, lib, pkgs, ...}:
|
|
|
|
with lib;
|
|
let
|
|
cfg = config.virtualisation.oci-containers;
|
|
proxy_env = config.networking.proxy.envVars;
|
|
|
|
runDirSetup = ''
|
|
if [ -z ''${XDG_RUNTIME_DIR} ]; then
|
|
export XDG_RUNTIME_DIR="/run/";
|
|
fi
|
|
'';
|
|
|
|
podOptions =
|
|
{ ... }: {
|
|
|
|
options = {
|
|
|
|
ports = mkOption {
|
|
type = with types; listOf str;
|
|
default = [];
|
|
description = lib.mdDoc ''
|
|
Network ports to publish from the pod to the outer host.
|
|
Valid formats:
|
|
- `<ip>:<hostPort>:<podPort>`
|
|
- `<ip>::<podPort>`
|
|
- `<hostPort>:<podPort>`
|
|
- `<podPort>`
|
|
Both `hostPort` and `podPort` can be specified as a range of
|
|
ports. When specifying ranges for both, the number of pod
|
|
ports in the range must match the number of host ports in the
|
|
range. Example: `1234-1236:1234-1236/tcp`
|
|
When specifying a range for `hostPort` only, the `podPort`
|
|
must *not* be a range. In this case, the pod port is published
|
|
somewhere within the specified `hostPort` range.
|
|
Example: `1234-1236:1234/tcp`
|
|
'';
|
|
example = literalExpression ''
|
|
[
|
|
"8080:9000"
|
|
]
|
|
'';
|
|
};
|
|
|
|
volumes = mkOption {
|
|
type = with types; listOf str;
|
|
default = [];
|
|
description = lib.mdDoc ''
|
|
List of volumes to attach to this pod.
|
|
Note that this is a list of `"src:dst"` strings to
|
|
allow for `src` to refer to `/nix/store` paths, which
|
|
would be difficult with an attribute set. There are
|
|
also a variety of mount options available as a third
|
|
field;
|
|
'';
|
|
example = literalExpression ''
|
|
[
|
|
"volume_name:/path/inside/container"
|
|
"/path/on/host:/path/inside/container"
|
|
]
|
|
'';
|
|
};
|
|
|
|
enableInfra = mkOption {
|
|
type = types.bool;
|
|
default = true;
|
|
};
|
|
|
|
infraImage = mkOption {
|
|
type = types.str;
|
|
default = "";
|
|
};
|
|
|
|
infraName = mkOption {
|
|
type = types.str;
|
|
default = "";
|
|
};
|
|
|
|
dependsOn = mkOption {
|
|
type = with types; listOf str;
|
|
default = [];
|
|
description = lib.mdDoc ''
|
|
Define which other containers this one depends on. They will be added to both After and Requires for the unit.
|
|
Use the same name as the attribute under `virtualisation.oci-containers.containers`.
|
|
'';
|
|
example = literalExpression ''
|
|
virtualisation.oci-containers.containers = {
|
|
node1 = {};
|
|
node2 = {
|
|
dependsOn = [ "node1" ];
|
|
}
|
|
}
|
|
'';
|
|
};
|
|
|
|
contains = mkOption {
|
|
type = with types; listOf str;
|
|
default = [];
|
|
description = lib.mkDoc ''
|
|
Define what containers are contained within this pod,
|
|
with shared ports and volumes as decribed above.
|
|
'';
|
|
example = literalExpression ''
|
|
virtualisation.oci-containers.containers = {
|
|
containers = {
|
|
node1 = {};
|
|
node2 = {};
|
|
};
|
|
pods = {
|
|
nodes = {
|
|
contains = [
|
|
"node1"
|
|
"node2"
|
|
];
|
|
};
|
|
};
|
|
}
|
|
'';
|
|
};
|
|
|
|
extraOptions = mkOption {
|
|
type = with types; listOf str;
|
|
default = [];
|
|
description = lib.mdDoc "Extra options for {command}`${defaultBackend} run`.";
|
|
example = literalExpression ''
|
|
["--network=host"]
|
|
'';
|
|
};
|
|
|
|
autoStart = mkOption {
|
|
type = types.bool;
|
|
default = true;
|
|
description = lib.mdDoc ''
|
|
When enabled, the container is automatically started on boot.
|
|
If this option is set to false, the container has to be started on-demand via its service.
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
mkService = name: pod: let
|
|
dependsOn = map (x: "${cfg.backend}-${x}.service") pod.dependsOn;
|
|
contains = map (x: "${cfg.backend}-${x}.service") pod.contains;
|
|
escapedName = escapeShellArg "${name}_pod";
|
|
podPID = "$XDG_RUNTIME_DIR/${escapedName}.pid";
|
|
in rec {
|
|
wantedBy = [] ++ optional (pod.autoStart) "multi-user.target";
|
|
after = dependsOn;
|
|
before = contains;
|
|
requires = dependsOn;
|
|
wants = contains;
|
|
environment = proxy_env;
|
|
path = [ config.virtualisation.podman.package ];
|
|
|
|
preStart = runDirSetup + ''
|
|
${cfg.backend} pod rm --ignore -f --pod-id-file=${podPID} || true
|
|
'';
|
|
|
|
script = runDirSetup + (concatStringsSep " \\\n " ([
|
|
"exec ${cfg.backend} pod create"
|
|
"--name=${escapedName}"
|
|
"--pod-id-file=${podPID}"
|
|
"--replace"
|
|
] ++ map escapeShellArg pod.extraOptions
|
|
++ (if pod.enableInfra then ([
|
|
"--infra-conmon-pidfile=$XDG_RUNTIME_DIR/${escapedName}-infra.pid"
|
|
(if (pod.infraImage == "") then "" else "--infra-image=${pod.infraImage}")
|
|
"--infra-name=${escapedName}-infra"
|
|
] ++ (map (p: "-p ${p}") pod.ports)
|
|
++ (map (v: "-v ${v}") pod.volumes)) else [
|
|
""
|
|
])
|
|
++ ["--infra=${lib.trivial.boolToString pod.enableInfra}"]
|
|
));
|
|
|
|
preStop = runDirSetup + "${cfg.backend} pod stop --ignore --pod-id-file=${podPID}";
|
|
postStop = runDirSetup + ''
|
|
${cfg.backend} pod rm --ignore -f --pod-id-file=${podPID} || true
|
|
rm ${podPID}
|
|
'';
|
|
|
|
serviceConfig = {
|
|
RemainAfterExit="yes";
|
|
};
|
|
};
|
|
in
|
|
{
|
|
options.virtualisation.oci-containers.pods = mkOption {
|
|
default = {};
|
|
type = types.attrsOf (types.submodule podOptions);
|
|
description = lib.mdDoc "OCI (podman) Pods to run as a systemd service";
|
|
};
|
|
config = let
|
|
merge = p: lib.lists.foldr (e1: e2: e1 // e2) {} p;
|
|
joinPods = pods: lib.lists.foldr lib.attrsets.unionOfDisjoint {} (map merge (attrValues (mapAttrs (name: pod: map (cont: {"${cont}".extraOptions=["--pod=${name}_pod"];}) pod.contains) pods)));
|
|
makeBinds = pods: lib.lists.foldr lib.attrsets.unionOfDisjoint {} (map merge (attrValues (mapAttrs (name: pod: map (cont: {"${cfg.backend}-${cont}".partOf=["${cfg.backend}_pod-${name}.service"];}) pod.contains) pods)));
|
|
test = pkgs.writeText "THISISATEST" (joinPods cfg.pods);
|
|
in lib.mkIf (cfg.pods != {}) {
|
|
systemd.services = (mapAttrs'
|
|
(n: v: nameValuePair "${cfg.backend}_pod-${n}"
|
|
(mkService n v)) cfg.pods) // (makeBinds cfg.pods);
|
|
virtualisation.oci-containers.containers = joinPods cfg.pods;
|
|
};
|
|
}
|