-
Notifications
You must be signed in to change notification settings - Fork 1
/
install_apptainer.sh
176 lines (152 loc) · 5.84 KB
/
install_apptainer.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#!/usr/bin/env bash
# Made by Kasper Skytte Andersen (https://github.com/KasperSkytte)
# Only for ubuntu/debian 64-bit linux machines
# License: GNU General Public License v3.0
set -eu
VERSION="1.3"
# GO version
GOVERSION=1.19.3
# singularity/apptainer version
APPTAINER_VERSION="v1.1.8"
# required system packages for apptainer
pkgs="build-essential libseccomp-dev pkg-config uidmap squashfs-tools squashfuse fuse2fs fuse-overlayfs fakeroot cryptsetup curl wget git"
scriptMessage() {
#check user arguments
if [ ! $# -eq 1 ]
then
echo "Error: function must be passed exactly 1 argument" >&2
exit 1
fi
echo " *** [$(date '+%Y-%m-%d %H:%M:%S')] script message: $1"
}
#default error message if bad usage
usageError() {
echo "Invalid usage: $1" 1>&2
echo ""
eval "bash $0 -h"
}
#help text
description() {
echo "This script installs apptainer/singularity ${APPTAINER_VERSION}. By default for all users in /usr/local/apptainer. To install for the current user only provide a (writable) path with the -p option. This also assumes that all system dependencies are already installed."
echo "Please provide sudo password when asked."
}
OS=$(cat /etc/os-release | grep '^ID' | grep -oE 'debian|ubuntu')
if [ -n "$OS" ]
then
installDir=""
#fetch and check options provided by user
while getopts ":hp:" opt; do
case ${opt} in
h )
description
echo "Version: $VERSION"
echo "Options:"
echo " -h Display this help text and exit."
echo " -p Path to folder where apptainer will be installed (/apptainer subfolder will be created). If not provided, will be installed system-wide for all users in /usr/local/apptainer."
exit 1
;;
p )
installDir=$(realpath -m "$OPTARG")
mkdir -p "$installDir"
if [ ! -w "$installDir" ]
then
usageError "Destination folder ${installDir} is not writable, exiting..."
exit 1
fi
;;
\? )
usageError "Invalid Option: -$OPTARG"
exit 1
;;
: )
usageError "Option -$OPTARG requires an argument"
exit 1
;;
esac
done
shift $((OPTIND -1)) #reset option pointer
description
#sleep if interactive to be able to read message
if [ -t 0 ]
then
echo "sleeping for 10 seconds"
sleep 10
fi
scriptMessage "installing system requirements via APT..."
#first check if installed before running a sudo command
#ubuntu versions before 2018 need libgpgme11-dev instead of libgpgme-dev
ubuntuMajor=$(cat /etc/lsb-release |\
grep '^DISTRIB_RELEASE.*' |\
grep -o '=[0-9]*\.' |\
grep -o '[0-9]*')
if [ $ubuntuMajor -lt 18 ]
then
pkgs="${pkgs} libgpgme11-dev"
else
pkgs="${pkgs} libgpgme-dev"
fi
if ! dpkg -s $pkgs >/dev/null 2>&1
then
echo "One or more system dependencies are not installed, will try to install..."
sudo apt-get update -qqy
sudo apt-get install -y $pkgs
else
echo "all requirements are already installed..."
fi
scriptMessage "creating temporary folder for downloads and build files..."
tmp_dir=$(mktemp -d -t apptainer_installer_XXXXX)
pushd "$tmp_dir"
scriptMessage "downloading GO lang..."
wget -O go.tar.gz https://dl.google.com/go/go${GOVERSION}.linux-amd64.tar.gz
scriptMessage "unpacking go..."
tar -zxf go.tar.gz
rm -f go.tar.gz
#go is only needed for compiling apptainer
export GOPATH=${PWD}/go
export OLDPATH=${PATH} #save for later to avoid also adding Go path to $PATH
export PATH=${PWD}/go/bin:${PATH}
scriptMessage "downloading apptainer..."
git clone https://github.com/apptainer/apptainer.git apptainer
pushd apptainer
git checkout ${APPTAINER_VERSION}
if [ -n "$installDir" ]
then
scriptMessage "installing apptainer into ${installDir}/apptainer..."
./mconfig --without-suid --prefix=${installDir}/apptainer
make -j -C ./builddir
make -j -C ./builddir install
scriptMessage "Adding apptainer path to \$PATH and enabling apptainer bash auto-completion for current user by adjusting ${HOME}/.bashrc..."
#detect and remove lines in ~/.bashrc previously added by this
#script to avoid inflating $PATH if script is run more than once
sed -i '/# >>> apptainer installer >>>/,/# <<< apptainer installer <<</d' ${HOME}/.bashrc
#then add lines
echo "# >>> apptainer installer >>>" >> ${HOME}/.bashrc
echo "#these lines have been added by the install_apptainer.sh script" >> ${HOME}/.bashrc
echo "export PATH=${installDir}/apptainer/bin:$OLDPATH" >> ${HOME}/.bashrc
echo ". ${installDir}/apptainer/etc/bash_completion.d/apptainer" >> ${HOME}/.bashrc
echo "# <<< apptainer installer <<<" >> ${HOME}/.bashrc
scriptMessage "Removing temporary folder and its contents..."
chmod -R 777 "$tmp_dir"
rm -rf "$tmp_dir"
else
scriptMessage "installing apptainer system-wide into /usr/local/bin..."
./mconfig
sudo make -j -C ./builddir
sudo make -j -C ./builddir install
scriptMessage "enabling system-wide apptainer bash auto-completion by adjusting /etc/profile..."
#detect and remove lines in /etc/profile previously added by this script to avoid inflation
sudo sed -i '/# >>> apptainer installer >>>/,/# <<< apptainer installer <<</d' /etc/profile
#then add lines
echo "# >>> apptainer installer >>>" | sudo tee -a /etc/profile
echo "#these lines have been added by the install_apptainer.sh script" | sudo tee -a /etc/profile
echo ". /usr/local/etc/bash_completion.d/apptainer" | sudo tee -a /etc/profile
echo "# <<< apptainer installer <<<" | sudo tee -a /etc/profile
scriptMessage "Removing temporary folder and its contents..."
sudo rm -rf "$tmp_dir"
fi
scriptMessage "Done installing. Reload the current shell to enable apptainer command auto-completion right away."
else
echo "Unsupported OS type: ${OS}"
echo "This script is designed only for Ubuntu or Debian Linux, exiting..."
exit 1
fi