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 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
|
summary: Check that the basic snapshots functionality is ok
details: |
A snapshot is a copy of the user, system and configuration data stored
by snapd for one or more snaps on your system. This data can be found
in $HOME/snap/<snap-name> and /var/snap/<snap-name>.
Snapshots are generated manually with the snap save command and
automatically when a snap is removed (unless --purge is used with
remove, in which case no snapshot is created).
Having few snaps installed in the system, this test checks that
`snap save` command shows the created snapshots for the snaps. Then it runs
`snap check-snapshot` to check the snapshot created for the snaps are
valid. Finally, it verifies that the snapshots can be exported and restored
(the data is restored properly) and removed by running `snap forget` command.
environment:
# tar invoked when creating snapshots triggers OOM
SNAPD_NO_MEMORY_LIMIT: 1
prepare: |
snap install test-snapd-sh
snap install --edge test-snapd-just-edge
snap install --edge test-snapd-tools
restore: |
rm -f /var/snap/test-snapd-tools/common/huge
debug: |
snap list || true
snap info core || true
snap saved || true
execute: |
# use the snaps, so they create the dirs:
test-snapd-sh.sh -c 'true'
test-snapd-just-edge.snap-name >/dev/null
# drop in canaries:
for snap in test-snapd-sh test-snapd-just-edge; do
echo "hello versioned $snap" > ~/snap/$snap/current/canary.txt
echo "hello common $snap" > ~/snap/$snap/common/canary.txt
done
# create snapshot, grab its ID
SET_ID=$( snap save test-snapd-sh test-snapd-just-edge | cut -d\ -f1 | tail -n1 )
# check it includes both snaps
snap saved | MATCH test-snapd-sh
snap saved | MATCH test-snapd-just-edge
snap saved --id="$SET_ID" | grep test-snapd-sh
snap saved --id="$SET_ID" | grep test-snapd-just-edge
# and is valid
snap check-snapshot "$SET_ID"
# and is exportable
snap export-snapshot "$SET_ID" "${SET_ID}_export.snapshot"
test -e "${SET_ID}_export.snapshot"
test "$( tar -tvf "${SET_ID}_export.snapshot" | wc -l )" = "4"
# do it again and ensure it has the files have the same size
snap export-snapshot "$SET_ID" "${SET_ID}_export-2.snapshot"
test "$( tar -tvf "${SET_ID}_export-2.snapshot" | wc -l )" = "4"
s1="$(stat -c%s "${SET_ID}_export.snapshot" )"
s2="$(stat -c%s "${SET_ID}_export-2.snapshot" )"
test "$s1" = "$s2"
echo "and the same files are snapshoted"
f1="$(tar -tf "${SET_ID}_export.snapshot" )"
f2="$(tar -tf "${SET_ID}_export-2.snapshot" )"
test "$f1" = "$f2"
# remove the canaries
rm ~/snap/*/{current,common}/canary.txt
# restore one of them
snap restore "$SET_ID" test-snapd-sh
test -e ~/snap/test-snapd-sh/current/canary.txt
test -e ~/snap/test-snapd-sh/common/canary.txt
# it didn't restore the other one
test ! -e ~/snap/test-snapd-just-edge/current/canary.txt
test ! -e ~/snap/test-snapd-just-edge/common/canary.txt
# restore the other
snap restore "$SET_ID" test-snapd-just-edge
# now check everything's as we expect
for snap in test-snapd-sh test-snapd-just-edge; do
test "$( cat ~/snap/$snap/current/canary.txt )" = "hello versioned $snap"
test "$( cat ~/snap/$snap/common/canary.txt )" = "hello common $snap"
done
# check removal works
snap forget "$SET_ID"
snap saved --id="$SET_ID" | grep "No snapshots found"
echo "Check import fails if snapshot contains invalid filenames"
# trusty (14.04) relpath does not support --relative-to
if ! os.query is-trusty; then
fname=$(mktemp /tmp/1_XXXX)
relpath=$(realpath --relative-to="$(pwd)" "$fname")
cp "${SET_ID}_export.snapshot" "${SET_ID}_export.snapshot.invalid"
tar --update -f "${SET_ID}_export.snapshot.invalid" -P "$relpath"
# remove the file so we can check that the file does not get created when
# snapshot import fails
rm "$fname"
snap import-snapshot "${SET_ID}_export.snapshot.invalid" && exit 1
test ! -e "$fname"
rm "${SET_ID}_export.snapshot.invalid"
fi
echo "Check that import works"
RESTORE_ID=$( snap import-snapshot "${SET_ID}_export.snapshot" | head -n1 | cut -f2 -d'#' )
echo "And is valid"
snap check-snapshot "$RESTORE_ID"
NUM_SAVED=$(snap saved | wc -l)
echo "Import again doesn't create a duplicated snapshot"
IMPORTED_ID=$( snap import-snapshot "${SET_ID}_export-2.snapshot" | head -n1 | cut -f2 -d'#' )
[[ "$RESTORE_ID" == "$IMPORTED_ID" ]]
[[ "$NUM_SAVED" == $(snap saved | wc -l) ]]
snap forget "$RESTORE_ID"
echo "Import re-creates snapshots directory if misssing"
# precondition check
test -d /var/lib/snapd/snapshots
rm -rf /var/lib/snapd/snapshots
RESTORE_ID=$( snap import-snapshot "${SET_ID}_export.snapshot" | head -n1 | cut -f2 -d'#' )
# remove the exports and import
rm "${SET_ID}"_export*.snapshot
snap forget "$RESTORE_ID"
# check automatic snapshot can be disabled
snap set core snapshots.automatic.retention=no
snap remove test-snapd-sh
if snap saved | MATCH "test-snapd-sh"; then
echo "did not expect a snapshot for test-snapd-sh"
exit 1
fi
# re-enable snapshots, check automatic snapshot is created on snap remove
snap install test-snapd-sh
snap set core snapshots.automatic.retention=30h
snap remove test-snapd-sh
snap saved test-snapd-sh | MATCH "auto"
SET_ID=$( snap saved test-snapd-sh | cut -d\ -f1 | tail -n1 )
snap forget "$SET_ID"
# removing with --purge doesn't create automatic snapshot
snap set core snapshots.automatic.retention=30h
snap install test-snapd-sh
snap remove --purge test-snapd-sh
if snap saved test-snapd-sh | MATCH "auto" ; then
echo "automatic snapshot is not expected"
exit 1
fi
# check validation of the automatic snapshot expiration range
(snap set core snapshots.automatic.retention=1s 2>&1 || true) | MATCH "must be"
# check that expiration can be read back
snap get core snapshots.automatic.retention | MATCH "30h"
snap get core -d snapshots.automatic | MATCH '"retention"'
# check memory usage for larger snap snapshot data exporting
mkdir -p /var/snap/test-snapd-tools/common/
dd if=/dev/urandom of=/var/snap/test-snapd-tools/common/huge bs=1M count=100
# create snapshot, grab its ID
SET_ID=$( snap save test-snapd-tools | cut -d\ -f1 | tail -n1 )
snap saved --id="$SET_ID" | grep test-snapd-tools
snap check-snapshot "$SET_ID"
# export the large snap and record memory usage
"$TESTSTOOLS"/memory-observe-do -o memory-kb.txt snap export-snapshot \
"$SET_ID" "${SET_ID}_export.snapshot"
test -e "${SET_ID}_export.snapshot"
# Ensure our snapshot export file is at least 50MB. The data we created
# is 100MB of randomness so even with amazing compression we should never
# have a smaller file
test "$(stat -c%s "${SET_ID}_export.snapshot")" -gt 50000000
# the io.Copy uses a 32k buffer, so extra memory usage should be limited.
# The threshold in this test is set to about 40MB
test "$(cat memory-kb.txt)" -lt 40000
# check that snapshot set id from the filename has authority
snap install test-snapd-sh
snap save test-snapd-sh
SNAPSHOT_FILE=$(ls /var/lib/snapd/snapshots/*test-snapd-sh*.zip)
NEWSNAPSHOT_FILE=$(echo "$SNAPSHOT_FILE" | sed -e's/[1-9]\+_/123_/')
# rename the snapshot file to force a new set id.
mv "$SNAPSHOT_FILE" "$NEWSNAPSHOT_FILE"
snap saved | MATCH "123 +test-snapd-sh"
# make sure there is just one such snapshot
[[ $(snap saved | grep -c test-snapd-sh) == "1" ]]
snap saved --id=123 | MATCH "123 .+test-snapd-sh"
snap restore 123 test-snapd-sh
# snap configuration should work after restoring snapshots that didn't
# have config (LP #1917870).
"$TESTSTOOLS"/snaps-state install-local test-snap
SET_ID=$( snap save test-snap | cut -d\ -f1 | tail -n1 )
snap restore "$SET_ID"
snap set test-snap foo=baz
snap get test-snap foo | MATCH "baz"
|