File: setup_machine.sh

package info (click to toggle)
saunafs 5.1.2-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 12,820 kB
  • sloc: cpp: 109,287; sh: 18,755; python: 4,737; ansic: 4,023; makefile: 60; awk: 17
file content (285 lines) | stat: -rwxr-xr-x 9,901 bytes parent folder | download
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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
#!/usr/bin/env bash
set -eux -o pipefail
readonly self="$(readlink -f "${BASH_SOURCE[0]}")"
readonly script_dir="$(dirname "$self")"
readonly script_name="$(basename "${self}")"

usage() {
	cat >&2 <<-EOF
		Usage: ${script_name} setup hdd...

		This scripts prepares the machine to run SaunaFS tests here.
		Specifically:
		* creates users saunafstest, saunafstest_0, ..., saunafstest_9
		* adds all saunafstest users to the fuse group
		* grants all users rights to run programs as saunafstest users
		* grants all users rights to run 'pkill -9 -u <some saunafstest user>'
		* allows all users to mount fuse filesystem with allow_other option
		* creates a 2G ramdisk in /mnt/ramdisk
		* creates 6 files mounted using loop device

		Example:
		${script_name} setup /mnt
		${script_name} setup /mnt/hda /mnt/hdb

		You need root permissions to run this script
	EOF
	exit 1
}

tool_exists() {
	type -P -v "${1}" >/dev/null
}

minimum_number_of_args=2
if [[ ( ( "${1}" != "setup" ) && ( "${1}" != "setup-force" ) ) || ( ${#} -lt ${minimum_number_of_args} ) ]]; then
	usage >&2
fi

if grep -q 'saunafstest_loop' /etc/fstab; then
	if [[ "${1}" != "setup-force" ]]; then
		echo 'The machine is at least partially configured'
		echo 'Run revert-setup-machine.sh to revert the current configuration'
		exit 1
	fi
fi

shift
umask 0022

"$script_dir/install-packages.sh"

python_packages=(
	asciidoc
	black
	devscripts
	flask
	lcov_cobertura
	mypy
	pdfminer.six
	requests
	types-requests
)

gpg2 --list-keys
#setup gtest from sources
: "${GTEST_ROOT:=/usr/local}"
readonly gtest_temp_build_dir="$(mktemp -d)"
cmake -S /usr/src/googletest -B "${gtest_temp_build_dir}" -DCMAKE_INSTALL_PREFIX="${GTEST_ROOT}"
make -C "${gtest_temp_build_dir}" install
rm -rf "${gtest_temp_build_dir:?}"
# Setup python3 with a global virtual env (new recommended way)
VIRTUAL_ENV=/var/lib/saunafs_setup_machine_venv
export VIRTUAL_ENV
if ! grep -Eq 'PATH=.*'"${VIRTUAL_ENV}/bin\b"'' /etc/environment ; then
	# Add the virtualenv to the end of the PATH in /etc/environment
	# Select three groups: PATH=, optional quote, rest of the path,
	# then add the virtualenv bin directory to the end of the path, keeping the correct quoting
	sed -E 's@(PATH=)([:"'\'']?)(.*)\2@\1\2\3:'"${VIRTUAL_ENV}/bin"'\2@' -i /etc/environment;
fi
# Add VIRTUAL_ENV to /etc/environment if it's not there
sed '\@VIRTUAL_ENV="'"${VIRTUAL_ENV}"'"@!s@$@\nVIRTUAL_ENV="'"${VIRTUAL_ENV}"'"@' -zi /etc/environment
python3 -m venv "${VIRTUAL_ENV}"
"${VIRTUAL_ENV}/bin/python3" -m pip install "${python_packages[@]}"

echo ; echo 'Add group fuse'
groupadd -f fuse

echo ; echo 'Add user saunafstest'
if ! getent passwd saunafstest > /dev/null; then
	useradd --system --user-group --home /var/lib/saunafstest --create-home saunafstest
	chmod 755 /var/lib/saunafstest
fi

if ! groups saunafstest | grep -w fuse > /dev/null; then
	usermod -a -G fuse saunafstest # allow this user to mount fuse filesystem
fi
if ! groups saunafstest | grep -w adm > /dev/null; then
	usermod -a -G adm saunafstest # allow this user to read files from /var/log
fi

echo ; echo 'Prepare sudo configuration'
if ! [[ -d /etc/sudoers.d ]]; then
	# Sudo is not installed by default on Debian machines
	echo "sudo not installed!" >&2
	echo "Install it manually: apt-get install sudo" >&2
	echo "Then run this script again" >&2
	exit 1
fi
if ! [[ -f /etc/sudoers.d/saunafstest ]] || \
		! grep drop_caches /etc/sudoers.d/saunafstest >/dev/null; then
	cat >/etc/sudoers.d/saunafstest <<-END
		Defaults rlimit_core=default
		ALL ALL = (saunafstest) NOPASSWD: ALL
		ALL ALL = NOPASSWD: /usr/bin/pkill -9 -u saunafstest
		ALL ALL = NOPASSWD: /bin/rm -rf /tmp/saunafs_error_dir
		saunafstest ALL = NOPASSWD: /bin/sh -c echo\ 1\ >\ /proc/sys/vm/drop_caches
		saunafstest ALL = NOPASSWD: /usr/bin/cat .oplog
	END
	chmod 0440 /etc/sudoers.d/saunafstest
fi
if ! [[ -d /etc/security/limits.d ]]; then
	echo "pam module pam_limits is not installed!" >&2
	exit 1
fi
if ! [[ -f /etc/security/limits.d/10-saunafstests.conf ]]; then
	# Change limit of open files for user saunafstest
	echo "saunafstest hard nofile 10000" > /etc/security/limits.d/10-saunafstests.conf
	chmod 0644 /etc/security/limits.d/10-saunafstests.conf
fi
if ! grep 'pam_limits.so' /etc/pam.d/sudo > /dev/null; then
	cat >>/etc/pam.d/sudo <<-END
		### Reload pam limits on sudo - necessary for saunafs tests. ###
		session required pam_limits.so
	END
fi

echo ; echo 'Add users saunafstest_{0..9}'
for username in saunafstest_{0..9}; do
	if ! getent passwd ${username} > /dev/null; then
		useradd --system --user-group --home /var/lib/${username} --create-home \
				--groups fuse,saunafstest ${username}
		cat >>/etc/sudoers.d/saunafstest <<-END

			ALL ALL = (${username}) NOPASSWD: ALL
			ALL ALL = NOPASSWD: /usr/bin/pkill -9 -u ${username}
		END
	fi
done

if [ ! -f /etc/sudoers.d/saunafstest ] || ! grep -q '# SMR' /etc/sudoers.d/saunafstest >/dev/null; then
	cat <<-'END' >>/etc/sudoers.d/saunafstest
		# SMR
		saunafstest ALL = NOPASSWD: /usr/sbin/modprobe null_blk nr_devices=0
		saunafstest ALL = NOPASSWD: /usr/sbin/mkzonefs -f -o perm=666 /dev/sauna_nullb*
		saunafstest ALL = NOPASSWD: /usr/sbin/mkzonefs -f -o perm=666 /dev/nullb*
		saunafstest ALL = NOPASSWD: /usr/bin/mount -t zonefs /dev/sauna_nullb* /mnt/zoned/sauna_nullb*
		saunafstest ALL = NOPASSWD: /usr/bin/mount -t zonefs /dev/nullb* /mnt/zoned/sauna_nullb*
		saunafstest ALL = NOPASSWD: /usr/bin/umount -l /mnt/zoned/sauna_nullb*

		saunafstest ALL = NOPASSWD: /usr/bin/mkdir -pm 777 /mnt/zoned/sauna_nullb*
		saunafstest ALL = NOPASSWD: /usr/bin/mkdir /sys/kernel/config/nullb/sauna_nullb*
		saunafstest ALL = NOPASSWD: /usr/bin/rmdir /sys/kernel/config/nullb/sauna_nullb*
		saunafstest ALL = NOPASSWD: /usr/bin/tee /sys/kernel/config/nullb/sauna_nullb*
		saunafstest ALL = NOPASSWD: /usr/bin/tee /sys/block/sauna_nullb*
		saunafstest ALL = NOPASSWD: /usr/bin/tee /sys/block/nullb*
	END
fi

if [ ! -f /etc/sudoers.d/saunafstest ] || ! grep -q '# Ganesha' /etc/sudoers.d/saunafstest >/dev/null; then
	cat <<-'END' >>/etc/sudoers.d/saunafstest
		# Ganesha automated tests
		saunafstest ALL = NOPASSWD: /tmp/SaunaFS-autotests/mnt/sfs0/bin/ganesha.nfsd
		saunafstest ALL = NOPASSWD: /usr/bin/ganesha.nfsd
		saunafstest ALL = NOPASSWD: /usr/bin/pkill -9 ganesha.nfsd
		saunafstest ALL = NOPASSWD: /usr/bin/pkill -HUP rpcbind
		saunafstest ALL = NOPASSWD: /usr/bin/mkdir -p /var/run/ganesha
		saunafstest ALL = NOPASSWD: /usr/bin/touch /var/run/ganesha/ganesha.pid
		saunafstest ALL = NOPASSWD: /usr/bin/mount, /usr/bin/umount
	END
fi

if [ ! -f /etc/sudoers.d/saunafstest ] || ! grep -q '# Client' /etc/sudoers.d/saunafstest >/dev/null; then
	cat <<-'END' >>/etc/sudoers.d/saunafstest
		# Client
		saunafstest ALL = NOPASSWD: /usr/bin/tee /tmp/SaunaFS-autotests/mnt/sfs*
	END
fi

if [ ! -f /etc/sudoers.d/saunafstest ] || ! grep -q '# FoundationDB' /etc/sudoers.d/saunafstest > /dev/null; then
	cat <<-'END' >>/etc/sudoers.d/saunafstest
		# FoundationDB
		saunafstest ALL = NOPASSWD: /usr/lib/foundationdb/fdbmonitor --conffile*
		saunafstest ALL = NOPASSWD: /usr/bin/pkill -f fdbmonitor*
	END
fi

echo ; echo 'Install FoundationDB'
"$script_dir/ci_build/install-foundationdb.sh"

echo ; echo 'Fixing GIDs of users'
for name in saunafstest saunafstest_{0..9}; do
	uid=$(getent passwd "${name}" | cut -d: -f3)
	gid=$(getent group  "${name}" | cut -d: -f3)
	if [[ ${uid} == "" || ${gid} == "" ]]; then
		exit 1
	fi
	if [[ "${uid}" == "${gid}" ]]; then
		# UID is equal to GID -- we have to change it to something different,
		# so find some other free gid
		new_gid=$((gid * 2))
		while getent group ${new_gid}; do
			new_gid=$((new_gid + 1))
		done
		groupmod -g ${new_gid} ${name}
	fi
done

echo ; echo 'Prepare /etc/fuse.conf'
if ! grep '^[[:blank:]]*user_allow_other' /etc/fuse.conf >/dev/null; then
	echo "user_allow_other" >> /etc/fuse.conf
fi

echo ; echo 'Configure local port range for outbond connections'
if [ ! -f  /etc/sysctl.d/60-ip_port_range.conf ]; then
	echo "net.ipv4.ip_local_port_range=10000 64000" > /etc/sysctl.d/60-ip_port_range.conf
fi

echo ; echo 'Prepare empty /etc/saunafs_tests.conf'
if ! [[ -f /etc/saunafs_tests.conf ]]; then
	cat >/etc/saunafs_tests.conf <<-END
		: \${SAUNAFS_DISKS:="$*"}
		# : \${TEMP_DIR:=/tmp/SaunaFS-autotests}
		# : \${SAUNAFS_ROOT:=${HOME}/local}
		# : \${FIRST_PORT_TO_USE:=25000}
	END
fi

echo ; echo 'Prepare ramdisk'
if ! grep /mnt/ramdisk /etc/fstab >/dev/null; then
	echo "# Ramdisk used in SaunaFS tests" >> /etc/fstab
	echo "ramdisk  /mnt/ramdisk  tmpfs  mode=1777,size=2g" >> /etc/fstab
	mkdir -p /mnt/ramdisk
	mount /mnt/ramdisk
	# shellcheck disable=SC2016
	echo ': ${RAMDISK_DIR:=/mnt/ramdisk}' >> /etc/saunafs_tests.conf
fi

if grep -q Microsoft /proc/version && ! grep -q microsoft-standard /proc/version; then
	echo "Running on WSL1: skipping loop device creation."
else
	echo ; echo 'Prepare loop devices'
	#creating loop devices more or less evenly distributed between available disks
	i=0
	devices=6
	loops=()
	while [ ${i} -lt ${devices} ] ; do
		for disk in "$@"; do
			if (( i == devices )); then #stop if we have enough devices
				break
			fi
			loops+=("/mnt/saunafstest_loop_${i}")
			if grep -q "saunafstest_loop_${i}" /etc/fstab; then
				(( ++i ))
				continue
			fi
			mkdir -p "${disk}/saunafstest_images"
			# Create image file
			image="${disk}/saunafstest_images/image_${i}"
			truncate -s 1G "${image}"
			mkfs.ext4 -Fq "${image}"
			# Add it to fstab
			echo "$(readlink -m "${image}") /mnt/saunafstest_loop_${i}  ext4  loop" >> /etc/fstab
			mkdir -p "/mnt/saunafstest_loop_${i}"
			# Mount and set permissions
			mount "/mnt/saunafstest_loop_${i}"
			chmod 1777 "/mnt/saunafstest_loop_${i}"
			(( ++i ))
		done
	done
	# shellcheck disable=SC2016
	echo ': ${SAUNAFS_LOOP_DISKS:="'"${loops[*]}"'"}' >> /etc/saunafs_tests.conf
fi

set +x
echo 'Machine configured successfully'