Vendor common and buildah main

Update the common and buildah vendor to pull in the
platform code move.

[NO NEW TESTS NEEDED]

Signed-off-by: Urvashi Mohnani <umohnani@redhat.com>
This commit is contained in:
Urvashi Mohnani
2023-10-16 13:35:29 -04:00
parent dabf6c83a7
commit 1b0be2f348
10 changed files with 132 additions and 99 deletions

View File

@@ -8,6 +8,7 @@ import (
"github.com/containers/buildah/define"
"github.com/containers/common/libimage"
lplatform "github.com/containers/common/libimage/platform"
"github.com/containers/image/v5/types"
"github.com/containers/storage"
"github.com/containers/storage/pkg/archive"
@@ -41,7 +42,7 @@ func LookupImage(ctx *types.SystemContext, store storage.Store, image string) (*
// Wrapper around libimage.NormalizePlatform to return and consume
// v1.Platform instead of independent os, arch and variant.
func NormalizePlatform(platform v1.Platform) v1.Platform {
os, arch, variant := libimage.NormalizePlatform(platform.OS, platform.Architecture, platform.Variant)
os, arch, variant := lplatform.Normalize(platform.OS, platform.Architecture, platform.Variant)
return v1.Platform{
OS: os,
Architecture: arch,

View File

@@ -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.Normalize(options.OS, options.Architecture, options.Variant)
if options.SignaturePolicyPath != "" {
c.systemContext.SignaturePolicyPath = options.SignaturePolicyPath

View File

@@ -0,0 +1,11 @@
package define
// PlatformPolicy controls the behavior of image-platform matching.
type PlatformPolicy int
const (
// Only debug log if an image does not match the expected platform.
PlatformPolicyDefault PlatformPolicy = iota
// Warn if an image does not match the expected platform.
PlatformPolicyWarn
)

View File

@@ -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.ToString(os, arch, variant))
if err != nil {
return nil, false, fmt.Errorf("parsing host platform: %v", err)
}
fromImage, err := platforms.Parse(platform.ToString(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
}

View File

@@ -1,100 +1,26 @@
package libimage
import (
"context"
"fmt"
"runtime"
"github.com/containerd/containerd/platforms"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/sirupsen/logrus"
"github.com/containers/common/libimage/define"
"github.com/containers/common/libimage/platform"
)
// PlatformPolicy controls the behavior of image-platform matching.
type PlatformPolicy int
// Deprecated: new code should use define.PlatformPolicy directly.
type PlatformPolicy = define.PlatformPolicy
const (
// Only debug log if an image does not match the expected platform.
PlatformPolicyDefault PlatformPolicy = iota
// Deprecated: new code should reference define.PlatformPolicyDefault directly.
PlatformPolicyDefault = define.PlatformPolicyDefault
// Warn if an image does not match the expected platform.
PlatformPolicyWarn
// Deprecated: new code should reference define.PlatformPolicyWarn directly.
PlatformPolicyWarn = define.PlatformPolicyWarn
)
// NormalizePlatform normalizes (according to the OCI spec) the specified os,
// arch and variant. If left empty, the individual item will be normalized.
// arch and variant. If left empty, the individual item will be normalized.
// Deprecated: new code should call libimage/platform.Normalize() instead.
func NormalizePlatform(rawOS, rawArch, rawVariant string) (os, arch, variant string) {
platformSpec := v1.Platform{
OS: rawOS,
Architecture: rawArch,
Variant: rawVariant,
}
normalizedSpec := platforms.Normalize(platformSpec)
if normalizedSpec.Variant == "" && rawVariant != "" {
normalizedSpec.Variant = rawVariant
}
rawPlatform := toPlatformString(normalizedSpec.OS, normalizedSpec.Architecture, normalizedSpec.Variant)
normalizedPlatform, err := platforms.Parse(rawPlatform)
if err != nil {
logrus.Debugf("Error normalizing platform: %v", err)
return rawOS, rawArch, rawVariant
}
logrus.Debugf("Normalized platform %s to %s", rawPlatform, normalizedPlatform)
os = rawOS
if rawOS != "" {
os = normalizedPlatform.OS
}
arch = rawArch
if rawArch != "" {
arch = normalizedPlatform.Architecture
}
variant = rawVariant
if rawVariant != "" || (rawVariant == "" && normalizedPlatform.Variant != "") {
variant = normalizedPlatform.Variant
}
return os, arch, variant
}
func toPlatformString(os, arch, variant string) string {
if os == "" {
os = runtime.GOOS
}
if arch == "" {
arch = runtime.GOARCH
}
if variant == "" {
return fmt.Sprintf("%s/%s", os, arch)
}
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
return platform.Normalize(rawOS, rawArch, rawVariant)
}

View File

@@ -0,0 +1,57 @@
package platform
import (
"fmt"
"runtime"
"github.com/containerd/containerd/platforms"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/sirupsen/logrus"
)
// Normalize normalizes (according to the OCI spec) the specified os,
// arch and variant. If left empty, the individual item will be normalized.
func Normalize(rawOS, rawArch, rawVariant string) (os, arch, variant string) {
platformSpec := v1.Platform{
OS: rawOS,
Architecture: rawArch,
Variant: rawVariant,
}
normalizedSpec := platforms.Normalize(platformSpec)
if normalizedSpec.Variant == "" && rawVariant != "" {
normalizedSpec.Variant = rawVariant
}
rawPlatform := ToString(normalizedSpec.OS, normalizedSpec.Architecture, normalizedSpec.Variant)
normalizedPlatform, err := platforms.Parse(rawPlatform)
if err != nil {
logrus.Debugf("Error normalizing platform: %v", err)
return rawOS, rawArch, rawVariant
}
logrus.Debugf("Normalized platform %s to %s", rawPlatform, normalizedPlatform)
os = rawOS
if rawOS != "" {
os = normalizedPlatform.OS
}
arch = rawArch
if rawArch != "" {
arch = normalizedPlatform.Architecture
}
variant = rawVariant
if rawVariant != "" || (rawVariant == "" && normalizedPlatform.Variant != "") {
variant = normalizedPlatform.Variant
}
return os, arch, variant
}
func ToString(os, arch, variant string) string {
if os == "" {
os = runtime.GOOS
}
if arch == "" {
arch = runtime.GOARCH
}
if variant == "" {
return fmt.Sprintf("%s/%s", os, arch)
}
return fmt.Sprintf("%s/%s/%s", os, arch, variant)
}

View File

@@ -7,6 +7,8 @@ import (
"os"
"strings"
"github.com/containers/common/libimage/define"
"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 +186,7 @@ type LookupImageOptions struct {
Variant string
// Controls the behavior when checking the platform of an image.
PlatformPolicy PlatformPolicy
PlatformPolicy define.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 +285,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.Normalize(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 +437,9 @@ func (r *Runtime) lookupImageInLocalStorage(name, candidate string, namedCandida
return nil, nil
}
switch options.PlatformPolicy {
case PlatformPolicyDefault:
case define.PlatformPolicyDefault:
logrus.Debugf("%v", matchError)
case PlatformPolicyWarn:
case define.PlatformPolicyWarn:
logrus.Warnf("%v", matchError)
}
}