-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
make sure the workdir exists on container mount #9054
Conversation
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: vrothberg 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 |
@mheon PTAL |
@edsantiago PTAL |
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.
LGTM, with one suggestion. I'm always trying to encourage people to piggyback on existing tests. Every second we save is valuable, and podman build
takes a long long time.
I'm a little reluctant here - @giuseppe made this change in |
@edsantiago Logic was to catch user error - a workdir not specified by the image, that does not exist, is probably a typo. |
Thanks @mheon. I remember that now. Whichever way we go, we need to embed that decision in the code. If we go this route, please document it. If we reject this PR, I will add a system test that explicitly checks for failure and explains the reason in a test comment. |
Notes from the meeting: Consensus was on only creating the workdir if specified by the image. When specified by the user, Podman should error out if it does not exist. |
Updated. PTanotherL |
Integration failure looks legit. I will have a look tomorrow morning. |
libpod/container_internal_linux.go
Outdated
@@ -174,24 +174,35 @@ func (c *Container) prepare() error { | |||
return err | |||
} | |||
|
|||
// Ensure container entrypoint is created (if required) | |||
workdir := c.WorkingDir() | |||
resolvedWorkdir, err := securejoin.SecureJoin(c.state.Mountpoint, c.WorkingDir()) |
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.
how would it work with volumes?
if we have something like podman run -v /foo:/foo -w /foo/bar ...
the working dir must be looked up in the volume mount
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.
Very good point.
To make this work, we can reuse the copy code in pkg/domain/infra/abi/containers_stat.go
and move it into libpod
. But I think that should be a separate PR.
@mheon WDYT?
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.
Actually, we need to tackle this now to make system tests happy.
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.
Would your intention be to replace the copy-up code wholesale, or just move the bit that determines where the path in a container lives?
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.
Just the latter.
a56bc4f
to
019791b
Compare
Just out of curiosity, could you try this with a --read-only container? |
|
Excellent. |
2100b7e
to
0a50092
Compare
Merge me :) (assuming I am pleasing) |
libpod/container_api.go
Outdated
// resolve to the container's mount point or to a volume or bind mount. It | ||
// returns the root (e.g., container, volume or bind mount) and the fully | ||
// resolved path which is either equal to or a subdirectory of the root. | ||
func (c *Container) ResolvePath(ctx context.Context, path string) (string, string, error) { |
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.
This should do the standard lock + sync if it's a public function
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.
It's safe to use concurrently/
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.
Or shall I lock and then mount
and unmount
?
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.
My concern isn't really concurrency so much as removed containers - we could have the container removed out from under us midway through this, between Mount and Unmount, for example. Preference would be lock then mount()
/ unmount()
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.
Although, looking at it more, I think a lot of the logic in Unmount()
isn't duplicated in unmount()
... I don't think it can be safely moved in there, either (we have two cases for unmounting - cases like this, where an external user wants to access the container's root filesystem - the code in Unmount() works there - and cases where Libpod wants to stop the container - the code in Unmount works there).
@vrothberg What would you think about making ResolvePath()
be contingent on the container already being mounted? It seems like it would simplify the code, and potentially make things a bit more performant (we wouldn't need to call Mount more than once in the Copy code).
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.
@mheon sounds good to me. One early version of the change was exactly like that but I preferred to play it safe. I'll go as suggested and repush.
Add an API to libpod to resolve a path on the container. We can refactor the code that was originally written for copy. Other functions are requiring a proper path resolution, so libpod seems like a reasonable home for sharing that code. Signed-off-by: Valentin Rothberg <[email protected]>
A container's workdir can be specified via the CLI via `--workdir` and via an image config with the CLI having precedence. Since images have a tendency to specify workdirs without necessarily shipping the paths with the root FS, make sure that Podman creates the workdir. When specified via the CLI, do not create the path, but check for its existence and return a human-friendly error. NOTE: `crun` is performing a similar check that would yield exit code 127. With this change, however, Podman performs the check and yields exit code 126. Since this is specific to `crun`, I do not consider it to be a breaking change of Podman. Fixes: containers#9040 Signed-off-by: Valentin Rothberg <[email protected]>
Ready to go |
Marking as backport for 3.0. Please raise your voice in case you have concerns. |
I want @mheon to approve and merge. |
if m.Type != "bind" { | ||
continue | ||
} |
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.
to check for a bind mount, we'd need to look for bind
or rbind
in the options, the type is ignored by the runtime
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 think we require that Type also be set for Libpod - at the very least, all of our existing code is guaranteed to do so.
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.
Currently, i's detecting correctly when using --mount=type=bind
etc. It's pretty the code from cp
.
If there's something missing, let's fix that in a separate PR.
/lgtm |
/hold |
Oops, I think I was the only LGTM... Need one more to merge |
A container's workdir can be specified via the CLI via
--workdir
andvia an image config with the CLI having precedence.
Since images have a tendency to specify workdirs without necessarily
shipping the paths with the root FS, make sure that Podman creates the
workdir. When specified via the CLI, do not create the path, but check
for its existence and return a human-friendly error.
Fixes: #9040
Signed-off-by: Valentin Rothberg [email protected]