From 392908bb419af24b776734b8500f4004d4489fac Mon Sep 17 00:00:00 2001 From: Urvashi Mohnani Date: Tue, 10 Oct 2023 19:04:55 -0400 Subject: [PATCH] Move platform code to its own directory Move the platform code into its own directory under libimage so it can be used by farm build in podman without causing the binary size to increase a lot. Signed-off-by: Urvashi Mohnani --- libimage/copier.go | 3 +- libimage/image.go | 34 +++++++++++++++++++++ libimage/normalize_test.go | 3 +- libimage/{ => platform}/platform.go | 39 ++---------------------- libimage/{ => platform}/platform_test.go | 4 +-- libimage/runtime.go | 9 +++--- 6 files changed, 48 insertions(+), 44 deletions(-) rename libimage/{ => platform}/platform.go (53%) rename libimage/{ => platform}/platform_test.go (87%) diff --git a/libimage/copier.go b/libimage/copier.go index fd10dd72df..c6b23d12ea 100644 --- a/libimage/copier.go +++ b/libimage/copier.go @@ -11,6 +11,7 @@ import ( "time" "github.com/containers/common/libimage/manifests" + "github.com/containers/common/libimage/platform" "github.com/containers/common/pkg/config" "github.com/containers/common/pkg/retry" "github.com/containers/image/v5/copy" @@ -239,7 +240,7 @@ func (r *Runtime) newCopier(options *CopyOptions) (*copier, error) { c.systemContext.DockerArchiveAdditionalTags = options.dockerArchiveAdditionalTags - c.systemContext.OSChoice, c.systemContext.ArchitectureChoice, c.systemContext.VariantChoice = NormalizePlatform(options.OS, options.Architecture, options.Variant) + c.systemContext.OSChoice, c.systemContext.ArchitectureChoice, c.systemContext.VariantChoice = platform.NormalizePlatform(options.OS, options.Architecture, options.Variant) if options.SignaturePolicyPath != "" { c.systemContext.SignaturePolicyPath = options.SignaturePolicyPath diff --git a/libimage/image.go b/libimage/image.go index e4198a792c..2771709402 100644 --- a/libimage/image.go +++ b/libimage/image.go @@ -9,6 +9,8 @@ import ( "strings" "time" + "github.com/containerd/containerd/platforms" + "github.com/containers/common/libimage/platform" "github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/manifest" storageTransport "github.com/containers/image/v5/storage" @@ -1021,3 +1023,35 @@ func getImageID(ctx context.Context, src types.ImageReference, sys *types.System } return "@" + imageDigest.Encoded(), nil } + +// Checks whether the image matches the specified platform. +// Returns +// - 1) a matching error that can be used for logging (or returning) what does not match +// - 2) a bool indicating whether architecture, os or variant were set (some callers need that to decide whether they need to throw an error) +// - 3) a fatal error that occurred prior to check for matches (e.g., storage errors etc.) +func (i *Image) matchesPlatform(ctx context.Context, os, arch, variant string) (error, bool, error) { + if err := i.isCorrupted(""); err != nil { + return err, false, nil + } + inspectInfo, err := i.inspectInfo(ctx) + if err != nil { + return nil, false, fmt.Errorf("inspecting image: %w", err) + } + + customPlatform := len(os)+len(arch)+len(variant) != 0 + + expected, err := platforms.Parse(platform.ToPlatformString(os, arch, variant)) + if err != nil { + return nil, false, fmt.Errorf("parsing host platform: %v", err) + } + fromImage, err := platforms.Parse(platform.ToPlatformString(inspectInfo.Os, inspectInfo.Architecture, inspectInfo.Variant)) + if err != nil { + return nil, false, fmt.Errorf("parsing image platform: %v", err) + } + + if platforms.NewMatcher(expected).Match(fromImage) { + return nil, customPlatform, nil + } + + return fmt.Errorf("image platform (%s) does not match the expected platform (%s)", platforms.Format(fromImage), platforms.Format(expected)), customPlatform, nil +} diff --git a/libimage/normalize_test.go b/libimage/normalize_test.go index 9b9dfb4647..a3a6e12dce 100644 --- a/libimage/normalize_test.go +++ b/libimage/normalize_test.go @@ -3,6 +3,7 @@ package libimage import ( "testing" + lplatform "github.com/containers/common/libimage/platform" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -83,7 +84,7 @@ func TestNormalizePlatform(t *testing.T) { platform{"linux", "arm", "v6"}, }, } { - os, arch, variant := NormalizePlatform(test.input.os, test.input.arch, test.input.variant) + os, arch, variant := lplatform.NormalizePlatform(test.input.os, test.input.arch, test.input.variant) assert.Equal(t, test.expected.os, os, test.input) assert.Equal(t, test.expected.arch, arch, test.input) assert.Equal(t, test.expected.variant, variant, test.input) diff --git a/libimage/platform.go b/libimage/platform/platform.go similarity index 53% rename from libimage/platform.go rename to libimage/platform/platform.go index 06c15ee648..19bcc0a380 100644 --- a/libimage/platform.go +++ b/libimage/platform/platform.go @@ -1,7 +1,6 @@ -package libimage +package platform import ( - "context" "fmt" "runtime" @@ -32,7 +31,7 @@ func NormalizePlatform(rawOS, rawArch, rawVariant string) (os, arch, variant str if normalizedSpec.Variant == "" && rawVariant != "" { normalizedSpec.Variant = rawVariant } - rawPlatform := toPlatformString(normalizedSpec.OS, normalizedSpec.Architecture, normalizedSpec.Variant) + rawPlatform := ToPlatformString(normalizedSpec.OS, normalizedSpec.Architecture, normalizedSpec.Variant) normalizedPlatform, err := platforms.Parse(rawPlatform) if err != nil { logrus.Debugf("Error normalizing platform: %v", err) @@ -54,7 +53,7 @@ func NormalizePlatform(rawOS, rawArch, rawVariant string) (os, arch, variant str return os, arch, variant } -func toPlatformString(os, arch, variant string) string { +func ToPlatformString(os, arch, variant string) string { if os == "" { os = runtime.GOOS } @@ -66,35 +65,3 @@ func toPlatformString(os, arch, variant string) string { } return fmt.Sprintf("%s/%s/%s", os, arch, variant) } - -// Checks whether the image matches the specified platform. -// Returns -// - 1) a matching error that can be used for logging (or returning) what does not match -// - 2) a bool indicating whether architecture, os or variant were set (some callers need that to decide whether they need to throw an error) -// - 3) a fatal error that occurred prior to check for matches (e.g., storage errors etc.) -func (i *Image) matchesPlatform(ctx context.Context, os, arch, variant string) (error, bool, error) { - if err := i.isCorrupted(""); err != nil { - return err, false, nil - } - inspectInfo, err := i.inspectInfo(ctx) - if err != nil { - return nil, false, fmt.Errorf("inspecting image: %w", err) - } - - customPlatform := len(os)+len(arch)+len(variant) != 0 - - expected, err := platforms.Parse(toPlatformString(os, arch, variant)) - if err != nil { - return nil, false, fmt.Errorf("parsing host platform: %v", err) - } - fromImage, err := platforms.Parse(toPlatformString(inspectInfo.Os, inspectInfo.Architecture, inspectInfo.Variant)) - if err != nil { - return nil, false, fmt.Errorf("parsing image platform: %v", err) - } - - if platforms.NewMatcher(expected).Match(fromImage) { - return nil, customPlatform, nil - } - - return fmt.Errorf("image platform (%s) does not match the expected platform (%s)", platforms.Format(fromImage), platforms.Format(expected)), customPlatform, nil -} diff --git a/libimage/platform_test.go b/libimage/platform/platform_test.go similarity index 87% rename from libimage/platform_test.go rename to libimage/platform/platform_test.go index 36104107b9..fbaea18c5f 100644 --- a/libimage/platform_test.go +++ b/libimage/platform/platform_test.go @@ -1,4 +1,4 @@ -package libimage +package platform import ( "fmt" @@ -19,7 +19,7 @@ func TestToPlatformString(t *testing.T) { {"", "", "", fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)}, {"", "", "c", fmt.Sprintf("%s/%s/c", runtime.GOOS, runtime.GOARCH)}, } { - platform := toPlatformString(test.os, test.arch, test.variant) + platform := ToPlatformString(test.os, test.arch, test.variant) require.Equal(t, test.expected, platform) } } diff --git a/libimage/runtime.go b/libimage/runtime.go index 6d90272c38..45a24b593e 100644 --- a/libimage/runtime.go +++ b/libimage/runtime.go @@ -7,6 +7,7 @@ import ( "os" "strings" + "github.com/containers/common/libimage/platform" "github.com/containers/common/pkg/config" "github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/pkg/shortnames" @@ -184,7 +185,7 @@ type LookupImageOptions struct { Variant string // Controls the behavior when checking the platform of an image. - PlatformPolicy PlatformPolicy + PlatformPolicy platform.PlatformPolicy // If set, do not look for items/instances in the manifest list that // match the current platform but return the manifest list as is. @@ -283,7 +284,7 @@ func (r *Runtime) LookupImage(name string, options *LookupImageOptions) (*Image, options.Variant = r.systemContext.VariantChoice } // Normalize platform to be OCI compatible (e.g., "aarch64" -> "arm64"). - options.OS, options.Architecture, options.Variant = NormalizePlatform(options.OS, options.Architecture, options.Variant) + options.OS, options.Architecture, options.Variant = platform.NormalizePlatform(options.OS, options.Architecture, options.Variant) // Second, try out the candidates as resolved by shortnames. This takes // "localhost/" prefixed images into account as well. @@ -435,9 +436,9 @@ func (r *Runtime) lookupImageInLocalStorage(name, candidate string, namedCandida return nil, nil } switch options.PlatformPolicy { - case PlatformPolicyDefault: + case platform.PlatformPolicyDefault: logrus.Debugf("%v", matchError) - case PlatformPolicyWarn: + case platform.PlatformPolicyWarn: logrus.Warnf("%v", matchError) } }