1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
summary: |
Ensure `snap validate --enforce` works with validation-sets from the store.
details: |
A validation set is an assertion that lists specific snaps that are either
required to be installed together or are permitted to be installed together
on a device or system.
When enforcing a validation set, snapd will ensure that:
1. Snaps required by a validation set are both present and, if specified,
at the correct revision.
2. Snaps are only refreshed to newer revisions if they continue to satisfy
whatever validation sets are in use.
3. Invalid snaps are not allowed to be installed. Attempting to install them
will result in an error.
Enforcing can be disabled for select validation sets with the
`snap validate --forget` command.
This test verifies that setting validation set in enforce mode fails when snap
is not installed. Then, once the validation set is enforced, it checks that
the validation set is listed and an invalid snap cannot be installed, but it can
be installed with --ignore-validation flag. It also verifies that a snap cannot
be removed when required until the validation set is forgotten.
Finally, it validates that a snap can be refreshed to a newer revision and
the validation set status remains valid.
# This test uses validation set assertions from the store uploaded upfront
# with my (stolowski) private store key (account-id: xSfWKGdLoQBoQx88vIM1MpbFNMq53t1f,
# public-key-sha3: o_x83A3wpIvJznIHBJIK7jRmRZKLlqx5jOr30HUsloFfBseXNF0ztoj18EvNualy);
# the input assertion provided with the test is testenforce1-seq1.yaml and testenforce1-seq2.yaml;
# they are included for reference and in case this needs to be recreated with another
# developer account, but otherwise are not used in the test.
#
# If this needs to be redone with another developer account, the steps are:
# 1. update account-id in the testenforce-*.yaml files for the developer to use.
# 2. upload validation-set assertions to the store (repeat for sequence 1 and sequence 2,
# paste respective testenforceX-seqN.yaml file when snapcraft opens up the editor):
# snapcraft edit-validation-sets <account-id> testenforce1 1
# snapcraft edit-validation-sets <account-id> testenforce1 2
# snapcraft edit-validation-sets <account-id> testenforce2 1
# 3. change account-ids in the test with the desired developer key
environment:
ACCOUNT_ID: xSfWKGdLoQBoQx88vIM1MpbFNMq53t1f
restore: |
snap validate --forget "$ACCOUNT_ID"/testenforce1 || true
snap validate --forget "$ACCOUNT_ID"/testenforce2 || true
execute: |
echo "Setting validation set in enforce mode fails when snap is not installed"
if snap validate --enforce "$ACCOUNT_ID"/testenforce1 > log.txt 2>&1; then
echo "Expected snap validate to fail"
exit 1
fi
MATCH "error: cannot apply validation set: cannot enforce validation set: validation sets assertions are not met:" < log.txt
MATCH "missing required snaps:" < log.txt
MATCH "test-snapd-validation-set-enforcing \(required at any revision by sets xSfWKGdLoQBoQx88vIM1MpbFNMq53t1f/testenforce1\)" < log.txt
echo "Install the required snap and enable enforcing mode, pinned at sequence point 1"
snap install --beta test-snapd-validation-set-enforcing
snap validate --enforce "$ACCOUNT_ID"/testenforce1=1
echo "Check that the validation set is listed and enforced"
snap validate | MATCH "^$ACCOUNT_ID/testenforce1=1 +enforce +1 +valid"
snap list | MATCH "test-snapd-validation-set-enforcing +1\.0\.0 +1 +latest/beta"
echo "Check that an invalid snap cannot be installed"
if snap install hello-world > log.txt 2>&1; then
echo "Expected snap install to fail"
exit 1
fi
"$TESTSTOOLS"/to-one-line "$(cat log.txt)" | MATCH "error: cannot install \"hello-world\": cannot install snap \"hello-world\" due to enforcing rules of validation set 16/$ACCOUNT_ID/testenforce1/1"
echo "But it can be installed with --ignore-validation flag"
snap install --ignore-validation hello-world
snap validate | MATCH "^$ACCOUNT_ID/testenforce1=1 +enforce +1 +invalid"
snap remove --purge hello-world
echo "Snap cannot be removed when required"
if snap remove test-snapd-validation-set-enforcing > log.txt 2>&1; then
echo "Expected snap remove to fail"
exit 1
fi
MATCH 'error: cannot remove "test-snapd-validation-set-enforcing": snap' < log.txt
MATCH '"test-snapd-validation-set-enforcing" is not removable: snap' < log.txt
MATCH '"test-snapd-validation-set-enforcing" is required by validation sets:' < log.txt
MATCH "16/$ACCOUNT_ID/testenforce1/1" < log.txt
echo "Refresh the snap from edge channel (while the validation set is pinned)"
snap switch --edge test-snapd-validation-set-enforcing
snap refresh
snap validate | MATCH "^$ACCOUNT_ID/testenforce1=1 +enforce +1 +valid"
snap list | MATCH "test-snapd-validation-set-enforcing +2\.0\.0 +2 +latest/edge"
echo "And snap can be removed once validation set is forgotten"
snap validate --forget "$ACCOUNT_ID"/testenforce1
snap remove --purge test-snapd-validation-set-enforcing
echo "Use two validation sets, one requiring specific snap revision, no pinning"
snap install --edge test-snapd-validation-set-enforcing
snap validate --enforce "$ACCOUNT_ID"/testenforce1
snap validate --enforce "$ACCOUNT_ID"/testenforce2
# testenforce1 is at seq 2 since it wasn't pinned
snap validate | MATCH "^$ACCOUNT_ID/testenforce1 +enforce +2 +valid"
snap validate | MATCH "^$ACCOUNT_ID/testenforce2 +enforce +1 +valid"
snap list | MATCH "test-snapd-validation-set-enforcing +2\.0\.0 +2 +latest/edge"
echo "Check that enforcing can be updated to pin and un-pin and pin at a different sequence"
snap validate --enforce "$ACCOUNT_ID"/testenforce1=1
snap validate | MATCH "^$ACCOUNT_ID/testenforce1=1 +enforce +1 +valid"
snap validate --enforce "$ACCOUNT_ID"/testenforce1
snap validate | MATCH "^$ACCOUNT_ID/testenforce1 +enforce +2 +valid"
snap validate --enforce "$ACCOUNT_ID"/testenforce1=2
snap validate | MATCH "^$ACCOUNT_ID/testenforce1=2 +enforce +2 +valid"
snap validate --enforce "$ACCOUNT_ID"/testenforce1=1
snap validate | MATCH "^$ACCOUNT_ID/testenforce1=1 +enforce +1 +valid"
snap validate --enforce "$ACCOUNT_ID"/testenforce1=3 2>&1 | MATCH "error: cannot find validation set assertion: validation-set \(3; series:16 account-id:$ACCOUNT_ID name:testenforce1\) not found"
snap validate | MATCH "^$ACCOUNT_ID/testenforce1=1 +enforce +1 +valid"
|