Repository navigation
Expand file tree
/
Copy pathbuild_sysext
More file actions
executable file
·434 lines (365 loc) · 19.2 KB
/
Copy pathbuild_sysext
File metadata and controls
executable file
·434 lines (365 loc) · 19.2 KB
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
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
#!/bin/bash
# Copyright (c) 2023 The Flatcar Maintainers.
# Use of this source code is governed by a BSD-style license that can
# be found in the LICENSE file.
#
# Script to generate sysext. See systemd-sysext(8). Prerequisite is
# that you've run build_packages and build_image.
SCRIPT_ROOT=$(dirname "$(readlink -f "$0")")
. "${SCRIPT_ROOT}/common.sh" || exit 1
# Script must run inside the chroot
assert_inside_chroot
assert_root_user
default_imagedir="$(readlink -f "${SCRIPT_ROOT}/../build/images")/<BOARD>/latest/"
default_install_root_basename='install-root'
# All these are used to set up the 'BUILD_DIR' variable
DEFINE_string board "${DEFAULT_BOARD}" \
"The board to build a sysext for."
DEFINE_string metapkgs '' \
"Comma-separated list of meta-packages to build from source and install into sysext image."
DEFINE_string squashfs_base '' \
"The path to the squashfs base image. Defaults to the most current image built in '${default_imagedir}/${FLATCAR_PRODUCTION_IMAGE_SYSEXT_BASE}'."
DEFINE_string image_builddir '' \
"Custom directory to build the sysext in. Defaults to a 'sysext' sub-directory of the directory the squashfs base image resides in; '${default_imagedir}/sysext' by default."
DEFINE_boolean strip_binaries "${FLAGS_FALSE}" \
"After installation, scan sysext root for unstripped binaries and strip these. WARNING - this can subtly break some packages, e.g. Docker (see https://github.com/moby/moby/blob/master/project/PACKAGERS.md#stripping-binaries)."
DEFINE_string manglefs_script '' \
"A path to executable that will customize the rootfs of the sysext image."
DEFINE_boolean generate_pkginfo "${FLAGS_FALSE}" \
"Generate an additional squashfs '<sysext_name>_pkginfo.raw' with portage package meta-information (/var/db ...). Useful for creating sysext dependencies; see 'base_pkginfo' below."
DEFINE_string base_pkginfo "" \
"Colon-separated list of pkginfo squashfs paths / files generated via 'generate_pkginfo' to base this sysext on. The corresponding base sysexts are expected to be merged with the sysext generated."
DEFINE_string compression "zstd" \
"Compression to use for sysext squashfs. One of 'gzip', 'lzo', 'lz4', 'xz', or 'zstd'. Must be supported by the Flatcar squashfs kernel module in order for the sysext to work."
DEFINE_string mksquashfs_opts "" \
"Additional command line options to pass to mksquashfs. See 'man 1 mksquashfs'. If <compression> is 'zstd' (the default), this option defaults to '-Xcompression-level 22 -b 512K'. Otherwise the default is empty."
DEFINE_boolean ignore_version_mismatch "${FLAGS_FALSE}" \
"Ignore version mismatch between SDK board packages and base squashfs. DANGEROUS."
DEFINE_string install_root_basename "${default_install_root_basename}" \
"Name of a root directory where packages will be installed. ${default_install_root_basename@Q} by default."
FLAGS_HELP="USAGE: build_sysext [flags] <sysext_name> <binary_package> [<binary_package> ...]
This script is used to build a Flatcar sysext image.
The sysext will be based on an OS image build's sysext base squashfs, i.e. it is specific to
a Flatcar build or release.
The base squashfs can either come from a local build or downloaded from an official release.
By default, the sysext will be built in a 'sysext' sub-dir of the directory the squashfs base image
is in, but this can be changed with the --image_builddir option.
Examples:
Builds a sysext image named 'interpreters' with 'dev-lang/python' and 'dev-lang/perl' packages for the
most recent production image (default architecture, likely amd64) in the defaut build directory:
sudo build_sysext \\
interpreters dev-lang/python dev-lang/perl
Builds a sysext image named 'oem-azure' in the 'oem-images' sub-directory with
metapackage 'coreos-base/oem-azure' for the arm64 squashfs base at
'build/artifacts/flatcar_production_image_sysext.squashfs':
sudo build_sysext \\
--board=arm64-usr \\
--metapkgs=coreos-base/oem-azure \\
--mangle_fs=sdk_container/src/third_party/coreos-overlay/coreos-base/oem-azure/files/manglefs.sh \\
--squashfs_base=build/artifacts/flatcar_production_image_sysext.squashfs \\
--image_builddir=oem-images \\
oem-azure
Mandatory command line parameters:
<sysext_name> - name of the sysext output file.
<binary_package> - List of existing binary packages to install. Can be omitted if --metapkgs was specified.
"
show_help_if_requested "$@"
# Parse command line
FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"
# Only now can we die on error. shflags functions leak non-zero error codes,
# so will die prematurely if 'switch_to_strict_mode' is specified before now.
switch_to_strict_mode -uo pipefail
# Validate command line parameters
SYSEXTNAME="${1:-}"
if [[ -z "${SYSEXTNAME}" ]]; then
die "No sysext name provided."
fi
shift
if [[ -z "$FLAGS_squashfs_base" ]] ; then
FLAGS_squashfs_base="$(readlink -f "${SCRIPT_ROOT}/../build/images/${FLAGS_board}/latest/${FLATCAR_PRODUCTION_IMAGE_SYSEXT_BASE}")"
fi
if [[ ! -f "${FLAGS_squashfs_base}" ]] ; then
die "Squashfs base '${FLAGS_squashfs_base}' not found."
fi
if [[ -z "${FLAGS_image_builddir}" ]]; then
FLAGS_image_builddir="$(dirname "${FLAGS_squashfs_base}")/sysext"
fi
BUILD_DIR=$(realpath "${FLAGS_image_builddir}")
mkdir -p "${BUILD_DIR}"
if [[ "${FLAGS_compression}" = "zstd" && -z "${FLAGS_mksquashfs_opts}" ]] ; then
FLAGS_mksquashfs_opts="-Xcompression-level 22 -b 512k"
fi
source "${BUILD_LIBRARY_DIR}/toolchain_util.sh" || exit 1
source "${BUILD_LIBRARY_DIR}/board_options.sh" || exit 1
source "${BUILD_LIBRARY_DIR}/reports_util.sh" || exit 1
if [[ "${PACKAGE_SOURCE_MODE}" == "RPM" ]]; then
source "${BUILD_LIBRARY_DIR}/rpm/build_sysext"
fi
# Architecture values are taken from systemd.unit(5).
declare -A SYSEXT_ARCHES
SYSEXT_ARCHES['amd64-usr']='x86-64'
SYSEXT_ARCHES['arm64-usr']='arm64'
declare -r SYSEXT_ARCHES
# Usage: _get_sysext_arch board [board...]
_get_sysext_arch() {
local board=${1}
if [[ ${#SYSEXT_ARCHES["${board}"]} -ne 0 ]]; then
echo "${SYSEXT_ARCHES["${board}"]}"
else
die "Unknown board '${board}'"
fi
}
cleanup() {
local dirs=(
"${BUILD_DIR}/fs-root"
"${BUILD_DIR}/${FLAGS_install_root_basename}"
"${BUILD_DIR}/workdir"
"${BUILD_DIR}/img-rootfs"
)
umount "${dirs[@]}" 2>/dev/null || true
rm -rf "${dirs[@]}" || true
if [[ -d "${BUILD_DIR}/base-pkginfo" ]] ; then
umount "${BUILD_DIR}/base-pkginfo"/* 2>/dev/null || true
rm -rf "${BUILD_DIR}/base-pkginfo" || true
fi
rm -rf "${BUILD_DIR}/img-pkginfo"
# Remove RPM package log (created by rpm_install_package, root-owned)
rm -f "${BUILD_DIR}/.rpm-packages-explicit"
rm -f "${BUILD_DIR}/.rpm-base-manifest.tmp" "${BUILD_DIR}/.rpm-all-manifest.tmp" "${BUILD_DIR}/.rpm-sysext-manifest.tmp" \
"${BUILD_DIR}/.rpm-base.tmp" "${BUILD_DIR}/.rpm-all.tmp"
}
# Set up trap to execute cleanup() on script exit
trap cleanup EXIT
ARCH=$(_get_sysext_arch "${FLAGS_board}")
cleanup
# If we need to handle pkginfo squashfs files, create mount points under
# ${BUILD_DIR}/base-pkginfo, mount the squashfs images, and add the mount paths to
# the list of lowerdirs.
pkginfo_lowerdirs=""
if [[ -n "${FLAGS_base_pkginfo}" ]] ; then
for entry in $(echo ${FLAGS_base_pkginfo} | sed 's/:/ /g'); do
ppath="$(readlink -f "${entry}")"
if [[ ! -f "${ppath}" ]] ; then
error "--base_pkginfo contains invalid entries."
error "Pkginfo file '${ppath}' does not exist."
die "Full --base_pkginfo: '${FLAGS_base_pkginfo}'"
fi
pfile="$(basename "${ppath}")"
pmdir="${BUILD_DIR}/base-pkginfo/${pfile}"
mkdir -p "${pmdir}"
mount -rt squashfs -o loop,nodev "${ppath}" "${pmdir}"
pkginfo_lowerdirs="${pkginfo_lowerdirs}:${pmdir}"
info "Added packageinfo from '${ppath}' to base layers."
done
fi
mkdir "${BUILD_DIR}/fs-root"
mount -rt squashfs -o loop,nodev "${FLAGS_squashfs_base}" "${BUILD_DIR}/fs-root"
mkdir "${BUILD_DIR}/${FLAGS_install_root_basename}"
mkdir "${BUILD_DIR}/workdir"
mount -t overlay overlay -o lowerdir="${BUILD_DIR}/fs-root${pkginfo_lowerdirs}",upperdir="${BUILD_DIR}/${FLAGS_install_root_basename}",workdir="${BUILD_DIR}/workdir" "${BUILD_DIR}/${FLAGS_install_root_basename}"
REPO_BUILD_ID=$(source "${REPO_MANIFESTS_DIR}/version.txt"; echo "$FLATCAR_BUILD_ID")
REPO_FLATCAR_VERSION=$(source "${REPO_MANIFESTS_DIR}/version.txt"; echo "$FLATCAR_VERSION")
VERSION_BOARD=$(source "${BUILD_DIR}/fs-root/usr/lib/os-release" && echo "$VERSION")
if [[ -z $REPO_BUILD_ID ]] && [[ ${COREOS_OFFICIAL:-0} -ne 1 ]]; then
BASE_SQUASHFS_BUILD_ID=$(source "${BUILD_DIR}/fs-root/usr/lib/os-release" && echo -n "$BUILD_ID")
info "This is a dev rebuild of an official release tag: No BUILD ID set in '${REPO_MANIFESTS_DIR}/version.txt'. Will use base squashfs BUILD ID for version check."
info "Repo root FLATCAR_VERSION is '$REPO_FLATCAR_VERSION', squashfs build ID is '$BASE_SQUASHFS_BUILD_ID'"
FLATCAR_VERSION="${REPO_FLATCAR_VERSION}${BASE_SQUASHFS_BUILD_ID:++}${BASE_SQUASHFS_BUILD_ID}"
info "Setting FLATCAR_VERSION to '$FLATCAR_VERSION'"
fi
# In RPM mode, os-release VERSION uses IMAGE_VERSION (independent of FLATCAR_VERSION).
# Compare against IMAGE_VERSION instead so the check doesn't false-positive.
_expected_version="${FLATCAR_VERSION}"
if [[ "${PACKAGE_SOURCE_MODE}" == "RPM" && -n "${IMAGE_VERSION:-}" ]]; then
_expected_version="${IMAGE_VERSION}"
fi
if [ "$VERSION_BOARD" != "$_expected_version" ]; then
warn "Base squashfs version: $VERSION_BOARD"
warn "Expected version: $_expected_version"
if [[ "${FLAGS_ignore_version_mismatch}" = "${FLAGS_TRUE}" ]] ; then
warn "Ignoring version mismatch as requested."
else
die "Version mismatch between board flatcar release and SDK container flatcar release."
fi
fi
if [[ -n "${FLAGS_metapkgs}" ]]; then
mapfile -t metapkgs < <(tr ',' '\n' <<<"${FLAGS_metapkgs}")
# In RPM mode the metapkg ebuild is not needed — packages are resolved
# via the RPM catalog. Only build the portage binpkg in portage mode.
if [[ "${PACKAGE_SOURCE_MODE}" != "RPM" ]]; then
"emerge-${FLAGS_board}" --nodeps --buildpkgonly --usepkg n --verbose "${metapkgs[@]}"
fi
set -- "${metapkgs[@]}" "${@}"
fi
if [[ ${#} -lt 1 ]]; then
error 'No packages or meta packages to install.'
show_help_if_requested -h
fi
info "Building '${SYSEXTNAME}' squashfs with (meta-)packages '${@}' in '${BUILD_DIR}' using '${FLAGS_compression}' compression".
# Unlike Portage (one dir per package), RPM uses a single DB file that gets
# fully copied-up by overlayfs on any write, so rpm -qa after install returns
# base + new packages. Snapshot here to diff later.
if [[ "${PACKAGE_SOURCE_MODE}" == "RPM" ]] && [[ -f "${BUILD_DIR}/${FLAGS_install_root_basename}/var/lib/rpm/rpmdb.sqlite" ]]; then
rpm_query_packages "${BUILD_DIR}/${FLAGS_install_root_basename}" > "${BUILD_DIR}/.rpm-base.tmp"
rpm_query_manifest "${BUILD_DIR}/${FLAGS_install_root_basename}" | sort > "${BUILD_DIR}/.rpm-base-manifest.tmp"
fi
for package; do
echo "Installing package into sysext image: $package"
if [[ "${PACKAGE_SOURCE_MODE}" == "PORTAGE" ]]; then
# Fall back to Portage for PORTAGE mode or packages not in RPM catalog
FEATURES="-ebuild-locks binpkg-multi-instance" emerge \
--root="${BUILD_DIR}/${FLAGS_install_root_basename}" \
--config-root="/build/${FLAGS_board}" \
--sysroot="/build/${FLAGS_board}" \
--usepkgonly \
--binpkg-respect-use=y \
--getbinpkg \
--verbose \
--jobs=${NUM_JOBS} \
"${package}"
elif [[ "${PACKAGE_SOURCE_MODE}" == "RPM" ]]; then
rpm_install_package_using_portage_name "${BUILD_DIR}/${FLAGS_install_root_basename}" "$package"
fi
done
# Pins mksquashfs timestamps and the package manifest's created field to one
# value per image build. os-release is rewritten on every build, so this is the
# build's stamp time rather than a fixed epoch. Split from the export so set -e
# still catches a failing stat.
SOURCE_DATE_EPOCH=$(stat -c '%Y' "${BUILD_DIR}/fs-root/usr/lib/os-release")
export SOURCE_DATE_EPOCH
# Unmount in order to get rid of the overlay
umount "${BUILD_DIR}/${FLAGS_install_root_basename}"
umount "${BUILD_DIR}/fs-root"
if [[ "$FLAGS_generate_pkginfo" = "${FLAGS_TRUE}" ]] ; then
info " Creating pkginfo squashfs '${BUILD_DIR}/${SYSEXTNAME}_pkginfo.raw'"
mkdir -p "${BUILD_DIR}/img-pkginfo/var/db"
# In RPM mode, Portage's /var/db/pkg may not exist if packages were installed via RPM
if [[ "${PACKAGE_SOURCE_MODE}" == "PORTAGE" ]]; then
cp -R "${BUILD_DIR}/${FLAGS_install_root_basename}/var/db/pkg" "${BUILD_DIR}/img-pkginfo/var/db/"
else
info " No Portage package database found (RPM mode) - creating empty pkginfo"
fi
mksquashfs "${BUILD_DIR}/img-pkginfo" "${BUILD_DIR}/${SYSEXTNAME}_pkginfo.raw" \
-noappend -xattrs-exclude '^btrfs.' -comp "${FLAGS_compression}" ${FLAGS_mksquashfs_opts}
pad_squashfs_for_loopdev "${BUILD_DIR}/${SYSEXTNAME}_pkginfo.raw"
fi
if [[ "${PACKAGE_SOURCE_MODE}" == "PORTAGE" ]]; then
info "Writing ${SYSEXTNAME}_packages.txt"
ROOT="${BUILD_DIR}/${FLAGS_install_root_basename}" PORTAGE_CONFIGROOT="${BUILD_DIR}/${FLAGS_install_root_basename}" \
equery --no-color list --format '$cpv::$repo' '*' > "${BUILD_DIR}/${SYSEXTNAME}_packages.txt"
fi
if [[ "${FLAGS_strip_binaries}" = "${FLAGS_TRUE}" ]]; then
chost="$("portageq-${BOARD}" envvar CHOST)"
strip="${chost}-strip"
info "Stripping all non-stripped binaries in sysext using '${strip}'"
# Find all non-stripped binaries, remove ':' from filepath, and strip 'em
find "${BUILD_DIR}/${FLAGS_install_root_basename}" -exec file \{\} \; \
| awk '/not stripped/ {print substr($1, 1, length($1)-1)}' \
| while read bin; do
info " ${strip} ${bin}"
"${strip}" "${bin}"
done
fi
if [[ -n "${FLAGS_manglefs_script}" ]]; then
if [[ ! -x "${FLAGS_manglefs_script}" ]]; then
die "${FLAGS_manglefs_script} is not executable"
fi
"${FLAGS_manglefs_script}" "${BUILD_DIR}/${FLAGS_install_root_basename}"
fi
# extension-release VERSION_ID must match the host os-release VERSION_ID.
# In RPM mode that's IMAGE_VERSION_ID, not FLATCAR_VERSION_ID.
_sysext_version_id="${FLATCAR_VERSION_ID}"
if [[ "${PACKAGE_SOURCE_MODE:-PORTAGE}" == "RPM" && -n "${IMAGE_VERSION_ID:-}" ]]; then
_sysext_version_id="${IMAGE_VERSION_ID}"
fi
# In RPM mode, write packages.txt after manglefs so that packages removed
# by mangle scripts (e.g. containerd2/runc from docker) are excluded.
if [[ "${PACKAGE_SOURCE_MODE}" == "RPM" ]]; then
info "Writing ${SYSEXTNAME}_packages.txt"
# Create the files unconditionally; they'll be overwritten with actual contents
# when an RPM database is present. Truncate rather than touch since BUILD_DIR
# is caller-supplied and shared across sysexts, so may not be empty.
: > "${BUILD_DIR}/${SYSEXTNAME}_packages.txt"
: > "${BUILD_DIR}/.rpm-sysext-manifest.tmp"
# Taking a snapshot is conditional on the base image having an rpmdb. Absent
# one, every sysext will diff to nothing, and without this check, would skip
# its manifest with no error.
if [[ ! -s "${BUILD_DIR}/.rpm-base.tmp" ]]; then
die "No pre-install package snapshot for ${SYSEXTNAME}; ${FLAGS_squashfs_base##*/} has no RPM database"
fi
# Diff against pre-install snapshot to list only sysext-added packages.
if [[ -f "${BUILD_DIR}/${FLAGS_install_root_basename}/var/lib/rpm/rpmdb.sqlite" ]]; then
rpm_query_packages "${BUILD_DIR}/${FLAGS_install_root_basename}" > "${BUILD_DIR}/.rpm-all.tmp"
rpm_query_manifest "${BUILD_DIR}/${FLAGS_install_root_basename}" | sort > "${BUILD_DIR}/.rpm-all-manifest.tmp"
# comm -13: output lines unique to the right file (i.e. newly installed packages only)
comm -13 "${BUILD_DIR}/.rpm-base.tmp" "${BUILD_DIR}/.rpm-all.tmp" > "${BUILD_DIR}/${SYSEXTNAME}_packages.txt"
comm -13 "${BUILD_DIR}/.rpm-base-manifest.tmp" "${BUILD_DIR}/.rpm-all-manifest.tmp" > "${BUILD_DIR}/.rpm-sysext-manifest.tmp"
rm -f "${BUILD_DIR}/.rpm-base.tmp" "${BUILD_DIR}/.rpm-all.tmp"
rm -f "${BUILD_DIR}/.rpm-base-manifest.tmp" "${BUILD_DIR}/.rpm-all-manifest.tmp"
else
warn "No RPM database found for ${SYSEXTNAME}; ${SYSEXTNAME}_packages.txt will be empty"
fi
# Empty means either nothing was installed or the base image already had every
# package this sysext asks for. Both are valid sysexts with nothing of their
# own to describe.
if [[ -s "${BUILD_DIR}/${SYSEXTNAME}_packages.txt" ]]; then
# _sysext_version_id is pinned to the host os-release VERSION_ID and so is
# only date-granular in the pipeline. The manifest is not bound by that
# contract and needs the build id to keep its documentNamespace unique.
write_package_manifest \
sysext \
"${BUILD_DIR}/${FLAGS_install_root_basename}" \
"${SYSEXTNAME}" \
"${_sysext_version_id}${IMAGE_BUILD_ID:++${IMAGE_BUILD_ID}}" \
"${BUILD_DIR}/${SYSEXTNAME}_packages.txt" \
"${SOURCE_DATE_EPOCH}"
else
info "No packages unique to ${SYSEXTNAME}: skipping package manifest generation"
fi
fi
info "Removing non-/usr directories from sysext image"
for entry in "${BUILD_DIR}/${FLAGS_install_root_basename}"/*; do
if [[ "${entry}" = */usr ]]; then
continue
fi
info " Removing ${entry##*/}"
rm -rf "${entry}"
done
mkdir -p "${BUILD_DIR}/${FLAGS_install_root_basename}/usr/lib/extension-release.d"
# Set OS branding based on package source mode
if [[ "${PACKAGE_SOURCE_MODE}" == "PORTAGE" ]]; then
OS_ID="flatcar"
elif [[ "${PACKAGE_SOURCE_MODE}" == "RPM" ]]; then
OS_ID="azurelinux"
fi
version_field="${VERSION_FIELD_OVERRIDE:-VERSION_ID=${_sysext_version_id}}"
all_fields=(
"ID=${OS_ID}"
"${version_field}"
"ARCHITECTURE=${ARCH}"
)
printf '%s\n' "${all_fields[@]}" >"${BUILD_DIR}/${FLAGS_install_root_basename}/usr/lib/extension-release.d/extension-release.${SYSEXTNAME}"
info "Removing opaque directory markers to always merge all contents"
find "${BUILD_DIR}/${FLAGS_install_root_basename}" -xdev -type d -exec sh -c 'if [ "$(attr -R -q -g overlay.opaque {} 2>/dev/null)" = y ]; then attr -R -r overlay.opaque {}; fi' \;
info "Checking for invalid file ownership"
invalid_files=$(find "${BUILD_DIR}/${FLAGS_install_root_basename}" -user sdk -or -group sdk)
if [[ -n "${invalid_files}" ]]; then
die "Invalid file ownership: ${invalid_files}"
fi
mksquashfs "${BUILD_DIR}/${FLAGS_install_root_basename}" "${BUILD_DIR}/${SYSEXTNAME}.raw" \
-noappend -xattrs-exclude '^btrfs.' -comp "${FLAGS_compression}" ${FLAGS_mksquashfs_opts}
pad_squashfs_for_loopdev "${BUILD_DIR}/${SYSEXTNAME}.raw"
rm -rf "${BUILD_DIR}"/{fs-root,"${FLAGS_install_root_basename}",workdir}
# Generate reports
mkdir "${BUILD_DIR}/img-rootfs"
mount -rt squashfs -o loop,nodev "${BUILD_DIR}/${SYSEXTNAME}.raw" "${BUILD_DIR}/img-rootfs"
sysext_rpm_manifest=""
if [[ "${PACKAGE_SOURCE_MODE}" == "RPM" && -s "${BUILD_DIR}/.rpm-sysext-manifest.tmp" ]]; then
sysext_rpm_manifest="${BUILD_DIR}/.rpm-sysext-manifest.tmp"
fi
write_sysext_sbom "${BUILD_DIR}/img-rootfs" "${BUILD_DIR}/${SYSEXTNAME}_sbom.json" "${sysext_rpm_manifest}"
write_contents "${BUILD_DIR}/img-rootfs" "${BUILD_DIR}/${SYSEXTNAME}_contents.txt"
write_contents_with_technical_details "${BUILD_DIR}/img-rootfs" "${BUILD_DIR}/${SYSEXTNAME}_contents_wtd.txt"
write_disk_space_usage_in_paths "${BUILD_DIR}/img-rootfs" "${BUILD_DIR}/${SYSEXTNAME}_disk_usage.txt"
umount "${BUILD_DIR}/img-rootfs"