Skip to content

Commit

Permalink
Merge pull request #318 from bcressey/more-image-features
Browse files Browse the repository at this point in the history
add and remove image features
  • Loading branch information
bcressey committed Jul 2, 2024
2 parents 13dc97b + 828198d commit 8a29af7
Show file tree
Hide file tree
Showing 6 changed files with 189 additions and 135 deletions.
56 changes: 37 additions & 19 deletions tools/buildsys/src/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,24 @@ kernel-parameters = [
]
`image-features` is a map of image feature flags, which can be enabled or disabled. This allows us
to conditionally use or exclude certain firmware-level features in variants.
to conditionally use or exclude certain image-level features in variants.
`in-place-updates` means that the disk layout for the variant will support in-place updates, which
requires a parallel set of partition table entries to use as the active and passive banks. For
backwards compatibility, this feature is enabled by default unless explicitly disabled.
```ignore
[package.metadata.build-variant.image-features]
in-place-updates = true
```
`host-containers` means that software support for host and bootstrap containers will be included in
the variant. This provides a way to extend the host OS with additional software packaged as a
container, which can be run on boot or as a background service. For backwards compatibility, this
feature is enabled by default unless explicitly disabled.
```ignore
[package.metadata.build-variant.image-features]
host-containers = true
```
`grub-set-private-var` means that the grub image for the current variant includes the command to
find the BOTTLEROCKET_PRIVATE partition and set the appropriate `$private` variable for the grub
Expand All @@ -187,16 +204,6 @@ flag is meant primarily for development, and will be removed when development ha
systemd-networkd = true
```
`unified-cgroup-hierarchy` makes systemd set up a unified cgroup hierarchy on
boot, i.e. the host will use cgroup v2 by default. This feature flag allows
old variants to continue booting with cgroup v1 and new variants to move to
cgroup v2, while users will still be able to override the default via command
line arguments set in the boot configuration.
```ignore
[package.metadata.build-variant.image-features]
unified-cgroup-hierarchy = true
```
`xfs-data-partition` changes the filesystem for the data partition from ext4 to xfs. The
default will remain ext4 and xfs is opt-in.
Expand Down Expand Up @@ -471,11 +478,19 @@ impl ManifestInfo {

/// Convenience method to return the enabled image features for this variant.
pub fn image_features(&self) -> Option<HashSet<ImageFeature>> {
self.build_variant().and_then(|b| {
b.image_features
.as_ref()
.map(|m| m.iter().filter(|(_k, v)| **v).map(|(k, _v)| *k).collect())
})
let variant = self.build_variant()?;
let mut features =
HashSet::from([ImageFeature::InPlaceUpdates, ImageFeature::HostContainers]);
if let Some(image_features) = &variant.image_features {
for (feature, enabled) in image_features.iter() {
if *enabled {
features.insert(*feature);
} else {
features.remove(feature);
}
}
}
Some(features)
}

/// Returns the type of build the manifest is requesting.
Expand Down Expand Up @@ -766,10 +781,11 @@ impl SupportedArch {
pub enum ImageFeature {
GrubSetPrivateVar,
SystemdNetworkd,
UnifiedCgroupHierarchy,
XfsDataPartition,
UefiSecureBoot,
Fips,
InPlaceUpdates,
HostContainers,
}

impl TryFrom<String> for ImageFeature {
Expand All @@ -778,10 +794,11 @@ impl TryFrom<String> for ImageFeature {
match s.as_str() {
"grub-set-private-var" => Ok(ImageFeature::GrubSetPrivateVar),
"systemd-networkd" => Ok(ImageFeature::SystemdNetworkd),
"unified-cgroup-hierarchy" => Ok(ImageFeature::UnifiedCgroupHierarchy),
"xfs-data-partition" => Ok(ImageFeature::XfsDataPartition),
"uefi-secure-boot" => Ok(ImageFeature::UefiSecureBoot),
"fips" => Ok(ImageFeature::Fips),
"in-place-updates" => Ok(ImageFeature::InPlaceUpdates),
"host-containers" => Ok(ImageFeature::HostContainers),
_ => error::ParseImageFeatureSnafu { what: s }.fail()?,
}
}
Expand All @@ -792,10 +809,11 @@ impl fmt::Display for ImageFeature {
match self {
ImageFeature::GrubSetPrivateVar => write!(f, "GRUB_SET_PRIVATE_VAR"),
ImageFeature::SystemdNetworkd => write!(f, "SYSTEMD_NETWORKD"),
ImageFeature::UnifiedCgroupHierarchy => write!(f, "UNIFIED_CGROUP_HIERARCHY"),
ImageFeature::XfsDataPartition => write!(f, "XFS_DATA_PARTITION"),
ImageFeature::UefiSecureBoot => write!(f, "UEFI_SECURE_BOOT"),
ImageFeature::Fips => write!(f, "FIPS"),
ImageFeature::InPlaceUpdates => write!(f, "IN_PLACE_UPDATES"),
ImageFeature::HostContainers => write!(f, "HOST_CONTAINERS"),
}
}
}
Expand Down
18 changes: 12 additions & 6 deletions twoliter/embedded/build.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,9 @@ ARG VARIANT_FLAVOR
ARG GRUB_SET_PRIVATE_VAR
ARG UEFI_SECURE_BOOT
ARG SYSTEMD_NETWORKD
ARG UNIFIED_CGROUP_HIERARCHY
ARG XFS_DATA_PARTITION
ARG IN_PLACE_UPDATES
ARG HOST_CONTAINERS
ARG FIPS

USER builder
Expand All @@ -225,8 +226,9 @@ RUN \
&& echo -e -n "${FIPS:+%bcond_without fips\n}" >> "${RPM_BCONDS}" \
&& echo -e -n "${UEFI_SECURE_BOOT:+%bcond_without uefi_secure_boot\n}" >> "${RPM_BCONDS}" \
&& echo -e -n "${SYSTEMD_NETWORKD:+%bcond_without systemd_networkd\n}" >> "${RPM_BCONDS}" \
&& echo -e -n "${UNIFIED_CGROUP_HIERARCHY:+%bcond_without unified_cgroup_hierarchy\n}" >> "${RPM_BCONDS}" \
&& echo -e -n "${XFS_DATA_PARTITION:+%bcond_without xfs_data_partition\n}" >> "${RPM_BCONDS}"
&& echo -e -n "${XFS_DATA_PARTITION:+%bcond_without xfs_data_partition\n}" >> "${RPM_BCONDS}" \
&& echo -e -n "${IN_PLACE_UPDATES:+%bcond_without in_place_updates\n}" >> "${RPM_BCONDS}" \
&& echo -e -n "${HOST_CONTAINERS:+%bcond_without host_containers\n}" >> "${RPM_BCONDS}"

# =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^=
# Creates an RPM repository from packages created in Section 1 and kits from Section 2.
Expand Down Expand Up @@ -330,6 +332,7 @@ ARG KERNEL_PARAMETERS
ARG GRUB_SET_PRIVATE_VAR
ARG XFS_DATA_PARTITION
ARG UEFI_SECURE_BOOT
ARG IN_PLACE_UPDATES
ENV VARIANT=${VARIANT} VERSION_ID=${VERSION_ID} BUILD_ID=${BUILD_ID} \
PRETTY_NAME=${PRETTY_NAME} IMAGE_NAME=${IMAGE_NAME} \
KERNEL_PARAMETERS=${KERNEL_PARAMETERS}
Expand Down Expand Up @@ -365,9 +368,10 @@ RUN --mount=target=/host \
--data-image-publish-size-gib="${DATA_IMAGE_PUBLISH_SIZE_GIB}" \
--partition-plan="${PARTITION_PLAN}" \
--ovf-template="/bypass/variants/${VARIANT}/template.ovf" \
${XFS_DATA_PARTITION:+--xfs-data-partition=yes} \
${XFS_DATA_PARTITION:+--with-xfs-data-partition=yes} \
${GRUB_SET_PRIVATE_VAR:+--with-grub-set-private-var=yes} \
${UEFI_SECURE_BOOT:+--with-uefi-secure-boot=yes} && \
${UEFI_SECURE_BOOT:+--with-uefi-secure-boot=yes} \
${IN_PLACE_UPDATES:+--with-in-place-updates=yes} && \
rm -rf /local/rpms && \
chown -R "${BUILDER_UID}:${BUILDER_UID}" /output/ && \
rm /output && \
Expand Down Expand Up @@ -469,6 +473,7 @@ ARG PARTITION_PLAN
ARG OS_IMAGE_PUBLISH_SIZE_GIB
ARG DATA_IMAGE_PUBLISH_SIZE_GIB
ARG UEFI_SECURE_BOOT
ARG IN_PLACE_UPDATES
ENV VARIANT=${VARIANT} VERSION_ID=${VERSION_ID} BUILD_ID=${BUILD_ID}
WORKDIR /root

Expand Down Expand Up @@ -502,7 +507,8 @@ RUN --mount=target=/host \
--data-image-publish-size-gib="${DATA_IMAGE_PUBLISH_SIZE_GIB}" \
--partition-plan="${PARTITION_PLAN}" \
--ovf-template="/bypass/variants/${VARIANT}/template.ovf" \
${UEFI_SECURE_BOOT:+--with-uefi-secure-boot=yes} && \
${UEFI_SECURE_BOOT:+--with-uefi-secure-boot=yes} \
${IN_PLACE_UPDATES:+--with-in-place-updates=yes} && \
chown -R "${BUILDER_UID}:${BUILDER_UID}" /output/ && \
rm /output && \
rm /bypass && \
Expand Down
14 changes: 10 additions & 4 deletions twoliter/embedded/img2img
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ OUTPUT_FMT="raw"
OVF_TEMPLATE=""

UEFI_SECURE_BOOT="no"
IN_PLACE_UPDATES="no"

for opt in "$@"; do
optarg="$(expr "${opt}" : '[^=]*=\(.*\)')"
Expand All @@ -21,6 +22,7 @@ for opt in "$@"; do
--partition-plan=*) PARTITION_PLAN="${optarg}" ;;
--ovf-template=*) OVF_TEMPLATE="${optarg}" ;;
--with-uefi-secure-boot=*) UEFI_SECURE_BOOT="${optarg}" ;;
--with-in-place-updates=*) IN_PLACE_UPDATES="${optarg}" ;;
*)
echo "unexpected arg: ${opt}" >&2
exit 1
Expand Down Expand Up @@ -81,7 +83,8 @@ EFI_MOUNT="$(mktemp -p "${WORKDIR}" -d efi.XXXXXXXXXX)"
# Collect partition sizes and offsets from the partition plan.
declare -A partsize partoff
set_partition_sizes \
"${OS_IMAGE_SIZE_GIB}" "${DATA_IMAGE_SIZE_GIB}" "${PARTITION_PLAN}" \
"${OS_IMAGE_SIZE_GIB}" "${DATA_IMAGE_SIZE_GIB}" \
"${PARTITION_PLAN}" "${IN_PLACE_UPDATES}" \
partsize partoff

# Process and stage the input images to the working directory.
Expand All @@ -91,18 +94,21 @@ stage_images "${INPUT_DIR}" "${OUTPUT_FMT}" OS_IMAGE DATA_IMAGE
# Collect partition sizes and offsets from the OS image.
declare -A imgsize imgoff
get_partition_sizes \
"${OS_IMAGE}" "" "${PARTITION_PLAN}" imgsize imgoff
"${OS_IMAGE}" "" \
imgsize imgoff

# Compare the offsets between the partition plan and the input image.
for part in "${!imgoff[@]}"; do
for part in "${!partoff[@]}"; do
[[ "${part}" == DATA-* ]] && continue
if [[ "${partoff["${part}"]}" -ne "${imgoff["${part}"]}" ]]; then
echo "start mismatch between partition plan and disk: '${part}'" >&2
exit 1
fi
done

# Compare the sizes between the partition plan and the input image.
for part in "${!imgsize[@]}"; do
for part in "${!partsize[@]}"; do
[[ "${part}" == DATA-* ]] && continue
if [[ "${partsize["${part}"]}" -ne "${imgsize["${part}"]}" ]]; then
echo "size mismatch between partition plan and disk: '${part}'" >&2
exit 1
Expand Down
18 changes: 12 additions & 6 deletions twoliter/embedded/metadata.spec
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ Provides: %{_cross_os}variant-runtime(%{_cross_variant_runtime})
Provides: %{_cross_os}variant-family(%{_cross_variant_family})
Provides: %{_cross_os}variant-flavor(%{_cross_variant_flavor})

%if %{with in_place_updates}
Provides: %{_cross_os}image-feature(in-place-updates)
%else
Provides: %{_cross_os}image-feature(no-in-place-updates)
%endif

%if %{with host_containers}
Provides: %{_cross_os}image-feature(host-containers)
%else
Provides: %{_cross_os}image-feature(no-host-containers)
%endif

%if %{with grub_set_private_var}
Provides: %{_cross_os}image-feature(grub-set-private-var)
%else
Expand All @@ -32,12 +44,6 @@ Provides: %{_cross_os}image-feature(systemd-networkd)
Provides: %{_cross_os}image-feature(no-systemd-networkd)
%endif

%if %{with unified_cgroup_hierarchy}
Provides: %{_cross_os}image-feature(unified-cgroup-hierarchy)
%else
Provides: %{_cross_os}image-feature(no-unified-cgroup-hierarchy)
%endif

%if %{with xfs_data_partition}
Provides: %{_cross_os}image-feature(xfs-data-partition)
%else
Expand Down
Loading

0 comments on commit 8a29af7

Please sign in to comment.