193 lines
6.3 KiB
Go
193 lines
6.3 KiB
Go
//go:build !remote
|
|
|
|
package libimage
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/containers/common/pkg/config"
|
|
"github.com/containers/image/v5/pkg/compression"
|
|
"github.com/containers/image/v5/types"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestPush(t *testing.T) {
|
|
runtime := testNewRuntime(t)
|
|
ctx := context.Background()
|
|
|
|
// Prefetch alpine.
|
|
pullOptions := &PullOptions{}
|
|
pullOptions.Writer = os.Stdout
|
|
_, err := runtime.Pull(ctx, "quay.io/libpod/alpine:latest", config.PullPolicyAlways, pullOptions)
|
|
require.NoError(t, err)
|
|
|
|
pushOptions := &PushOptions{}
|
|
pushOptions.Writer = os.Stdout
|
|
|
|
workdir := t.TempDir()
|
|
|
|
for _, test := range []struct {
|
|
source string
|
|
destination string
|
|
expectError bool
|
|
}{
|
|
{"alpine", "dir:" + workdir + "/dir", false},
|
|
{"alpine", "oci:" + workdir + "/oci", false},
|
|
{"alpine", "oci-archive:" + workdir + "/oci-archive", false},
|
|
{"alpine", "docker-archive:" + workdir + "/docker-archive", false},
|
|
{"alpine", "containers-storage:localhost/another:alpine", false},
|
|
} {
|
|
_, err := runtime.Push(ctx, test.source, test.destination, pushOptions)
|
|
if test.expectError {
|
|
require.Error(t, err, "%v", test)
|
|
continue
|
|
}
|
|
require.NoError(t, err, "%v", test)
|
|
pulledImages, err := runtime.Pull(ctx, test.destination, config.PullPolicyAlways, pullOptions)
|
|
require.NoError(t, err, "%v", test)
|
|
require.Len(t, pulledImages, 1, "%v", test)
|
|
}
|
|
|
|
// Now there should only be two images: alpine in Docker format and
|
|
// alpine in OCI format.
|
|
listOptions := ListImagesOptions{SetListData: true}
|
|
listedImages, err := runtime.ListImages(ctx, &listOptions)
|
|
require.NoError(t, err, "error listing images")
|
|
require.Len(t, listedImages, 2, "there should only be two images (alpine in Docke/OCI)")
|
|
for _, image := range listedImages {
|
|
require.NotNil(t, image.ListData.IsDangling, "IsDangling should be set")
|
|
}
|
|
|
|
// And now remove all of them.
|
|
rmReports, rmErrors := runtime.RemoveImages(ctx, nil, nil)
|
|
require.Len(t, rmErrors, 0)
|
|
require.Len(t, rmReports, 2)
|
|
|
|
for i, image := range listedImages {
|
|
require.Equal(t, image.ID(), rmReports[i].ID)
|
|
require.True(t, rmReports[i].Removed)
|
|
}
|
|
}
|
|
|
|
func TestPushOtherPlatform(t *testing.T) {
|
|
runtime := testNewRuntime(t)
|
|
ctx := context.Background()
|
|
|
|
// Prefetch alpine.
|
|
pullOptions := &PullOptions{}
|
|
pullOptions.Writer = os.Stdout
|
|
pullOptions.Architecture = "arm64"
|
|
pulledImages, err := runtime.Pull(ctx, "quay.io/libpod/alpine:latest", config.PullPolicyAlways, pullOptions)
|
|
require.NoError(t, err)
|
|
require.Len(t, pulledImages, 1)
|
|
|
|
data, err := pulledImages[0].Inspect(ctx, nil)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "arm64", data.Architecture)
|
|
|
|
pushOptions := &PushOptions{}
|
|
pushOptions.Writer = os.Stdout
|
|
tmp, err := os.CreateTemp(t.TempDir(), "")
|
|
require.NoError(t, err)
|
|
tmp.Close()
|
|
_, err = runtime.Push(ctx, "quay.io/libpod/alpine:latest", "docker-archive:"+tmp.Name(), pushOptions)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
func TestPushWithForceCompression(t *testing.T) {
|
|
runtime := testNewRuntime(t)
|
|
ctx := context.Background()
|
|
|
|
// Prefetch alpine.
|
|
pullOptions := &PullOptions{}
|
|
pullOptions.Writer = os.Stdout
|
|
pullOptions.Architecture = "arm64"
|
|
pulledImages, err := runtime.Pull(ctx, "quay.io/libpod/alpine:latest", config.PullPolicyAlways, pullOptions)
|
|
require.NoError(t, err)
|
|
require.Len(t, pulledImages, 1)
|
|
|
|
data, err := pulledImages[0].Inspect(ctx, nil)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "arm64", data.Architecture)
|
|
|
|
// Push newly pulled alpine to directory with uncompressed blobs
|
|
pushOptions := &PushOptions{}
|
|
pushOptions.SystemContext = &types.SystemContext{}
|
|
pushOptions.SystemContext.DirForceDecompress = true
|
|
pushOptions.Writer = os.Stdout
|
|
dirDest := t.TempDir()
|
|
_, err = runtime.Push(ctx, "quay.io/libpod/alpine:latest", "dir:"+dirDest, pushOptions)
|
|
require.NoError(t, err)
|
|
|
|
// Pull uncompressed alpine from `dir:dirDest` as source.
|
|
pullOptions = &PullOptions{}
|
|
pullOptions.Writer = os.Stdout
|
|
pullOptions.Architecture = "arm64"
|
|
pulledImages, err = runtime.Pull(ctx, "dir:"+dirDest, config.PullPolicyAlways, pullOptions)
|
|
require.NoError(t, err)
|
|
require.Len(t, pulledImages, 1)
|
|
|
|
// create `oci` image from uncompressed alpine.
|
|
pushOptions = &PushOptions{}
|
|
pushOptions.OciAcceptUncompressedLayers = true
|
|
pushOptions.Writer = os.Stdout
|
|
ociDest := t.TempDir()
|
|
_, err = runtime.Push(ctx, "quay.io/libpod/alpine:latest", "oci:"+ociDest, pushOptions)
|
|
require.NoError(t, err)
|
|
|
|
// blobs from first push
|
|
entries, err := os.ReadDir(filepath.Join(ociDest, "blobs", "sha256"))
|
|
require.NoError(t, err)
|
|
blobsFirstPush := []string{}
|
|
for _, e := range entries {
|
|
blobsFirstPush = append(blobsFirstPush, e.Name())
|
|
}
|
|
|
|
// Note: Compression is changed from `uncompressed` to `Gzip` but blobs
|
|
// should still be same since `ForceCompressionFormat` is `false`.
|
|
pushOptions = &PushOptions{}
|
|
pushOptions.Writer = os.Stdout
|
|
pushOptions.CompressionFormat = &compression.Gzip
|
|
pushOptions.ForceCompressionFormat = false
|
|
_, err = runtime.Push(ctx, "quay.io/libpod/alpine:latest", "oci:"+ociDest, pushOptions)
|
|
require.NoError(t, err)
|
|
|
|
// blobs from second push
|
|
entries, err = os.ReadDir(filepath.Join(ociDest, "blobs", "sha256"))
|
|
require.NoError(t, err)
|
|
blobsSecondPush := []string{}
|
|
for _, e := range entries {
|
|
blobsSecondPush = append(blobsSecondPush, e.Name())
|
|
}
|
|
|
|
// All blobs of first push should be equivalent to blobs of
|
|
// second push since same compression was used
|
|
assert.Equal(t, blobsSecondPush, blobsFirstPush)
|
|
|
|
// Note: Compression is changed from `uncompressed` to `Gzip` but blobs
|
|
// should still be same since `ForceCompressionFormat` is `false`.
|
|
pushOptions = &PushOptions{}
|
|
pushOptions.Writer = os.Stdout
|
|
pushOptions.CompressionFormat = &compression.Gzip
|
|
pushOptions.ForceCompressionFormat = true
|
|
_, err = runtime.Push(ctx, "quay.io/libpod/alpine:latest", "oci:"+ociDest, pushOptions)
|
|
require.NoError(t, err)
|
|
|
|
// collect blobs from third push
|
|
entries, err = os.ReadDir(filepath.Join(ociDest, "blobs", "sha256"))
|
|
require.NoError(t, err)
|
|
blobsThirdPush := []string{}
|
|
for _, e := range entries {
|
|
blobsThirdPush = append(blobsThirdPush, e.Name())
|
|
}
|
|
|
|
// All blobs of third push should not be equivalent to blobs of
|
|
// first push since new compression was used and `ForceCompressionFormat`
|
|
// was `true`.
|
|
assert.NotEqual(t, blobsThirdPush, blobsFirstPush)
|
|
}
|