Merge pull request #9095 from thaJeztah/isolate_platform
This commit is contained in:
commit
3f315fcabf
47
api/types/platform_helpers.go
Normal file
47
api/types/platform_helpers.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
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 types
|
||||||
|
|
||||||
|
import oci "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
|
|
||||||
|
// OCIPlatformToProto converts from a slice of OCI [specs.Platform] to a
|
||||||
|
// slice of the protobuf definition [Platform].
|
||||||
|
func OCIPlatformToProto(platforms []oci.Platform) []*Platform {
|
||||||
|
ap := make([]*Platform, len(platforms))
|
||||||
|
for i := range platforms {
|
||||||
|
ap[i] = &Platform{
|
||||||
|
OS: platforms[i].OS,
|
||||||
|
Architecture: platforms[i].Architecture,
|
||||||
|
Variant: platforms[i].Variant,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ap
|
||||||
|
}
|
||||||
|
|
||||||
|
// OCIPlatformFromProto converts a slice of the protobuf definition [Platform]
|
||||||
|
// to a slice of OCI [specs.Platform].
|
||||||
|
func OCIPlatformFromProto(platforms []*Platform) []oci.Platform {
|
||||||
|
op := make([]oci.Platform, len(platforms))
|
||||||
|
for i := range platforms {
|
||||||
|
op[i] = oci.Platform{
|
||||||
|
OS: platforms[i].OS,
|
||||||
|
Architecture: platforms[i].Architecture,
|
||||||
|
Variant: platforms[i].Variant,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return op
|
||||||
|
}
|
@ -156,7 +156,7 @@ func (iis *ImageExportStream) UnmarshalAny(ctx context.Context, sm streaming.Str
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
specified := platforms.FromProto(s.Platforms)
|
specified := types.OCIPlatformFromProto(s.Platforms)
|
||||||
iis.stream = tstreaming.WriteByteStream(ctx, stream)
|
iis.stream = tstreaming.WriteByteStream(ctx, stream)
|
||||||
iis.mediaType = s.MediaType
|
iis.mediaType = s.MediaType
|
||||||
iis.platforms = specified
|
iis.platforms = specified
|
||||||
|
@ -363,7 +363,7 @@ func (is *Store) MarshalAny(context.Context, streaming.StreamCreator) (typeurl.A
|
|||||||
Labels: is.imageLabels,
|
Labels: is.imageLabels,
|
||||||
ManifestLimit: uint32(is.manifestLimit),
|
ManifestLimit: uint32(is.manifestLimit),
|
||||||
AllMetadata: is.allMetadata,
|
AllMetadata: is.allMetadata,
|
||||||
Platforms: platforms.ToProto(is.platforms),
|
Platforms: types.OCIPlatformToProto(is.platforms),
|
||||||
ExtraReferences: referencesToProto(is.extraReferences),
|
ExtraReferences: referencesToProto(is.extraReferences),
|
||||||
Unpacks: unpackToProto(is.unpacks),
|
Unpacks: unpackToProto(is.unpacks),
|
||||||
}
|
}
|
||||||
@ -380,7 +380,7 @@ func (is *Store) UnmarshalAny(ctx context.Context, sm streaming.StreamGetter, a
|
|||||||
is.imageLabels = s.Labels
|
is.imageLabels = s.Labels
|
||||||
is.manifestLimit = int(s.ManifestLimit)
|
is.manifestLimit = int(s.ManifestLimit)
|
||||||
is.allMetadata = s.AllMetadata
|
is.allMetadata = s.AllMetadata
|
||||||
is.platforms = platforms.FromProto(s.Platforms)
|
is.platforms = types.OCIPlatformFromProto(s.Platforms)
|
||||||
is.extraReferences = referencesFromProto(s.ExtraReferences)
|
is.extraReferences = referencesFromProto(s.ExtraReferences)
|
||||||
is.unpacks = unpackFromProto(s.Unpacks)
|
is.unpacks = unpackFromProto(s.Unpacks)
|
||||||
|
|
||||||
|
@ -19,12 +19,12 @@ package platforms
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/containerd/containerd/errdefs"
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ func getCPUInfo(pattern string) (info string, err error) {
|
|||||||
return "", err
|
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
|
// getCPUVariantFromArch get CPU variant from arch through a system call
|
||||||
@ -83,7 +83,7 @@ func getCPUVariantFromArch(arch string) (string, error) {
|
|||||||
if arch == "aarch64" {
|
if arch == "aarch64" {
|
||||||
variant = "8"
|
variant = "8"
|
||||||
} else if arch[0:4] == "armv" && len(arch) >= 5 {
|
} 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] {
|
switch arch[3:5] {
|
||||||
case "v8":
|
case "v8":
|
||||||
variant = "8"
|
variant = "8"
|
||||||
@ -101,7 +101,7 @@ func getCPUVariantFromArch(arch string) (string, error) {
|
|||||||
variant = "unknown"
|
variant = "unknown"
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
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
|
// This is to cover running ARM in emulated environment on x86 host as this field in /proc/cpuinfo
|
||||||
// was not present.
|
// was not present.
|
||||||
func getCPUVariant() (string, error) {
|
func getCPUVariant() (string, error) {
|
||||||
|
|
||||||
variant, err := getCPUInfo("Cpu architecture")
|
variant, err := getCPUInfo("Cpu architecture")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errdefs.IsNotFound(err) {
|
if errors.Is(err, errNotFound) {
|
||||||
//Let's try getting CPU variant from machine architecture
|
// Let's try getting CPU variant from machine architecture
|
||||||
arch, err := getMachineArch()
|
arch, err := getMachineArch()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failure getting machine architecture: %v", err)
|
return "", fmt.Errorf("failure getting machine architecture: %v", err)
|
||||||
|
@ -20,8 +20,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"runtime"
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/containerd/containerd/errdefs"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCPUVariant(t *testing.T) {
|
func TestCPUVariant(t *testing.T) {
|
||||||
@ -107,13 +105,13 @@ func TestGetCPUVariantFromArch(t *testing.T) {
|
|||||||
name: "Test invalid input which doesn't start with armv",
|
name: "Test invalid input which doesn't start with armv",
|
||||||
input: "armxxxx",
|
input: "armxxxx",
|
||||||
output: "",
|
output: "",
|
||||||
expectedErr: errdefs.ErrInvalidArgument,
|
expectedErr: errInvalidArgument,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Test invalid input whose length is less than 5",
|
name: "Test invalid input whose length is less than 5",
|
||||||
input: "armv",
|
input: "armv",
|
||||||
output: "",
|
output: "",
|
||||||
expectedErr: errdefs.ErrInvalidArgument,
|
expectedErr: errInvalidArgument,
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
t.Run(testcase.name, func(t *testing.T) {
|
t.Run(testcase.name, func(t *testing.T) {
|
||||||
|
@ -21,8 +21,6 @@ package platforms
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/containerd/containerd/errdefs"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func getCPUVariant() (string, error) {
|
func getCPUVariant() (string, error) {
|
||||||
@ -49,10 +47,8 @@ func getCPUVariant() (string, error) {
|
|||||||
default:
|
default:
|
||||||
variant = "unknown"
|
variant = "unknown"
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} 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
|
return variant, nil
|
||||||
|
30
platforms/errors.go
Normal file
30
platforms/errors.go
Normal file
@ -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")
|
||||||
|
)
|
@ -118,9 +118,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
|
|
||||||
"github.com/containerd/containerd/api/types"
|
|
||||||
"github.com/containerd/containerd/errdefs"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -186,14 +183,14 @@ func ParseAll(specifiers []string) ([]specs.Platform, error) {
|
|||||||
func Parse(specifier string) (specs.Platform, error) {
|
func Parse(specifier string) (specs.Platform, error) {
|
||||||
if strings.Contains(specifier, "*") {
|
if strings.Contains(specifier, "*") {
|
||||||
// TODO(stevvooe): need to work out exact wildcard handling
|
// 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, "/")
|
parts := strings.Split(specifier, "/")
|
||||||
|
|
||||||
for _, part := range parts {
|
for _, part := range parts {
|
||||||
if !specifierRe.MatchString(part) {
|
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)
|
return specs.Platform{}, fmt.Errorf("%q is an invalid component of %q: platform specifier component must match %q: %w", part, specifier, specifierRe.String(), errInvalidArgument)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +226,7 @@ func Parse(specifier string) (specs.Platform, error) {
|
|||||||
return p, nil
|
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:
|
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/arch pair. We don't care
|
||||||
// about whether or not we know of the platform.
|
// about whether or not we know of the platform.
|
||||||
@ -259,7 +256,7 @@ func Parse(specifier string) (specs.Platform, error) {
|
|||||||
return p, nil
|
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.
|
// MustParse is like Parses but panics if the specifier cannot be parsed.
|
||||||
@ -291,30 +288,3 @@ func Normalize(platform specs.Platform) specs.Platform {
|
|||||||
|
|
||||||
return platform
|
return platform
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToProto converts from a slice of [Platform] to a slice of
|
|
||||||
// the protobuf definition [types.Platform].
|
|
||||||
func ToProto(platforms []Platform) []*types.Platform {
|
|
||||||
ap := make([]*types.Platform, len(platforms))
|
|
||||||
for i := range platforms {
|
|
||||||
p := types.Platform{
|
|
||||||
OS: platforms[i].OS,
|
|
||||||
Architecture: platforms[i].Architecture,
|
|
||||||
Variant: platforms[i].Variant,
|
|
||||||
}
|
|
||||||
ap[i] = &p
|
|
||||||
}
|
|
||||||
return ap
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromProto converts a slice of the protobuf definition [types.Platform]
|
|
||||||
// to a slice of [Platform].
|
|
||||||
func FromProto(platforms []*types.Platform) []Platform {
|
|
||||||
op := make([]Platform, len(platforms))
|
|
||||||
for i := range platforms {
|
|
||||||
op[i].OS = platforms[i].OS
|
|
||||||
op[i].Architecture = platforms[i].Architecture
|
|
||||||
op[i].Variant = platforms[i].Variant
|
|
||||||
}
|
|
||||||
return op
|
|
||||||
}
|
|
||||||
|
@ -24,9 +24,9 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
api "github.com/containerd/containerd/api/services/introspection/v1"
|
api "github.com/containerd/containerd/api/services/introspection/v1"
|
||||||
|
"github.com/containerd/containerd/api/types"
|
||||||
"github.com/containerd/containerd/errdefs"
|
"github.com/containerd/containerd/errdefs"
|
||||||
"github.com/containerd/containerd/filters"
|
"github.com/containerd/containerd/filters"
|
||||||
"github.com/containerd/containerd/platforms"
|
|
||||||
"github.com/containerd/containerd/plugin"
|
"github.com/containerd/containerd/plugin"
|
||||||
ptypes "github.com/containerd/containerd/protobuf/types"
|
ptypes "github.com/containerd/containerd/protobuf/types"
|
||||||
"github.com/containerd/containerd/services"
|
"github.com/containerd/containerd/services"
|
||||||
@ -222,7 +222,7 @@ func pluginsToPB(plugins []*plugin.Plugin) []*api.Plugin {
|
|||||||
Type: p.Registration.Type.String(),
|
Type: p.Registration.Type.String(),
|
||||||
ID: p.Registration.ID,
|
ID: p.Registration.ID,
|
||||||
Requires: requires,
|
Requires: requires,
|
||||||
Platforms: platforms.ToProto(p.Meta.Platforms),
|
Platforms: types.OCIPlatformToProto(p.Meta.Platforms),
|
||||||
Capabilities: p.Meta.Capabilities,
|
Capabilities: p.Meta.Capabilities,
|
||||||
Exports: p.Meta.Exports,
|
Exports: p.Meta.Exports,
|
||||||
InitErr: initErr,
|
InitErr: initErr,
|
||||||
|
Loading…
Reference in New Issue
Block a user