-
Notifications
You must be signed in to change notification settings - Fork 144
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
fix: keep container uid the same as host to allow ops on workdir root #3483
base: main
Are you sure you want to change the base?
Conversation
tmt/steps/provision/podman.py
Outdated
self.package_manager.install(FileSystemPath('/usr/bin/setfacl')) | ||
self.execute(ShellScript( | ||
f""" | ||
sudo chmod -R o+rwX {self.workdir_root}; |
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.
Wouldn't this also change read-only files to writable? Is that an expected, or even desired course of action?
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.
That's a really good point. Because the directory is mounted in the host, it will make /var/tmp/tmt
on the host world writable.
The other solution I can think of is a deeper change, basically, making the logic around TEST_WRAPPER_TEMPLATE
different for container, leveraging the fact that the container directory is mounted.
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 other solution I can think of is a deeper change, basically, making the logic around
TEST_WRAPPER_TEMPLATE
different for container, leveraging the fact that the container directory is mounted.
That we can do as well, the wrapper does not have to be the same for everything. It's a Jinja template, two shell files, we can do whatever we need to do to make all things work - permissions, TTY, duration, signals, and whatever else is waiting there to bite us. I tried to document and improve wrappers a bit, if you wish to give this avenue a try, please, start on top of this PR.
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.
So the logic creating the pid files would need to not be executed on the container, but on the host, assuming it would be available to the container, and assuming flock works on the mount that podman does. That is necessary so it can be placed in the /var/tmp/tmt
directory as the other PR is trying to do.
Basically, it is a change not just to the TEST_WRAPPER_TEMPLATE
but to the code using it as well, adding different execution paths for containers. I can look into it.
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.
Pid file exists so tmt-reboot
, called by a different tmt instance, could safely notify about upcoming reboot, and kill the test process our tmt manages. This presumes both the test and tmt-reboot
run on the same guest, sharing it, like a baremetal machine or a VM from a cloud - thinking about it now, it does make much less sense in the context of containers.
Seems like a topic for tomorrow's tmt hacking meeting, make we could introduce some feature flag signaling to tmt when keeping pidfile makes sense, maybe provided by the guest class implementation.
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.
added to hacking
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.
@happz , did you have a chance to look into it?
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 didn't, let's give it a try now.
There are several provision
plugins, what does the existence of the PID file and the out-of-session tmt-reboot
mean for them? The PID file exists so tmt-reboot
can update the running test with reboot command and timeout, and then kill the test process spawned by a tmt managing the test. tmt-reboot
runs on the guest, not on the runner, and the killed process was running on the guest, not on the runner. And the more I think about it, the more I'm getting lost in various combinations :/
Let's focus on the workdir permissions and the original issue, "Containers that mount the workdir but run with non-root users are not able to operate on the workdir because the mounted volume appears as read only." Isn't it possible to fix this by some careful podman run
setup? Like mapping ownership, permissions, etc?
SSH-capable guests do have something similar, but they seem to get away with just read+executable permissions:
def setup(self) -> None:
if self.is_dry_run:
return
if not self.facts.is_superuser and self.become:
self.package_manager.install(FileSystemPath('/usr/bin/setfacl'))
workdir_root = effective_workdir_root()
self.execute(
ShellScript(
f"""
mkdir -p {workdir_root};
setfacl -d -m o:rX {workdir_root}
"""
)
)
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 did try to devise a solution using uidmaps but no luck. I'll give --userns
a try.
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.
moved the milestone, seems this is not making the release today |
b9b152b
to
caf1de9
Compare
03f012f
to
82588fb
Compare
/packit build |
tmt/steps/provision/podman.py
Outdated
'--name', | ||
self.container, | ||
'-v', | ||
f'{workdir}:{workdir}:z', | ||
f'{self.workdir_root}:{self.workdir_root}:z', |
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.
Why the change from self.parent.plan.workdir
to self.workdir_root
? I don't believe the yare the same thing, workdir_root
will contain files completely unrelated to the current run.
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.
Mainly because the new pid code is trying to create the pid in the /var/tmp/tmt
dir, which doesn't match any of the permission if the mount is /var/tmp/tmt/run-001/etc...
.
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.
Hmmm, I believe I can still do it with the workdir
if I bring the setup(..)
method back without the recursive chmod change. It would be a little bit more over the place since it is modifying the parent dir /var/tmp/tmt created by the mount with some permissions but with a different set of permission for the subdirectories as inherited by the userns and the mount itself, but it might 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.
OK, I added a new commit bringing setup(..)
back, but without the recursive chmod. It works as well on the pid change branch. This approach may feel a little bit less consistent in the sense that the workdir_root
has now permissions to allow modifications in it outside the plan execution, but the plan execution itself (a subdir) is mounted with a different set of permissions as set by volume mount with the keep-id userns option.
@happz, Let me know, I can revert that last commit.
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.
Sure. BTW is there a test that would demonstrate the problem, a test we could watch turn green once the fix is correct? :)
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.
provision/facts/guest
is failing because the preparation step to install setfacl is doing a sudo
but the user is nobody
, so it is asking for the sudo password in that step.
provision_options="--image fedora:39"
bfu_provision_options="$provision_options --user=nobody"
Should the test be changed to use a similar unprivileged container image with a passwordless sudo fedora user? I can make that change if that's OK.
The provision/user
one is failing because the workdir
is actually not a subdirectory of self.workdir_root
, so I pushed a change to add mkdir -p {self.workdir_root}
, and it is going to be needed for the pid change as well.
Volume mounts on the container are by default read only for non-root users. This prevents the necessary access for rootless container. The change in this commit makes the container uid be the same as the host uid so that the user under which podman runs, which owns the workdir root, is the same user uid on the container, so the permissions also match. Signed-off-by: Carlos Rodriguez-Fernandez <carlosrodrifernandez@gmail.com>
Signed-off-by: Carlos Rodriguez-Fernandez <carlosrodrifernandez@gmail.com>
/packit build |
Signed-off-by: Carlos Rodriguez-Fernandez <carlosrodrifernandez@gmail.com>
Volume mounts on the container are by default read only for non-root users.
This prevents the necessary access for rootless container. The change in this
commit makes the container uid be the same as the host uid so that the user
under which podman runs, which owns the workdir root, is the same user uid on
the container, so the permissions also match.
Pull Request Checklist
Related: #3252