hpc / charliecloud

Now hosted on GitLab.
https://gitlab.com/charliecloud/main
Apache License 2.0
313 stars 61 forks source link

How to use docker environment variables? #442

Closed morrisonlevi closed 3 years ago

morrisonlevi commented 5 years ago

I see from #224 that the ch-docker2tar command will now save the environment information into /etc/environment. However, I don't see how to properly use it.

If I do an ch-run --unset-env="*" --set-env="/var/tmp/$image/etc/environment" ... /var/tmp/$image -- bash then my PATH has quotes around it, eg:

"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"

Instead of:

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

If I don't do anything my outside environment variables are still set. How am I supposed to invoke this?

morrisonlevi commented 5 years ago

Oops, didn't mean to close. The quotes aren't an issue, it seems. It still seems odd that I need to use both these flags, though. Is there a simpler way?

j-ogas commented 5 years ago

Hello @morrisonlevi, the docker environment is saved at the container image root directory, not in /etc. That said, an environment file does exist there and is admittedly confusing.

Using the centos7 image from the test suite as an example:

$ cat /var/tmp/pre0.9.10/img/centos7/etc/environment
$ cat /var/tmp/pre0.9.10/img/centos7/environment
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

We want to target the latter:

$ ./bin/ch-run --unset-env='*' --set-env=/var/tmp/pre0.9.10/img/centos7/environment  /var/tmp/pre0.9.10/img/centos7 -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Does this help?

morrisonlevi commented 5 years ago

For me, there is nothing in that environment file in the root, so it fails to launch:

ch-run[134139]: can't execve(2): bash: No such file or directory (charliecloud.c:437 2)

This particular image was built using podman instead of docker, which is obviously a hack, so that could be the issue; will report back later

j-ogas commented 5 years ago

Aha, ch-docker2tar interacts with the docker deamon via docker --inspect to get the image environment metadata and populate the environment file. If we can query Podman to obtain image metadata then we can expand on this feature.

For now, a work around would be to create a file with key value pairs (described here):

For example:

$ echo PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games > "${image_path}/environment"
$ echo FOO=fizz:buzz >> "${image_path}/environment"
$ ch-run --unset-env='*' --set-env=${image_path}/environment -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
FOO=fizz:buzz
reidpr commented 5 years ago

I would add that we're looking to generalize ch-build; see e.g. PR #431. So the logistics to accomplish saving environment variables with Podman could be embedded into ch-build.

Generally speaking, we want to be agnostic to image builder, so if Podman isn't working for some reason, that's probably a bug on our end, and we'd like to know more.

We did go round a few times on what the right interface for --set-env and --unset-env was and are open to feedback.

yuvipanda commented 5 years ago

If you know you're going to be used with charliecloud, you can symlink /environment to /etc/profile.d/000-<something>.sh to have a login shell like /bin/bash -l automatically source it.

This is what I do in repo2charliecloud - https://github.com/yuvipanda/repo2charliecloud/blob/525efdf97094d0973b0920b2d0b0dfcd3acb7298/repo2charliecloud/__init__.py#L67. You can probably put that ln -s behind a conditional if you want to generalize that.

reidpr commented 3 years ago

This issue hasn't had any traffic in some time, and environment handling has changed quite a bit, so I'm going to close it. If there are further questions on this topic, please open a new Discussion, or a new issue if anyone has a specific change request.