From 8b842ac7af7ce9a54c8259329cd1adadcddcabdc Mon Sep 17 00:00:00 2001 From: CrazyMax <1951866+crazy-max@users.noreply.github.com> Date: Sun, 22 Dec 2024 03:53:47 +0100 Subject: [PATCH] switch to github.com/containerd/platforms --- .golangci.yml | 2 + go.mod | 2 +- go.sum | 4 +- internal/app/undock.go | 2 +- pkg/extractor/image/image.go | 2 +- .../github.com/containerd/containerd/NOTICE | 16 ---- .../containerd/platforms/.gitattributes | 1 + .../containerd/platforms/.golangci.yml | 30 ++++++ .../{containerd => platforms}/LICENSE | 0 .../github.com/containerd/platforms/README.md | 32 +++++++ .../{containerd => }/platforms/compare.go | 0 .../{containerd => }/platforms/cpuinfo.go | 0 .../platforms/cpuinfo_linux.go | 13 ++- .../platforms/cpuinfo_other.go | 6 +- .../{containerd => }/platforms/database.go | 0 .../{containerd => }/platforms/defaults.go | 6 +- .../platforms/defaults_darwin.go | 0 .../platforms/defaults_freebsd.go | 0 .../platforms/defaults_unix.go | 0 .../platforms/defaults_windows.go | 15 ++- .../github.com/containerd/platforms/errors.go | 30 ++++++ .../platforms/platform_compat_windows.go | 78 +++++++++++++++ .../{containerd => }/platforms/platforms.go | 96 ++++++++++++------- .../platforms/platforms_other.go | 4 - .../platforms/platforms_windows.go | 8 -- vendor/modules.txt | 6 +- 26 files changed, 263 insertions(+), 90 deletions(-) delete mode 100644 vendor/github.com/containerd/containerd/NOTICE create mode 100644 vendor/github.com/containerd/platforms/.gitattributes create mode 100644 vendor/github.com/containerd/platforms/.golangci.yml rename vendor/github.com/containerd/{containerd => platforms}/LICENSE (100%) create mode 100644 vendor/github.com/containerd/platforms/README.md rename vendor/github.com/containerd/{containerd => }/platforms/compare.go (100%) rename vendor/github.com/containerd/{containerd => }/platforms/cpuinfo.go (100%) rename vendor/github.com/containerd/{containerd => }/platforms/cpuinfo_linux.go (94%) rename vendor/github.com/containerd/{containerd => }/platforms/cpuinfo_other.go (95%) rename vendor/github.com/containerd/{containerd => }/platforms/database.go (100%) rename vendor/github.com/containerd/{containerd => }/platforms/defaults.go (81%) rename vendor/github.com/containerd/{containerd => }/platforms/defaults_darwin.go (100%) rename vendor/github.com/containerd/{containerd => }/platforms/defaults_freebsd.go (100%) rename vendor/github.com/containerd/{containerd => }/platforms/defaults_unix.go (100%) rename vendor/github.com/containerd/{containerd => }/platforms/defaults_windows.go (88%) create mode 100644 vendor/github.com/containerd/platforms/errors.go create mode 100644 vendor/github.com/containerd/platforms/platform_compat_windows.go rename vendor/github.com/containerd/{containerd => }/platforms/platforms.go (74%) rename vendor/github.com/containerd/{containerd => }/platforms/platforms_other.go (94%) rename vendor/github.com/containerd/{containerd => }/platforms/platforms_windows.go (85%) diff --git a/.golangci.yml b/.golangci.yml index 95df8665..ba853b0e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -54,6 +54,8 @@ linters-settings: rules: main: deny: + - pkg: "github.com/containerd/containerd/platforms" + desc: The containerd platforms package was migrated to a separate module. Use github.com/containerd/platforms instead. - pkg: "io/ioutil" desc: The io/ioutil package has been deprecated. forbidigo: diff --git a/go.mod b/go.mod index 70a17945..c099e1bf 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.23.0 require ( github.com/alecthomas/kong v0.9.0 - github.com/containerd/containerd v1.7.18 + github.com/containerd/platforms v0.2.1 github.com/containers/image/v5 v5.31.1 github.com/docker/docker v26.1.4+incompatible github.com/mholt/archiver/v4 v4.0.0-alpha.8 diff --git a/go.sum b/go.sum index 08f3d1ce..a85cabf0 100644 --- a/go.sum +++ b/go.sum @@ -65,12 +65,12 @@ github.com/connesc/cipherio v0.2.1 h1:FGtpTPMbKNNWByNrr9aEBtaJtXjqOzkIXNYJp6OEyc github.com/connesc/cipherio v0.2.1/go.mod h1:ukY0MWJDFnJEbXMQtOcn2VmTpRfzcTz4OoVrWGGJZcA= github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0= github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0= -github.com/containerd/containerd v1.7.18 h1:jqjZTQNfXGoEaZdW1WwPU0RqSn1Bm2Ay/KJPUuO8nao= -github.com/containerd/containerd v1.7.18/go.mod h1:IYEk9/IO6wAPUz2bCMVUbsfXjzw5UNP5fLz4PsUygQ4= github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM= github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= +github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU= github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk= github.com/containers/image/v5 v5.31.1 h1:3x9soI6Biml/GiDLpkSmKrkRSwVGctxu/vONpoUdklA= diff --git a/internal/app/undock.go b/internal/app/undock.go index fed89deb..68a90a07 100644 --- a/internal/app/undock.go +++ b/internal/app/undock.go @@ -5,7 +5,7 @@ import ( "os" "strings" - "github.com/containerd/containerd/platforms" + "github.com/containerd/platforms" "github.com/crazy-max/undock/internal/config" ximage "github.com/crazy-max/undock/pkg/extractor/image" "github.com/crazy-max/undock/pkg/image" diff --git a/pkg/extractor/image/image.go b/pkg/extractor/image/image.go index 0085d1c4..5bca0523 100644 --- a/pkg/extractor/image/image.go +++ b/pkg/extractor/image/image.go @@ -8,7 +8,7 @@ import ( "path/filepath" "strings" - "github.com/containerd/containerd/platforms" + "github.com/containerd/platforms" "github.com/containers/image/v5/manifest" "github.com/crazy-max/undock/pkg/extractor" ocispecs "github.com/opencontainers/image-spec/specs-go/v1" diff --git a/vendor/github.com/containerd/containerd/NOTICE b/vendor/github.com/containerd/containerd/NOTICE deleted file mode 100644 index 8915f027..00000000 --- a/vendor/github.com/containerd/containerd/NOTICE +++ /dev/null @@ -1,16 +0,0 @@ -Docker -Copyright 2012-2015 Docker, Inc. - -This product includes software developed at Docker, Inc. (https://www.docker.com). - -The following is courtesy of our legal counsel: - - -Use and transfer of Docker may be subject to certain restrictions by the -United States and other governments. -It is your responsibility to ensure that your use and/or transfer does not -violate applicable laws. - -For more information, please see https://www.bis.doc.gov - -See also https://www.apache.org/dev/crypto.html and/or seek legal counsel. diff --git a/vendor/github.com/containerd/platforms/.gitattributes b/vendor/github.com/containerd/platforms/.gitattributes new file mode 100644 index 00000000..a0717e4b --- /dev/null +++ b/vendor/github.com/containerd/platforms/.gitattributes @@ -0,0 +1 @@ +*.go text eol=lf \ No newline at end of file diff --git a/vendor/github.com/containerd/platforms/.golangci.yml b/vendor/github.com/containerd/platforms/.golangci.yml new file mode 100644 index 00000000..a695775d --- /dev/null +++ b/vendor/github.com/containerd/platforms/.golangci.yml @@ -0,0 +1,30 @@ +linters: + enable: + - exportloopref # Checks for pointers to enclosing loop variables + - gofmt + - goimports + - gosec + - ineffassign + - misspell + - nolintlint + - revive + - staticcheck + - tenv # Detects using os.Setenv instead of t.Setenv since Go 1.17 + - unconvert + - unused + - vet + - dupword # Checks for duplicate words in the source code + disable: + - errcheck + +run: + timeout: 5m + skip-dirs: + - api + - cluster + - design + - docs + - docs/man + - releases + - reports + - test # e2e scripts diff --git a/vendor/github.com/containerd/containerd/LICENSE b/vendor/github.com/containerd/platforms/LICENSE similarity index 100% rename from vendor/github.com/containerd/containerd/LICENSE rename to vendor/github.com/containerd/platforms/LICENSE diff --git a/vendor/github.com/containerd/platforms/README.md b/vendor/github.com/containerd/platforms/README.md new file mode 100644 index 00000000..2059de77 --- /dev/null +++ b/vendor/github.com/containerd/platforms/README.md @@ -0,0 +1,32 @@ +# platforms + +A Go package for formatting, normalizing and matching container platforms. + +This package is based on the Open Containers Image Spec definition of a [platform](https://github.com/opencontainers/image-spec/blob/main/specs-go/v1/descriptor.go#L52). + +## Platform Specifier + +While the OCI platform specifications provide a tool for components to +specify structured information, user input typically doesn't need the full +context and much can be inferred. To solve this problem, this package introduces +"specifiers". A specifier has the format +`||/[/]`. The user can provide either the +operating system or the architecture or both. + +An example of a common specifier is `linux/amd64`. If the host has a default +runtime that matches this, the user can simply provide the component that +matters. For example, if an image provides `amd64` and `arm64` support, the +operating system, `linux` can be inferred, so they only have to provide +`arm64` or `amd64`. Similar behavior is implemented for operating systems, +where the architecture may be known but a runtime may support images from +different operating systems. + +## Project details + +**platforms** is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE). +As a containerd sub-project, you will find the: + * [Project governance](https://github.com/containerd/project/blob/main/GOVERNANCE.md), + * [Maintainers](https://github.com/containerd/project/blob/main/MAINTAINERS), + * and [Contributing guidelines](https://github.com/containerd/project/blob/main/CONTRIBUTING.md) + +information in our [`containerd/project`](https://github.com/containerd/project) repository. \ No newline at end of file diff --git a/vendor/github.com/containerd/containerd/platforms/compare.go b/vendor/github.com/containerd/platforms/compare.go similarity index 100% rename from vendor/github.com/containerd/containerd/platforms/compare.go rename to vendor/github.com/containerd/platforms/compare.go diff --git a/vendor/github.com/containerd/containerd/platforms/cpuinfo.go b/vendor/github.com/containerd/platforms/cpuinfo.go similarity index 100% rename from vendor/github.com/containerd/containerd/platforms/cpuinfo.go rename to vendor/github.com/containerd/platforms/cpuinfo.go diff --git a/vendor/github.com/containerd/containerd/platforms/cpuinfo_linux.go b/vendor/github.com/containerd/platforms/cpuinfo_linux.go similarity index 94% rename from vendor/github.com/containerd/containerd/platforms/cpuinfo_linux.go rename to vendor/github.com/containerd/platforms/cpuinfo_linux.go index e07aa99c..98c7001f 100644 --- a/vendor/github.com/containerd/containerd/platforms/cpuinfo_linux.go +++ b/vendor/github.com/containerd/platforms/cpuinfo_linux.go @@ -19,12 +19,12 @@ package platforms import ( "bufio" "bytes" + "errors" "fmt" "os" "runtime" "strings" - "github.com/containerd/errdefs" "golang.org/x/sys/unix" ) @@ -70,7 +70,7 @@ func getCPUInfo(pattern string) (info string, err error) { return "", err } - return "", fmt.Errorf("getCPUInfo for pattern %s: %w", pattern, errdefs.ErrNotFound) + return "", fmt.Errorf("getCPUInfo for pattern %s: %w", pattern, errNotFound) } // getCPUVariantFromArch get CPU variant from arch through a system call @@ -83,7 +83,7 @@ func getCPUVariantFromArch(arch string) (string, error) { if arch == "aarch64" { variant = "8" } else if arch[0:4] == "armv" && len(arch) >= 5 { - //Valid arch format is in form of armvXx + // Valid arch format is in form of armvXx switch arch[3:5] { case "v8": variant = "8" @@ -101,7 +101,7 @@ func getCPUVariantFromArch(arch string) (string, error) { variant = "unknown" } } else { - return "", fmt.Errorf("getCPUVariantFromArch invalid arch: %s, %w", arch, errdefs.ErrInvalidArgument) + return "", fmt.Errorf("getCPUVariantFromArch invalid arch: %s, %w", arch, errInvalidArgument) } return variant, nil } @@ -112,11 +112,10 @@ func getCPUVariantFromArch(arch string) (string, error) { // This is to cover running ARM in emulated environment on x86 host as this field in /proc/cpuinfo // was not present. func getCPUVariant() (string, error) { - variant, err := getCPUInfo("Cpu architecture") if err != nil { - if errdefs.IsNotFound(err) { - //Let's try getting CPU variant from machine architecture + if errors.Is(err, errNotFound) { + // Let's try getting CPU variant from machine architecture arch, err := getMachineArch() if err != nil { return "", fmt.Errorf("failure getting machine architecture: %v", err) diff --git a/vendor/github.com/containerd/containerd/platforms/cpuinfo_other.go b/vendor/github.com/containerd/platforms/cpuinfo_other.go similarity index 95% rename from vendor/github.com/containerd/containerd/platforms/cpuinfo_other.go rename to vendor/github.com/containerd/platforms/cpuinfo_other.go index 8cbcbb24..97a1fe8a 100644 --- a/vendor/github.com/containerd/containerd/platforms/cpuinfo_other.go +++ b/vendor/github.com/containerd/platforms/cpuinfo_other.go @@ -21,8 +21,6 @@ package platforms import ( "fmt" "runtime" - - "github.com/containerd/errdefs" ) func getCPUVariant() (string, error) { @@ -49,10 +47,8 @@ func getCPUVariant() (string, error) { default: variant = "unknown" } - } else { - return "", fmt.Errorf("getCPUVariant for OS %s: %v", runtime.GOOS, errdefs.ErrNotImplemented) - + return "", fmt.Errorf("getCPUVariant for OS %s: %v", runtime.GOOS, errNotImplemented) } return variant, nil diff --git a/vendor/github.com/containerd/containerd/platforms/database.go b/vendor/github.com/containerd/platforms/database.go similarity index 100% rename from vendor/github.com/containerd/containerd/platforms/database.go rename to vendor/github.com/containerd/platforms/database.go diff --git a/vendor/github.com/containerd/containerd/platforms/defaults.go b/vendor/github.com/containerd/platforms/defaults.go similarity index 81% rename from vendor/github.com/containerd/containerd/platforms/defaults.go rename to vendor/github.com/containerd/platforms/defaults.go index cfa3ff34..9d898d60 100644 --- a/vendor/github.com/containerd/containerd/platforms/defaults.go +++ b/vendor/github.com/containerd/platforms/defaults.go @@ -16,9 +16,11 @@ package platforms -// DefaultString returns the default string specifier for the platform. +// DefaultString returns the default string specifier for the platform, +// with [PR#6](https://github.com/containerd/platforms/pull/6) the result +// may now also include the OSVersion from the provided platform specification. func DefaultString() string { - return Format(DefaultSpec()) + return FormatAll(DefaultSpec()) } // DefaultStrict returns strict form of Default. diff --git a/vendor/github.com/containerd/containerd/platforms/defaults_darwin.go b/vendor/github.com/containerd/platforms/defaults_darwin.go similarity index 100% rename from vendor/github.com/containerd/containerd/platforms/defaults_darwin.go rename to vendor/github.com/containerd/platforms/defaults_darwin.go diff --git a/vendor/github.com/containerd/containerd/platforms/defaults_freebsd.go b/vendor/github.com/containerd/platforms/defaults_freebsd.go similarity index 100% rename from vendor/github.com/containerd/containerd/platforms/defaults_freebsd.go rename to vendor/github.com/containerd/platforms/defaults_freebsd.go diff --git a/vendor/github.com/containerd/containerd/platforms/defaults_unix.go b/vendor/github.com/containerd/platforms/defaults_unix.go similarity index 100% rename from vendor/github.com/containerd/containerd/platforms/defaults_unix.go rename to vendor/github.com/containerd/platforms/defaults_unix.go diff --git a/vendor/github.com/containerd/containerd/platforms/defaults_windows.go b/vendor/github.com/containerd/platforms/defaults_windows.go similarity index 88% rename from vendor/github.com/containerd/containerd/platforms/defaults_windows.go rename to vendor/github.com/containerd/platforms/defaults_windows.go index d10fa901..427ed72e 100644 --- a/vendor/github.com/containerd/containerd/platforms/defaults_windows.go +++ b/vendor/github.com/containerd/platforms/defaults_windows.go @@ -22,7 +22,6 @@ import ( "strconv" "strings" - "github.com/Microsoft/hcsshim/osversion" specs "github.com/opencontainers/image-spec/specs-go/v1" "golang.org/x/sys/windows" ) @@ -52,29 +51,29 @@ func (m windowsmatcher) Match(p specs.Platform) bool { if match && m.OS == "windows" { // HPC containers do not have OS version filled - if p.OSVersion == "" { + if m.OSVersion == "" || p.OSVersion == "" { return true } - hostOsVersion := GetOsVersion(m.osVersionPrefix) - ctrOsVersion := GetOsVersion(p.OSVersion) - return osversion.CheckHostAndContainerCompat(hostOsVersion, ctrOsVersion) + hostOsVersion := getOSVersion(m.osVersionPrefix) + ctrOsVersion := getOSVersion(p.OSVersion) + return checkHostAndContainerCompat(hostOsVersion, ctrOsVersion) } return match } -func GetOsVersion(osVersionPrefix string) osversion.OSVersion { +func getOSVersion(osVersionPrefix string) osVersion { parts := strings.Split(osVersionPrefix, ".") if len(parts) < 3 { - return osversion.OSVersion{} + return osVersion{} } majorVersion, _ := strconv.Atoi(parts[0]) minorVersion, _ := strconv.Atoi(parts[1]) buildNumber, _ := strconv.Atoi(parts[2]) - return osversion.OSVersion{ + return osVersion{ MajorVersion: uint8(majorVersion), MinorVersion: uint8(minorVersion), Build: uint16(buildNumber), diff --git a/vendor/github.com/containerd/platforms/errors.go b/vendor/github.com/containerd/platforms/errors.go new file mode 100644 index 00000000..5ad721e7 --- /dev/null +++ b/vendor/github.com/containerd/platforms/errors.go @@ -0,0 +1,30 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package platforms + +import "errors" + +// These errors mirror the errors defined in [github.com/containerd/containerd/errdefs], +// however, they are not exported as they are not expected to be used as sentinel +// errors by consumers of this package. +// +//nolint:unused // not all errors are used on all platforms. +var ( + errNotFound = errors.New("not found") + errInvalidArgument = errors.New("invalid argument") + errNotImplemented = errors.New("not implemented") +) diff --git a/vendor/github.com/containerd/platforms/platform_compat_windows.go b/vendor/github.com/containerd/platforms/platform_compat_windows.go new file mode 100644 index 00000000..89e66f0c --- /dev/null +++ b/vendor/github.com/containerd/platforms/platform_compat_windows.go @@ -0,0 +1,78 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package platforms + +// osVersion is a wrapper for Windows version information +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx +type osVersion struct { + Version uint32 + MajorVersion uint8 + MinorVersion uint8 + Build uint16 +} + +// Windows Client and Server build numbers. +// +// See: +// https://learn.microsoft.com/en-us/windows/release-health/release-information +// https://learn.microsoft.com/en-us/windows/release-health/windows-server-release-info +// https://learn.microsoft.com/en-us/windows/release-health/windows11-release-information +const ( + // rs5 (version 1809, codename "Redstone 5") corresponds to Windows Server + // 2019 (ltsc2019), and Windows 10 (October 2018 Update). + rs5 = 17763 + + // v21H2Server corresponds to Windows Server 2022 (ltsc2022). + v21H2Server = 20348 + + // v22H2Win11 corresponds to Windows 11 (2022 Update). + v22H2Win11 = 22621 +) + +// List of stable ABI compliant ltsc releases +// Note: List must be sorted in ascending order +var compatLTSCReleases = []uint16{ + v21H2Server, +} + +// CheckHostAndContainerCompat checks if given host and container +// OS versions are compatible. +// It includes support for stable ABI compliant versions as well. +// Every release after WS 2022 will support the previous ltsc +// container image. Stable ABI is in preview mode for windows 11 client. +// Refer: https://learn.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/version-compatibility?tabs=windows-server-2022%2Cwindows-10#windows-server-host-os-compatibility +func checkHostAndContainerCompat(host, ctr osVersion) bool { + // check major minor versions of host and guest + if host.MajorVersion != ctr.MajorVersion || + host.MinorVersion != ctr.MinorVersion { + return false + } + + // If host is < WS 2022, exact version match is required + if host.Build < v21H2Server { + return host.Build == ctr.Build + } + + var supportedLtscRelease uint16 + for i := len(compatLTSCReleases) - 1; i >= 0; i-- { + if host.Build >= compatLTSCReleases[i] { + supportedLtscRelease = compatLTSCReleases[i] + break + } + } + return ctr.Build >= supportedLtscRelease && ctr.Build <= host.Build +} diff --git a/vendor/github.com/containerd/containerd/platforms/platforms.go b/vendor/github.com/containerd/platforms/platforms.go similarity index 74% rename from vendor/github.com/containerd/containerd/platforms/platforms.go rename to vendor/github.com/containerd/platforms/platforms.go index 44bc24a5..1bbbdb91 100644 --- a/vendor/github.com/containerd/containerd/platforms/platforms.go +++ b/vendor/github.com/containerd/platforms/platforms.go @@ -102,6 +102,9 @@ // unless it is explicitly provided. This is treated as equivalent to armhf. A // previous architecture, armel, will be normalized to arm/v6. // +// Similarly, the most common arm64 version v8, and most common amd64 version v1 +// are represented without the variant. +// // While these normalizations are provided, their support on arm platforms has // not yet been fully implemented and tested. package platforms @@ -115,14 +118,15 @@ import ( "strings" specs "github.com/opencontainers/image-spec/specs-go/v1" - - "github.com/containerd/errdefs" ) var ( - specifierRe = regexp.MustCompile(`^[A-Za-z0-9_-]+$`) + specifierRe = regexp.MustCompile(`^[A-Za-z0-9_-]+$`) + osAndVersionRe = regexp.MustCompile(`^([A-Za-z0-9_-]+)(?:\(([A-Za-z0-9_.-]*)\))?$`) ) +const osAndVersionFormat = "%s(%s)" + // Platform is a type alias for convenience, so there is no need to import image-spec package everywhere. type Platform = specs.Platform @@ -155,40 +159,68 @@ func (m *matcher) Match(platform specs.Platform) bool { } func (m *matcher) String() string { - return Format(m.Platform) + return FormatAll(m.Platform) +} + +// ParseAll parses a list of platform specifiers into a list of platform. +func ParseAll(specifiers []string) ([]specs.Platform, error) { + platforms := make([]specs.Platform, len(specifiers)) + for i, s := range specifiers { + p, err := Parse(s) + if err != nil { + return nil, fmt.Errorf("invalid platform %s: %w", s, err) + } + platforms[i] = p + } + return platforms, nil } // Parse parses the platform specifier syntax into a platform declaration. // -// Platform specifiers are in the format `||/[/]`. +// Platform specifiers are in the format `[()]||[()]/[/]`. // The minimum required information for a platform specifier is the operating -// system or architecture. If there is only a single string (no slashes), the +// system or architecture. The OSVersion can be part of the OS like `windows(10.0.17763)` +// When an OSVersion is specified, then specs.Platform.OSVersion is populated with that value, +// and an empty string otherwise. +// If there is only a single string (no slashes), the // value will be matched against the known set of operating systems, then fall // back to the known set of architectures. The missing component will be // inferred based on the local environment. func Parse(specifier string) (specs.Platform, error) { if strings.Contains(specifier, "*") { // TODO(stevvooe): need to work out exact wildcard handling - return specs.Platform{}, fmt.Errorf("%q: wildcards not yet supported: %w", specifier, errdefs.ErrInvalidArgument) + return specs.Platform{}, fmt.Errorf("%q: wildcards not yet supported: %w", specifier, errInvalidArgument) } - parts := strings.Split(specifier, "/") + // Limit to 4 elements to prevent unbounded split + parts := strings.SplitN(specifier, "/", 4) - for _, part := range parts { - if !specifierRe.MatchString(part) { - return specs.Platform{}, fmt.Errorf("%q is an invalid component of %q: platform specifier component must match %q: %w", part, specifier, specifierRe.String(), errdefs.ErrInvalidArgument) + var p specs.Platform + for i, part := range parts { + if i == 0 { + // First element is [()] + osVer := osAndVersionRe.FindStringSubmatch(part) + if osVer == nil { + return specs.Platform{}, fmt.Errorf("%q is an invalid OS component of %q: OSAndVersion specifier component must match %q: %w", part, specifier, osAndVersionRe.String(), errInvalidArgument) + } + + p.OS = normalizeOS(osVer[1]) + p.OSVersion = osVer[2] + } else { + if !specifierRe.MatchString(part) { + return specs.Platform{}, fmt.Errorf("%q is an invalid component of %q: platform specifier component must match %q: %w", part, specifier, specifierRe.String(), errInvalidArgument) + } } } - var p specs.Platform switch len(parts) { case 1: - // in this case, we will test that the value might be an OS, then look - // it up. If it is not known, we'll treat it as an architecture. Since + // in this case, we will test that the value might be an OS (with or + // without the optional OSVersion specified) and look it up. + // If it is not known, we'll treat it as an architecture. Since // we have very little information about the platform here, we are // going to be a little more strict if we don't know about the argument // value. - p.OS = normalizeOS(parts[0]) if isKnownOS(p.OS) { // picks a default architecture p.Architecture = runtime.GOARCH @@ -196,10 +228,6 @@ func Parse(specifier string) (specs.Platform, error) { p.Variant = cpuVariant() } - if p.OS == "windows" { - p.OSVersion = GetWindowsOsVersion() - } - return p, nil } @@ -212,37 +240,27 @@ func Parse(specifier string) (specs.Platform, error) { return p, nil } - return specs.Platform{}, fmt.Errorf("%q: unknown operating system or architecture: %w", specifier, errdefs.ErrInvalidArgument) + return specs.Platform{}, fmt.Errorf("%q: unknown operating system or architecture: %w", specifier, errInvalidArgument) case 2: - // In this case, we treat as a regular os/arch pair. We don't care + // In this case, we treat as a regular OS[(OSVersion)]/arch pair. We don't care // about whether or not we know of the platform. - p.OS = normalizeOS(parts[0]) p.Architecture, p.Variant = normalizeArch(parts[1], "") if p.Architecture == "arm" && p.Variant == "v7" { p.Variant = "" } - if p.OS == "windows" { - p.OSVersion = GetWindowsOsVersion() - } - return p, nil case 3: // we have a fully specified variant, this is rare - p.OS = normalizeOS(parts[0]) p.Architecture, p.Variant = normalizeArch(parts[1], parts[2]) if p.Architecture == "arm64" && p.Variant == "" { p.Variant = "v8" } - if p.OS == "windows" { - p.OSVersion = GetWindowsOsVersion() - } - return p, nil } - return specs.Platform{}, fmt.Errorf("%q: cannot parse platform specifier: %w", specifier, errdefs.ErrInvalidArgument) + return specs.Platform{}, fmt.Errorf("%q: cannot parse platform specifier: %w", specifier, errInvalidArgument) } // MustParse is like Parses but panics if the specifier cannot be parsed. @@ -264,6 +282,20 @@ func Format(platform specs.Platform) string { return path.Join(platform.OS, platform.Architecture, platform.Variant) } +// FormatAll returns a string specifier that also includes the OSVersion from the +// provided platform specification. +func FormatAll(platform specs.Platform) string { + if platform.OS == "" { + return "unknown" + } + + if platform.OSVersion != "" { + OSAndVersion := fmt.Sprintf(osAndVersionFormat, platform.OS, platform.OSVersion) + return path.Join(OSAndVersion, platform.Architecture, platform.Variant) + } + return path.Join(platform.OS, platform.Architecture, platform.Variant) +} + // Normalize validates and translate the platform to the canonical value. // // For example, if "Aarch64" is encountered, we change it to "arm64" or if diff --git a/vendor/github.com/containerd/containerd/platforms/platforms_other.go b/vendor/github.com/containerd/platforms/platforms_other.go similarity index 94% rename from vendor/github.com/containerd/containerd/platforms/platforms_other.go rename to vendor/github.com/containerd/platforms/platforms_other.go index 59beeb3d..03f4dcd9 100644 --- a/vendor/github.com/containerd/containerd/platforms/platforms_other.go +++ b/vendor/github.com/containerd/platforms/platforms_other.go @@ -28,7 +28,3 @@ func newDefaultMatcher(platform specs.Platform) Matcher { Platform: Normalize(platform), } } - -func GetWindowsOsVersion() string { - return "" -} diff --git a/vendor/github.com/containerd/containerd/platforms/platforms_windows.go b/vendor/github.com/containerd/platforms/platforms_windows.go similarity index 85% rename from vendor/github.com/containerd/containerd/platforms/platforms_windows.go rename to vendor/github.com/containerd/platforms/platforms_windows.go index 733d18dd..950e2a2d 100644 --- a/vendor/github.com/containerd/containerd/platforms/platforms_windows.go +++ b/vendor/github.com/containerd/platforms/platforms_windows.go @@ -17,10 +17,7 @@ package platforms import ( - "fmt" - specs "github.com/opencontainers/image-spec/specs-go/v1" - "golang.org/x/sys/windows" ) // NewMatcher returns a Windows matcher that will match on osVersionPrefix if @@ -35,8 +32,3 @@ func newDefaultMatcher(platform specs.Platform) Matcher { }, } } - -func GetWindowsOsVersion() string { - major, minor, build := windows.RtlGetNtVersionNumbers() - return fmt.Sprintf("%d.%d.%d", major, minor, build) -} diff --git a/vendor/modules.txt b/vendor/modules.txt index ee8ba4d1..d0ca750a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -85,15 +85,15 @@ github.com/connesc/cipherio # github.com/containerd/cgroups/v3 v3.0.3 ## explicit; go 1.18 github.com/containerd/cgroups/v3/cgroup1/stats -# github.com/containerd/containerd v1.7.18 -## explicit; go 1.21 -github.com/containerd/containerd/platforms # github.com/containerd/errdefs v0.1.0 ## explicit; go 1.20 github.com/containerd/errdefs # github.com/containerd/log v0.1.0 ## explicit; go 1.20 github.com/containerd/log +# github.com/containerd/platforms v0.2.1 +## explicit; go 1.20 +github.com/containerd/platforms # github.com/containerd/stargz-snapshotter/estargz v0.15.1 ## explicit; go 1.19 github.com/containerd/stargz-snapshotter/estargz