podman: generate v2 registries.conf

Convert `services.podman.settings.registries` output to v2 format.
Keep legacy `insecure` and `block` inputs, add `registry` entries,
and warn when legacy options are used.

Update podman configuration tests and expected registries.conf output.

Resolves #9501
This commit is contained in:
Thierry Delafontaine 2026-06-18 14:58:39 +02:00 committed by Austin Horstman
parent 78e7d8b13e
commit e3e24bfd0f
3 changed files with 160 additions and 35 deletions

View file

@ -8,15 +8,60 @@ let
cfg = config.services.podman;
toml = pkgs.formats.toml { };
registriesCfg = cfg.settings.registries;
legacyRegistryEntries =
(map (location: {
inherit location;
insecure = true;
}) registriesCfg.insecure)
++ (map (location: {
inherit location;
blocked = true;
}) registriesCfg.block);
registryEntries = lib.mapAttrsToList (
location: entries:
let
merged =
builtins.foldl'
(acc: entry: {
inherit location;
insecure = if entry ? insecure && entry.insecure != null then entry.insecure else acc.insecure;
blocked = if entry ? blocked && entry.blocked != null then entry.blocked else acc.blocked;
})
{
inherit location;
insecure = null;
blocked = null;
}
entries;
in
{
inherit (merged) location;
}
// lib.optionalAttrs (merged.insecure != null) {
inherit (merged) insecure;
}
// lib.optionalAttrs (merged.blocked != null) {
inherit (merged) blocked;
}
) (lib.groupBy (entry: entry.location) (legacyRegistryEntries ++ registriesCfg.registry));
registriesConfSettings = {
unqualified-search-registries = registriesCfg.search;
}
// lib.optionalAttrs (registryEntries != [ ]) {
registry = registryEntries;
};
configFiles = {
"policy.json" =
if cfg.settings.policy != { } then
pkgs.writeText "policy.json" (builtins.toJSON cfg.settings.policy)
else
"${pkgs.skopeo.policy}/default-policy.json";
"registries.conf" = toml.generate "registries.conf" {
registries = lib.mapAttrs (_n: v: { registries = v; }) cfg.settings.registries;
};
"registries.conf" = toml.generate "registries.conf" registriesConfSettings;
"storage.conf" = toml.generate "storage.conf" cfg.settings.storage;
"containers.conf" = toml.generate "containers.conf" cfg.settings.containers;
}
@ -91,6 +136,35 @@ in
List of blocked repositories.
'';
};
registry = lib.mkOption {
default = [ ];
type = lib.types.listOf (
lib.types.submodule {
options = {
location = lib.mkOption {
type = lib.types.str;
description = "Registry location.";
};
insecure = lib.mkOption {
type = lib.types.nullOr lib.types.bool;
default = null;
description = "Whether the registry is insecure.";
};
blocked = lib.mkOption {
type = lib.types.nullOr lib.types.bool;
default = null;
description = "Whether the registry is blocked.";
};
};
}
);
description = ''
List of per-registry configuration entries.
Prefer this over the deprecated `insecure` and `block` lists.
'';
};
};
policy = lib.mkOption {
@ -119,33 +193,49 @@ in
};
};
config = lib.mkIf cfg.enable {
home.packages = [ cfg.package ];
config = lib.mkIf cfg.enable (
lib.mkMerge [
{
home.packages = [ cfg.package ];
services.podman.settings.storage.storage.driver = lib.mkDefault "overlay";
services.podman.settings.storage.storage.driver = lib.mkDefault "overlay";
# On Linux, podman reads its configuration directly from
# `$XDG_CONFIG_HOME/containers`. On Darwin the same files are placed there
# as real files by an activation script and bind-mounted into the podman
# machine VM (see darwin.nix).
xdg.configFile = lib.mkIf pkgs.stdenv.hostPlatform.isLinux (
lib.mapAttrs' (name: src: lib.nameValuePair "containers/${name}" { source = src; }) cfg._configFiles
);
home.activation.podmanContainersConfig = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin (
lib.hm.dag.entryBetween [ "podmanMachines" ] [ "linkGeneration" ] ''
run mkdir -p "$HOME/.config/containers"
# On Linux, podman reads its configuration directly from
# `$XDG_CONFIG_HOME/containers`. On Darwin the same files are placed there
# as real files by an activation script and bind-mounted into the podman
# machine VM (see darwin.nix).
xdg.configFile = lib.mkIf pkgs.stdenv.hostPlatform.isLinux (
lib.mapAttrs' (name: src: lib.nameValuePair "containers/${name}" { source = src; }) cfg._configFiles
);
home.activation.podmanContainersConfig = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin (
lib.hm.dag.entryBetween [ "podmanMachines" ] [ "linkGeneration" ] ''
run mkdir -p "$HOME/.config/containers"
# Remove only files this module manages.
for f in ${lib.escapeShellArgs (builtins.attrNames cfg._configFiles)}; do
run rm -f "$HOME/.config/containers/$f"
done
# Remove only files this module manages.
for f in ${lib.escapeShellArgs (builtins.attrNames cfg._configFiles)}; do
run rm -f "$HOME/.config/containers/$f"
done
${lib.concatStringsSep "\n" (
lib.mapAttrsToList (
name: src: ''run install -m 0644 ${src} "$HOME/.config/containers/${name}"''
) cfg._configFiles
)}
''
);
};
${lib.concatStringsSep "\n" (
lib.mapAttrsToList (
name: src: ''run install -m 0644 ${src} "$HOME/.config/containers/${name}"''
) cfg._configFiles
)}
''
);
}
(lib.mkIf (registriesCfg.insecure != [ ] || registriesCfg.block != [ ]) {
warnings = [
''
`services.podman.settings.registries.insecure` and
`services.podman.settings.registries.block` are deprecated and will be
removed in a future release.
Use `services.podman.settings.registries.registry` entries with
`location`, `insecure`, and `blocked` instead.
''
];
})
]
);
}

View file

@ -1,8 +1,18 @@
[registries.block]
registries = ["ghcr.io", "gallery.ecr.aws"]
unqualified-search-registries = ["docker.io"]
[registries.insecure]
registries = ["quay.io"]
[[registry]]
blocked = false
location = "gallery.ecr.aws"
[registries.search]
registries = ["docker.io"]
[[registry]]
blocked = true
location = "ghcr.io"
[[registry]]
blocked = true
insecure = true
location = "quay.io"
[[registry]]
insecure = true
location = "registry.fedoraproject.org"

View file

@ -25,12 +25,26 @@
};
};
registries = {
search = [ "docker.io" ];
block = [
"ghcr.io"
"gallery.ecr.aws"
];
insecure = [ "quay.io" ];
search = [ "docker.io" ];
registry = [
{
location = "quay.io";
blocked = true;
}
{
location = "gallery.ecr.aws";
blocked = false;
}
{
location = "registry.fedoraproject.org";
insecure = true;
}
];
};
policy = {
default = [ { type = "insecureAcceptAnything"; } ];
@ -39,6 +53,17 @@
};
};
test.asserts.warnings.expected = [
''
`services.podman.settings.registries.insecure` and
`services.podman.settings.registries.block` are deprecated and will be
removed in a future release.
Use `services.podman.settings.registries.registry` entries with
`location`, `insecure`, and `blocked` instead.
''
];
nmt.script =
if pkgs.stdenv.hostPlatform.isDarwin then
''