Add stable/2402 branch and remove stable/2306 branch to docker executor image scripts
[ci-management.git] / docker / scripts / lib_csit.sh
1 # lib_csit.sh - Docker build script CSIT library.
2 #               For import only.
3
4 # Copyright (c) 2023 Cisco and/or its affiliates.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at:
8 #
9 #     http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # Don't import more than once.
18 if [ -n "$(alias lib_csit_imported 2> /dev/null)" ] ; then
19     return 0
20 fi
21 alias lib_csit_imported=true
22
23 export CIMAN_DOCKER_SCRIPTS="${CIMAN_DOCKER_SCRIPTS:-$(dirname ${BASH_SOURCE[0]})}"
24 . "$CIMAN_DOCKER_SCRIPTS/lib_common.sh"
25 . "$CIMAN_DOCKER_SCRIPTS/lib_apt.sh"
26
27 CSIT_SUPPORTED_EXECUTOR_CLASSES="builder csit_dut"
28 csit_supported_executor_class() {
29     if ! grep -q "${1:-}" <<< "$CSIT_SUPPORTED_EXECUTOR_CLASSES" ; then
30         return 1
31     fi
32     return 0
33 }
34
35 csit_supported_os() {
36     case "$1" in
37         ubuntu-22.04) return 0 ;;
38                    *) ;;
39     esac
40     return 1
41 }
42
43 csit_checkout_branch_for_vpp() {
44     local vpp_branch="$1"
45     local csit_dir="$DOCKER_CSIT_DIR"
46     local csit_bash_function_dir="$csit_dir/resources/libraries/bash/function"
47
48     # import checkout_csit_for_vpp() if not defined
49     set +e && [ -z "$(declare -f checkout_csit_for_vpp)" ] \
50         && source "$csit_bash_function_dir/branch.sh"
51     CSIT_DIR="$csit_dir" checkout_csit_for_vpp "$vpp_branch"
52
53     # shellcheck disable=SC2034,SC2063
54     csit_branch="$(git branch | grep -e '^*' | mawk '{print $2}')"
55 }
56
57 csit_install_packages() {
58     local branch="$1"
59     local branchname
60     branchname="$(echo $branch | sed -e 's,/,_,')"
61     local csit_dir="$DOCKER_CSIT_DIR"
62     local csit_ansible_dir="$csit_dir/fdio.infra.ansible"
63     if [ ! -d "$csit_ansible_dir" ] ; then
64         csit_ansible_dir="$csit_dir/resources/tools/testbed-setup/ansible"
65     fi
66     local bld_log="$DOCKER_BUILD_LOG_DIR/$FDIOTOOLS_IMAGENAME"
67     bld_log="${bld_log}-$branchname-csit_install_packages-bld.log"
68
69     git clean -qfdx
70     python3 -m pip install pyyaml
71
72     local exclude_roles="-e calibration -e kernel -e mellanox -e nomad -e consul -e aws -e vpp"
73     [ "$OS_ARCH" = "aarch64" ] && exclude_roles="$exclude_roles -e iperf"
74
75     # Not in double quotes to let bash remove newline characters
76     local yaml_files
77     yaml_files="$(grep -r packages_by $csit_ansible_dir | cut -d: -f1 | sort -u | grep -v $exclude_roles)"
78     packages="$(dbld_csit_find_ansible_packages.py --$OS_ID --$OS_ARCH $yaml_files)"
79     packages="${packages/jammy /}"
80     packages="${packages/focal /}"
81     packages="${packages/libmbedcrypto1/libmbedcrypto3}"
82     packages="${packages/libmbedtls10/libmbedtls12}"
83     packages="$(echo ${packages//python\-/python3\-} | tr ' ' '\n' | sort -u | xargs)"
84
85     if [ -n "$packages" ] ; then
86         case "$OS_NAME" in
87             ubuntu*)
88                 apt_install_packages "$packages" 2>&1 | tee -a "$bld_log"
89                 ;;
90             debian*)
91                 apt_install_packages "$packages" 2>&1 | tee -a "$bld_log"
92                 ;;
93             *)
94                 echo "Unsupported OS ($OS_ID): CSIT packages NOT INSTALLED!"
95                 ;;
96         esac
97     fi
98 }
99
100 csit_install_hugo() {
101     local branch="$1"
102     CSIT_DIR="$DOCKER_CSIT_DIR"
103
104     if [ -f "$CSIT_DIR/VPP_REPO_URL" ] \
105            && [ -f "$CSIT_DIR/requirements.txt" ]; then
106
107         local branchname
108         # use bash variable substitution to replace '/' with '_' to convert from
109         # vpp to csit branch name nomenclature
110         branchname="${branch////_}"
111         local csit_bash_function_dir="$CSIT_DIR/resources/libraries/bash/function"
112         local bld_log="$DOCKER_BUILD_LOG_DIR"
113         bld_log="${bld_log}/$FDIOTOOLS_IMAGENAME-$branchname-csit_install_hugo-bld.log"
114
115         description="Install CSIT hugo packages from $branch branch"
116         echo_log "    Starting  $description..."
117         git clean -qfdx
118
119         source "$csit_bash_function_dir"/hugo.sh
120         go_install 2>&1 | tee -a "$bld_log"
121         hugo_install 2>&1 | tee -a "$bld_log"
122
123     else
124         echo_log "ERROR: Missing or invalid CSIT_DIR: '$CSIT_DIR'!"
125         return 1
126     fi
127 }
128
129 csit_pip_cache() {
130     local branch="$1"
131     # ensure PS1 is defined (used by virtualenv activate script)
132     PS1=${PS1:-"#"}
133     CSIT_DIR="$DOCKER_CSIT_DIR"
134
135     if [ -f "$CSIT_DIR/VPP_REPO_URL" ] \
136            && [ -f "$CSIT_DIR/requirements.txt" ]; then
137
138         local branchname
139         # use bash variable substitution to replace '/' with '_' to convert from
140         # vpp to csit branch name nomenclature
141         branchname="${branch////_}"
142         local csit_bash_function_dir="$CSIT_DIR/resources/libraries/bash/function"
143         local bld_log="$DOCKER_BUILD_LOG_DIR"
144         bld_log="${bld_log}/$FDIOTOOLS_IMAGENAME-$branchname-csit_pip_cache-bld.log"
145         export PYTHONPATH=$CSIT_DIR
146
147         description="Install CSIT python packages from $branch branch"
148         echo_log "    Starting  $description..." 2>&1 | tee -a "$bld_log"
149         git clean -qfdx 2>&1 | tee -a "$bld_log"
150         rm -rf "$PYTHONPATH/env"
151
152         # Activate / install CSIT python virtualenv ($CSIT_DIR/requirements.txt)
153         local common_sh="$csit_bash_function_dir/common.sh"
154         # shellcheck disable=1090
155         source "$common_sh"
156         activate_virtualenv "${CSIT_DIR}" "${CSIT_DIR}/requirements.txt" 2>&1 | tee -a "$bld_log"
157
158         # Install tox python requirements
159         activate_virtualenv "${CSIT_DIR}" "${CSIT_DIR}/tox-requirements.txt" 2>&1 |\
160             tee -a "$bld_log"
161
162         # Clean up virtualenv directories
163         git checkout -q -- .
164         git clean -qfdx
165         echo_log "    Completed $description!" 2>&1 | tee -a "$bld_log"
166     else
167         echo_log "ERROR: Missing or invalid CSIT_DIR: '$CSIT_DIR'!"
168         return 1
169     fi
170 }
171
172 docker_build_setup_csit() {
173     if csit_supported_executor_class "$EXECUTOR_CLASS" ; then
174         if [ ! -d "$DOCKER_CSIT_DIR" ] ; then
175             echo_log "Cloning CSIT into $DOCKER_CSIT_DIR..."
176             git clone -q https://gerrit.fd.io/r/csit "$DOCKER_CSIT_DIR"
177         fi
178         clean_git_repo "$DOCKER_CSIT_DIR"
179     fi
180 }
181
182 csit_dut_generate_docker_build_files() {
183     local build_files_dir="$DOCKER_BUILD_FILES_DIR"
184
185     mkdir -p "$build_files_dir"
186     cat <<EOF >"$build_files_dir/supervisord.conf"
187 [unix_http_server]
188 file = /tmp/supervisor.sock
189 chmod = 0777
190
191 [rpcinterface:supervisor]
192 supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
193
194 [supervisorctl]
195 serverurl = unix:///tmp/supervisor.sock
196
197 [supervisord]
198 pidfile = /tmp/supervisord.pid
199 identifier = supervisor
200 directory = /tmp
201 logfile = /tmp/supervisord.log
202 loglevel = debug
203 nodaemon = false
204
205 [program:vpp]
206 command = /usr/bin/vpp -c /etc/vpp/startup.conf
207 autostart = false
208 autorestart = true
209 redirect_stderr = true
210 priority = 1
211 EOF
212 }
213
214 csit_builder_generate_docker_build_files() {
215     local build_files_dir="$DOCKER_BUILD_FILES_DIR"
216     local dashes="-----"
217     local dbeg="${dashes}BEGIN"
218     local dend="${dashes}END"
219     local pvt="PRIVATE"
220     local kd="KEY$dashes"
221
222     # TODO: Verify why badkey is required & figure out how to avoid it.
223     mkdir -p "$build_files_dir"
224     cat <<EOF >"$build_files_dir/badkey"
225 $dbeg RSA $pvt $kd
226 MIIEowIBAAKCAQEAslDXf4kZOQI8OGQQdIF8o83nBM0B4fzHLYLxxiY2rKiQ5MGM
227 mQa7p1KKzmd5/NlvFRnXefnjSDQljjPxEY7mh457rX2nXvqHD4GUXZPpBIE73rQ1
228 TViIAXdDzFXJ6ee4yX8ewmVakzYBnlUPDidkWyRnjm/xCgKUCO+CD5AH3ND0onks
229 OYAtHqhDh29/QMIKdMnK87FBxfzhInHwpqPur76zBnpw3u36ylKEymDFrO5dwzsh
230 QvDWjsYRg9ydTXubtwP6+MOpjdR1SNKxcCHKJrPrdAeJW9jg1imYmYpEHZ/P3qsL
231 Jm0hGWbFjdxZLIYIz0vN/nTalcAeqT2OWKrXuwIDAQABAoIBAQCcj1g2FOR9ZlYD
232 WPANqucJVy4/y9OcXHlwnyiyRjj47WOSRdGxRfUa2uEeikHT3ACo8TB8WwfQDGDw
233 8u/075e+az5xvAJo5OQSnD3sz4Hmv6UWSvkFuPZo+xMe5C/M2/QljiQuoBifaeqP
234 3rTCQ5ncYCFAMU7b8BmTot551Ybhu2jCbDMHU7nFHEFOvYinkwfVcaqkrVDUuH+D
235 c3NkAEH9Jz2MEYA2Va4uqFpGt5lfGiED2kMenwPa8eS5LS5HJsxkfMHGlaHXHFUb
236 D+dG/qJtSslVxdzVPgEGvzswo6TgtY1nZTQcB8U63rktFg38B7QGtOkvswAYzxyk
237 HdMIiU3RAoGBAOdIEQRcAThj9eiIFywtBgLBOSg4SoOnvELLr6lgUg2+ICmx06LQ
238 yaai1QRdOWw1VwZ6apNCD00kaUhBu+ou93yLSDnR2uYftkylhcnVuhDyIeNyb81V
239 hV2z0WuNv3aKBFlBxaq391S7WW1XxhpAAagm8fZZur73wV390EVd/hZJAoGBAMVf
240 negT2bg5PVKWvsiEU6eZ00W97tlEDLclkiZawXNnM2/c+2x1Tks6Yf1E/j2FFTB4
241 r0fesbwN346hCejtq5Bup5YEdFA3KtwT5UyeQQLFGYlCtRmBtOd10wkRS93D0tpX
242 iIqkf43Gpx6iFdvBWY5A7N+ZmojCy9zpL5TJ4G3jAoGADOGEoRuGrd9TWMoLkFhJ
243 l2mvhz/rVn3HDGlPtT06FK3cGLZgtRavxGoZNw8CHbayzBeRS/ZH5+H5Qx72GkrX
244 WcZgFWhMqrhlbMtjMiSHIl556LL86xCyRs+3ACh6211AdMAnBCUOz1dH2cEjtV6P
245 ORBCNZg1wGEIEfYK3XIorpECgYBubXfQj8KhUs0fdx3Y3Ehdni/ZdlG7F1qx4YBq
246 mx5e7d+Wd6Hn5Z3fcxO9+yrvypS3YN5YrJzuZSiuCSWdP9RcY7y5r1ZQRv1g0nTZ
247 MDWZUiNea4cddTd8xKxFB3tV4SkIZi8LustuzDVWa0Mlh4EOmP6uf6c5WxtqRsEL
248 UwORFwKBgEjZsfmZGBurjOtSrcsteulOB0D2nOqPVRWXmbSNJT/l73DkEllvVyA/
249 wdW39nyFrA2Qw1K2F+l8DkzMd/WEjmioSWCsvTkXlvrqPfByKg01zCbYy/mhRW7d
250 7sQrPOIl8ygsc3JrxmvzibdWmng1MehvpAM1ogWeTUa1lsDTNJ/6
251 $dend RSA $pvt $kd
252 EOF
253     chmod 600 "$build_files_dir/badkey"
254     cat <<EOF >"$build_files_dir/sshconfig"
255 Host 172.17.0.*
256         StrictHostKeyChecking no
257         UserKnownHostsFile=/dev/null
258 EOF
259 }
260
261 csit_shim_generate_docker_build_files() {
262     local build_files_dir="$DOCKER_BUILD_FILES_DIR"
263     # TODO: Verify why badkey is required & figure out how to avoid it.
264     local badkey='AAAAB3NzaC1yc2EAAAADAQABAAABAQCyUNd/iRk5Ajw4ZBB0gXyjzecEzQHh/MctgvHGJjasqJDkwYyZBrunUorOZ3n82W8VGdd5+eNINCWOM/ERjuaHjnutfade+ocPgZRdk+kEgTvetDVNWIgBd0PMVcnp57jJfx7CZVqTNgGeVQ8OJ2RbJGeOb/EKApQI74IPkAfc0PSieSw5gC0eqEOHb39Awgp0ycrzsUHF/OEicfCmo+6vvrMGenDe7frKUoTKYMWs7l3DOyFC8NaOxhGD3J1Ne5u3A/r4w6mN1HVI0rFwIcoms+t0B4lb2ODWKZiZikQdn8/eqwsmbSEZZsWN3FkshgjPS83+dNqVwB6pPY5Yqte7'
265
266     mkdir -p "$build_files_dir"
267     # TODO: Verify why badkeypub is required & figure out how to avoid it.
268     echo "ssh-rsa $badkey ejk@bhima.local" >"$build_files_dir/badkeypub"
269
270     cat <<EOF >"$build_files_dir/sshconfig"
271 Host 172.17.0.*
272         StrictHostKeyChecking no
273         UserKnownHostsFile=/dev/null
274 EOF
275     cat <<EOF >"$build_files_dir/wrapdocker"
276 #!/bin/bash
277
278 # Ensure that all nodes in /dev/mapper correspond to mapped devices currently loaded by the device-mapper kernel driver
279 dmsetup mknodes
280
281 # First, make sure that cgroups are mounted correctly.
282 CGROUP=/sys/fs/cgroup
283 : {LOG:=stdio}
284
285 [ -d \$CGROUP ] ||
286     mkdir \$CGROUP
287
288 mountpoint -q \$CGROUP ||
289     mount -n -t tmpfs -o uid=0,gid=0,mode=0755 cgroup \$CGROUP || {
290         echo "Could not make a tmpfs mount. Did you use --privileged?"
291         exit 1
292     }
293
294 if [ -d /sys/kernel/security ] && ! mountpoint -q /sys/kernel/security
295 then
296     mount -t securityfs none /sys/kernel/security || {
297         echo "Could not mount /sys/kernel/security."
298         echo "AppArmor detection and --privileged mode might break."
299     }
300 fi
301
302 # Mount the cgroup hierarchies exactly as they are in the parent system.
303 for SUBSYS in \$(cut -d: -f2 /proc/1/cgroup)
304 do
305         [ -d \$CGROUP/\$SUBSYS ] || mkdir \$CGROUP/\$SUBSYS
306         mountpoint -q \$CGROUP/\$SUBSYS ||
307                 mount -n -t cgroup -o \$SUBSYS cgroup \$CGROUP/\$SUBSYS
308
309         # The two following sections address a bug which manifests itself
310         # by a cryptic "lxc-start: no ns_cgroup option specified" when
311         # trying to start containers withina container.
312         # The bug seems to appear when the cgroup hierarchies are not
313         # mounted on the exact same directories in the host, and in the
314         # container.
315
316         # Named, control-less cgroups are mounted with "-o name=foo"
317         # (and appear as such under /proc/<pid>/cgroup) but are usually
318         # mounted on a directory named "foo" (without the "name=" prefix).
319         # Systemd and OpenRC (and possibly others) both create such a
320         # cgroup. To avoid the aforementioned bug, we symlink "foo" to
321         # "name=foo". This shouldn't have any adverse effect.
322         echo \$SUBSYS | grep -q ^name= && {
323                 NAME=\$(echo \$SUBSYS | sed s/^name=//)
324                 ln -s \$SUBSYS \$CGROUP/\$NAME
325         }
326
327         # Likewise, on at least one system, it has been reported that
328         # systemd would mount the CPU and CPU accounting controllers
329         # (respectively "cpu" and "cpuacct") with "-o cpuacct,cpu"
330         # but on a directory called "cpu,cpuacct" (note the inversion
331         # in the order of the groups). This tries to work around it.
332         [ \$SUBSYS = cpuacct,cpu ] && ln -s \$SUBSYS \$CGROUP/cpu,cpuacct
333 done
334
335 # Note: as I write those lines, the LXC userland tools cannot setup
336 # a "sub-container" properly if the "devices" cgroup is not in its
337 # own hierarchy. Let's detect this and issue a warning.
338 grep -q :devices: /proc/1/cgroup ||
339     echo "WARNING: the 'devices' cgroup should be in its own hierarchy."
340 grep -qw devices /proc/1/cgroup ||
341     echo "WARNING: it looks like the 'devices' cgroup is not mounted."
342
343 # Now, close extraneous file descriptors.
344 pushd /proc/self/fd >/dev/null
345 for FD in *
346 do
347     case "\$FD" in
348     # Keep stdin/stdout/stderr
349     [012])
350         ;;
351     # Nuke everything else
352     *)
353         eval exec "\$FD>&-"
354         ;;
355     esac
356 done
357 popd >/dev/null
358
359
360 # If a pidfile is still around (for example after a container restart),
361 # delete it so that docker can start.
362 rm -rf /var/run/docker.pid
363
364 # If we were given a PORT environment variable, start as a simple daemon;
365 # otherwise, spawn a shell as well
366 if [ "\$PORT" ]
367 then
368     exec dockerd -H 0.0.0.0:\$PORT -H unix:///var/run/docker.sock \
369         \$DOCKER_DAEMON_ARGS
370 else
371     if [ "\$LOG" == "file" ]
372     then
373         dockerd \$DOCKER_DAEMON_ARGS &>/var/log/docker.log &
374     else
375         dockerd \$DOCKER_DAEMON_ARGS &
376     fi
377     (( timeout = 60 + SECONDS ))
378     until docker info >/dev/null 2>&1
379     do
380         if (( SECONDS >= timeout )); then
381             echo 'Timed out trying to connect to internal docker host.' >&2
382             break
383         fi
384         sleep 1
385     done
386     [[ \$1 ]] && exec "\$@"
387     exec bash --login
388 fi
389 EOF
390 }