• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/bash
2# shellcheck disable=SC1091
3# shellcheck disable=SC2034
4# shellcheck disable=SC2059
5# shellcheck disable=SC2086 # we want word splitting
6
7. "$SCRIPTS_DIR"/setup-test-env.sh
8
9# Boot script for devices attached to a PoE switch, using NFS for the root
10# filesystem.
11
12# We're run from the root of the repo, make a helper var for our paths
13BM=$CI_PROJECT_DIR/install/bare-metal
14CI_COMMON=$CI_PROJECT_DIR/install/common
15CI_INSTALL=$CI_PROJECT_DIR/install
16
17# Runner config checks
18if [ -z "$BM_SERIAL" ]; then
19  echo "Must set BM_SERIAL in your gitlab-runner config.toml [[runners]] environment"
20  echo "This is the serial port to listen the device."
21  exit 1
22fi
23
24if [ -z "$BM_POE_ADDRESS" ]; then
25  echo "Must set BM_POE_ADDRESS in your gitlab-runner config.toml [[runners]] environment"
26  echo "This is the PoE switch address to connect for powering up/down devices."
27  exit 1
28fi
29
30if [ -z "$BM_POE_INTERFACE" ]; then
31  echo "Must set BM_POE_INTERFACE in your gitlab-runner config.toml [[runners]] environment"
32  echo "This is the PoE switch interface where the device is connected."
33  exit 1
34fi
35
36if [ -z "$BM_POWERUP" ]; then
37  echo "Must set BM_POWERUP in your gitlab-runner config.toml [[runners]] environment"
38  echo "This is a shell script that should power up the device and begin its boot sequence."
39  exit 1
40fi
41
42if [ -z "$BM_POWERDOWN" ]; then
43  echo "Must set BM_POWERDOWN in your gitlab-runner config.toml [[runners]] environment"
44  echo "This is a shell script that should power off the device."
45  exit 1
46fi
47
48if [ ! -d /nfs ]; then
49  echo "NFS rootfs directory needs to be mounted at /nfs by the gitlab runner"
50  exit 1
51fi
52
53if [ ! -d /tftp ]; then
54  echo "TFTP directory for this board needs to be mounted at /tftp by the gitlab runner"
55  exit 1
56fi
57
58# job config checks
59if [ -z "$BM_ROOTFS" ]; then
60  echo "Must set BM_ROOTFS to your board's rootfs directory in the job's variables"
61  exit 1
62fi
63
64if [ -z "$BM_BOOTFS" ] && { [ -z "$BM_KERNEL" ] || [ -z "$BM_DTB" ]; } ; then
65  echo "Must set /boot files for the TFTP boot in the job's variables or set kernel and dtb"
66  exit 1
67fi
68
69if [ -z "$BM_CMDLINE" ]; then
70  echo "Must set BM_CMDLINE to your board's kernel command line arguments"
71  exit 1
72fi
73
74section_start prepare_rootfs "Preparing rootfs components"
75
76set -ex
77
78date +'%F %T'
79
80# Clear out any previous run's artifacts.
81rm -rf results/
82mkdir -p results
83
84# Create the rootfs in the NFS directory.  rm to make sure it's in a pristine
85# state, since it's volume-mounted on the host.
86rsync -a --delete $BM_ROOTFS/ /nfs/
87
88date +'%F %T'
89
90# If BM_BOOTFS is an URL, download it
91if echo $BM_BOOTFS | grep -q http; then
92  curl -L --retry 4 -f --retry-all-errors --retry-delay 60 \
93    "${FDO_HTTP_CACHE_URI:-}$BM_BOOTFS" -o /tmp/bootfs.tar
94  BM_BOOTFS=/tmp/bootfs.tar
95fi
96
97date +'%F %T'
98
99# If BM_BOOTFS is a file, assume it is a tarball and uncompress it
100if [ -f "${BM_BOOTFS}" ]; then
101  mkdir -p /tmp/bootfs
102  tar xf $BM_BOOTFS -C /tmp/bootfs
103  BM_BOOTFS=/tmp/bootfs
104fi
105
106# If BM_KERNEL and BM_DTS is present
107if [ -n "${EXTERNAL_KERNEL_TAG}" ]; then
108  if [ -z "${BM_KERNEL}" ] || [ -z "${BM_DTB}" ]; then
109    echo "This machine cannot be tested with external kernel since BM_KERNEL or BM_DTB missing!"
110    exit 1
111  fi
112
113  curl -L --retry 4 -f --retry-all-errors --retry-delay 60 \
114      "${FDO_HTTP_CACHE_URI:-}${KERNEL_IMAGE_BASE}/${DEBIAN_ARCH}/${BM_KERNEL}" -o "${BM_KERNEL}"
115  curl -L --retry 4 -f --retry-all-errors --retry-delay 60 \
116      "${FDO_HTTP_CACHE_URI:-}${KERNEL_IMAGE_BASE}/${DEBIAN_ARCH}/${BM_DTB}.dtb" -o "${BM_DTB}.dtb"
117  curl -L --retry 4 -f --retry-all-errors --retry-delay 60 \
118      "${FDO_HTTP_CACHE_URI:-}${KERNEL_IMAGE_BASE}/${DEBIAN_ARCH}/modules.tar.zst" -o modules.tar.zst
119fi
120
121date +'%F %T'
122
123# Install kernel modules (it could be either in /lib/modules or
124# /usr/lib/modules, but we want to install in the latter)
125if [ -n "${EXTERNAL_KERNEL_TAG}" ]; then
126  tar --keep-directory-symlink --zstd -xf modules.tar.zst -C /nfs/
127  rm modules.tar.zst &
128elif [ -n "${BM_BOOTFS}" ]; then
129  [ -d $BM_BOOTFS/usr/lib/modules ] && rsync -a $BM_BOOTFS/usr/lib/modules/ /nfs/usr/lib/modules/
130  [ -d $BM_BOOTFS/lib/modules ] && rsync -a $BM_BOOTFS/lib/modules/ /nfs/lib/modules/
131else
132  echo "No modules!"
133fi
134
135
136date +'%F %T'
137
138# Install kernel image + bootloader files
139if [ -n "${EXTERNAL_KERNEL_TAG}" ] || [ -z "$BM_BOOTFS" ]; then
140  mv "${BM_KERNEL}" "${BM_DTB}.dtb" /tftp/
141else  # BM_BOOTFS
142  rsync -aL --delete $BM_BOOTFS/boot/ /tftp/
143fi
144
145date +'%F %T'
146
147# Set up the pxelinux config for Jetson Nano
148mkdir -p /tftp/pxelinux.cfg
149cat <<EOF >/tftp/pxelinux.cfg/default-arm-tegra210-p3450-0000
150PROMPT 0
151TIMEOUT 30
152DEFAULT primary
153MENU TITLE jetson nano boot options
154LABEL primary
155      MENU LABEL CI kernel on TFTP
156      LINUX Image
157      FDT tegra210-p3450-0000.dtb
158      APPEND \${cbootargs} $BM_CMDLINE
159EOF
160
161# Set up the pxelinux config for Jetson TK1
162cat <<EOF >/tftp/pxelinux.cfg/default-arm-tegra124-jetson-tk1
163PROMPT 0
164TIMEOUT 30
165DEFAULT primary
166MENU TITLE jetson TK1 boot options
167LABEL primary
168      MENU LABEL CI kernel on TFTP
169      LINUX zImage
170      FDT tegra124-jetson-tk1.dtb
171      APPEND \${cbootargs} $BM_CMDLINE
172EOF
173
174# Create the rootfs in the NFS directory
175. $BM/rootfs-setup.sh /nfs
176
177date +'%F %T'
178
179echo "$BM_CMDLINE" > /tftp/cmdline.txt
180
181# Add some options in config.txt, if defined
182if [ -n "$BM_BOOTCONFIG" ]; then
183  printf "$BM_BOOTCONFIG" >> /tftp/config.txt
184fi
185
186section_end prepare_rootfs
187
188set +e
189STRUCTURED_LOG_FILE=results/job_detail.json
190python3 $CI_INSTALL/custom_logger.py ${STRUCTURED_LOG_FILE} --update dut_job_type "${DEVICE_TYPE}"
191python3 $CI_INSTALL/custom_logger.py ${STRUCTURED_LOG_FILE} --update farm "${FARM}"
192ATTEMPTS=3
193first_attempt=True
194while [ $((ATTEMPTS--)) -gt 0 ]; do
195  section_start dut_boot "Booting hardware device ..."
196  python3 $CI_INSTALL/custom_logger.py ${STRUCTURED_LOG_FILE} --create-dut-job dut_name "${CI_RUNNER_DESCRIPTION}"
197  # Update subtime time to CI_JOB_STARTED_AT only for the first run
198  if [ "$first_attempt" = "True" ]; then
199    python3 $CI_INSTALL/custom_logger.py ${STRUCTURED_LOG_FILE} --update-dut-time submit "${CI_JOB_STARTED_AT}"
200  else
201    python3 $CI_INSTALL/custom_logger.py ${STRUCTURED_LOG_FILE} --update-dut-time submit
202  fi
203  python3 $BM/poe_run.py \
204          --dev="$BM_SERIAL" \
205          --powerup="$BM_POWERUP" \
206          --powerdown="$BM_POWERDOWN" \
207          --boot-timeout-seconds ${BOOT_PHASE_TIMEOUT_SECONDS:-300} \
208          --test-timeout-minutes ${TEST_PHASE_TIMEOUT_MINUTES:-$((CI_JOB_TIMEOUT/60 - ${TEST_SETUP_AND_UPLOAD_MARGIN_MINUTES:-5}))}
209  ret=$?
210
211  if [ $ret -eq 2 ]; then
212    python3 $CI_INSTALL/custom_logger.py ${STRUCTURED_LOG_FILE} --close-dut-job
213    first_attempt=False
214    error "Device failed to boot; will retry"
215  else
216    # We're no longer in dut_boot by this point
217    unset CURRENT_SECTION
218    ATTEMPTS=0
219  fi
220done
221
222section_start dut_cleanup "Cleaning up after job"
223python3 $CI_INSTALL/custom_logger.py ${STRUCTURED_LOG_FILE} --close-dut-job
224python3 $CI_INSTALL/custom_logger.py ${STRUCTURED_LOG_FILE} --close
225set -e
226
227date +'%F %T'
228
229# Bring artifacts back from the NFS dir to the build dir where gitlab-runner
230# will look for them.
231cp -Rp /nfs/results/. results/
232
233date +'%F %T'
234section_end dut_cleanup
235
236exit $ret
237