aboutsummaryrefslogtreecommitdiff
path: root/test/system/120-load.bats
blob: f5ba93d8af80fd733597b7500e0aa35281f059c3 (plain)
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
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
#!/usr/bin/env bats   -*- bats -*-
#
# tests for podman load
#

load helpers

# Custom helpers for this test only. These just save us having to duplicate
# the same thing four times (two tests, each with -i and stdin).
#
# initialize, read image ID and name
get_iid_and_name() {
    run_podman images -a --format '{{.ID}} {{.Repository}}:{{.Tag}}'
    read iid img_name <<<"$output"

    archive=$PODMAN_TMPDIR/myimage-$(random_string 8).tar
}

# Simple verification of image ID and name
verify_iid_and_name() {
    run_podman images -a --format '{{.ID}} {{.Repository}}:{{.Tag}}'
    read new_iid new_img_name < <(echo "$output")

    # Verify
    is "$new_iid"      "$iid" "Image ID of loaded image == original"
    is "$new_img_name" "$1"   "Name & tag of restored image"
}

@test "podman load invalid file" {
    # Regression test for #9672 to make sure invalid input yields errors.
    invalid=$PODMAN_TMPDIR/invalid
    echo "I am an invalid file and should cause a podman-load error" > $invalid
    run_podman 125 load -i $invalid
    # podman and podman-remote emit different messages; this is a common string
    is "$output" ".*payload does not match any of the supported image formats:.*" \
       "load -i INVALID fails with expected diagnostic"
}

@test "podman save to pipe and load" {
    # Generate a random name and tag (must be lower-case)
    local random_name=x0$(random_string 12 | tr A-Z a-z)
    local random_tag=t0$(random_string 7 | tr A-Z a-z)
    local fqin=localhost/$random_name:$random_tag
    run_podman tag $IMAGE $fqin

    # Believe it or not, 'podman load' would barf if any path element
    # included a capital letter
    archive=$PODMAN_TMPDIR/MySubDirWithCaps/MyImage-$(random_string 8).tar
    mkdir -p $(dirname $archive)

    # We can't use run_podman because that uses the BATS 'run' function
    # which redirects stdout and stderr. Here we need to guarantee
    # that podman's stdout is a pipe, not any other form of redirection
    $PODMAN save --format oci-archive $fqin | cat >$archive
    if [ "$status" -ne 0 ]; then
        die "Command failed: podman save ... | cat"
    fi

    # Make sure we can reload it
    run_podman rmi $fqin
    run_podman load -i $archive

    # FIXME: cannot compare IID, see #7371, so we check only the tag
    run_podman images $fqin --format '{{.Repository}}:{{.Tag}}'
    is "${lines[0]}" "$fqin" "image preserves name across save/load"

    # Load with a new tag
    local new_name=x1$(random_string 14 | tr A-Z a-z)
    local new_tag=t1$(random_string 6 | tr A-Z a-z)
    run_podman rmi $fqin

    run_podman load -i $archive
    run_podman images --format '{{.Repository}}:{{.Tag}}' --sort tag
    is "${lines[0]}" "$IMAGE"     "image is preserved"
    is "${lines[1]}" "$fqin"      "image is reloaded with old fqin"

    # Clean up
    run_podman rmi $fqin
}

@test "podman image scp transfer" {
    skip_if_remote "only applicable under local podman"
    if is_ubuntu; then
        skip "I don't have time to deal with this"
    fi

    # The testing is the same whether we're root or rootless; all that
    # differs is the destination (not-me) username.
    if is_rootless; then
        # Simple: push to root.
        whoami=$(id -un)
        notme=root
        _sudo() { command sudo -n "$@"; }
    else
        # Harder: our CI infrastructure needs to define this & set up the acct
        whoami=root
        notme=${PODMAN_ROOTLESS_USER}
        if [[ -z "$notme" ]]; then
            skip "To run this test, set PODMAN_ROOTLESS_USER to a safe username"
        fi
        _sudo() { command sudo -n -u "$notme" "$@"; }
    fi

    # If we can't sudo, we can't test.
    _sudo true || skip "cannot sudo to $notme"

    # FIXME FIXME FIXME: it'd be reeeeeeally nice if we could pass --root
    #                    to the non-self user, hence avoid vandalizing
    #                    their storage.

    # Preserve digest of original image; we will compare against it later
    run_podman image inspect --format '{{.Digest}}' $IMAGE
    src_digest=$output

    # image name that is not likely to exist in the destination
    newname=foo.bar/nonesuch/c_$(random_string 10 | tr A-Z a-z):mytag
    run_podman tag $IMAGE $newname

    # Copy it there.
    # FIXME: the first '.*' in the expect string below is unfortunate; it's
    #        a workaround for Ubuntu which gripes:
    #        "warning.*defaulting to su since machinectl is not available"
    #        Reexamine this once #12829 is fixed
    run_podman image scp $newname ${notme}@localhost::
    is "$output" ".*Copying blob .*Copying config.*Writing manifest.*Storing signatures"

    # confirm that image was copied. FIXME: also try $PODMAN image inspect?
    _sudo $PODMAN image exists $newname

    # Copy it back, this time using -q
    run_podman untag $IMAGE $newname
    run_podman image scp -q ${notme}@localhost::$newname

    expect="Loaded image(s): $newname"
    # FIXME FIXME FIXME: ubuntu has no machinectl, emits useless warning message instead
    if ! is_rootless; then
        # FIXME: root on fedora uses machinectl, which emits useless \n and \r (#12829)
        NL=$'\n'
        CR=$'\r'
        expect="$NL$expect$CR"
    fi
    is "$output" "$expect" "-q silences output"

    # Confirm that we have it, and that its digest matches our original
    run_podman image inspect --format '{{.Digest}}' $newname
    is "$output" "$src_digest" "Digest of re-fetched image matches original"

    # Clean up
    _sudo $PODMAN image rm $newname
    run_podman untag $IMAGE $newname

    # Negative test for nonexistent image.
    # FIXME FIXME: cannot test on root, because it uses machinectl (#12829)
    if is_rootless; then
        # FIXME: error message is 2 lines, the 2nd being "exit status 125".
        # FIXME: is that fixable, or do we have to live with it?
        nope="nope.nope/nonesuch:notag"
        run_podman 125 image scp ${notme}@localhost::$nope
        is "$output" "Error: $nope: image not known.*" "Pulling nonexistent image"

        run_podman 125 image scp $nope ${notme}@localhost::
        is "$output" "Error: $nope: image not known.*" "Pushing nonexistent image"
    fi

    # Negative test for copying to a different name
    run_podman 125 image scp $IMAGE ${notme}@localhost::newname:newtag
    is "$output" "Error: cannot specify an image rename: invalid argument" \
       "Pushing with a different name: not allowed"

    # FIXME: any point in copying by image ID? What else should we test?
}


@test "podman load - by image ID" {
    # FIXME: how to build a simple archive instead?
    get_iid_and_name

    # Save image by ID, and remove it.
    run_podman save $iid -o $archive
    run_podman rmi $iid

    # Load using -i; IID should be preserved, but name is not.
    run_podman load -i $archive
    verify_iid_and_name "<none>:<none>"

    # Same as above, using stdin
    run_podman rmi $iid
    run_podman load < $archive
    verify_iid_and_name "<none>:<none>"

    # Same as above, using stdin but with `podman image load`
    run_podman rmi $iid
    run_podman image load < $archive
    verify_iid_and_name "<none>:<none>"

    # Cleanup: since load-by-iid doesn't preserve name, re-tag it;
    # otherwise our global teardown will rmi and re-pull our standard image.
    run_podman tag $iid $img_name
}

@test "podman load - by image name" {
    get_iid_and_name
    run_podman save $img_name -o $archive
    run_podman rmi $iid

    # Load using -i; this time the image should be tagged.
    run_podman load -i $archive
    verify_iid_and_name $img_name
    run_podman rmi $iid

    # Also make sure that `image load` behaves the same.
    run_podman image load -i $archive
    verify_iid_and_name $img_name
    run_podman rmi $iid

    # Same as above, using stdin
    run_podman load < $archive
    verify_iid_and_name $img_name
}

@test "podman load - from URL" {
    get_iid_and_name
    run_podman save $img_name -o $archive
    run_podman rmi $iid

    HOST_PORT=$(random_free_port)
    SERVER=http://127.0.0.1:$HOST_PORT

    # Bind-mount the archive to a container running httpd
    run_podman run -d --name myweb -p "$HOST_PORT:80" \
            -v $archive:/var/www/image.tar:Z \
            -w /var/www \
            $IMAGE /bin/busybox-extras httpd -f -p 80

    run_podman load -i $SERVER/image.tar
    verify_iid_and_name $img_name

    run_podman rm -f -t0 myweb
}

@test "podman load - redirect corrupt payload" {
    run_podman 125 load <<< "Danger, Will Robinson!! This is a corrupt tarball!"
    is "$output" \
        ".*payload does not match any of the supported image formats:.*" \
        "Diagnostic from 'podman load' unknown/corrupt payload"
}

@test "podman load - multi-image archive" {
    # img1 & 2 should be images that are not locally present; they must also
    # be usable on the host arch. The nonlocal image (:000000xx) is kept
    # up-to-date for all RHEL/Fedora arches; the other image we use is
    # the one tagged ':multiimage', which as of 2021-07-15 is :20210610
    # but that tag will grow stale over time. If/when this test fails,
    # your first approach should be to manually update :multiimage to
    # point to a more recent testimage. (Use the quay.io GUI, it's waaay
    # easier than pulling/pushing the correct manifest.)
    img1=${PODMAN_NONLOCAL_IMAGE_FQN}
    img2="$PODMAN_TEST_IMAGE_REGISTRY/$PODMAN_TEST_IMAGE_USER/$PODMAN_TEST_IMAGE_NAME:multiimage"
    archive=$PODMAN_TMPDIR/myimage-$(random_string 8).tar

    run_podman pull $img1
    run_podman pull $img2

    run_podman save -m -o $archive $img1 $img2
    run_podman rmi -f $img1 $img2
    run_podman load -i $archive

    run_podman image exists $img1
    run_podman image exists $img2
    run_podman rmi -f $img1 $img2
}

@test "podman load - multi-image archive with redirect" {
    # (see comments in test above re: img1 & 2)
    img1=${PODMAN_NONLOCAL_IMAGE_FQN}
    img2="$PODMAN_TEST_IMAGE_REGISTRY/$PODMAN_TEST_IMAGE_USER/$PODMAN_TEST_IMAGE_NAME:multiimage"
    archive=$PODMAN_TMPDIR/myimage-$(random_string 8).tar

    run_podman pull $img1
    run_podman pull $img2

    # We can't use run_podman because that uses the BATS 'run' function
    # which redirects stdout and stderr. Here we need to guarantee
    # that podman's stdout is a pipe, not any other form of redirection
    $PODMAN save -m $img1 $img2 | cat >$archive
    if [ "$status" -ne 0 ]; then
        die "Command failed: podman save ... | cat"
    fi

    run_podman rmi -f $img1 $img2
    run_podman load -i $archive

    run_podman image exists $img1
    run_podman image exists $img2
    run_podman rmi -f $img1 $img2
}

@test "podman save --oci-accept-uncompressed-layers" {
    archive=$PODMAN_TMPDIR/myimage-$(random_string 8).tar
    untar=$PODMAN_TMPDIR/myuntar-$(random_string 8)
    mkdir -p $untar

    # Create a tarball, unpack it and make sure the layers are uncompressed.
    run_podman save -o $archive --format oci-archive --uncompressed $IMAGE
    run tar -C $untar -xvf $archive
    run file $untar/blobs/sha256/*
    is "$output" ".*POSIX tar archive" "layers are uncompressed"
}

# vim: filetype=sh