Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

Add chown and root_chown options for image volume mount #18986

Closed
fangpenlin opened this issue Jun 23, 2023 · 5 comments
Closed

Add chown and root_chown options for image volume mount #18986

fangpenlin opened this issue Jun 23, 2023 · 5 comments
Labels
kind/feature Categorizes issue or PR as related to a new feature. stale-issue

Comments

@fangpenlin
Copy link
Contributor

fangpenlin commented Jun 23, 2023

Feature request description

I really love that the podman supports image mount, but I encountered a problem while trying to use it. One major issue I saw was that the root folder of mounted image volume seems like fixed to owner root with mode 555. If you are running the container with a non-root user, you are not going to be able to write anything into the root folder of the image mount point.

I made a docker image with just simple data in it for demo purpose.

fangpenlin/pure-data-image-demo

And its Dockerfile:

FROM scratch
ADD --chown=2000:2000 my-note.txt /

Then here's the commands for showcasing the issue:

podman pull fangpenlin/pure-data-image-demo
podman run \
  --user 2000:2000 \
  --mount type=image,source=fangpenlin/pure-data-image-demo,target=/data,rw=true \
  -w /data \
  --entrypoint=/bin/sh -it \
  alpine -c 'ls -al && touch my-note-v2.txt'

And the result looks like this

total 12
dr-xr-xr-x    1 root     root          4096 Jun 23 19:34 .
dr-xr-xr-x    1 root     root          4096 Jun 23 19:34 ..
-rw-r--r--    1 2000     2000            12 Jun 23 19:21 my-note.txt
touch: my-note-v2.txt: Permission denied

As you can see I got the files in the image with owner 2000:2000, surely I can write to the file, but if I run

touch my-note-v2.txt

and there will be a permission error because the root folder comes with root as the owner and 555 mode. I will be forced to added extra nested folder with the correct owner or permission in the image content to make things work.

Suggest potential solution

I think it would be great to have chown option for the image mount as well just like the bind mount. However, given that if the mounted image's nature is mostly for data purpose, recursive chown might be very slow. I like Kubernete's new fsGroupChangePolicy: "OnRootMismatch" option for mounted volume:

https://kubernetes.io/blog/2020/12/14/kubernetes-release-1.20-fsgroupchangepolicy-fsgrouppolicy/#allow-users-to-skip-recursive-permission-changes-on-mount

It only changes the root owner. So I wonder, maybe we can add two options, one is chown comes with recursive owner changes for the whole image mount. Another is root_chown only changes the root folder.

Have you considered any alternatives?

From the end-user endpoint, an alternative could be avoid writing anything new to the root dir. While that could solve the problem, but it also limits what you can do with the image mount.

To solve the problem for our own use cases before the new feature is added in podman, I will build an OCI hook that reads annotations like

com.launchplatform.oci-hooks.data.root-chown.mount-point="/data"
com.launchplatform.oci-hooks.data.root-chown.owner="2000:2000"

Pretty much like this one I built a while back: https://github.com/LaunchPlatform/oci-hooks-archive-overlay

Additional context

Add any other context or screenshots about the feature request here.

@fangpenlin fangpenlin added the kind/feature Categorizes issue or PR as related to a new feature. label Jun 23, 2023
@fangpenlin
Copy link
Contributor Author

fangpenlin commented Jun 23, 2023

Created a new oci hook as mentioned in the issue here

https://github.com/LaunchPlatform/oci-hooks-mount-chown/

I think this could be used as a reference for the feature.

podman run \
    --user 2000:2000 \
    --annotation=com.launchplatform.oci-hooks.mount-chown.data.mount-point=/data \
    --annotation=com.launchplatform.oci-hooks.mount-chown.data.owner=2000:2000 \
    --annotation=com.launchplatform.oci-hooks.mount-chown.data.policy=root-only \
    --mount type=image,source=my-data-image,destination=/data,rw=true \
    -it alpine
# Now you can write to the root folder of the image mount
touch /data/my-data.lock

Instead of the root_chown, I think maybe it makes more sense the follow Kubernete's chown policy. So I added a new policy with two options

  • recursive - chown recursively (default)
  • root-only - chown only for the root folder of mount-pooint

The chown-policy as an optional can be passed in as needed. The only problem is, if we should follow the bind mount's option value, making it true to chown to the user given by the command, or do we make it like the 2000:2000 style string to make it possible to change the fs to something else.

@fangpenlin
Copy link
Contributor Author

Hmmm, maybe this problem cannot be resolved by just using a hook?

time="2023-06-23T15:28:40-07:00" level=error msg="Failed to get stat of /data for data with error lstat /data: no such file or directory"
time="2023-06-23T15:28:40-07:00" level=info msg=Done

Just tested my hook, but I guess at the point of createContainer, the mounts were not created yet :/

@fangpenlin
Copy link
Contributor Author

nvm, turned out createdContainer is before pivot_root so I have to chown based on the root path of the container in the host filesystem. Now my OCI hook works:

podman pull fangpenlin/pure-data-image-demo
podman run \
    --user 2000:2000 \
    --annotation=com.launchplatform.oci-hooks.mount-chown.data.path=/data \
    --annotation=com.launchplatform.oci-hooks.mount-chown.data.owner=2000:2000 \
    --annotation=com.launchplatform.oci-hooks.mount-chown.data.policy=root-only \
    --mount type=image,source=fangpenlin/pure-data-image-demo,destination=/data,rw=true \
    -it alpine

then

/data $ id
uid=2000(2000) gid=2000(2000) groups=2000(2000)
/data $ chmod 755 .
~ $ touch /data/my-note.txt.lock
~ $ ls -al /data
total 12
drwxr-xr-x    1 2000     2000          4096 Jun 24 02:08 .
dr-xr-xr-x    1 root     root          4096 Jun 24 01:21 ..
-rw-r--r--    1 2000     2000            12 Jun 23 19:21 my-note.txt
-rw-r--r--    1 2000     2000             0 Jun 24 02:08 my-note.txt.lock

@fangpenlin
Copy link
Contributor Author

Just realized, if we only care about being able to write new files to the root mount path, we ca actually chmod of it. With the idea, I added mode option to my OCI hook. Changing the folder mode from 555 to something like 777 helps if non-root user wants to write file in it.

Here's the example with the latest OCI hook I built

podman run \
    --user 2000:2000 \
    --annotation=com.launchplatform.oci-hooks.mount-chown.data.path=/data \
    --annotation=com.launchplatform.oci-hooks.mount-chown.data.mode=777 \
    --annotation=run.oci.hooks.stderr=/tmp/hooks-stderr \
    --mount type=image,source=fangpenlin/pure-data-image-demo,destination=/data,rw=true \
    -it alpine

then

~ $ id
uid=2000(2000) gid=2000(2000) groups=2000(2000)
~ $ touch /data/foo
~ $ ls -al /data/
total 12
drwxrwxrwx    1 root     root          4096 Jun 24 19:12 .
dr-xr-xr-x    1 root     root          4096 Jun 24 19:11 ..
-rw-r--r--    1 2000     2000             0 Jun 24 19:13 foo
-rw-r--r--    1 2000     2000            12 Jun 23 19:21 my-note.txt

So I wonder, one possible alternative of chown could be just allow user to change mode of the image mount point folder.

@github-actions
Copy link

A friendly reminder that this issue had no activity for 30 days.

@containers containers locked and limited conversation to collaborators Jul 28, 2023
@rhatdan rhatdan converted this issue into discussion #19415 Jul 28, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
kind/feature Categorizes issue or PR as related to a new feature. stale-issue
Projects
None yet
Development

No branches or pull requests

1 participant