diff --git a/nixos/modules/virtualisation/oci-containers.nix b/nixos/modules/virtualisation/oci-containers.nix index d81246e31383..851726ff4cf9 100644 --- a/nixos/modules/virtualisation/oci-containers.nix +++ b/nixos/modules/virtualisation/oci-containers.nix @@ -434,6 +434,7 @@ let }; effectiveUser = container.podman.user or "root"; + inherit (config.users.users.${effectiveUser}) uid; dependOnLingerService = cfg.backend == "podman" && effectiveUser != "root" && config.users.users.${effectiveUser}.linger; in @@ -441,7 +442,7 @@ let wantedBy = [ ] ++ optional (container.autoStart) "multi-user.target"; wants = lib.optional (container.imageFile == null && container.imageStream == null) "network-online.target" - ++ lib.optional dependOnLingerService "linger-users.service"; + ++ lib.optionals dependOnLingerService [ "linger-users.service" ]; after = lib.optionals (cfg.backend == "docker") [ "docker.service" @@ -452,8 +453,15 @@ let "network-online.target" ] ++ dependsOn - ++ lib.optional dependOnLingerService "linger-users.service"; - requires = dependsOn; + ++ lib.optionals dependOnLingerService [ "linger-users.service" ] + ++ lib.optionals (effectiveUser != "root" && container.podman.sdnotify == "healthy") [ + "user@${toString uid}.service" + ]; + requires = + dependsOn + ++ lib.optionals (effectiveUser != "root" && container.podman.sdnotify == "healthy") [ + "user@${toString uid}.service" + ]; environment = lib.mkMerge [ proxy_env (mkIf (cfg.backend == "podman" && container.podman.user != "root") { @@ -523,6 +531,10 @@ let else "${cfg.backend} rm -f ${name} || true"; + unitConfig = mkIf (effectiveUser != "root") { + RequiresMountsFor = "/run/user/${toString uid}/containers"; + }; + serviceConfig = { ### There is no generalized way of supporting `reload` for docker @@ -616,6 +628,15 @@ in assertion = cfg.backend == "docker" -> podman == null; message = "virtualisation.oci-containers.containers.${name}: Cannot set `podman` option if backend is `docker`."; } + { + assertion = + cfg.backend == "podman" && podman.sdnotify == "healthy" && podman.user != "root" + -> config.users.users.${podman.user}.uid != null; + message = '' + Rootless container ${name} (with podman and sdnotify=healthy) + requires that its running user ${podman.user} has a statically specified uid. + ''; + } ]; in concatMap (name: toAssertions name cfg.containers.${name}) (lib.attrNames cfg.containers); diff --git a/nixos/tests/oci-containers.nix b/nixos/tests/oci-containers.nix index 073f62cf5155..a22bd9c6b431 100644 --- a/nixos/tests/oci-containers.nix +++ b/nixos/tests/oci-containers.nix @@ -80,6 +80,7 @@ let home = "/var/lib/redis"; linger = type == "healthy"; createHome = true; + uid = 2342; subUidRanges = [ { count = 65536;