Skip to content

ENH: First cut at script to run singularity images in Docker#11

Merged
yarikoptic merged 8 commits intoReproNim:masterfrom
mjtravers:enh-singularity-via-docker
Jun 27, 2019
Merged

ENH: First cut at script to run singularity images in Docker#11
yarikoptic merged 8 commits intoReproNim:masterfrom
mjtravers:enh-singularity-via-docker

Conversation

@mjtravers
Copy link
Contributor

@yarikoptic

Fixes #3

Here's a first cut at the proxy Docker script.

Any directories that are bound into the container must be relative to the $PWD where the script is run.

I am still experimenting to verify that it works on Windows but have confirmed it works on Linux machines. Will need a volunteer to test on a Mac.

Copy link
Member

@yarikoptic yarikoptic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

provided in separate comments

# - cleansed environment variables
# while bind mounting (and starting from) current directory.
#
# COPYRIGHT: Yaroslav Halchenko 2019
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think I am the one who did it ;)


docker run -ti --privileged --rm \
-v $PWD:/working-dir \
-v $tmpdir:/working-temp \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably some inconsistent tabs and spaces use above so indentation jumps

-w /working-dir \
singularityware/singularity:latest \
"$cmd" -e -c -W /working-temp -H "$updir/binds/HOME" \
-B /working-dir --pwd /working-dir "$@"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to retain similarity to how singularity works natively and how we invoke it within our singularityware/singularity, $PWD should be a $PWD inside the container. So I guess, if it is mapped to /workdir-dir at docker level, it should be mapped back to $PWD within singularity call. but may be the best would be to bind-mount to $PWD within docker call, without changing to /working-dir

# Create a dedicated temporary directory to be removed upon completion
tmpdir=$(mktemp -d --suffix=singtmp)
info "created temp dir $tmpdir"
trap "rm -fr '$tmpdir' && info 'removed temp dir $tmpdir'" exit
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is no need for a dedicated /tmp here for the docker sake


if [ ! -z "${DATALAD_CONTAINER_NAME:-}" ]; then
export SINGULARITYENV_DATALAD_CONTAINER_NAME="$DATALAD_CONTAINER_NAME"
fi
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess no need for any of the above analysis for cmd and the env var

-v $tmpdir:/working-temp \
-w /working-dir \
singularityware/singularity:latest \
"$cmd" -e -c -W /working-temp -H "$updir/binds/HOME" \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that the singularity_cmd should get those $BHOME and $tmpdir exposed via some environment variable(s) (e.g. REPRONIM_CONTAINERS_BINDS) so this script would just bind mount them...
Overall think about "interaction" between that singularity_cmd and this script, or just moving this "docker run ... singularity" invocation instead of plain "singularity" call within that script, to be triggered via SINGULARITY_VIA_DOCKER env variable, which is if empty decided based on OS (non-Linux - use docker).

@mjtravers
Copy link
Contributor Author

I moved the docker call into the singularity_cmd script and made the updates suggested above.

To force the use of docker, the user can set a REPRONIM_USE_DOCKER env variable

Copy link
Member

@yarikoptic yarikoptic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Singularity environment should feel/behave identically regardless either ran through docker or directly, so bind mounts set and home should be the same

-v $PWD:$PWD \
-w $PWD \
singularityware/singularity:latest \
"$cmd" -e -c -B $PWD --pwd $PWD "$@"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about -W and -H in this call?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yarikoptic
Those two switches are not needed. For -W, the system /tmp and /var_tmp are isolated at 2 levels, first by the -c switch we pass and because we are running singularity in a docker container for additional isolation of those system directories from the host. The -H encounters the same isolation as the -W, plus we decided on only $PWD for binding within the singularity container.

Actually, why are we passing those two switches in the non-Docker singularity call? Will the user want to write output to a surrogate home directory?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surrogate home directory provides needed (by git and datalad) .gitconfig and uniform .bashrc . As for /tmp indeed not needed probably, if only for uniform operation

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In https://github.com/ReproNim/containers/pull/9/files I might also rely on being able to copy bash history for the interactive session from that temporary directory, so would be to have it visible on the host system

@mjtravers
Copy link
Contributor Author

@yarikoptic
Okay, I added a Docker binding for BHOME that passes through to the singularity command. It works fine on my Ubuntu-based OS. I don't have a platform to run the Mac or Windows installations, though. Windows needs Pro and I only have the HOME version with can only run the Docker Toolkit, which in turn uses VirtualBox.

@yarikoptic
Copy link
Member

@chaselgrove could you please test this script on your osx laptop?

@yarikoptic
Copy link
Member

@mjtravers - have you approached the 2nd checkbox in #3 on user mapping? Currently it would run as root:

$> REPRONIM_USE_DOCKER=1 scripts/singularity_cmd exec images/bids/bids-validator--1.2.3.sing ls -aLl
total 32
drwx------    1 47521    47522          140 May 30 22:28 .
drwxr-xr-x    3 root     root            60 Jun 17 12:59 ..
drwx------    1 47521    47522           40 May 22 18:53 .datalad
drwx------    1 47521    47522          234 Jun 17 12:51 .git
-rw-------    1 47521    47522           97 Apr 19 18:17 .gitattributes
-rw-------    1 47521    47522         1207 Apr 19 15:59 .gitignore
-rw-------    1 47521    47522        11357 May 15 22:14 LICENSE
-rw-------    1 47521    47522         8266 May 30 22:02 README.md
drwx------    1 47521    47522            8 Apr 19 15:35 binds
drwx------    1 47521    47522           42 May 16 20:55 images
drwx------    1 47521    47522           70 Jun 17 12:58 scripts
1 10882.....................................:Mon 17 Jun 2019 08:59:39 AM EDT:.
(git-annex)hopa:~/proj/repronim/containers[pull/origin/11/head]git-annex
$> REPRONIM_USE_DOCKER=1 scripts/singularity_cmd exec images/bids/bids-validator--1.2.3.sing touch 123
1 10883.....................................:Mon 17 Jun 2019 08:59:52 AM EDT:.
(git-annex)hopa:~/proj/repronim/containers[pull/origin/11/head]git-annex
$> ls -ld 123
-rw-r--r-- 1 root root 0 Jun 17 08:59 123

I am not sure yet if we somehow could make use of -u for docker run and/or would need first create that user within docker (USER within that singularity image is root so should be possible) and su that singularity call into the outside user or anything else todo.

@mjtravers
Copy link
Contributor Author

This last commit addresses the 3 issues discussed at the last status meeting:

testing: I added a test using the BATS test framework (https://github.com/bats-core/bats-core). We started using this framework for NITRC-CE testing and it is easy to use and run. I can rollback if it turns out to be not what we want for this repo.

"$@" issues: This sorted out fairly easily when I gave up on "su" and implemented the singularity call using "sudo -u" instead.

HEREDOC: Figured out a way to get a HEREDOC in a Dockerfile RUN statement

@yarikoptic
Copy link
Member

awesome -- I will try it out a bit later.

bats -- great! You made decision for us, so subsequent tests might as well be done in bats as well ;-)

scripts/tests/arg-test.simg -- we shouldn't commit images directly here. 2.5M is not much but they would add up so "doesn't sale". Although a chicken-egg-problem of a kind, I would rename singularity file into Singularity.arg-test (use . to separate out a tag), that will cause image to built on singularity hub with arg-test tag when we merge this PR, and then with subsequent PR we should enable Travis and run that test using singularity pull to get the image first/

@test "verifying arguments passed to singularity_cmd Docker shim" {
export REPRONIM_USE_DOCKER=1
run ../singularity_cmd \
exec arg-test.simg /singularity "foo bar" blah 45.5 /dir
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would you be kind to add one more (or just include to existing one) obscure one with & ; and '${something}' in it/them? ;-)

@yarikoptic
Copy link
Member

re .simg -- please amend/rewrite and existing commit so there is no commit to merge with this heavy object

@mjtravers
Copy link
Contributor Author

I thought about that but we need the .simg file to run the test. I could use the singularity_cmd itself to build the image temporarily, I suppose. The .img file is 2.7MB

@yarikoptic
Copy link
Member

yeap, 2.7MB in this version... then if we change anything, would be +2.7MB and so on.

I think it would be ok if you just build locally and for tests to assume that it is there for now. Whenever we get tagged Singularity build we could add it to reside under git-annex and make bats fetch it using "git annex get" from singularity hub or wherever it would be made available from.

@yarikoptic
Copy link
Member

continuing on our brief hangout discussion -- it was the https://www.shellcheck.net/ . To avoid conflicts I guess I will not make this script fully compliant but will attend to create_singularities and enable it on travis in a separate PR

singularityware contianer so that the user who launches the
singularity_cmd script with have ownership of the files created.
Added BATS framework test for singularity-in-docker version of singularity_cmd
Changed bash code in Dockerfile to a more readable HEREDOC
Renamed the Singularity build file to meet the naming standard
Quoted switch arguments to docker run command in singularity_cmd
@yarikoptic
Copy link
Member

you would've needed to squash 6a2844c and its parent cc77adb, or just rewrite both so there is no trace of the .simg file being added in git. Since you have merged master in the most recent commit... I did that and rebased on top of master, with the last commit being

ENH: Renamed singularity-shim Dockerfile to match file naming convention

is it ok to force push?

@mjtravers
Copy link
Contributor Author

Yes, force push is a-okay... BTW is that some sort of Star Wars reference? :)

@yarikoptic yarikoptic force-pushed the enh-singularity-via-docker branch from 9a4cdc6 to 0a5a643 Compare June 27, 2019 18:07
@yarikoptic yarikoptic merged commit 617bd98 into ReproNim:master Jun 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docker Singularity "proxy" to invoke singularity containers on non-Linux systems via docker

2 participants