|
| 1 | +# Faking a native app installation within a Singularity container |
| 2 | + |
| 3 | +How would you like to install an app with one more more commands inside of a Singularity container and then just forget it's in a container and use it like any other app? |
| 4 | + |
| 5 | +In the last example, we took a step in that direction by creating a `runscript` to accept input and output, but we still had to set an environment variable and our container was not actually using the cowsay program as written. Not to mention, it gave us zero access to the `fortune` and `lolcat` programs. In other words, it could only do what our `runscript` told it to do. |
| 6 | + |
| 7 | +In this section, we are going to look at a simple, flexible method for creating containerized app installations that you can "set and forget". This is the same method that Biowulf staff members use to install containerized applications on the NIH HPC systems. As of today, around 100 applications are installed like this, and most of them are used all the time by scientists who may never know or care that the app they depend on is actually running inside of a container! |
| 8 | + |
| 9 | +First, we will `cd` back into our `~/lolcow` directory (if we are not already there) and delete everything in it. |
| 10 | + |
| 11 | +--- |
| 12 | +**NOTE** |
| 13 | + |
| 14 | +This class is taught using virtual machines, but you should still _always_ be careful and double check your location, permissions, and mental state before issuing a `rm -rf` command. That goes double when issuing the command as root. |
| 15 | + |
| 16 | +--- |
| 17 | + |
| 18 | +``` |
| 19 | +$ cd ~/lolcow |
| 20 | +
|
| 21 | +$ pwd # double check |
| 22 | +/home/student/lolcow |
| 23 | +
|
| 24 | +$ sudo rm -rf * # caution! see NOTE above! |
| 25 | +``` |
| 26 | + |
| 27 | +Now we'll make a few new directories to keep things tidy. |
| 28 | + |
| 29 | +``` |
| 30 | +$ mkdir libexec bin |
| 31 | +``` |
| 32 | + |
| 33 | +Next we'll create the contents of the `libexec` directory. It will contain the container, and a rather trickly little wrapper script. |
| 34 | + |
| 35 | +``` |
| 36 | +$ singularity pull libexec/lolcow.sif library://godlovedc/funny/lolcow |
| 37 | +
|
| 38 | +$ cat >libexec/lolcow.sh<<"EOF" |
| 39 | +#!/bin/bash |
| 40 | +export SINGULARITY_BINDPATH="/data" |
| 41 | +dir="$(dirname $(readlink -f ${BASH_SOURCE[0]}))" |
| 42 | +img="lolcow.sif" |
| 43 | +cmd=$(basename "$0") |
| 44 | +arg="$@" |
| 45 | +echo running: singularity exec "${dir}/${img}" $cmd $arg |
| 46 | +singularity exec "${dir}/${img}" $cmd $arg |
| 47 | +EOF |
| 48 | +
|
| 49 | +$ chmod 755 libexec/lolcow.sh |
| 50 | +``` |
| 51 | + |
| 52 | +Now for the trick. The `lolcow.sh` wrapper script is written in such a way that whatever symlinks you create to it will run inside of the container. We've temporarily given it an `echo` line to help clarify what it's doing. Let's make a few symlinks in the `bin` directory. |
| 53 | + |
| 54 | +``` |
| 55 | +$ ln -s ../libexec/lolcow.sh bin/fortune |
| 56 | +
|
| 57 | +$ ln -s ../libexec/lolcow.sh bin/cowsay |
| 58 | +
|
| 59 | +$ ln -s ../libexec/lolcow.sh bin/lolcat |
| 60 | +``` |
| 61 | + |
| 62 | +Here's what the directory should look like: |
| 63 | + |
| 64 | +``` |
| 65 | +lolcow/ |
| 66 | +├── bin |
| 67 | +│ ├── cowsay -> ../libexec/lolcow.sh |
| 68 | +│ ├── fortune -> ../libexec/lolcow.sh |
| 69 | +│ └── lolcat -> ../libexec/lolcow.sh |
| 70 | +└── libexec |
| 71 | + ├── lolcow.sh |
| 72 | + └── lolcow.sif |
| 73 | +``` |
| 74 | + |
| 75 | +Now let's see how it works: |
| 76 | + |
| 77 | +``` |
| 78 | +$ cd ~ |
| 79 | +
|
| 80 | +$ export PATH=$PATH:~/lolcow/bin |
| 81 | +
|
| 82 | +$ which cowsay fortune lolcat |
| 83 | +/home/student/lolcow/bin/cowsay |
| 84 | +/home/student/lolcow/bin/fortune |
| 85 | +/home/student/lolcow/bin/lolcat |
| 86 | +
|
| 87 | +$ cowsay moo |
| 88 | +running: singularity exec /home/student/lolcow/libexec/lolcow.sif cowsay moo |
| 89 | + _____ |
| 90 | +< moo > |
| 91 | + ----- |
| 92 | + \ ^__^ |
| 93 | + \ (oo)\_______ |
| 94 | + (__)\ )\/\ |
| 95 | + ||----w | |
| 96 | + || || |
| 97 | +
|
| 98 | +$ lolcat --help |
| 99 | +running: singularity exec /home/student/lolcow/libexec/lolcow.sif lolcat --help |
| 100 | +
|
| 101 | +Usage: lolcat [OPTION]... [FILE]... |
| 102 | +
|
| 103 | +Concatenate FILE(s), or standard input, to standard output. |
| 104 | +With no FILE, or when FILE is -, read standard input. |
| 105 | +
|
| 106 | + --spread, -p <f>: Rainbow spread (default: 3.0) |
| 107 | + --freq, -F <f>: Rainbow frequency (default: 0.1) |
| 108 | + --seed, -S <i>: Rainbow seed, 0 = random (default: 0) |
| 109 | + --animate, -a: Enable psychedelics |
| 110 | + --duration, -d <i>: Animation duration (default: 12) |
| 111 | + --speed, -s <f>: Animation speed (default: 20.0) |
| 112 | + --force, -f: Force color even when stdout is not a tty |
| 113 | + --version, -v: Print version and exit |
| 114 | + --help, -h: Show this message |
| 115 | +
|
| 116 | +Examples: |
| 117 | + lolcat f - g Output f's contents, then stdin, then g's contents. |
| 118 | + lolcat Copy standard input to standard output. |
| 119 | + fortune | lolcat Display a rainbow cookie. |
| 120 | +
|
| 121 | +Report lolcat bugs to <http://www.github.org/busyloop/lolcat/issues> |
| 122 | +lolcat home page: <http://www.github.org/busyloop/lolcat/> |
| 123 | +Report lolcat translation bugs to <http://speaklolcat.com/> |
| 124 | +``` |
| 125 | + |
| 126 | +Once you understand how it works, remove (or comment) the echo line in `lolcow/libexec/lolcow.sh` and even things like this should work without a hitch: |
| 127 | + |
| 128 | +``` |
| 129 | +$ fortune | cowsay -n | lolcat |
| 130 | + ___________________________________________________________ |
| 131 | +< You never hesitate to tackle the most difficult problems. > |
| 132 | + ----------------------------------------------------------- |
| 133 | + \ ^__^ |
| 134 | + \ (oo)\_______ |
| 135 | + (__)\ )\/\ |
| 136 | + ||----w | |
| 137 | + || || |
| 138 | +``` |
| 139 | + |
| 140 | +--- |
| 141 | +**NOTE** |
| 142 | + |
| 143 | +If you have too much time on your hands, you might try linking things like `sh`, `bash`, `ls`, or `cd` to the container wrapper script. But otherwise **don't**... because it will cause you a lot of trouble. :-) |
| 144 | + |
| 145 | +--- |
0 commit comments