-
Notifications
You must be signed in to change notification settings - Fork 582
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tests: verify that factory reset after remodeling to a new snapd works
- Loading branch information
1 parent
b382f37
commit 766759f
Showing
2 changed files
with
224 additions
and
0 deletions.
There are no files selected for viewing
21 changes: 21 additions & 0 deletions
21
tests/nested/manual/update-snapd-seed-and-factory-reset/find-orphan-keys.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import json | ||
import sys | ||
|
||
doc = json.load(sys.stdin) | ||
|
||
slot_to_token = {} | ||
for k, v in doc.get('tokens', {}).items(): | ||
for slot in v.get('keyslots', []): | ||
slot_to_token[slot] = k | ||
|
||
orphans = [] | ||
for k, v in doc.get('keyslots', {}).items(): | ||
if k not in slot_to_token: | ||
orphans.append(k) | ||
|
||
if len(orphans) > 0: | ||
formatted = ', '.join(orphans) | ||
print(f'orphan key slots: {formatted}', file=sys.stderr) | ||
sys.exit(1) | ||
else: | ||
sys.exit(0) |
203 changes: 203 additions & 0 deletions
203
tests/nested/manual/update-snapd-seed-and-factory-reset/task.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
summary: Test that remodeling with a new snapd in seed will be able to factory reset | ||
|
||
details: | | ||
With the refactoring of FDE, new snapd provisions with named key | ||
slots and key data, whereas old snapd uses static key slots and | ||
sealed key objects. It is fine to update snapd because in run | ||
mode, snapd will only care about unlocking disk, and the seed will | ||
still contain an old snapd. However, if snapd is updated in the | ||
seed and we factory reset the device, we will have to reprovision | ||
with an old save. This test covers that case. | ||
systems: [ubuntu-2*] | ||
|
||
environment: | ||
NESTED_CUSTOM_MODEL: $(pwd)/model-old.model | ||
NESTED_ENABLE_TPM/tpm: true | ||
NESTED_ENABLE_SECURE_BOOT/tpm: true | ||
|
||
NESTED_FAKESTORE_BLOB_DIR: $(pwd)/fake-store-blobdir | ||
NESTED_UBUNTU_IMAGE_SNAPPY_FORCE_SAS_URL: http://localhost:11028 | ||
REMOTE_SAS_URL: http://10.0.2.2:11028 | ||
|
||
# We will sign manually because we need to move files around | ||
NESTED_SIGN_SNAPS_FAKESTORE: false | ||
|
||
# 2.63 | ||
OLD_SNAPD_REVISION: 21759 | ||
OLD_SNAPD_COMMIT: 40efd81c2f35213eabf2df83fb9efabe88fa124e | ||
|
||
prepare: | | ||
# Install what is needed before using the fake store | ||
snap install jq remarshal | ||
snap install test-snapd-swtpm --edge | ||
# We could use our own names and ids since we will provide our own | ||
# store. But to avoid errors with some hardcoded checks, let's use | ||
# the same as the store. | ||
VERSION="$(tests.nested show version)" | ||
core_name="core${VERSION}" | ||
if tests.nested is-nested uc20; then | ||
core_id="DLqre5XGLbDqg9jPtiAhRRjDuPVa5X1q" | ||
elif tests.nested is-nested uc22; then | ||
core_id="amcUKQILKXHHTlmSa7NMdnXSx02dNeeT" | ||
elif tests.nested is-nested uc24; then | ||
core_id="dwTAh7MZZ01zyriOZErqd1JynQLiOGvM" | ||
else | ||
echo "Unknown system" 1>&2 | ||
exit 1 | ||
fi | ||
"${TESTSTOOLS}/store-state" setup-fake-store "${NESTED_FAKESTORE_BLOB_DIR}" | ||
cp "${TESTSLIB}/assertions/developer1.account" "${NESTED_FAKESTORE_BLOB_DIR}/asserts" | ||
cp "${TESTSLIB}/assertions/developer1.account-key" "${NESTED_FAKESTORE_BLOB_DIR}/asserts" | ||
cp "${TESTSLIB}/assertions/testrootorg-store.account-key" "${NESTED_FAKESTORE_BLOB_DIR}/asserts" | ||
for model_version in old new; do | ||
gendeveloper1 sign-model <<EOF >"model-${model_version}.model" | ||
{ | ||
"type": "model", | ||
"authority-id": "developer1", | ||
"series": "16", | ||
"brand-id": "developer1", | ||
"model": "update-snapd-seed-and-factory-reset-${model_version}", | ||
"architecture": "amd64", | ||
"timestamp": "$(date -Iseconds --utc)", | ||
"grade": "dangerous", | ||
"base": "${core_name}", | ||
"serial-authority": [ | ||
"generic" | ||
], | ||
"snaps": [ | ||
{ | ||
"default-channel": "${VERSION}/edge", | ||
"id": "UqFziVZDHLSyO3TqSWgNBoAdHbLI4dAH", | ||
"name": "pc", | ||
"type": "gadget" | ||
}, | ||
{ | ||
"default-channel": "${VERSION}/edge", | ||
"id": "pYVQrBcKmBa0mZ4CCN7ExT6jH8rY1hza", | ||
"name": "pc-kernel", | ||
"type": "kernel" | ||
}, | ||
{ | ||
"default-channel": "${VERSION}/edge", | ||
"id": "${core_id}", | ||
"name": "${core_name}", | ||
"type": "base" | ||
}, | ||
{ | ||
"default-channel": "${model_version}/edge", | ||
"id": "PMrrV4ml8uWuEUDBT8dSGnKUYbevVhc4", | ||
"name": "snapd", | ||
"type": "snapd" | ||
} | ||
] | ||
} | ||
EOF | ||
done | ||
extra="$(tests.nested get extra-snaps-path)" | ||
tests.nested prepare-essential-snaps | ||
# Now we want to start with the old snap for snapd, and keep the | ||
# prepared snap (containing new code), for the new model | ||
mv "${extra}"/snapd_*.snap snapd_new.snap | ||
snap download snapd --revision="${OLD_SNAPD_REVISION}" --basename=snapd_old | ||
unsquashfs -d snapd_old snapd_old.snap | ||
rm -rf snapd_old.snap | ||
git clone https://github.com/canonical/snapd.git snapd_old_source | ||
git -C snapd_old_source checkout "${OLD_SNAPD_COMMIT}" | ||
pushd snapd_old_source | ||
./get-deps.sh --skip-unused-check | ||
./mkversion.sh "2.63" | ||
CGO_ENABLED=1 go build -mod=vendor -tags withtestkeys -o ../snapd_old/usr/lib/snapd/snapd github.com/snapcore/snapd/cmd/snapd | ||
popd | ||
rm -rf snapd_old_source | ||
snap pack snapd_old --filename="${extra}/snapd_old.snap" | ||
rm -rf snapd_old | ||
# We need to set the serial to match fakedevicesvc | ||
unsquashfs -d pc "${extra}"/pc.snap | ||
rm -f "${extra}"/pc.snap | ||
install -Dm755 -t pc/meta/hooks prepare-device | ||
echo 7777 >pc/serial | ||
snap pack pc --filename="${extra}"/pc.snap | ||
rm -rf pc | ||
unsquashfs -d core "${extra}/${core_name}.snap" | ||
rm "${extra}/${core_name}.snap" | ||
mkdir -p core/usr/lib/systemd/system.conf.d | ||
cat <<EOF >core/usr/lib/systemd/system.conf.d/50-fakestore.conf | ||
[Manager] | ||
DefaultEnvironment=SNAPPY_FORCE_API_URL=${REMOTE_SAS_URL} SNAPPY_FORCE_SAS_URL=${REMOTE_SAS_URL} | ||
EOF | ||
snap pack core --filename="${extra}/${core_name}.snap" | ||
rm -rf core | ||
add_to_channel() { | ||
FILENAME=$1 | ||
CHANNEL=$2 | ||
SUM="$(snap info --verbose "$(realpath "${FILENAME}")" | sed '/^sha3-384: */{;s///;q;};d')" | ||
mkdir -p "${NESTED_FAKESTORE_BLOB_DIR}/channels" | ||
echo "${CHANNEL}" >"${NESTED_FAKESTORE_BLOB_DIR}/channels/${SUM}" | ||
} | ||
"${TESTSTOOLS}/store-state" make-snap-installable --noack --revision 1 "${NESTED_FAKESTORE_BLOB_DIR}" "${extra}/pc.snap" "UqFziVZDHLSyO3TqSWgNBoAdHbLI4dAH" | ||
add_to_channel "${extra}/pc.snap" "${VERSION}/edge" | ||
"${TESTSTOOLS}/store-state" make-snap-installable --noack --revision 1 "${NESTED_FAKESTORE_BLOB_DIR}" "${extra}/pc-kernel.snap" "pYVQrBcKmBa0mZ4CCN7ExT6jH8rY1hza" | ||
add_to_channel "${extra}/pc-kernel.snap" "${VERSION}/edge" | ||
"${TESTSTOOLS}/store-state" make-snap-installable --noack --revision 1 "${NESTED_FAKESTORE_BLOB_DIR}" "${extra}/${core_name}.snap" "${core_id}" | ||
add_to_channel "${extra}/${core_name}.snap" "${VERSION}/edge" | ||
"${TESTSTOOLS}/store-state" make-snap-installable --noack --revision 1 "${NESTED_FAKESTORE_BLOB_DIR}" "${extra}/snapd_old.snap" "PMrrV4ml8uWuEUDBT8dSGnKUYbevVhc4" | ||
add_to_channel "${extra}/snapd_old.snap" "old/edge" | ||
"${TESTSTOOLS}/store-state" make-snap-installable --noack --revision 2 "${NESTED_FAKESTORE_BLOB_DIR}" "snapd_new.snap" "PMrrV4ml8uWuEUDBT8dSGnKUYbevVhc4" | ||
add_to_channel "snapd_new.snap" "new/edge" | ||
systemd-run --collect --unit fakedevicesvc fakedevicesvc localhost:11029 | ||
NESTED_BUILD_SNAPD_FROM_CURRENT=false tests.nested build-image core | ||
tests.nested create-vm core | ||
restore: | | ||
systemctl stop fakedevicesvc || true | ||
"${TESTSTOOLS}/store-state" teardown-fake-store "${NESTED_FAKESTORE_BLOB_DIR}" || true | ||
rm -f model-{old,new}.model snapd_{old,new}.snap | ||
rm -rf pc core snapd_old_source snapd_old | ||
execute: | | ||
remote.exec "snap model --assertion" | MATCH '^model: update-snapd-seed-and-factory-reset-old$' | ||
remote.exec "snap version" | MATCH "^snapd *2.63$" | ||
remote.push model-new.model | ||
boot_id="$(tests.nested boot-id)" | ||
change_id="$(remote.exec sudo snap remodel --no-wait model-new.model)" | ||
remote.wait-for reboot "${boot_id}" | ||
retry -n 100 --wait 5 sh -c "remote.exec sudo snap changes | MATCH '^${change_id}\s+(Done|Undone|Error)'" | ||
remote.exec "sudo snap changes" | MATCH "^${change_id}\s+Done" | ||
remote.exec "snap model --assertion" | MATCH '^model: update-snapd-seed-and-factory-reset-new$' | ||
remote.exec "snap model --assertion" | NOMATCH '^model: update-snapd-seed-and-factory-reset-old$' | ||
remote.exec "snap version" | NOMATCH "^snapd *2.63$" | ||
boot_id="$(tests.nested boot-id)" | ||
remote.exec "sudo snap reboot --factory-reset" || true | ||
remote.wait-for reboot "${boot_id}" | ||
remote.exec "snap model --assertion" | MATCH '^model: update-snapd-seed-and-factory-reset-new$' | ||
remote.exec "snap model --assertion" | NOMATCH '^model: update-snapd-seed-and-factory-reset-old$' | ||
remote.exec "snap version" | NOMATCH "^snapd *2.63$" | ||
remote.exec "sudo cryptsetup luksDump /dev/disk/by-partlabel/ubuntu-save --dump-json-metadata" | python3 find-orphan-keys.py | ||
remote.exec "sudo cryptsetup luksDump /dev/disk/by-partlabel/ubuntu-data --dump-json-metadata" | python3 find-orphan-keys.py |