Closed tcptomato closed 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
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.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!
Hey Luke,
Thanks for your reply.
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.
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.
Cool, sounds good
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?
Sure. And if I can help somehow, please tell me.
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!
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:
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
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
Do the user/group changing in the container from an entrypoint script, that needs to be executed as root
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?
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
I implemented the entrypoint / chown solution in a test container. It works, but it increased container start time with 30 seconds.
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.
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.
Hey @LukeMondy. Any new developments on the front?
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.
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.
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.
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
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 withDownloading 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.
It worked for me :) Our build container is now 2 GB smaller.
Great, good to hear! Sorry again it took so long.
I've merged it internally, should get pushed out soon.
:thinking: I thought that would tag this as merged
. Ah well, thanks again for the contribution!
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.