From ae9a8be6fee184d606e278be771384081ac8fee3 Mon Sep 17 00:00:00 2001 From: Gabriel Arazas Date: Mon, 9 Dec 2024 19:12:10 +0800 Subject: [PATCH] nixos/virtualisation/oci-containers/networks: init --- modules/nixos/default.nix | 1 + .../virtualisation/oci-containers/default.nix | 5 + .../oci-containers/networks.nix | 98 +++++++++++++++++++ 3 files changed, 104 insertions(+) create mode 100644 modules/nixos/virtualisation/oci-containers/default.nix create mode 100644 modules/nixos/virtualisation/oci-containers/networks.nix diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix index 6f58da47..6bf4f54e 100644 --- a/modules/nixos/default.nix +++ b/modules/nixos/default.nix @@ -16,5 +16,6 @@ ./services/vouch-proxy.nix ./services/yt-dlp.nix ./xdg/mime-desktop-specific.nix + ./virtualisation/oci-containers ]; } diff --git a/modules/nixos/virtualisation/oci-containers/default.nix b/modules/nixos/virtualisation/oci-containers/default.nix new file mode 100644 index 00000000..5126b779 --- /dev/null +++ b/modules/nixos/virtualisation/oci-containers/default.nix @@ -0,0 +1,5 @@ +{ + imports = [ + ./networks.nix + ]; +} diff --git a/modules/nixos/virtualisation/oci-containers/networks.nix b/modules/nixos/virtualisation/oci-containers/networks.nix new file mode 100644 index 00000000..ffe3f768 --- /dev/null +++ b/modules/nixos/virtualisation/oci-containers/networks.nix @@ -0,0 +1,98 @@ +{ config, lib, options, pkgs, ... }: + +let + cfg = config.virtualisation.oci-containers; + inherit (lib) escapeShellArg; + + networkVolume = { config, lib, ... }: { + options = { + labels = lib.mkOption { + type = with lib.types; attrsOf str; + default = { }; + description = '' + A list of labels to be attached to the network at runtime. + ''; + example = { + "foo" = "baz"; + }; + }; + + ipv6 = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Enable IPv6 networking"; + example = false; + }; + + extraOptions = lib.mkOption { + type = with lib.types; listOf str; + description = '' + A list of extra arguments to be passed to {command}`${options.virtualisation.oci-containers.backend.default} run`. + ''; + default = [ ]; + }; + + preRunExtraOptions = lib.mkOption { + type = with lib.types; listOf str; + description = '' + A list of extra arguments to be passed to {command}`${options.virtualisation.oci-containers.backend.default}`. + ''; + default = [ ]; + }; + }; + + config.extraOptions = + lib.optionals config.ipv6 [ "--ipv6" ] + ++ lib.mapAttrsToList (name: value: "--label ${name}=${value}") config.labels; + }; + + mkService = name: value: let + removeScript = + if cfg.backend == "podman" + then "podman network rm --force ${name}" + else "${cfg.backend} network rm -f ${name}"; + + preStartScript = pkgs.writeShellScript "pre-start-oci-container-network-${name}" '' + ${removeScript} + ''; + in { + path = + if cfg.backend == "docker" then [ config.virtualisation.docker.package ] + else if cfg.backend == "podman" then [ config.virtualisation.podman.package ] + else throw "Unhandled backend: ${cfg.backend}"; + script = lib.concatStringsSep " \\\n " ([ + "exec ${cfg.backend} " + ] ++ (map escapeShellArg value.preRunExtraOptions) ++ [ + "network create" + ] ++ (map escapeShellArg value.extraOptions) ++ [ + name + ]); + postStop = removeScript; + + serviceConfig = { + ExecStartPre = [ preStartScript ]; + Type = "oneshot"; + RemainAfterExit = true; + }; + + before = [ "multi-user.target" ]; + wantedBy = [ "multi-user.target" ]; + }; +in +{ + options.virtualisation.oci-containers.networks = lib.mkOption { + type = with lib.types; attrsOf (submodule networkVolume); + description = '' + A set of networks to be created into the container engine at runtime. + ''; + default = { }; + example = { + penpot = { }; + foo.labels = { "bar" = "baz"; }; + }; + }; + + config = lib.mkIf (cfg.networks != { }) { + systemd.services = lib.mapAttrs' (n: v: lib.nameValuePair "${cfg.backend}-network-${n}" (mkService n v)) cfg.networks; + }; +}