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 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
|
#!/bin/bash -e
show_help() {
echo "usage: pack-local <snap-name>"
echo " install-local <snap-name> [OPTIONS]"
echo " install-local-as <snap-name> <dest-name> [OPTIONS]"
echo " install-local-variant <snap-dir-base> <snap-name> [OPTIONS]"
echo " show-name <snap>"
echo " show-revision <snap>"
echo " is-confinement-supported <classic|devmode|strict>"
echo " repack-snapd-deb-into-snap <snapd|core>"
echo " repack-core-snap-into-snapd-snap"
echo ""
echo "Available options:"
echo " --devmode --jailmode --classic"
echo "Supported names:"
echo " core kernel gadget"
echo ""
echo "Pack and install commands save the packed snap for future uses,"
echo "which is reused on the following calls."
echo "The paths for locating the sources of the snaps to either pack or"
echo "install are the local path and then 'tests/lib/snaps/'"
}
pack_local() {
local SNAP_NAME="$1"
local SNAP_DIR="${2:-$TESTSLIB/snaps/${SNAP_NAME}}"
local SNAP_VERSION="${3:-1.0}"
# Use local snap in case it exists
if [ -d "$SNAP_NAME" ]; then
SNAP_DIR="$PWD/$SNAP_NAME"
fi
if [ ! -d "$SNAP_DIR" ]; then
echo "snaps-state: can't pack $SNAP_NAME, snap directory not found"
exit 1
fi
local META_FILE META_NAME SNAP_FILE
META_FILE="$SNAP_DIR/meta/snap.yaml"
if [ ! -f "$META_FILE" ]; then
echo "snap.yaml file not found for $SNAP_NAME snap"
return 1
fi
META_NAME="$(grep '^name:' "$META_FILE" | awk '{ print $2 }' | tr -d ' ')"
SNAP_FILE="${SNAP_DIR}/${META_NAME}_${SNAP_VERSION}_all.snap"
# assigned in a separate step to avoid hiding a failure
if [ ! -f "$SNAP_FILE" ]; then
snap pack "$SNAP_DIR" "$SNAP_DIR" >/dev/null
fi
# echo the snap name
if [ -f "$SNAP_FILE" ]; then
echo "$SNAP_FILE"
else
find "$SNAP_DIR" -name "${META_NAME}_*.snap"| head -n1
fi
}
install_local() {
local SNAP_NAME="$1"
local SNAP_DIR="$TESTSLIB/snaps/${SNAP_NAME}"
shift
if [ -d "$SNAP_NAME" ]; then
SNAP_DIR="$PWD/$SNAP_NAME"
fi
SNAP_FILE=$(pack_local "$SNAP_NAME" "$SNAP_DIR")
snap install --dangerous "$@" "$SNAP_FILE"
}
install_local_as() {
local snap="$1"
local name="$2"
shift 2
install_local "$snap" --name "$name" "$@"
}
install_local_variant() {
local SNAP_DIR_BASE="$1"
local SNAP_NAME="$2"
local SNAP_DIR="$TESTSLIB/snaps/$SNAP_DIR_BASE"
shift 2
if [ -d "$SNAP_DIR_BASE" ]; then
SNAP_DIR="$PWD/$SNAP_DIR_BASE"
fi
SNAP_FILE=$(pack_local "$SNAP_NAME" "$SNAP_DIR")
snap install --dangerous "$@" "$SNAP_FILE"
}
show_name() {
case "${1:-}" in
core)
local core_name
core_name="$(snap model --verbose | grep -Po "^base:\\s+\\K.*" || true)"
if [ -z "$core_name" ]; then
core_name="core"
fi
echo "$core_name"
;;
kernel)
snap list | grep 'kernel$' | awk '{ print $1 }'
;;
gadget)
snap list | grep 'gadget$' | awk '{ print $1 }'
;;
*)
echo "snaps-state: unsupported snap $1" >&2
show_help
exit 1
;;
esac
}
show_revision() {
local snap="$1"
if not snap list "$snap" &>/dev/null; then
echo "snaps-state: the snap $snap is not installed" >&2
exit 1
fi
snap info "$snap" | awk "/installed: / {print(\$3)}" | sed -e 's/(\(.*\))/\1/'
}
is_confinement_supported() {
local confinement="$1"
if [ -z "$confinement" ]; then
echo "snaps-state: a confinement is required"
show_help
exit 1
fi
snap debug sandbox-features --required=confinement-options:"$confinement"
}
# The function will re-pack either core or snapd snap using the assets
# from the snapd deb installed on the system
repack_snapd_deb_into_snap() {
local snap_name="$1"
local target_dir="${2:-$PWD}"
local deb_file="${3:-$(ls "$GOHOME"/snapd_*.deb)}"
if [ ! -e "$deb_file" ]; then
echo "snaps-state: deb file used to repack not found: $deb_file"
exit 1
fi
case "$snap_name" in
core)
# use snapd from edge as a recent snap that should be close to what we will
# have in the snapd deb
snap download core --basename=core --edge
unsquashfs -d ./core-unpacked core.snap
rm core.snap
# extract all the files from the snapd deb
dpkg-deb -x "$deb_file" ./core-unpacked
# repack into the target dir specified
snap pack --filename=core-from-snapd-deb.snap core-unpacked "$target_dir"
# cleanup
rm -rf core-unpacked
;;
*)
echo "snaps-state: use either core or snapd snaps for repack, snapd $snap_name not supported"
show_help
exit 1
;;
esac
}
# This function will re-pack the current core snap as the snapd snap,
# using the snapd snap from edge as the set of files to use from the core snap.
# This is primarily meant to be used in UC16 tests that need to use the snapd
# snap because neither the snapd snap, nor the snapd deb built for the spread
# run are seeded on the image
# The built snap is located in the current working directory with the
# filename snapd-from-core.snap.
repack_core_snap_into_snapd_snap() {
# FIXME: maybe build the snapd snap from the deb in prepare_ubuntu_core /
# setup_reflash_magic and include it somewhere in the image so we don't need
# to do this hack here?
# get the snap.yaml and a list of all the snapd snap files using edge
# NOTE: this may break if a spread run adds files to the snapd snap that
# don't exist in the snapd snap on edge and those files are necessary
# for snapd to run or revert, etc.
local core_snap current
if [ $# -eq 0 ]; then
current="$(readlink /snap/core/current)"
core_snap="${1:-/var/lib/snapd/snaps/core_"$current".snap}"
else
core_snap=$1
if [ ! -e "$core_snap" ]; then
echo "snaps-state: core snap used to repack not found: $core_snap"
exit 1
fi
fi
snap download snapd --basename=snapd-upstream --edge
unsquashfs -d ./snapd-upstream snapd-upstream.snap
rm snapd-upstream.snap
(
cd snapd-upstream || exit 1
# find all files and symlinks - not directories because when unsquashfs
# is provided a directory it will extract all the files in that directory
find . \( -type l -o -type f \) | cut -c3- > ../files.txt
)
# only unpack files from the core snap that are in the snapd snap - this
# is kosher because the set of files in the core snap is a superset of
# all the files in the snapd snap
#shellcheck disable=2046
unsquashfs -d ./snapd-local "$core_snap" $(cat files.txt)
# replace snap.yaml from the core snap with the snapd snap, and pack the snap
cp snapd-upstream/meta/snap.yaml snapd-local/meta/snap.yaml
snap pack snapd-local --filename=snapd-from-core.snap
# cleanup the snaps we downloaded and built
rm -rf snapd-local snapd-upstream* files.txt
}
main() {
if [ $# -eq 0 ]; then
show_help
exit 0
fi
local subcommand="$1"
local action=
while [ $# -gt 0 ]; do
case "$1" in
-h|--help)
show_help
exit 0
;;
*)
action=$(echo "$subcommand" | tr '-' '_')
shift
break
;;
esac
done
if [ -z "$(declare -f "$action")" ]; then
echo "snaps-state: no such command: $subcommand"
show_help
exit 1
fi
"$action" "$@"
}
main "$@"
|