-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
podman: Added build, image, and volume quadlet support #6137
base: master
Are you sure you want to change the base?
Conversation
Cursory testing appears to have everything functioning as intended, but submitting PR to get more eyes on it to try to break things. Will also do more in depth testing when I get a moment. Also looking for a bit of feedback on:
Other notes:
I just realized I forgot to add in the integration tests for the build quadlet. I am also expecting the container dependencies for build quadlets won't be quite right. Also looks like the docs are not building properly. Will look into all this in a few hours. (EDIT: Resolved.) |
After playing around with this more, I am wondering if we should add an option to The current functionality when setting Alternatively, there could be an option like |
590a90d
to
4204b61
Compare
still haven’t had time to have a proper play around and review, but I would go with your first option - add a persistent/preserve option to volumes that defaults true, set a label |
4204b61
to
1218ac5
Compare
All good. Should be good to go with that change. |
Ran into a couple snags with the Builds quadlets. Fixed an issue where it should be referencing One issue that I'm having a bit of a harder time with is that the Pull option appears to be breaking the ability to build an image because it appears podman is understanding the value set for
It works when executed with an
I am thinking that I may remove the |
e2f1f3f
to
9cfb44e
Compare
WantedBy = (if buildDef.autoStart then [ | ||
"default.target" | ||
"multi-user.target" | ||
] else | ||
[ ]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can use optionals
. Something like
WantedBy = (if buildDef.autoStart then [ | |
"default.target" | |
"multi-user.target" | |
] else | |
[ ]); | |
WantedBy = optionals buildDef.autoStart [ | |
"default.target" | |
"multi-user.target" | |
]; |
ought to work.
type = with types; nullOr str; | ||
default = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can change types.submodule {
to types.submodule ({name, ...}: {
and then change this like so:
type = with types; nullOr str; | |
default = null; | |
type = with types; nullOr str; | |
default = "Service for build ${name}"; | |
defaultText = "Service for build \${name}"; |
Description = (if (builtins.isString buildDef.description) then | ||
buildDef.description | ||
else | ||
"Service for build ${name}"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The parentheses are unnecessary
Description = (if (builtins.isString buildDef.description) then | |
buildDef.description | |
else | |
"Service for build ${name}"); | |
Description = if isString buildDef.description then | |
buildDef.description | |
else | |
"Service for build ${name}"; |
but I think the better solution is to make description
have type str
and default the value to "Service for build ${name}"
. See my other comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went ahead and made the changes in your other comment, then set this as Description = buildDef.description;
. If it is null, then it is automatically dropped. Much simpler!
type = types.bool; | ||
default = true; | ||
description = | ||
"Whether to start the build on boot. (Requires user lingering)"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Whether to start the build on boot. (Requires user lingering)"; | |
"Whether to start the build on boot. Requires user lingering."; |
services.podman.internal.quadletDefinitions = buildQuadlets; | ||
assertions = flatten (map (build: build.assertions) buildQuadlets); | ||
|
||
home.file."${config.xdg.configHome}/podman/images.manifest".text = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure why the podman module ended up using this home.file
format, seems to me that it would be possible to simply use xdg.configFile
.
home.file."${config.xdg.configHome}/podman/images.manifest".text = | |
xdg.configFile."podman/images.manifest".text = |
ImageTag = ([ "homemanager/${name}" ] ++ buildDef.tags); | ||
Label = (buildDef.labels // { "nix.home-manager.managed" = true; }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ImageTag = ([ "homemanager/${name}" ] ++ buildDef.tags); | |
Label = (buildDef.labels // { "nix.home-manager.managed" = true; }); | |
ImageTag = [ "homemanager/${name}" ] ++ buildDef.tags; | |
Label = buildDef.labels // { "nix.home-manager.managed" = true; }; |
|
||
createQuadletSource = name: buildDef: | ||
let | ||
buildConfig = (podman-lib.deepMerge { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
buildConfig = (podman-lib.deepMerge { | |
buildConfig = podman-lib.deepMerge { |
buildSection = if (builtins.hasAttr "Build" extraConfig) then | ||
extraConfig.Build | ||
else | ||
{ }; | ||
imageTags = if (builtins.hasAttr "ImageTag" buildSection) then | ||
buildSection.ImageTag | ||
else | ||
[ ]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps this could be simplified to
buildSection = if (builtins.hasAttr "Build" extraConfig) then | |
extraConfig.Build | |
else | |
{ }; | |
imageTags = if (builtins.hasAttr "ImageTag" buildSection) then | |
buildSection.ImageTag | |
else | |
[ ]; | |
imageTags = (extraConfig.Build or {}).ImageTag or []; |
containsRequiredTag = (if builtins.length imageTags > 0 then | ||
builtins.elemAt imageTags 0 | ||
else | ||
"") == "homemanager/${quadletName}"; | ||
in if (containsRequiredTag || builtins.length imageTags == 0) then | ||
[ ] | ||
else [{ | ||
assertion = false; | ||
message = '' | ||
In '${quadletName}' config. Build.ImageTag: '[ "${ | ||
builtins.concatStringsSep ''" "'' imageTags | ||
}" ]' does not have 'homemanager/${quadletName}' at index 0.''; | ||
}]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this tag really have to be in position 0? Perhaps something like
containsRequiredTag = (if builtins.length imageTags > 0 then | |
builtins.elemAt imageTags 0 | |
else | |
"") == "homemanager/${quadletName}"; | |
in if (containsRequiredTag || builtins.length imageTags == 0) then | |
[ ] | |
else [{ | |
assertion = false; | |
message = '' | |
In '${quadletName}' config. Build.ImageTag: '[ "${ | |
builtins.concatStringsSep ''" "'' imageTags | |
}" ]' does not have 'homemanager/${quadletName}' at index 0.''; | |
}]; | |
containsRequiredTag = builtins.elem "homemanager/${quadletName}" imageTags; | |
imageTagsStr = concatMapStringsSep " " toString imageTags; | |
in [{ | |
assertion = imageTags == [ ] || containsRequiredTag; | |
message = '' | |
In '${quadletName}' config. Build.ImageTag: '[ ${imageTagsStr} ]' does not contain 'homemanager/${quadletName}'.''; | |
}]; |
would work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason that I had it forced to position 0 was so that you could easily discern which ones were from Home Manager and which ones were built outside of Home Manager. That said, it probably isn't really that important and this code is a lot more straight forward. Will make the swap.
Thanks! Looks quite impressive. I've added a few mostly stylistic comments. I cannot comment on the functionality since I don't use the module myself. |
Thanks for all of your feedback @rycee. Incorporating it into a new commit now. I went ahead and took the suggestions that you made towards As for as the functionality goes, I have been converting all my containers from the way I used to manage them into this module. Have yet to notice any significant problems that haven't already been addressed. |
9cfb44e
to
927433c
Compare
Description
build
,image
, andvolume
quadletspkgs.podman
withservices.podman.package
Checklist
Change is backwards compatible.
Code formatted with
./format
.Code tested through
nix-shell --pure tests -A run.all
ornix develop --ignore-environment .#all
using Flakes.Test cases updated/added. See example.
Commit messages are formatted like
See CONTRIBUTING for more information and recent commit messages for examples.
If this PR adds a new module
Maintainer CC
@n-hass @bamhm182