Closed rugk closed 8 months ago
Ah now I see why you did this: When you use the -u
a (likely running as root) containered podlet thinks it has system permission and thus should use the system's systemd path /usr/share/containers/systemd/
.
Thus, remapping the path solves this.
However, the disadvantage is that you still get a wrong output:
Wrote to file: /usr/share/containers/systemd/….container
As such, IMHO, this is still nor idea.
I tried using -u
to switch to user execution, but then you have the problem your user likely does not exist in the docker container.
This can be solved by using your $UID instead…
I am already at, but this still fails due to permission errors:
alias podlet='podman run --rm -u $(id -u) --security-opt label=disable -v "$PWD":"$PWD:Z" -v "$HOME/.config/containers/systemd/":"$HOME/.config/containers/systemd/:Z" -w "$PWD" --pull=newer quay.io/k9withabone/podlet'
--userns=keep-id
also does not seem to make a difference… uff
Okay with keep-id it should actually work. i tested it with a bash shell and it works.
Is this maybe actually a problem in podlet? Because it seems to try to use
$ podlet -u --install --overwrite compose docker-compose.yml
Error:
0: Failed to create/open file: [THE_PWD]/.config/containers/systemd/grocy.container
1: No such file or directory (os error 2)
Location:
src/cli.rs:526
Suggestion: Make sure the directory exists and you have write permissions for the file
Backtrace omitted. Run with RUST_BACKTRACE=1 environment variable to display it.
Run with RUST_BACKTRACE=full to include source snippets.
Ah no of course, it uses $HOME, but does not have this, so we need to pass this through, too.
# https://github.com/k9withabone/podlet#in-a-container
alias podlet='podman run --rm --userns keep-id -e HOME --user $(id -u) -v "$PWD":"$PWD:Z" -v "$HOME/.config/containers/systemd/":"$HOME/.config/containers/systemd/:Z" -w "$PWD" --pull=newer quay.io/k9withabone/podlet'
Finally works.
blindly copied that command
Blindly copying a command (especially from the internet) is never a good idea.
@Nitrousoxide could you take a look at this PR?
@rugk I don't use podlet (or command line applications in general) in a container, so I don't know what the best practices are and am not the best person to review this. I mostly use containers for self-hosted web services and am by no means an expert on containers/podman. @Nitrousoxide is the one who originally wrote the suggested command for using podlet in a container, so maybe they can explain this better?
With rootless podman, by default, the root user inside a container corresponds to the user running podman. However, Fedora CoreOS might have different defaults than this. I personally use Fedora Workstation and Server, but have no experience with CoreOS. The podlet --unit-directory
option changes its behavior based on whether podlet thinks it's running as root. From podlet --help
:
-u, --unit-directory
Generate a file in the podman unit directory instead of printing to stdout
Conflicts with the --file option
Equivalent to `--file $XDG_CONFIG_HOME/containers/systemd/` for non-root users, or `--file /etc/containers/systemd/` for root.
The name of the file can be specified with the --name option.
[aliases: unit-dir]
So the example podman command mapping the user's quadlet unit directory ($HOME/.config/containers/systemd/
) to the system's (/etc/containers/systemd/
) inside the container makes sense. Since podlet as root inside the container maps to the user running podman, there also shouldn't be permission issues.
The only downside, from what I can tell, is that podlet reports saving the file to a different path than perhaps naively expected when using the --unit-directory
option. But running applications inside a container always have quirks around file system paths.
https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html is the readme for quadlet
~/.config/containers/systemd/ is a perfectly valid place to drop the quadlets (and is what a systemctl --user daemon-reload would look at when generating new .service files so that aspect is a fine change.)
I don't think the :z suffux is needed here since the command is excluding any selinux labeling with --security-opt label=disable set since it's envisioning that you might run this anywhere in home (including $HOME), to pick up the compose file to convert into quadlet files. using selinux labels like :z shouldn't matter then.
If you're looking to run this in a specific location in home where selinux relabeling won't screw something up then it might be okay. In that case though you should remove the --security-opt label=disable flag.
As to the user issue: this is the info on how it handles user namespace https://docs.podman.io/en/v4.6.1/markdown/options/userns.container.html
Generally, if you are going to run a container that might pick up anything in $HOME I'd either run it as the default user namespace (where root in the container is the user running podman, usually user 1000 if you are the only user on the machines) then you're fine. The container cannot grab more permissions than the user has, so it can't do anything with a "real root"
Since this container is expected to run anywhere on $HOME to pick up an arbitrary docker-compose.yml file and convert it, running it in the user-ns or as the default (where user 0 in the container is the user running podman) is probably preferable. Though you can do --userns keep-id
and set the user running in the container to be --user $(id -u)
. That's perfectly valid as well. It is effectively running as the same user either way.
I don't think the :z suffux is needed here since the command is excluding any selinux labeling with --security-opt label=disable set since it's envisioning that you might run this anywhere in home (including $HOME), to pick up the compose file to convert into quadlet files. using selinux labels like :z shouldn't matter then. […] In that case though you should remove the --security-opt label=disable flag.
See https://github.com/k9withabone/podlet/pull/51 for now. I've split the feature into two PRs, so you can merge one or the other only.
Also, in this PR there is no :z
suffix. The other ones removes relabeling.
running it in the user-ns or as the default (where user 0 in the container is the user running podman) is probably preferable.
You mean the behavior before: root inside the container, user outside. The problem here was explained by me before:
When you use the -u a (likely running as root) containered podlet thinks it has system permission and thus should use the system's systemd path /usr/share/containers/systemd/. Thus, remapping the path solves this.
However, the disadvantage is that you still get a wrong output: Wrote to file: /usr/share/containers/systemd/….container
So it technically works, but it causes confusing console output (with the "wrong" path) for the user. This PR intends to solve this and cause the "correct" console output with the actual path. @k9withabone also said this:
The only downside, from what I can tell, is that podlet reports saving the file to a different path than perhaps naively expected when using the --unit-directory option
So again, this is what this PR solves. And I see no disadvantage in mapping the user namespace and user into it? I know the previous solution also works, but this is better, is not it? Or are there any other disadvantages?
I don't see any problem with the user-ns change. You'd want to use the podman ns in most containers to increase separation between the host and containers, but here you want a short-lived container to grab an arbitary compose file from (presumably) somewhere in $HOME and drop the converted .container, .volume, and .network files into the quadlet search path.
As you said, avoiding using root inside the container is usually preferable, since even if it doesn't actually grant any real additional permission in (non rootful) podman, it does lead to less confusion as to what the permission set available to the app is in the container and stdout logs.
So again, this is what this PR solves.
Honestly, I was having a hard time telling what the goal of this PR was. Now that I do understand it seems like a good change to me.
I think adding -e XDG_CONFIG_HOME
to the command would also be a good idea as it might be set to something other than ~/.config/
and that is what podlet and quadlet check first.
Thanks, yeah. My PR was a bit unclear due to me experimenting with it at the same time, so sorry for that. Also quoted the variables, while I was at it. See https://www.shellcheck.net/wiki/SC2086
This looks good to merge to me. Unless anyone has objections I'll merge this tomorrow. I'll probably do a squash merge so that the commit history is a little clearer.
I am curious why you would suggest that. I have just spend useless time debugging why my path could not be found, because I blindly copied that command and thought it was just a 1:1 mapping.
If podlet does not support user systemd directories, it should also not support that in the container due to some strange mapping, should it? If it does support that, then no reason to re-map it, it should work as usual, should not it?