Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions build_image
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,12 @@ different forms. This scripts can be used to build the following:
prod - Production image for CoreOS. This image is for booting (default if no argument is given).
prodtar - Production container tar ball (implies prod). This can e.g. be used to run the Flatcar production image as a container (run machinectl import-tar or docker import).
container - Developer image with single filesystem, bootable by nspawn.
sysext - Build extra sysexts (podman, python, zfs, etc.).
oem_sysext - Build OEM sysexts for all supported platforms.

Examples:

build_image --board=<board> [prod] [prodtar] [container] - builds developer and production images/tars.
build_image --board=<board> [prod] [prodtar] [container] [sysext] [oem_sysext] - builds developer and production images/tars.
...
"
show_help_if_requested "$@"
Expand All @@ -81,7 +83,7 @@ DEFINE_string version "" \
# Parse command line.
FLAGS "$@" || exit 1

eval set -- "${FLAGS_ARGV:-prod}"
eval set -- "${FLAGS_ARGV:-prod oem_sysext}"

# 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.
Expand All @@ -103,17 +105,20 @@ fi
. "${BUILD_LIBRARY_DIR}/test_image_content.sh" || exit 1
. "${BUILD_LIBRARY_DIR}/vm_image_util.sh" || exit 1
. "${BUILD_LIBRARY_DIR}/extra_sysexts.sh" || exit 1
. "${BUILD_LIBRARY_DIR}/oem_sysexts.sh" || exit 1

PROD_IMAGE=0
PROD_TAR=0
CONTAINER=0
SYSEXT=0
OEM_SYSEXT=0
for arg in "$@"; do
case "${arg}" in
prod) PROD_IMAGE=1 ;;
prodtar) PROD_IMAGE=1 PROD_TAR=1 ;;
container) CONTAINER=1 ;;
sysext) SYSEXT=1 ;;
oem_sysext) OEM_SYSEXT=1 ;;
*) die_notrace "Unknown image type ${arg}" ;;
esac
done
Expand Down Expand Up @@ -187,6 +192,9 @@ fi
if [[ "${SYSEXT}" -eq 1 ]]; then
create_prod_sysexts "${FLATCAR_PRODUCTION_IMAGE_NAME}"
fi
if [[ "${OEM_SYSEXT}" -eq 1 ]]; then
create_oem_sysexts "${FLATCAR_PRODUCTION_IMAGE_NAME}"
fi

if [[ ${FLAGS_extract_update} -eq ${FLAGS_TRUE} ]]; then
zip_update_tools
Expand Down
84 changes: 84 additions & 0 deletions build_library/oem_sysexts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#!/bin/bash
# OEM sysext helpers.

get_oem_overlay_root() {
local scripts_repo="$1"
local overlay_root="/mnt/host/source/src/third_party/coreos-overlay"

if [[ ! -d "${overlay_root}" ]]; then
overlay_root="${scripts_repo}/sdk_container/src/third_party/coreos-overlay"
fi

if [[ ! -d "${overlay_root}" ]]; then
echo "No coreos-overlay repo found (tried SDK and ${scripts_repo})" >&2
exit 1
fi

printf '%s' "${overlay_root}"
}

_get_oem_ids() {
local scripts_repo arch list_var_name
scripts_repo=${1}; shift
arch=${1}; shift
list_var_name=${1}; shift

local overlay_root
overlay_root=$(get_oem_overlay_root "${scripts_repo}")

local -a ebuilds=("${overlay_root}/coreos-base/common-oem-files/common-oem-files-"*'.ebuild')
if [[ ${#ebuilds[@]} -eq 0 ]] || [[ ! -e ${ebuilds[0]} ]]; then
echo "No coreos-base/common-oem-files ebuilds?!" >&2
exit 1
fi

# This defines local COMMON_OEMIDS, AMD64_ONLY_OEMIDS,
# ARM64_ONLY_OEMIDS and OEMIDS variable. We don't use the last
# one. Also defines global-by-default EAPI, which we make local
# here to avoid making it global.
local EAPI
source "${ebuilds[0]}" flatcar-local-variables

local -n arch_oemids_ref="${arch^^}_ONLY_OEMIDS"
local all_oemids=(
"${COMMON_OEMIDS[@]}"
"${arch_oemids_ref[@]}"
)

mapfile -t "${list_var_name}" < <(printf '%s\n' "${all_oemids[@]}" | sort)
}

# Gets a list of OEMs that are using sysexts.
#
# 1 - scripts repo
# 2 - arch
# 3 - name of an array variable to store the result in
get_oem_id_list() {
_get_oem_ids "$@"
}

# Gets a list of OEM sysext descriptors.
#
# 1 - scripts repo
# 2 - arch
# 3 - name of an array variable to store the result in
#
# Format: "name|metapackage|useflags"
get_oem_sysext_matrix() {
local scripts_repo arch list_var_name
scripts_repo=${1}; shift
arch=${1}; shift
list_var_name=${1}; shift

local -a oem_ids
_get_oem_ids "${scripts_repo}" "${arch}" oem_ids

local -a matrix=()
local oem_id
for oem_id in "${oem_ids[@]}"; do
matrix+=("oem-${oem_id}|coreos-base/oem-${oem_id}|${oem_id}")
done

local -n matrix_ref="${list_var_name}"
matrix_ref=("${matrix[@]}")
}
52 changes: 52 additions & 0 deletions build_library/prod_image_util.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

source "${BUILD_LIBRARY_DIR}/oem_sysexts.sh" || exit 1

# Lookup the current version of a binary package, downloading it if needed.
# Usage: get_binary_pkg some-pkg/name
# Prints: some-pkg/name-1.2.3
Expand Down Expand Up @@ -170,6 +172,10 @@ EOF
# Remove source locale data, only need to ship the compiled archive.
sudo rm -rf ${root_fs_dir}/usr/share/i18n/

# Inject ephemeral sysext signing certificate
sudo mkdir -p "${root_fs_dir}/usr/lib/verity.d"
sudo cp "${SYSEXT_SIGNING_KEY_DIR}/sysexts.crt" "${root_fs_dir}/usr/lib/verity.d"

# Finish image will move files from /etc to /usr/share/flatcar/etc.
# Note that image filesystem contents generated by finish_image will not
# include sysext contents (only the sysext squashfs files themselves).
Expand Down Expand Up @@ -269,6 +275,52 @@ create_prod_sysexts() {
done
}

create_oem_sysexts() {
local image_name="$1"
local image_sysext_base="${image_name%.bin}_sysext.squashfs"
local overlay_path
overlay_path=$(portageq get_repo_path / coreos-overlay)

local -a oem_sysexts
get_oem_sysext_matrix "${SCRIPT_ROOT}" "${ARCH}" oem_sysexts

local sysext name metapkg useflags
for sysext in "${oem_sysexts[@]}"; do
IFS="|" read -r name metapkg useflags <<< "${sysext}"

# Check for manglefs script in the package's files directory
local mangle_script="${overlay_path}/${metapkg}/files/manglefs.sh"
if [[ ! -x "${mangle_script}" ]]; then
mangle_script=
fi

sudo rm -f "${BUILD_DIR}/${name}.raw" \
"${BUILD_DIR}/flatcar_test_update-${name}.gz" \
"${BUILD_DIR}/${name}_"*

info "Building OEM sysext ${name} with USE=${useflags}"
# The --install_root_basename="${name}-oem-sysext-rootfs" flag is
# important - it sets the name of a rootfs directory, which is
# used to determine the package target in
# coreos/base/profile.bashrc
#
# OEM sysexts use no compression here since they will be stored
# in a compressed OEM partition.
USE="${useflags}" sudo -E "${SCRIPT_ROOT}/build_sysext" --board="${BOARD}" \
--squashfs_base="${BUILD_DIR}/${image_sysext_base}" \
--image_builddir="${BUILD_DIR}" \
--metapkgs="${metapkg}" \
--install_root_basename="${name}-oem-sysext-rootfs" \
--compression=none \
${mangle_script:+--manglefs_script="${mangle_script}"} \
"${name}"
delta_generator \
-private_key "/usr/share/update_engine/update-payload-key.key.pem" \
-new_image "${BUILD_DIR}/${name}.raw" \
-out_file "${BUILD_DIR}/flatcar_test_update-${name}.gz"
done
}

sbsign_prod_image() {
local image_name="$1"
local disk_layout="$2"
Expand Down
36 changes: 29 additions & 7 deletions build_library/sysext_prod_builder
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,15 @@ create_prod_sysext() {
# The --install_root_basename="${name}-base-sysext-rootfs" flag is
# important - it sets the name of a rootfs directory, which is used
# to determine the package target in coreos/base/profile.bashrc
sudo "FLATCAR_BUILD_ID=$FLATCAR_BUILD_ID" "${SCRIPTS_DIR}/build_sysext" \
#
# Built-in sysexts are stored in the compressed /usr partition, so we
# disable compression to avoid double-compression.
sudo -E "FLATCAR_BUILD_ID=$FLATCAR_BUILD_ID" "${SCRIPTS_DIR}/build_sysext" \
--board="${BOARD}" \
--image_builddir="${workdir}/sysext-build" \
--squashfs_base="${base_sysext}" \
--generate_pkginfo \
--compression=none \
--install_root_basename="${name}-base-sysext-rootfs" \
"${build_sysext_opts[@]}" \
"${name}" "${grp_pkg[@]}"
Expand Down Expand Up @@ -99,6 +103,14 @@ sysext_mountdir="${BUILD_DIR}/prod-sysext-work/mounts"
sysext_base="${sysext_workdir}/base-os.squashfs"

function cleanup() {
IFS=':' read -r -a mounted_sysexts <<< "$sysext_lowerdirs"
# skip the rootfs
mounted_sysexts=("${mounted_sysexts[@]:1}")

for sysext in "${mounted_sysexts[@]}"; do
sudo systemd-dissect --umount --rmdir "$sysext"
done

sudo umount "${sysext_mountdir}"/* || true
rm -rf "${sysext_workdir}" || true
}
Expand All @@ -116,6 +128,7 @@ sudo mksquashfs "${root_fs_dir}" "${sysext_base}" -noappend -xattrs-exclude '^bt
# for combined overlay later.
prev_pkginfo=""
sysext_lowerdirs="${sysext_mountdir}/rootfs-lower"
mkdir -p "${sysext_mountdir}"
for sysext in ${sysexts_list//,/ }; do
# format is "<name>:<group>/<package>"
name="${sysext%|*}"
Expand All @@ -129,12 +142,21 @@ for sysext in ${sysexts_list//,/ }; do
"${grp_pkg}" \
"${prev_pkginfo}"

mkdir -p "${sysext_mountdir}/${name}" \
"${sysext_mountdir}/${name}_pkginfo"
sudo mount -rt squashfs -o loop,nodev "${sysext_output_dir}/${name}.raw" \
"${sysext_mountdir}/${name}"
sudo mount -rt squashfs -o loop,nodev "${sysext_output_dir}/${name}_pkginfo.raw" \
"${sysext_mountdir}/${name}_pkginfo"
sudo systemd-dissect \
--read-only \
--mount \
--mkdir \
--image-policy='root=encrypted+unprotected+absent:usr=encrypted+unprotected+absent' \
"${sysext_output_dir}/${name}.raw" \
"${sysext_mountdir}/${name}"

sudo systemd-dissect \
--read-only \
--mount \
--mkdir \
--image-policy='root=encrypted+unprotected+absent:usr=encrypted+unprotected+absent' \
"${sysext_output_dir}/${name}_pkginfo.raw" \
"${sysext_mountdir}/${name}_pkginfo"

sysext_lowerdirs="${sysext_lowerdirs}:${sysext_mountdir}/${name}"
sysext_lowerdirs="${sysext_lowerdirs}:${sysext_mountdir}/${name}_pkginfo"
Expand Down
54 changes: 10 additions & 44 deletions build_library/vm_image_util.sh
Original file line number Diff line number Diff line change
Expand Up @@ -568,67 +568,33 @@ install_oem_package() {
sudo rm -rf "${oem_tmp}"
}

# Write the OEM sysext file into the OEM partition.
# Install the prebuilt OEM sysext file into the OEM partition.
# The sysext should have been built by 'build_image oem_sysext'.
install_oem_sysext() {
local oem_sysext=$(_get_vm_opt OEM_SYSEXT)

if [[ -z "${oem_sysext}" ]]; then
return 0
fi

local built_sysext_dir="${FLAGS_to}/${oem_sysext}-sysext"
local built_sysext_filename="${oem_sysext}.raw"
local built_sysext_path="${built_sysext_dir}/${built_sysext_filename}"
local prebuilt_sysext_filename="${oem_sysext}.raw"
local prebuilt_sysext_path="${FLAGS_from}/${prebuilt_sysext_filename}"
local version="${FLATCAR_VERSION}"
local metapkg="coreos-base/${oem_sysext}"
# The --install_root_basename="${name}-oem-sysext-rootfs" flag is
# important - it sets the name of a rootfs directory, which is
# used to determine the package target in
# coreos/base/profile.bashrc
local build_sysext_flags=(
--board="${BOARD}"
--squashfs_base="${VM_SRC_SYSEXT_IMG}"
--image_builddir="${built_sysext_dir}"
--metapkgs="${metapkg}"
--install_root_basename="${VM_IMG_TYPE}-oem-sysext-rootfs"
)
local overlay_path mangle_fs
overlay_path=$(portageq get_repo_path / coreos-overlay)
mangle_fs="${overlay_path}/${metapkg}/files/manglefs.sh"
if [[ -x "${mangle_fs}" ]]; then
build_sysext_flags+=(
--manglefs_script="${mangle_fs}"
)
fi

mkdir -p "${built_sysext_dir}"
sudo "${build_sysext_env[@]}" "${SCRIPT_ROOT}/build_sysext" "${build_sysext_flags[@]}" "${oem_sysext}"
if [[ ! -f "${prebuilt_sysext_path}" ]]; then
die "Prebuilt OEM sysext not found at ${prebuilt_sysext_path}. Run 'build_image oem_sysext' first."
fi

local installed_sysext_oem_dir='/oem/sysext'
local installed_sysext_file_prefix="${oem_sysext}-${version}"
local installed_sysext_filename="${installed_sysext_file_prefix}.raw"
local installed_sysext_abspath="${installed_sysext_oem_dir}/${installed_sysext_filename}"
info "Installing ${oem_sysext} sysext"

info "Installing ${oem_sysext} sysext from prebuilt image"
sudo install -Dpm 0644 \
"${built_sysext_path}" \
"${prebuilt_sysext_path}" \
"${VM_TMP_ROOT}${installed_sysext_abspath}" ||
die "Could not install ${oem_sysext} sysext"
# Move sysext image and reports to a destination directory to
# upload them, thus making them available as separate artifacts to
# download.
local upload_dir to_move
upload_dir="$(_dst_dir)"
for to_move in "${built_sysext_dir}/${oem_sysext}"*; do
mv "${to_move}" "${upload_dir}/${to_move##*/}"
done
# Generate dev-key-signed update payload for testing
delta_generator \
-private_key "/usr/share/update_engine/update-payload-key.key.pem" \
-new_image "${upload_dir}/${built_sysext_filename}" \
-out_file "${upload_dir}/flatcar_test_update-${oem_sysext}.gz"
# Remove sysext_dir if building sysext and installing it
# succeeded.
rm -rf "${built_sysext_dir}"

# Mark the installed sysext as active.
sudo touch "${VM_TMP_ROOT}${installed_sysext_oem_dir}/active-${oem_sysext}"
Expand Down
Loading