Skip to content

Commit

Permalink
fix: fixes escaping.
Browse files Browse the repository at this point in the history
  • Loading branch information
SEIAROTg committed Feb 24, 2025
1 parent 8cb4a9c commit ab4d525
Show file tree
Hide file tree
Showing 9 changed files with 192 additions and 15 deletions.
22 changes: 21 additions & 1 deletion container.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ let
example = [ "NET_ADMIN" ];
description = "--cap-add";
property = "AddCapability";
encoding = "quoted_unescaped";
};

addHosts = quadletUtils.mkOption {
Expand All @@ -31,6 +32,7 @@ let
example = [ "/dev/foo" ];
description = "--device";
property = "AddDevice";
encoding = "quoted_unescaped";
};

annotations = quadletUtils.mkOption {
Expand All @@ -39,6 +41,7 @@ let
example = [ "XYZ" ];
description = "--annotation";
property = "Annotation";
encoding = "quoted_escaped";
};

autoUpdate = quadletUtils.mkOption {
Expand Down Expand Up @@ -108,6 +111,7 @@ let
example = [ "NET_ADMIN" ];
description = "--cap-drop";
property = "DropCapability";
encoding = "quoted_unescaped";
};

entrypoint = quadletUtils.mkOption {
Expand All @@ -126,6 +130,7 @@ let
};
description = "--env";
property = "Environment";
encoding = "quoted_escaped";
};

environmentFiles = quadletUtils.mkOption {
Expand All @@ -134,6 +139,7 @@ let
example = [ "/tmp/env" ];
description = "--env-file";
property = "EnvironmentFile";
encoding = "quoted_escaped";
};

environmentHost = quadletUtils.mkOption {
Expand All @@ -144,11 +150,12 @@ let
};

exec = quadletUtils.mkOption {
type = types.nullOr types.str;
type = types.nullOr (types.oneOf [ types.str (types.listOf types.str) ]);
default = null;
example = "/usr/bin/command";
description = "Command after image specification";
property = "Exec";
encoding = "quoted_escaped_singleline";
};

exposePorts = quadletUtils.mkOption {
Expand All @@ -165,6 +172,7 @@ let
example = [ "0:10000:10" ];
description = "--gidmap";
property = "GIDMap";
encoding = "quoted_unescaped";
};

globalArgs = quadletUtils.mkOption {
Expand All @@ -173,6 +181,7 @@ let
example = [ "--log-level=debug" ];
description = "global args";
property = "GlobalArgs";
encoding = "quoted_escaped";
};

group = quadletUtils.mkOption {
Expand Down Expand Up @@ -341,6 +350,7 @@ let
example = [ "XYZ" ];
description = "--label";
property = "Label";
encoding = "quoted_escaped";
};

logDriver = quadletUtils.mkOption {
Expand All @@ -357,6 +367,7 @@ let
example = [ "path=/var/log/mykube.json" ];
description = "--log-opt";
property = "LogOpt";
encoding = "quoted_unescaped";
};

mask = quadletUtils.mkOption {
Expand All @@ -365,6 +376,7 @@ let
example = "/proc/sys/foo:/proc/sys/bar";
description = "--security-opt mask=...";
property = "Mask";
encoding = "quoted_escaped";
};

mounts = quadletUtils.mkOption {
Expand All @@ -373,6 +385,7 @@ let
example = [ "type=..." ];
description = "--mount";
property = "Mount";
encoding = "quoted_escaped";
};

networks = quadletUtils.mkOption {
Expand Down Expand Up @@ -426,6 +439,7 @@ let
example = [ "--add-host foobar" ];
description = "Additional podman arguments";
property = "PodmanArgs";
encoding = "quoted_escaped";
};

publishPorts = quadletUtils.mkOption {
Expand Down Expand Up @@ -487,6 +501,7 @@ let
example = [ "secret[,opt=opt …]" ];
description = "--secret";
property = "Secret";
encoding = "quoted_escaped";
};

securityLabelDisable = quadletUtils.mkOption {
Expand Down Expand Up @@ -582,6 +597,7 @@ let
};
description = "--sysctl";
property = "Sysctl";
encoding = "quoted_unescaped";
};

timezone = quadletUtils.mkOption {
Expand All @@ -606,6 +622,7 @@ let
example = [ "0:10000:10" ];
description = "--uidmap";
property = "UIDMap";
encoding = "quoted_unescaped";
};

ulimits = quadletUtils.mkOption {
Expand All @@ -622,6 +639,7 @@ let
example = "ALL";
description = "--security-opt unmask=...";
property = "Unmask";
encoding = "quoted_escaped";
};

user = quadletUtils.mkOption {
Expand Down Expand Up @@ -691,6 +709,7 @@ in
_serviceName = mkOption { internal = true; };
_configText = mkOption { internal = true; };
_autoStart = mkOption { internal = true; };
_autoEscapeRequired = mkOption { internal = true; };
ref = mkOption { readOnly = true; };
};

Expand All @@ -714,6 +733,7 @@ in
then config.rawConfig
else quadletUtils.unitConfigToText unitConfig;
_autoStart = config.autoStart;
_autoEscapeRequired = quadletUtils.autoEscapeRequired containerConfig containerOpts;
ref = "${name}.container";
};
}
38 changes: 37 additions & 1 deletion home-manager-module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
...
}:
let
inherit (lib) types mkOption attrValues mergeAttrsList mkIf getExe;
inherit (lib) types lists strings mkOption attrNames attrValues mergeAttrsList mkIf getExe;

cfg = config.virtualisation.quadlet;
quadletUtils = import ./utils.nix {
inherit lib;
systemdUtils = (libUtils { inherit lib config pkgs; }).systemdUtils;
podmanPackage = osConfig.virtualisation.podman.package or pkgs.podman;
autoEscape = config.virtualisation.quadlet.autoEscape;
};
containerOpts = types.submodule (import ./container.nix { inherit quadletUtils; });
networkOpts = types.submodule (import ./network.nix { inherit quadletUtils; });
Expand Down Expand Up @@ -53,6 +54,15 @@ in
type = types.attrsOf volumeOpts;
default = { };
};
autoEscape = mkOption {
type = types.bool;
default = false;
description = ''
Enables appropriate quoting / escaping.
Not enabled by default to avoid breaking existing configurations. In the future this will be required.
'';
};
};
config =
let
Expand All @@ -64,6 +74,32 @@ in
]);
in
{
assertions =
let
containerPodConflicts = lists.intersectLists (attrNames cfg.containers) (attrNames cfg.pods);
in
[
{
assertion = containerPodConflicts == [ ];
message = ''
The container/pod names should be unique!
See: https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html#podname
The following names are not unique: ${strings.concatStringsSep " " containerPodConflicts}
'';
}
];
warnings =
quadletUtils.assertionsToWarnings [
{
assertion = !(builtins.any (p: p._autoEscapeRequired) allObjects);
message = ''
`virtualisation.quadlet.autoEscape = true` is required because this configuration contains characters that require quoting or escaping.
This will become a hard error in the future. If you have manual quoting or escaping in place, please undo those and enable `autoEscape`.
'';
}
];

home.activation.quadletNix = mkIf (lib.length allObjects > 0) activationScript;

xdg.configFile =
Expand Down
6 changes: 6 additions & 0 deletions network.nix
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ let
example = [ "--log-level=debug" ];
description = "global args";
property = "GlobalArgs";
encoding = "quoted_escaped";
};

internal = quadletUtils.mkOption {
Expand Down Expand Up @@ -106,6 +107,7 @@ let
example = [ "XYZ" ];
description = "--label";
property = "Label";
encoding = "quoted_escaped";
};

name = quadletUtils.mkOption {
Expand All @@ -122,6 +124,7 @@ let
example = "isolate";
description = "--opt";
property = "Options";
encoding = "quoted_escaped";
};

podmanArgs = quadletUtils.mkOption {
Expand All @@ -130,6 +133,7 @@ let
example = [ "--dns=192.168.55.1" ];
description = "extra arguments to podman";
property = "PodmanArgs";
encoding = "quoted_escaped";
};

subnets = quadletUtils.mkOption {
Expand Down Expand Up @@ -170,6 +174,7 @@ in
_serviceName = mkOption { internal = true; };
_configText = mkOption { internal = true; };
_autoStart = mkOption { internal = true; };
_autoEscapeRequired = mkOption { internal = true; };
ref = mkOption { readOnly = true; };
};

Expand All @@ -194,6 +199,7 @@ in
then config.rawConfig
else quadletUtils.unitConfigToText unitConfig;
_autoStart = config.autoStart;
_autoEscapeRequired = quadletUtils.autoEscapeRequired networkConfig networkOpts;
ref = "${name}.network";
};
}
22 changes: 22 additions & 0 deletions nixos-module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ let
inherit lib;
systemdUtils = (libUtils { inherit lib config pkgs; }).systemdUtils;
podmanPackage = config.virtualisation.podman.package;
autoEscape = config.virtualisation.quadlet.autoEscape;
};

containerOpts = types.submodule (import ./container.nix { inherit quadletUtils; });
Expand Down Expand Up @@ -42,6 +43,16 @@ in
type = types.attrsOf volumeOpts;
default = { };
};

autoEscape = mkOption {
type = types.bool;
default = false;
description = ''
Enables appropriate quoting / escaping.
Not enabled by default to avoid breaking existing configurations. In the future this will be required.
'';
};
};
};

Expand Down Expand Up @@ -70,6 +81,17 @@ in
'';
}
];
warnings =
quadletUtils.assertionsToWarnings [
{
assertion = !(builtins.any (p: p._autoEscapeRequired) allObjects);
message = ''
`virtualisation.quadlet.autoEscape = true` is required because this configuration contains characters that require quoting or escaping.
This will become a hard error in the future. If you have manual quoting or escaping in place, please undo those and enable `autoEscape`.
'';
}
];
environment.etc =
# TODO: switch to `systemd.user.generators` once 24.11 is released.
# Ensure podman-user-generator is available for systemd user services.
Expand Down
6 changes: 6 additions & 0 deletions pod.nix
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ let
example = [ "0:10000:10" ];
description = "--gidmap";
property = "GIDMap";
encoding = "quoted_unescaped";
};

globalArgs = quadletUtils.mkOption {
Expand All @@ -71,6 +72,7 @@ let
example = [ "--log-level=debug" ];
description = "global args";
property = "GlobalArgs";
encoding = "quoted_escaped";
};

ip = quadletUtils.mkOption {
Expand Down Expand Up @@ -111,6 +113,7 @@ let
example = [ "--cpus=2" ];
description = "Additional podman arguments";
property = "PodmanArgs";
encoding = "quoted_escaped";
};

publishPorts = quadletUtils.mkOption {
Expand Down Expand Up @@ -151,6 +154,7 @@ let
example = [ "0:10000:10" ];
description = "--uidmap";
property = "UIDMap";
encoding = "quoted_unescaped";
};

userns = quadletUtils.mkOption {
Expand Down Expand Up @@ -199,6 +203,7 @@ in
_serviceName = mkOption { internal = true; };
_configText = mkOption { internal = true; };
_autoStart = mkOption { internal = true; };
_autoEscapeRequired = mkOption { internal = true; };
ref = mkOption { readOnly = true; };
};

Expand All @@ -225,6 +230,7 @@ in
_configText = if config.rawConfig != null
then config.rawConfig
else quadletUtils.unitConfigToText unitConfig;
_autoEscapeRequired = quadletUtils.autoEscapeRequired podConfig podOpts;
_autoStart = config.autoStart;
ref = "${name}.pod";
};
Expand Down
Loading

0 comments on commit ab4d525

Please sign in to comment.