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

Always chown volumes when mounting into a container #22727

Merged
merged 1 commit into from
May 23, 2024

Conversation

mheon
Copy link
Member

@mheon mheon commented May 16, 2024

This is done to better match Docker's behavior. Our current behavior is to only chown a volume once, the first time it is mounted into a container; that doesn't match what Docker does. Docker chowns every time a container mounts a volume, to ensure it is always accessible to the last container to mount it.

Fortunately, this is a relatively easy fix. We have a bool in volume state as to whether a volume needs to be chowned, which we set to false when the volume was first chowned; so just stop doing that.

I was really hoping to eliminate the NeedsChown bool entirely, but things are a bit of a mess. There are some cases where we do want to completely inhibit chowning, like when the user explicitly requests that a volume be a specific UID and GID. Unfortunately, those are both ints, not *int, so we can't tell whether they were actually set, and the solution we were using was to force the NeedsChown bool to false - so we really need to keep it around. And even if we could change volume UID/GID to pointers, we're setting them in places we really shouldn't be - for example, container anonymous volumes set UID/GID to current container UID/GID, despite the fact that the volume will immediately chown itself from that to match the directory it's mounting over? In short, the current code's a mess and I don't see a way to fix it without breaking changes.

Fixes #22571

Does this PR introduce a user-facing change?

Podman now changes volume ownership every time a volume is mounted into a container, not just the first time.

@openshift-ci openshift-ci bot added release-note approved Indicates a PR has been approved by an approver from all required OWNERS files. labels May 16, 2024
@mheon
Copy link
Member Author

mheon commented May 16, 2024

Still needs a test

Copy link

Ephemeral COPR build failed. @containers/packit-build please check.

@Luap99
Copy link
Member

Luap99 commented May 16, 2024

btw this branch seems very out of date so you must rebase

@mheon mheon force-pushed the chown_all_the_time branch from 3166ea2 to 917ab1e Compare May 20, 2024 15:25
@mheon
Copy link
Member Author

mheon commented May 20, 2024

Logic majorly updated to reflect further observations of Docker. Tests added.

@mheon mheon force-pushed the chown_all_the_time branch 10 times, most recently from 09e291e to d12c015 Compare May 22, 2024 12:29
@mheon
Copy link
Member Author

mheon commented May 22, 2024

Each of the 3 tests I added is taking ~30s to run, which is suboptimal. Maybe I should push the image to Quay and cache it?

@mheon mheon force-pushed the chown_all_the_time branch from d12c015 to 56db093 Compare May 22, 2024 14:06
@Luap99
Copy link
Member

Luap99 commented May 22, 2024

Each of the 3 tests I added is taking ~30s to run, which is suboptimal. Maybe I should push the image to Quay and cache it?

How big is the final image? If the image is the same for all three tests than pushing to quay.io/libpod and adding in the image cache will almost certainly help speed compared to having it to build three times

@Luap99
Copy link
Member

Luap99 commented May 22, 2024

Each of the 3 tests I added is taking ~30s to run, which is suboptimal. Maybe I should push the image to Quay and cache it?

How big is the final image? If the image is the same for all three tests than pushing to quay.io/libpod and adding in the image cache will almost certainly help speed compared to having it to build three times

If you do decide to push the image in quay then please make sure to add the Containefile + build instructions here in the repo somewhere under test, e.g. like test/testvol

@mheon
Copy link
Member Author

mheon commented May 22, 2024

The final image shouldn't be much bigger than the fedoraMinimal we already cache, it has extra layers but they're all useradd/chown, no files of substance. The image is different for all 3 but not sufficiently different that I can't combine them.

@mheon mheon force-pushed the chown_all_the_time branch from 56db093 to c4c4fb3 Compare May 22, 2024 15:15
Comment on lines 35 to 40
check := podmanTest.Podman([]string{"run", "-v", fmt.Sprintf("%s:%s", volName, volPath), imgName, "ls", "-al", volPath})
check.WaitWithDefaultTimeout()
Expect(check).Should(ExitCleanly())
Expect(check.OutputToString()).To(MatchRegexp(`^drwxr-xr-x\.\s+[0-9]+\s+%s\s+%s\s*[0-9]\s+.+\s+\.$`, expectedOwner, expectedOwner))
// Should match lines of this format, but with arbitrary username. Permissions always fixed, directory always .
// drwxr-xr-x. 1 mheon mheon 0 May 22 09:49 .
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why use ls -al when the output is hard to match? either use ls -n to only get the ids or better use stat -c %u:%g
stat should be part of the regual alpine based image

RUN chown test1:test1 /test1
RUN chown test2:test2 /test2
RUN chown test3:test3 /test4
RUN chmod 755 /test1 /test2 /test3 /test4`, fedoraMinimal)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a reason for fedora-minimal? The image is still much bigger than alpine based so it slows the build down.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Presence of useradd, vs adduser, useradd being a lot easier to use with numeric groups. I can refactor to use alpine though.

@mheon mheon force-pushed the chown_all_the_time branch 3 times, most recently from ccc623b to b6c41c8 Compare May 22, 2024 20:31
@rhatdan
Copy link
Member

rhatdan commented May 22, 2024

LGTM

When an empty volume is mounted into a container, Docker will
chown that volume appropriately for use in the container. Podman
does this as well, but there are differences in the details. In
Podman, a chown is presently a one-and-done deal; in Docker, it
will continue so long as the volume remains empty. Mount into a
dozen containers, but never add content, the chown occurs every
time. The chown is also linked to copy-up; it will always occur
when a copy-up occurred, despite the volume now not being empty.
This PR changes our logic to (mostly) match Docker's.

For some reason, the chowning also stops if the volume is chowned
to root at any point. This feels like a Docker bug, but as they
say, bug for bug compatible.

In retrospect, using bools for NeedsChown and NeedsCopyUp was a
mistake. Docker isn't actually tracking this stuff; they're just
doing a copy-up and permissions change unconditionally as long as
the volume is empty. They also have the two linked as one
operation, seemingly, despite happening at very different times
during container init. Replicating that in our stateful system is
nontrivial, hence the need for the new CopiedUp field. Basically,
we never want to chown a volume with contents in it, except if
that data is a result of a copy-up that resulted from mounting
into the current container. Tracking who did the copy-up is the
easiest way to do this.

Fixes containers#22571

Signed-off-by: Matthew Heon <[email protected]>
@mheon mheon force-pushed the chown_all_the_time branch from b6c41c8 to 046c0e5 Compare May 22, 2024 21:47
@mheon
Copy link
Member Author

mheon commented May 23, 2024

Passing now

@mheon
Copy link
Member Author

mheon commented May 23, 2024

/cherry-pick v5.1

@openshift-cherrypick-robot
Copy link
Collaborator

@mheon: once the present PR merges, I will cherry-pick it on top of v5.1 in a new PR and assign it to you.

In response to this:

/cherry-pick v5.1

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

Copy link
Member

@Luap99 Luap99 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label May 23, 2024
Copy link
Contributor

openshift-ci bot commented May 23, 2024

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: Luap99, mheon

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-bot openshift-merge-bot bot merged commit eee0dc2 into containers:main May 23, 2024
89 checks passed
@openshift-cherrypick-robot
Copy link
Collaborator

@mheon: new pull request created: #22790

In response to this:

/cherry-pick v5.1

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@stale-locking-app stale-locking-app bot added the locked - please file new issue/PR Assist humans wanting to comment on an old issue or PR with locked comments. label Aug 22, 2024
@stale-locking-app stale-locking-app bot locked as resolved and limited conversation to collaborators Aug 22, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged. locked - please file new issue/PR Assist humans wanting to comment on an old issue or PR with locked comments. release-note
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Volume mounting ownership inconsistent between Docker & Podman
4 participants