7 for (( index
=${#CLEANUP[@]}-1 ; index
>= 0 ; index--
)) ;do
16 REASON
="${2:-Unknown reason}"
22 trap cleanup EXIT TERM INT
38 DISTROBUILDER_GIT_BRANCH
44 for var
in "${REQUIRED_VARIABLES[@]}" ; do
45 if [ ! -v "$var" ] ; then
47 echo "Missing required variable: '${var}'" >&2
50 if [[ ! "${MISSING_VARS}" == "0" ]] ; then
51 fail
1 "Missing required variables"
55 INSTANCE_START_TIMEOUT
="${INSTANCE_START_TIMEOUT:-60}"
60 apt-get
install -y lxd-client
61 mkdir
-p ~
/.config
/lxc
62 cp "${LXD_CLIENT_CERT}" ~
/.config
/lxc
/client.crt
63 cp "${LXD_CLIENT_KEY}" ~
/.config
/lxc
/client.key
65 "rm -f ${HOME}/.config/lxc/client.crt"
66 "rm -f ${HOME}/.config/lxc/client.key"
68 lxc remote add ci
--accept-certificate --auth-type tls
"${LXD_HOST}"
71 # Exit gracefully if the lxc images: provides the base image
72 IMAGE_NAME
="${OS}/${RELEASE}/${VARIANT}/${ARCH}"
73 TYPE_FILTER
='type=container'
74 if [[ "${IMAGE_TYPE}" == "vm" ]] ; then
75 TYPE_FILTER
='type=virtual-machine'
77 if [[ "$(lxc image list -f csv images:"${IMAGE_NAME}" -- "${TYPE_FILTER}" | wc -l)" != "0" ]] ; then
78 echo "Image '${IMAGE_NAME}' provided by 'images:' remote"
83 apt-get
install -y wget
84 wget
-q "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" -O - |
tar -C /usr
/local -xzf -
85 export PATH
="${PATH}:/usr/local/go/bin"
87 # Install distrobuilder
88 apt-get
install -y debootstrap rsync gpg squashfs-tools git \
89 btrfs-progs dosfstools qemu-utils gdisk
91 git clone
--branch="${DISTROBUILDER_GIT_BRANCH}" "${DISTROBUILDER_GIT_URL}" distrobuilder
94 PATH
="${PATH}:${HOME}/go/bin"
98 git clone
--branch="${GIT_BRANCH}" "${GIT_URL}" ci
100 # Get the LXC CI repo
102 git clone
--branch="${LXC_CI_GIT_BRANCH}" "${LXC_CI_GIT_URL}" lxc-ci
105 "${WORKSPACE}/ci/automation/images"
106 "${WORKSPACE}/lxc-ci/images"
113 for IMAGE_DIR
in "${IMAGE_DIRS[@]}" ; do
114 for EXTENSION
in "${EXTENSIONS[@]}" ; do
115 if [ -f "${IMAGE_DIR}/${OS}-${RELEASE}.${EXTENSION}" ] ; then
116 IMAGE_FILE
="${IMAGE_DIR}/${OS}-${RELEASE}.${EXTENSION}"
120 for EXTENSION
in "${EXTENSIONS[@]}" ; do
121 if [ -f "${IMAGE_DIR}/${OS}.${EXTENSION}" ] ; then
122 IMAGE_FILE
="${IMAGE_DIR}/${OS}.${EXTENSION}"
128 if [[ "${IMAGE_FILE}" == "" ]] ; then
129 fail
1 "Unable to find image file for '${OS}' in ${IMAGE_DIRS[@]}"
132 if grep -q -E 'XX[A-Za-z0-9_]+XX' "${IMAGE_FILE}" ; then
133 while read -r VAR
; do
135 SHELLVAR
=$
(echo "${VAR}" |
sed 's/^XX//g' |
sed 's/XX$//g')
137 sed -i "s/${VAR}/${!SHELLVAR:-VARIABLENOTFOUND}/g" "${IMAGE_FILE}"
139 done < <(grep -E -o 'XX[A-Za-z0-9_]+XX' "${IMAGE_FILE}")
146 if [[ "${IMAGE_TYPE}" == "vm" ]] ; then
147 DISTROBUILDER_ARGS
+=('--vm')
151 # This could be quite large, and /tmp may be a tmpfs backed
152 # by memory, so instead make it relative to the workspace directory
153 BUILD_DIR
=$
(mktemp
-d -p "${WORKSPACE}")
155 "rm -rf ${BUILD_DIR}"
157 DISTROBUILDER_ARGS
+=(
161 "image.architecture=${ARCH}"
163 "image.variant=${VARIANT}"
165 "image.release=${RELEASE}"
167 "image.serial=$(date -u +%Y%m%dT%H:%M:%S%z)"
171 ${DISTROBUILDER_ARGS[@]}
174 # As 'distrobuilder --import-into-incus=alias' doesn't work since it only
175 # connects to the local unix socket, and the remote instance cannot be specified
177 ROOTFS
="${BUILD_DIR}/rootfs.squashfs"
178 if [[ "${IMAGE_TYPE}" == "vm" ]] ; then
179 ROOTFS
="${BUILD_DIR}/disk.qcow2"
182 # Work-around for lxd not using qemu-system-i386: set the architecture to x86_64
183 # which will use qemu-system-x86_64 and still run 32bit userspace/kernels fine.
184 if [[ "${ARCH}" == "i386" ]] ; then
187 tar -xf "${BUILD_DIR}/incus.tar.xz"
188 sed -i 's/architecture: i386/architecture: x86_64/' metadata.yaml
189 tar -cf "${BUILD_DIR}/incus.tar.xz" .
/*
194 # When using `lxc image import` two images cannot have the same alias -
195 # only the last image imported will keep the alias. Therefore, the
196 # image type is appended as part of the alias.
197 IMAGE_NAME
="${IMAGE_NAME}/${IMAGE_TYPE}"
198 lxc image import
"${BUILD_DIR}/incus.tar.xz" "${ROOTFS}" --alias="${IMAGE_NAME}" ci
:
200 if [[ "${TEST}" == "true" ]] ; then
203 if INSTANCE_NAME
="$(lxc -q launch -e ${VM_ARG[@]} -p default -p "${LXD_INSTANCE_PROFILE}" "${IMAGE_NAME}")" ; then
204 INSTANCE_NAME="$
(echo "${INSTANCE_NAME}" | cut
-d':' -f2 |
tr -d ' ')"
206 "lxc stop
${INSTANCE_NAME}"
209 fail 1 "Failed to launch instance using image
'${IMAGE_NAME}'"
211 TIME_REMAINING="${INSTANCE_START_TIMEOUT}"
214 INSTANCE_STATUS="$
(lxc
exec "${INSTANCE_NAME}" hostname
)"
215 if [[ "${INSTANCE_STATUS}" == "${INSTANCE_NAME}" ]] ; then
219 TIME_REMAINING=$((TIME_REMAINING - 1))
220 if [ "${TIME_REMAINING}" -lt "0" ] ; then
221 fail 1 "Timed out waiting
for instance to become available via
'lxc exec'"