How can I improve the podman user service?

I’m new to NixOS and really happy with the overall concept. Unfortunately, it is not that easy :wink:

I noticed that there is probably a bug in the podman user service. The KillMode should be control-group instead of process according this GitHub issue “podman.service: KillMode=process leaks pause process, breaks subsequent API invocations · Issue #7021 · containers/podman · GitHub”.

Now I tried several configurations to fix it. But I only found this one:

# part of configuration.nix
  systemd.packages = [
    (pkgs.runCommandNoCC "toplevel-overrides.conf" {
      preferLocalBuild = true;
      allowSubstitutes = false;
    } ''
      mkdir -p $out/etc/systemd/podman.service.d/
      echo -e "[Service]\nKillMode=control-group" > $out/etc/systemd/podman.service.d/overrides.conf
    '')
  ];

Inspired by How to use toplevel-overrides for systemd - #4 by hmenke.

I also tried the following both unnsuccessfully:

# part of configuration.nix
  systemd.user.services.podman.serviceConfig = {
    KillMode = "control-group";
  };
# overlay.nix

self: super:
{
  systemd = super.systemd.override // {
    user = super.user.override // {
      services = super.services.override // {
        podman = super.podman.override // {
          serviceConfig = super.serviceConfig.override // {
            KillMode = "control-group";
          };
        };
      };
    };
  };
}

My questions:

  • How can I solve this problem via Nix overrides/overlays?
  • Where can I find the wrong KillMode=process in nixpkgs? (to provide a PR)
  • What else could I do to correct the KillMode with Nix expressions?

Thanks!

Overlays are only for packages (not modules), so it is not surprising that your second attempt did not work. What went wrong with your first attempt?

Thanks for your advice.

The approach I wrote first works well. But I want to learn how to solve this in a more Nix-way.

Additionally, if I could fix this issue in nixpkgs, I will submit a pull-request. Unfortunately, I am not able to find the location in nixpkgs where KillMode is set to process.

Greetings !

systemd services are just text files. Some of those files are generated by nixpkgs, some of those files are shipped with packages from upstream.

serviceConfig

is an attribute that is used when generating systemd services from nixpkgs.

If you look at nixos/modules/virtualisation/podman/default.nix you can see that nixos module doesnt build podman.service file, it uses one from upstream ( podman )

assuming you have nixpkgs repository

 kirillvr@osaka:~/nixpkgs]$ nix-build -A podman
 /nix/store/axjrv47a4n6fd67j69r32d01cjv93x1q-podman-4.5.0
 
 [kirillvr@osaka:~/nixpkgs]$ ls ./result/share/systemd/user/podman.service 
 ./result/share/systemd/user/podman.service

in pkgs/applications/virtualization/podman/default.nix

you can add postPatch phase and patch podman.service file to have right KillMode value

the postPatch, you can do either using overrideAttrs pattern, or create PR for nixpkgs

the manual can be hard to read at first, due to large amount of new information but at this stage, I would recommend to read about phases, and substituteInPlace hopefully helps you to move forward

otherwise just let us know if you run into issues,

1 Like

@kirillrdy Thanks for your tips!

Now, I tried the following in my configuration.nix:

{ config, pkgs, ... }:

let
  my-podman = pkgs.podman.overrideAttrs (finalAttrs: previousAttrs: {
      postPatch = ''
        cat contrib/systemd/user/podman.service.in
        substituteInPlace contrib/systemd/user/podman.service.in --replace KillMode=process KillMode=control-group
        cat contrib/systemd/user/podman.service.in
      '';
    });
in
{
# [...]
  environment.systemPackages = with pkgs; [
    docker-compose
    my-podman
  ];

  virtualisation.podman.enable = true;
# [...]
}

This configuration actually builds a new podman (in ~6 mins on my slow machine) and hopefully replaces the KillMode. Unfortunately, it competes with the “old” package which provides the same files and wins :stuck_out_tongue: .

warning: collision between '/nix/store/mymm011ng9rm90z93dzq8asmb31vi7jl-podman-4.5.0-man/share/man/man1/podman-image.1.gz' and '/nix/store/q88z8x119l6b94r6x2v2rncsxkxn8aqa-podman-4.5.0-man/share/man/man1/podman-image.1.gz'

I assume the “old” package is loaded from the module where I configure the virtualization. Is it possible to replace it somehow with my special package?

Initially, I planed to create a PR to solve this issue. But in the meantime, I noticed that the KillMode was already improved several times in podman. So, it seems to be hard to find a general solution. Unfortunately, I’m not familiar enough with podmans und systemds interactions.
(History for contrib/systemd/system/podman.service.in - containers/podman · GitHub)

virtualisation.podman.package = my-podman;

you also don’t need to have it in systemPackages