Skip to content
Merged
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
config
logs/*
tmp/*
products/boot/build/
22 changes: 22 additions & 0 deletions bin/layer-lib
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ LAYER_SUBMOUNTS="run dev/pts dev proc sys"

LAYER_ZSTD_LEVEL=19

# The boot layer of an appliance (handbook decision 0052) is named after it
# with this suffix: the kernel, initrd, bootloaders and installer the ISO
# boots with and the container template never carries.
LAYER_BOOT_SUFFIX=-boot

# A unit is a component supplied to fab as a directory under the product's
# UNIT_DIRS, carrying any of these four inputs. fab resolves the plan, applies
# the overlay, runs the conf script and applies the removelist.
Expand Down Expand Up @@ -852,10 +857,15 @@ layer_parent_resolve() {
layer_manifest_get "$manifest" sha256
}

# layer_parse_args ARGS...: sets LAYER_NAME, LAYER_PARENT, LAYER_USE_EXISTING,
# LAYER_BOOT and LAYER_HELP, or LAYER_ERROR and returns 1. With --boot the
# name given is the appliance: the layer is APPLIANCE-boot and its parent is
# the appliance's layer (handbook decision 0052).
layer_parse_args() {
LAYER_NAME=
LAYER_PARENT=
LAYER_USE_EXISTING=
LAYER_BOOT=
LAYER_HELP=
LAYER_ERROR=
while [[ $# -gt 0 ]]; do
Expand All @@ -875,6 +885,9 @@ layer_parse_args() {
--use-existing|-u)
LAYER_USE_EXISTING=yes
;;
--boot|-b)
LAYER_BOOT=yes
;;
-*)
LAYER_ERROR="unrecognized option: $1"
return 1
Expand All @@ -897,5 +910,14 @@ layer_parse_args() {
LAYER_ERROR="a layer cannot be its own parent"
return 1
fi
if [[ -n "$LAYER_BOOT" ]]; then
if [[ -n "$LAYER_PARENT" ]]; then
# shellcheck disable=SC2034 # read by bt-layer: usage "$LAYER_ERROR"
LAYER_ERROR="--boot builds on the appliance it names; it takes no --parent"
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
return 1
fi
LAYER_PARENT=$LAYER_NAME
LAYER_NAME=$LAYER_NAME$LAYER_BOOT_SUFFIX
fi
return 0
}
12 changes: 12 additions & 0 deletions bt-layer
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ info() { echo "INFO [$APP]: $*"; }
usage() {
cat<<EOF
Syntax: $APP [-p|--parent LAYER] [-u] layer
$APP -b|--boot [-u] appliance
Builds product \$BT_PRODUCTS/layer to root.patched and exports it as a layer

Arguments::
Expand All @@ -35,6 +36,12 @@ Options::
needs
-u|--use-existing - skip the build and export the existing
build/root.patched (fails if it is missing)
-b|--boot - build the boot layer of the appliance: the layer
appliance-boot on top of the appliance's layer,
from the boot product (\$BT_BOOT_PRODUCT, default
products/boot here), with the kernel, initrd,
bootloaders and installer only the ISO uses
(handbook decision 0052)

Environment::

Expand All @@ -47,6 +54,8 @@ Environment::
FAB_PATH - fab tree (common/, altstraps/)
RELEASE, FAB_ARCH - default to the host release and architecture
BT_DEBUG - verbose output
BT_BOOT_PRODUCT - the product --boot builds; defaults to products/boot
in this checkout

Output, in \$BT_BUILDS/layers/::

Expand Down Expand Up @@ -93,6 +102,9 @@ parent=$LAYER_PARENT
[[ -n "$BT_PRODUCTS" ]] || fatal "BT_PRODUCTS not set"
[[ -n "$BT_BUILDS" ]] || fatal "BT_BUILDS not set"
product_dir=$BT_PRODUCTS/$layer
if [[ -n "$LAYER_BOOT" ]]; then
product_dir=${BT_BOOT_PRODUCT:-$BT/products/boot}
fi
[[ -f "$product_dir/Makefile" ]] || fatal "product not found: $product_dir"

RELEASE=${RELEASE:-debian/$(lsb_release -sc)}
Expand Down
14 changes: 14 additions & 0 deletions products/boot/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# The boot layer of an appliance (handbook decision 0052), built with
# "bt-layer --boot APPLIANCE" on top of the appliance's layer: the kernel,
# initrd, firmware, bootloaders and installer of plans/keel-boot in common,
# GRUB's overlay and conf. The ISO is made from the appliance's chain with
# this layer on top; the container template is assembled without it, and
# keel assemble refuses a template that has any of these packages.
#
# turnkey.mk puts turnkey.d first: bt-layer applies only what the parent
# did not, so this layer runs keel-boot and the turnkey.d steps every
# layer needs.
COMMON_OVERLAYS = keel-boot
COMMON_CONF = keel-boot

include $(FAB_PATH)/common/mk/turnkey.mk
2 changes: 2 additions & 0 deletions products/boot/plan/main
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/* the boot layer: plans/keel-boot of common (handbook decision 0052) */
#include <keel-boot>
47 changes: 44 additions & 3 deletions tests/layer
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@
# layer_hash_size (ok, missing); layer_write_sha256; layer_umount_targets
# (none, mounted); layer_parent_resolve (ok, no rootfs, no manifest);
# layer_parse_args (help, name, parent, use-existing, no name, two
# names, unknown option, parent without value, self parent).
# names, unknown option, parent without value, self parent, --boot,
# --boot with --parent).
# bt-layer: --help; usage error; missing config; missing FAB_PATH; missing
# product; bad epoch; rootfs build with warning on BT_GPGKEY, exported
# with an empty machine-id whatever the build left, refused when it
Expand All @@ -57,7 +58,9 @@
# stale altstrap symlink; parent manifest without conf list; product
# without a debug target; failing make removes the altstrap; TERM default;
# a rootfs layer with a unit; a child that composes the same unit; a child
# that adds one; a child with no unit of its own; a unit pinned to another
# that adds one; a child with no unit of its own; --boot (the boot layer
# on the appliance's, its product missing, with --parent; products/boot's
# conf and overlays); a unit pinned to another
# version than the parent applied; a unit whose conf fab would skip; a
# parent manifest written before the units field existed.

Expand Down Expand Up @@ -753,7 +756,11 @@ layer_parse_args -u lamp --parent core
assert_eq parse-parent "$LAYER_NAME|$LAYER_PARENT|$LAYER_USE_EXISTING" "lamp|core|yes"
layer_parse_args wordpress -p lamp --use-existing
assert_eq parse-short "$LAYER_NAME|$LAYER_PARENT|$LAYER_USE_EXISTING" "wordpress|lamp|yes"
for bad in "" "a b" "--bogus a" "a --parent" "a --parent a"; do
layer_parse_args --boot core
assert_eq parse-boot "$LAYER_NAME|$LAYER_PARENT|$LAYER_BOOT" "core-boot|core|yes"
layer_parse_args -u -b web
assert_eq parse-boot-short "$LAYER_NAME|$LAYER_PARENT|$LAYER_USE_EXISTING" "web-boot|web|yes"
for bad in "" "a b" "--bogus a" "a --parent" "a --parent a" "a --boot --parent b"; do
if layer_parse_args $bad 2>/dev/null; then
fatal "parse_args should have failed on '$bad'"
fi
Expand Down Expand Up @@ -969,5 +976,39 @@ assert_eq app5-build-units "$(layer_manifest_get "$L/app5.manifest" build_units)
"[email protected]"
assert_eq app5-units-used "$(cat "$tmp/products/app5/build/units.used")" "unit.d/broken"

info "23: bt-layer --boot core (the boot layer of decision 0052)"
# the product bt-layer --boot builds, here a stub; the real one is checked
# below against a stand-in for common's turnkey.mk
write_product "$tmp/products/bootprod" "turnkey.d keel-boot" "turnkey.d keel-boot"
expect_fail boot-default-product-missing "$sbt/bt-layer" --boot core
out=$(BT_BOOT_PRODUCT=$tmp/products/bootprod "$sbt/bt-layer" --boot core)
assert_file "$L/core-boot.tar.zst"
assert_eq boot-type "$(layer_manifest_get "$L/core-boot.manifest" type)" delta
assert_eq boot-parent "$(layer_manifest_get "$L/core-boot.manifest" parent)" core
assert_eq boot-parent-sha "$(layer_manifest_get "$L/core-boot.manifest" parent_sha256)" \
"$(layer_manifest_get "$L/core.manifest" sha256)"
assert_eq boot-build-conf "$(layer_manifest_get "$L/core-boot.manifest" build_conf)" \
"turnkey.d/hostname keel-boot"
assert_eq boot-build-overlays "$(layer_manifest_get "$L/core-boot.manifest" build_overlays)" \
"turnkey.d/tkl-bashlib turnkey.d/systemd-chroot keel-boot"
assert_eq boot-altstrap-used "$(cat "$tmp/products/bootprod/build/altstrap.used")" "$L/core.rootfs"
expect_fail boot-with-parent "$sbt/bt-layer" --boot core --parent lamp

info "23a: products/boot asks for keel-boot on top of turnkey.d"
mkdir -p "$tmp/fabstub/common/mk"
cat > "$tmp/fabstub/common/mk/turnkey.mk" <<'MK'
COMMON_OVERLAYS := turnkey.d $(COMMON_OVERLAYS)
COMMON_CONF := turnkey.d $(COMMON_CONF)
debug:
$(foreach v,$(V),$(warning $(v) = $($(v))))
@true
MK
cp -r "$BT/products/boot" "$tmp/bootcopy"
assert_eq boot-product-conf "$(FAB_PATH=$tmp/fabstub layer_make_var "$tmp/bootcopy" COMMON_CONF)" \
"turnkey.d keel-boot"
assert_eq boot-product-overlays "$(FAB_PATH=$tmp/fabstub layer_make_var "$tmp/bootcopy" COMMON_OVERLAYS)" \
"turnkey.d keel-boot"
grep -qx '#include <keel-boot>' "$tmp/bootcopy/plan/main" || fatal "products/boot does not resolve plans/keel-boot"

echo
info "all tests passed"
Loading