seL4 / seL4-CAmkES-L4v-dockerfiles

Dockerfiles defining the dependencies required to build seL4, CAmkES, and L4v.
13 stars 40 forks source link

Added the group "stack" and given it access to ghl #14

Closed tcptomato closed 4 years ago

tcptomato commented 4 years ago

Added a new group and given it permission to use stack which is installed by root. This way non-root users can use it without getting the files duplicated when trying to use chgrp/chmod in a later step.

LukeMondy commented 4 years ago

Hi, thanks for the PR!

I have a few questions about this. We recently changed our Dockerfiles to use scripts, and as part of that conversion, we tried to make the scripts as user agnostic as possible (via things like the as_root command).

So this brings up an issue, and a question. As per:

# Get stack
wget -O - https://get.haskellstack.org/ | sh
echo "export PATH=\"\$PATH:\$HOME/.local/bin\"" >> "$HOME/.bashrc"

groupadd stack

echo "allow-different-user: true" >> /root/.stack/config.yaml
chmod a+x /root && chgrp -R stack /root/.stack
chmod -R g=u /root/.stack
  1. The wget line will install stack as whatever user that the script was invoked as. For the most part, it will be root, particularly if it's built within our Docker containers as they stand. However, we can't assume that, so the references to /root/.stack need to be changed to $HOME, thanks.
  2. Assuming the Docker image has been built with the root user (so that /root/.stack has been used), how does the allow-different-user line allow a non-root user to use the actual stack command? Do they have to add /root/.local/bin to their $PATH? I don't have a ton of stack experience, so any insights you have are welcome!

Thanks!

tcptomato commented 4 years ago

Hey Luke,

Thanks for your reply.

  1. You are right here. We are still using the old version of the dockerfile, and I forgot to take the change into consideration. The new commit should fix it.

  2. From my reading of their documentation, by default stack doesn't allow other users besides the owner of the (~/.stack) to use the tool. This is solved ( on the stack side of the issue) by using allow-different-user. The Linux side is solved by creating the stack group and adding the group rights.

As a final step, for the new non-root user (jenkins in our case) we symlinked the stack folder into his $HOME and used it from there.

Currently we build our own image based on your camkes image, and we have a RUN step doing this chgrp/chmod calls, but due to dockers nature it adds 2.5 GB to the image when it changes the file rights.

LukeMondy commented 4 years ago

Cool, sounds good

LukeMondy commented 4 years ago

Update on this: I've been looking into it a bit more, and there was a small issue (the ~/.stack directory did not exist, so the permission operations were failing), but I've been looking at using the $STACK_ROOT variable to put all the stack stuff into an easier to get to place (e.g., /etc/stack).

I'm now hitting my own issues ( :sweat_smile: ), but will post something up soon. I can tack the commits onto this PR if you want to check it out?

tcptomato commented 4 years ago

Sure. And if I can help somehow, please tell me.

LukeMondy commented 4 years ago

I've added my work so far. The problem at the moment is the permissions on the /etc/stack (aka $STACK_ROOT) folder. I can't seem to the get the docker image to recognise that my user (within the container) is a member of the stack group, and hence I can't modify the $STACK_ROOT directory.

lmondy@in-container:/etc/stack$ groups lmondy
lmondy : lmondy sudo stack
lmondy@in-container:/etc/stack$ ls -lah
total 184K
drwxrwsr-x 1 root stack 4.0K Feb 18 14:04 .
drwxr-xr-x 1 root root  4.0K Feb 17 17:01 ..
-rw-rwxr-- 1 root stack   27 Feb 17 16:39 config.yaml
drwxrwsr-x 1 root stack 4.0K Feb 17 16:55 pantry
drwxrwsr-x 1 root stack 4.0K Feb 17 16:39 programs
drwxrwsr-x 1 root stack 4.0K Feb 17 16:43 setup-exe-cache
drwxrwsr-x 1 root stack 4.0K Feb 17 16:43 setup-exe-src
drwxrwsr-x 1 root stack 4.0K Feb 17 16:41 snapshots
-rw-rw-r-- 1 root stack 124K Feb 17 16:56 stack.sqlite3
-rw-rw-r-- 1 root stack    0 Feb 17 16:39 stack.sqlite3.pantry-write-lock
lmondy@in-container:/etc/stack$ touch hello
touch: cannot touch 'hello': Permission denied
lmondy@in-container:/etc/stack$ sudo -g stack touch hello
lmondy@in-container:/etc/stack$ ls -la
total 184
drwxrwsr-x 1 root   stack   4096 Feb 18 14:05 .
drwxr-xr-x 1 root   root    4096 Feb 17 17:01 ..
-rw-rwxr-- 1 root   stack     27 Feb 17 16:39 config.yaml
-rw-r--r-- 1 lmondy stack      0 Feb 18 14:05 hello
drwxrwsr-x 1 root   stack   4096 Feb 17 16:55 pantry
drwxrwsr-x 1 root   stack   4096 Feb 17 16:39 programs
drwxrwsr-x 1 root   stack   4096 Feb 17 16:43 setup-exe-cache
drwxrwsr-x 1 root   stack   4096 Feb 17 16:43 setup-exe-src
drwxrwsr-x 1 root   stack   4096 Feb 17 16:41 snapshots
-rw-rw-r-- 1 root   stack 126976 Feb 17 16:56 stack.sqlite3
-rw-rw-r-- 1 root   stack      0 Feb 17 16:39 stack.sqlite3.pantry-write-lock

Maybe I'm just missing something obvious! I'll keep checking it out, but any insights would be great!

tcptomato commented 4 years ago

That's docker in action. The main problem is that you pass only one group to docker run with-u uid:gid. The user actually running in the container isn't a member of the group stack, it only shows that it is. Same for me here with sudo.

thoboe01@in-container:/host$ id uid=1000(thoboe01) gid=1000(thoboe01) groups=1000(thoboe01) thoboe01@in-container:/host$ groups thoboe01 thoboe01@in-container:/host$ groups thoboe01 thoboe01 : thoboe01 sudo

There are a few options, all with some drawbacks. You can:

  1. Call docker run without specifying a gid in the -u flag. This breaks mounting of host directories if the user in the container and on the host have a different gid

  2. Call docker run with --group-add=stack, to add in the container stack as a secondary group for the user. You can pass as many as you like. Drawback is that the group needs to exist on the host machine

  3. Do the user/group changing in the container from an entrypoint script, that needs to be executed as root

LukeMondy commented 4 years ago

Ah, of course! Your 1. point I had completely forgotten about.

OK, well, I had been vaguely thinking about moving to an entrypoint script, so I think I'll check it out now. Any objections/recommendations?

tcptomato commented 4 years ago

No objections. It's the same way I was thinking about doing.

I imagined something like:

I found that chown has a nice feature that can be used here chown -R --from=uid:gid newuid:newgid

tcptomato commented 4 years ago

I implemented the entrypoint / chown solution in a test container. It works, but it increased container start time with 30 seconds.

tcptomato commented 4 years ago

Another options is to call docker run with --group-add=1001. 1001 being the group ID for the stack group in the container. This way you don't need the group to exist on the host machine.

LukeMondy commented 4 years ago

Agh, sorry for the radio silence, things have been a bit hectic. I should have some time this week to think about it some more. Thanks for the work you've put in so far.

tcptomato commented 4 years ago

Hey @LukeMondy. Any new developments on the front?

LukeMondy commented 4 years ago

Sorry, not as yet, has been quite hectic. This repo has a few other changes getting shepherded through at the moment too :sweat:.

I think the --group-add might be the best way to go, perhaps coupled with moving/changing the stack gid to something that won't clash easily (like some high number). The slow start up of an entrypoint chowning things doesn't sound ideal.

I will try to get something up and running on Friday or Monday.

LukeMondy commented 4 years ago

Hey, sorry again for the delay!

I've rebased this PR, and pushed on some more stuff, which I think is a working solution.

One caveat is that you will need to delete your $DOCKER_VOLUME_HOME, which you can do by doing:

docker volume ls
DRIVER              VOLUME NAME
local               lmondy-home
docker volume rm lmondy-home

but with your own one. This is mostly so that the ~/.bashrc is regenerated when you start the user container.

I did a test compiling Camkes, and it makes a significant speed up!

Let me know what you think.

LukeMondy commented 4 years ago

I rebased it, but a few extra commits that haven't made it through our CI got out too, sorry :sweat_smile: They should come out soon.

tcptomato commented 4 years ago

Hey @LukeMondy . Looks good.

Unfortunately I can't build it on my machine, I get a timeout. When executing ./build.sh -b camkes -s riscv it ends with Downloading manifest from https://bitbucket.ts.data61.csiro.au/scm/seL4/camkes-manifest.git manifests: fatal: unable to access 'https://bitbucket.ts.data61.csiro.au/scm/seL4/camkes-manifest.git/': Failed to connect to bitbucket.ts.data61.csiro.au port 443: Connection timed out

LukeMondy commented 4 years ago

Hey @LukeMondy . Looks good.

Unfortunately I can't build it on my machine, I get a timeout. When executing ./build.sh -b camkes -s riscv it ends with Downloading manifest from https://bitbucket.ts.data61.csiro.au/scm/seL4/camkes-manifest.git manifests: fatal: unable to access 'https://bitbucket.ts.data61.csiro.au/scm/seL4/camkes-manifest.git/': Failed to connect to bitbucket.ts.data61.csiro.au port 443: Connection timed out

Ah, sorry about that. There are some assumptions built in there about where things are building. They should assume that you're not building inside our network, but currently it is the opposite. You can override this by doing: ./build.sh -b camkes -s riscv -e SCM=https://github.com However, I will put in a change to switch around the assumption.

tcptomato commented 4 years ago

It worked for me :) Our build container is now 2 GB smaller.

LukeMondy commented 4 years ago

Great, good to hear! Sorry again it took so long.

I've merged it internally, should get pushed out soon.

LukeMondy commented 4 years ago

:thinking: I thought that would tag this as merged. Ah well, thanks again for the contribution!