Skip to content

Commit

Permalink
Add pod support
Browse files Browse the repository at this point in the history
Include some basic tests to ensure that the container + pod
configurations is valid.
Add test that ensures that the names for containers/pods/networks is
unique to avoid cryptic error messages.
  • Loading branch information
kai-tub committed Sep 23, 2024
1 parent ba5ab3d commit d59b1b6
Show file tree
Hide file tree
Showing 5 changed files with 295 additions and 13 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,17 @@ Compared to alternatives like [`virtualisation.oci-containers`](https://github.c
containers = {
nginx.containerConfig.image = "docker.io/library/nginx:latest";
nginx.containerConfig.networks = [ "host" "internal.network" ];
nginx.containerConfig.pod = "nginx-pod.pod";
nginx.serviceConfig.TimeoutStartSec = "60";
};
networks = {
internal.networkConfig.subnets = [ "10.0.123.1/24" ];
};
pods = {
nginx-pod = { };
};
};
}
```

See [`container.nix`](./container.nix) and [`network.nix`](./network.nix) for all options.
See [`container.nix`](./container.nix), [`network.nix`](./network.nix), and [`pod.nix`](./pod.nix) for all options.
15 changes: 10 additions & 5 deletions container.nix
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
lib,
...
}:

with lib;

let
containerOpts = {
addCapabilities = quadletUtils.mkOption {
Expand Down Expand Up @@ -259,7 +257,7 @@ let
type = types.listOf types.str;
default = [ ];
example = [ "host" ];
description = "--network";
description = "--net";
property = "Network";
};

Expand All @@ -285,6 +283,13 @@ let
property = "Notify";
};

pod = quadletUtils.mkOption {
type = types.nullOr types.str;
default = null;
description = "The full name of the pod to link to.";
property = "Pod";
};

podmanArgs = quadletUtils.mkOption {
type = types.listOf types.str;
default = [ ];
Expand Down Expand Up @@ -474,14 +479,14 @@ in
default = serviceConfigDefault;
};

_name = mkOption { internal = true; };
_configName = mkOption { internal = true; };
_unitName = mkOption { internal = true; };
_configText = mkOption { internal = true; };
};

config =
let
configRelPath = "containers/systemd/${name}.container";
containerName = if config.containerConfig.name != null then config.containerConfig.name else name;
containerConfig = config.containerConfig // {
name = containerName;
Expand All @@ -496,9 +501,9 @@ in
Container = quadletUtils.configToProperties containerConfig containerOpts;
Service = serviceConfigDefault // config.serviceConfig;
};
unitConfigText = quadletUtils.unitConfigToText unitConfig;
in
{
_name = containerName;
_configName = "${name}.container";
_unitName = "${name}.service";
_configText = quadletUtils.unitConfigToText unitConfig;
Expand Down
10 changes: 6 additions & 4 deletions network.nix
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
{ quadletUtils, pkgs }:
{
quadletUtils,
pkgs,
}:
{
config,
name,
lib,
...
}:

with lib;

let
networkOpts = {
disableDns = quadletUtils.mkOption {
Expand Down Expand Up @@ -135,13 +136,13 @@ in
};

_configName = mkOption { internal = true; };
_name = mkOption { internal = true; };
_unitName = mkOption { internal = true; };
_configText = mkOption { internal = true; };
};

config =
let
configRelPath = "containers/systemd/${name}.network";
networkName =
if config.networkConfig.name != null then config.networkConfig.name else "systemd-${name}";
networkConfig = config.networkConfig;
Expand All @@ -159,6 +160,7 @@ in
};
in
{
_name = networkName;
_configName = "${name}.network";
_unitName = "${name}-network.service";
_configText = quadletUtils.unitConfigToText unitConfig;
Expand Down
62 changes: 59 additions & 3 deletions nixos-module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
pkgs,
...
}@attrs:

with lib;

let
cfg = config.virtualisation.quadlet;
quadletUtils = import ./utils.nix {
Expand All @@ -22,6 +20,7 @@ let

containerOpts = types.submodule (import ./container.nix { inherit quadletUtils; });
networkOpts = types.submodule (import ./network.nix { inherit quadletUtils pkgs; });
podOpts = types.submodule (import ./pod.nix { inherit quadletUtils; });
in
{
options = {
Expand All @@ -35,15 +34,72 @@ in
type = types.attrsOf networkOpts;
default = { };
};

pods = mkOption {
type = types.attrsOf podOpts;
default = { };
};
};
};

config =
let
allObjects = (attrValues cfg.containers) ++ (attrValues cfg.networks);
allObjects = (attrValues cfg.containers) ++ (attrValues cfg.networks) ++ (attrValues cfg.pods);
in
{
virtualisation.podman.enable = true;
assertions =
let
count_occurances =
str_list:
lib.lists.foldl' (
acc: el: if acc ? ${el} then acc // { ${el} = acc.${el} + 1; } else acc // { ${el} = 1; }
) { } str_list;
find_duplicate_elements =
str_l: lib.attrsets.attrNames (lib.attrsets.filterAttrs (_: v: v > 1) (count_occurances str_l));
# assuming that only `name` defines the final name!
duplicate_elements = find_duplicate_elements (map (x: x._name) allObjects);
missing_pod_suffixes = lib.lists.foldl' (
acc: x:
if x.containerConfig ? pod && !(lib.strings.hasSuffix ".pod" x.containerConfig.pod) then
acc ++ [ x._name ]
else
[ ]
) [ ] (attrValues cfg.containers);
pods = map (x: x._name) (attrValues cfg.pods);
missing_pods = lib.lists.foldl' (
acc: x:
if
x.containerConfig ? pod && !(elem (lib.strings.removeSuffix ".pod" x.containerConfig.pod) pods)
then
acc ++ [ x._name ]
else
[ ]
) [ ] (attrValues cfg.containers);
in
[
{
assertion = duplicate_elements == [ ];
message = ''
The container/network/pod names should be unique!
The following names are not unique: ${lib.strings.concatStringsSep " " duplicate_elements}
'';
}
{
assertion = missing_pod_suffixes == [ ];
message = ''
The following containers have a defined a `pod`
but do not containt the required `.pod` suffix: ${lib.strings.concatStringsSep " " missing_pod_suffixes}
'';
}
{
assertion = missing_pods == [ ];
message = ''
The following containers are linked to a `pod` that isn't defined:
${lib.strings.concatStringsSep " " missing_pods}
'';
}
];
environment.etc = mergeAttrsList (
map (p: {
"containers/systemd/${p._configName}" = {
Expand Down
Loading

0 comments on commit d59b1b6

Please sign in to comment.