mirror of
https://git.launchpad.net/livecd-rootfs
synced 2025-12-19 18:13:28 +00:00
We have a mechanism in place to override a snap when building an image. Unfortunately, we didn't factor this in when forcing optional components to be included in the image. This was okay before because the stable model and the dangerous model had the same components declared. But now that pc-kernel has different components in the stable and the dangerous model, things are broken. Indeed, when building the stable image, we tried to include the pc-kernel from the stable model with the pc-kernel components from the dangerous model. But they are not compatible. Fixed by including components from the right model. If we're overriding a snap with a definition from a different model, then pull the components from that same model. Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
177 lines
5.7 KiB
Bash
177 lines
5.7 KiB
Bash
#!/bin/bash
|
|
|
|
# create the system seed for TPM-backed FDE in the live layer of the installer.
|
|
|
|
set -eux
|
|
|
|
case ${PASS:-} in
|
|
*.live)
|
|
;;
|
|
*)
|
|
exit 0
|
|
;;
|
|
esac
|
|
|
|
. config/binary
|
|
. config/functions
|
|
|
|
|
|
# Naive conversion from YAML to JSON. This is needed because yq is in universe
|
|
# (but jq is not).
|
|
yaml_to_json()
|
|
{
|
|
python3 -c '
|
|
import json
|
|
import sys
|
|
import yaml
|
|
|
|
json.dump(yaml.safe_load(sys.stdin), sys.stdout, default=str)
|
|
'
|
|
}
|
|
|
|
|
|
# Use jq to retrieve a list of --snap options from a given *signed* model.
|
|
get_snaps_args()
|
|
{
|
|
local model=$1
|
|
|
|
# The model is signed and is not valid YAML unless we get rid of the
|
|
# signature. Here we assume the only blank line is before the signature.
|
|
sed '/^$/,$d' -- "$model" \
|
|
| yaml_to_json \
|
|
| jq --raw-output '.snaps[] | "--snap=" + .name + "=" + .["default-channel"]'
|
|
}
|
|
|
|
_get_components_filtered()
|
|
{
|
|
local excluded=$1
|
|
local model=$2
|
|
local jq_filter='
|
|
# Find all snaps that are either filtered in or filtered out
|
|
# The filtered in (or out) snaps are passed as positional arguments so they end up in
|
|
# the $ARGS.positional array. The excluded variable is passed separately and
|
|
# tells if we want to filter in (i.e., excluded=false) or filter out (i.e.,
|
|
# excluded=true).
|
|
.snaps[] | select(.name | IN($ARGS.positional[]) | if $excluded then not else . end)
|
|
# and have components
|
|
| select(.components)
|
|
# Then save the name of each snap in a variable
|
|
| .name as $snap
|
|
# Then for each entry that has "optional"
|
|
| .components | to_entries | map(select(.value.presence == "optional"))
|
|
# Output its name with the snap name prepended
|
|
| "\($snap)" + "+" + .[].key'
|
|
|
|
shift 2
|
|
|
|
sed '/^$/,$d' -- "$model" \
|
|
| yaml_to_json \
|
|
| jq --raw-output "$jq_filter" --argjson excluded "$excluded" --args "$@"
|
|
}
|
|
|
|
# Get list of all components for all snaps
|
|
get_all_components()
|
|
{
|
|
local model=$1
|
|
# Provide an exclusion list but empty
|
|
_get_components_filtered true "$model"
|
|
}
|
|
|
|
# Get list of all components for all snaps except the ones specified.
|
|
get_components_excluding()
|
|
{
|
|
local model=$1
|
|
shift
|
|
_get_components_filtered true "$model" "$@"
|
|
}
|
|
|
|
# Get list of all components for the snaps specified.
|
|
get_components()
|
|
{
|
|
local model=$1
|
|
shift
|
|
_get_components_filtered false "$model" "$@"
|
|
}
|
|
|
|
# Generation of the model:
|
|
# * At https://github.com/canonical/models one can find a repo of raw,
|
|
# unsigned, input .json files, and their signed .model equivalents.
|
|
# * At least once per cycle, update the json for the new Ubuntu version.
|
|
# To do this, take the previous cycle ubuntu-classic-$ver-amd64.json file,
|
|
# rename for the new version, and do any necessary updates including fixing
|
|
# the versions of tracks.
|
|
# * When this is done, the json needs to be signed. This needs to be done by
|
|
# a Canonical employee - try asking someone who has recently opened PRs on
|
|
# https://github.com/canonical/models with the signed models.
|
|
# * Ensure the signed and unsigned version of the models are updated in the
|
|
# models repo.
|
|
# * The signed model can then be placed here in livecd-rootfs at
|
|
# live-build/${PROJECT}/ubuntu-classic-amd64.model
|
|
|
|
# env SNAPPY_STORE_NO_CDN=1 snap known --remote model series=16 brand-id=canonical model=ubuntu-classic-2410-amd64 > config/classic-model.model
|
|
#
|
|
dangerous_model=/usr/share/livecd-rootfs/live-build/${PROJECT}/ubuntu-classic-amd64-dangerous.model
|
|
stable_model=/usr/share/livecd-rootfs/live-build/${PROJECT}/ubuntu-classic-amd64.model
|
|
|
|
prepare_args=()
|
|
|
|
components=()
|
|
|
|
# for the dangerous subproject, we need the dangerous model!
|
|
if [ "$SUBPROJECT" = "dangerous" ]; then
|
|
# As with the "classically" seeded snaps, snaps from the edge channel may
|
|
# require different content snaps to be installed, so they must be
|
|
# included in the system as well. We just use the same list as was
|
|
# computed in snap_validate_seed.
|
|
model="${dangerous_model}"
|
|
while read snap; do
|
|
prepare_args+=("--snap=${snap}=edge")
|
|
done < config/missing-providers
|
|
|
|
for comp in $(get_all_components "$model"); do
|
|
components+=("$comp")
|
|
done
|
|
else
|
|
# Normally we use the stable model here. Use the dangerous one for now
|
|
# until we get snaps on stable 26.04 tracks and channels.
|
|
#model="${stable_model}"
|
|
model="${dangerous_model}"
|
|
# We're currently using the dangerous model for the stable image because it
|
|
# allows us to override snaps. But we don't want all snaps from edge like
|
|
# the dangerous model has, we want most of them from stable excluding:
|
|
# * snapd (for TPM/FDE)
|
|
# * firmware-updater (for TPM/FDE)
|
|
# * desktop-security-center (for TPM/FDE)
|
|
snaps_from_dangerous=(snapd firmware-updater desktop-security-center)
|
|
while read -r snap_arg; do
|
|
prepare_args+=("$snap_arg")
|
|
done < <(get_snaps_args "$stable_model" \
|
|
| grep -v -F -e snapd -e firmware-updater -e desktop-security-center)
|
|
|
|
for comp in $(get_components_excluding "$stable_model" "${snaps_from_dangerous[@]}"); do
|
|
components+=("$comp")
|
|
done
|
|
for comp in $(get_components "$dangerous_model" "${snaps_from_dangerous[@]}"); do
|
|
components+=("$comp")
|
|
done
|
|
fi
|
|
|
|
for comp in "${components[@]}"; do
|
|
prepare_args+=(--comp "$comp")
|
|
done
|
|
|
|
channel=""
|
|
if [ -n "${CHANNEL:-}" ]; then
|
|
channel="--channel $CHANNEL"
|
|
fi
|
|
|
|
# Set UBUNTU_STORE_COHORT_KEY="+" to force prepare-image to fetch the latest
|
|
# snap versions regardless of phasing status
|
|
|
|
env SNAPPY_STORE_NO_CDN=1 UBUNTU_STORE_COHORT_KEY="+" snap prepare-image \
|
|
--classic $model $channel "${prepare_args[@]}" chroot
|
|
|
|
mv chroot/system-seed/systems/* chroot/system-seed/systems/enhanced-secureboot-desktop
|
|
rsync -av chroot/system-seed/{systems,snaps} chroot/var/lib/snapd/seed
|
|
rm -rf chroot/system-seed/
|