Skip to content
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

Readme container doc: map user into podlet container #50

Merged
merged 4 commits into from
Jan 15, 2024

Conversation

rugk
Copy link
Contributor

@rugk rugk commented Jan 10, 2024

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?

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?
@rugk rugk changed the title Update README.md to not re-map systemd directory Readme container doc: not re-map systemd directory Jan 10, 2024
@rugk
Copy link
Contributor Author

rugk commented Jan 10, 2024

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

@rugk
Copy link
Contributor Author

rugk commented Jan 10, 2024

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.

I know not pretty but…

--user $(id -u) switches to the user (context), but without using non-existant usernames in the container
--userns keep-id is required to keep the user namespace
-e HOME is required to pass-through for podlet to resolve user paths correctly
@k9withabone
Copy link
Member

k9withabone commented Jan 12, 2024

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.

@Nitrousoxide
Copy link
Contributor

Nitrousoxide commented Jan 12, 2024

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.

@rugk
Copy link
Contributor Author

rugk commented Jan 12, 2024

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 #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?

@Nitrousoxide
Copy link
Contributor

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.

@k9withabone
Copy link
Member

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.

@k9withabone k9withabone added the documentation Improvements or additions to documentation label Jan 12, 2024
@k9withabone k9withabone changed the title Readme container doc: not re-map systemd directory Readme container doc: map user into podlet container Jan 12, 2024
@rugk
Copy link
Contributor Author

rugk commented Jan 14, 2024

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

@k9withabone
Copy link
Member

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.

@k9withabone k9withabone merged commit 2facfd4 into containers:main Jan 15, 2024
9 checks passed
@rugk rugk deleted the patch-1 branch January 16, 2024 21:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants