File: snaps-state

package info (click to toggle)
snapd 2.72-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 80,412 kB
  • sloc: sh: 16,506; ansic: 16,211; python: 11,213; makefile: 1,919; exp: 190; awk: 58; xml: 22
file content (255 lines) | stat: -rwxr-xr-x 7,925 bytes parent folder | download
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 "$@"