container: init service for linux and mac
Description
Evolved from the original PR based on https://github.com/nix-community/home-manager/pull/2630 by @MaeIsBad, this PR introduces 3 major options:
virtualisation.containers
From the original PR and nixpkgs, allows managing regstristries.conf (used by podman and others, but not docker) declaratively. containers.conf is modified by the aforementioned tools and managing by home-manager is considered out of scope of this PR.
virtualisation.oci-containers
Inspired by nixpkgs, a simple method to enable containers which will pick the appropriate/supported oci-container implementation of your platform. ATM only linux and mac are supported by activating virtualisation.podman.
virtualisation.oci-containers.enable = true and you're off.
virtualisation.podman
Enables support for podman on linux and mac. Linux is more simple as it activates as systemd user service and that's that.
Mac is the difficult child in this relationship as it requires a VM to function. I opted to support basic, declarative VM management using virtualisation.podman.machines.<name>. podman stores its VM configs in JSON and outputs them using the CLI in JSON as well. Since python is my forté and not bash + jq, I wrote a helper called podmactl which is called at activation of a new home-manager generation.
It diffs the existing machines from requested machines (JSON generated by nix) and the required machines are generated and only one is active (podman doesn't allow multiple running machines).
Checklist
-
[x] Change is backwards compatible.
-
[x] Code formatted with
./format. -
[x] Code tested through
nix-shell --pure tests -A run.allornix develop --ignore-environment .#allusing Flakes. -
[x] Test cases updated/added. See example.
-
[ ] Commit messages are formatted like
{component}: {description} {long description}See CONTRIBUTING for more information and recent commit messages for examples.
-
If this PR adds a new module
- [x] Added myself as module maintainer. See example.
Maintainer CC
I'd be glad to review this once it gets out of the draft stage and help with maintenance.
One thing to note is that for a while the regular nixos virtualisation.podman.enable option already installs a user systemd socket you can use
Thanks a lot! It would be great to have this functionality. I started adding a few comments. Will continue when I find some more time.
Thanks for the review @rycee . For now, I made only minimal changes after recovering @MaeIsBad's PR. There might be bigger changes coming tomorrow (I get to work on this once a week) as I have a look at how virtualisation.podman.enable currently works on nixpkgs. CNI isn't used for networking anymore and there may be more changes to incorporate.
@rycee I pushed some changes for mac and introduced oci-containers just like nixpkgs which K900 on matrix pointed me to.
ATM, the mac changes can't be fully tested as they generated an endless recursion error when generating the machines.json file on https://github.com/nix-community/home-manager/pull/4331/commits/1ec282936821c6198553e835591bcc03c4648ada#diff-c4ec42715ced2d6da0509ab4842b23451cacb94de96de6265d9fc86e16a67800R242
You can find the reasoning in the commit message https://github.com/nix-community/home-manager/pull/4331/commits/1ec282936821c6198553e835591bcc03c4648ada (used by script called by launchd to CRUD podman machines and start one). If you can spot why it's recursing endlessly, help would be much obliged.
Alright, I was dumb and hadn't pulled master in a year. Rebased the branch and the infinite recursion problem went away + was able to build docs again. What's left now is to test it live, but it's unclear how to do so. How would one go about doing that? Create a new user and somehow setup a channel that points to a local directory? Maybe I missed that point in the docs.
With flakes you can point the flake input by using git+file:///home/user/home-manager. That's how I test changes to home-manager
Thanks @MaeIsBad . I don't use flakes, so had to find another way. Turned out it was
cd $proj
nix-shell -A install
home-manager -I home-manager=$proj switch
The PR is ready for review. I'll leave comments where I'm unsure about stuff.
As for the commit messages: only noticed those while checking of the list. What to do? Just squash everything? I tried to add many comments in the code, so a huge commit might be acceptable? Otherwise I can rebase and reword each commit. Whatever is prefered.
Finally had a chance to look at this and overall looks very nice. I made some minor cleanups and squashed the commits but unfortunately was not allowed to push to this branch. Would you mind resetting the PR to https://github.com/nix-community/home-manager/commit/faa4b16358ebd8607499538dbea02bfba5930bd9
The only thing I'm concerned about is the inclusion of the Python project, I would feel more comfortable with it being a separate project and pulled from Nixpkgs. Then I imagine it could be used elsewhere as well, perhaps in nix-darwin or devenv?
Thanks for the review @rycee and happy new year!
If it's not an issue, I'll move the python code out to a repo I own and later try to get it into nixpkgs or nix-community or something. My experience with nixpkgs hasn't been good as PRs seem to take a considerable amount of time to be merged if they are merged at all, and I don't want that to hold up this PR.
My mac isn't with me at the moment, so the earliest I can test the changes will be this Sunday, 2024-01-07.
Cheers
Edit: I still need to rebase and merge the commits, but it should be ready for testing by somebody with a mac.
Alright, I moved out podmactl to https://github.com/michaelCTS/podmactl . After multiple tests, it seems quite functional on mac m1.
This should be ready to merge now :slightly_smiling_face:
Sorry about the delay. I had a chance to try this out. But I don't know how to get it to work. Firstly, the generated systemd service file seems to be invalid due to generating multiple ExecStart fields. Once I turned into a single command I get an error
Error: command required for rootless mode with multiple IDs:
exec: "newuidmap": executable file not found in $PATH
I didn't do any special configuration, just added
virtualisation.podman.enable = true;
in my HM configuration. Do I need some additional configuration to get the service up?
I'm pretty sure I copied the podman systemd unit from nixos, but that was months ago. I'll have to apply the changes you proposed. As for newuidmap, it must've worked on my nixos because it was installed globally somehow.
podman requires the binary with a setuid. https://github.com/NixOS/nixpkgs/issues/138423 has more information. Will have to test this on a non-nixos system again.
I'm sorry, I'll have to close this. The podman update to 5.0 made changes to podman machine that I'd have to integrate and I've since moved away from trying to support Mac as my company has another solution.
Anybody is free to try and take this over. I'll leave my branch up.
@michaelCTS Thank you so so much for your work on this PR (and the reviewers for their feedback on it)!
My humble suggestion/request for whoever picks up this wonderful work (unless #4801 gets merged before): I think macOS/Darwin support should not block the merge of this module, as the original @MaeIsBad PR this one is based off and #4336 indicate, this has been a need for a while (at least for me).
Imho, NixOS should be the priority, given it would enable proper rootless podman, since https://github.com/NixOS/nixpkgs/issues/207050 and https://github.com/NixOS/nixpkgs/issues/259770 are open, and the discussion in https://github.com/containers/podman/discussions/20573 seems to point in the direction of using systemd --user units, and not system systemd + User= (previously discussed in https://github.com/containers/podman/issues/12778).
After supporting NixOS, generic Linux systems, and only then, macOS/Darwin (which will always be a bit more complex). Linux-only support would already be a great improvement on QoL regarding podman on Nix-managed systems.
(With that said, taking the time to design an API that is extension-friendly (so as to allow supporting other platforms) is always good.)