image: implement CheckOS, deprecate pkg/system IsOSSupported

Implement a function that returns an error to replace existing uses of
the IsOSSupported utility, where callers had to produce the error after
checking.

The IsOSSupported function was used in combination with images, so implementing
a utility in "image" to prevent having to import pkg/system (which contains many
unrelated functions)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2023-09-06 12:35:50 +02:00
parent 150b657bad
commit a3c97beee0
No known key found for this signature in database
GPG key ID: 76698F39D527CE8C
16 changed files with 70 additions and 55 deletions

View file

@ -22,7 +22,6 @@ import (
"github.com/docker/docker/errdefs"
"github.com/docker/docker/image"
"github.com/docker/docker/pkg/jsonmessage"
"github.com/docker/docker/pkg/system"
"github.com/docker/go-connections/nat"
"github.com/moby/buildkit/frontend/dockerfile/instructions"
"github.com/moby/buildkit/frontend/dockerfile/parser"
@ -331,8 +330,8 @@ func dispatchWorkdir(ctx context.Context, d dispatchRequest, c *instructions.Wor
// RUN echo hi # cmd /S /C echo hi (Windows)
// RUN [ "echo", "hi" ] # echo hi
func dispatchRun(ctx context.Context, d dispatchRequest, c *instructions.RunCommand) error {
if !system.IsOSSupported(d.state.operatingSystem) {
return system.ErrNotSupportedOperatingSystem
if err := image.CheckOS(d.state.operatingSystem); err != nil {
return err
}
if len(c.FlagsUsed) > 0 {

View file

@ -28,8 +28,8 @@ import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/builder"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/image"
"github.com/docker/docker/oci"
"github.com/docker/docker/pkg/system"
"github.com/docker/docker/runconfig/opts"
"github.com/moby/buildkit/frontend/dockerfile/instructions"
"github.com/moby/buildkit/frontend/dockerfile/shell"
@ -213,21 +213,21 @@ func (s *dispatchState) hasFromImage() bool {
return s.imageID != "" || (s.baseImage != nil && s.baseImage.ImageID() == "")
}
func (s *dispatchState) beginStage(stageName string, image builder.Image) error {
func (s *dispatchState) beginStage(stageName string, img builder.Image) error {
s.stageName = stageName
s.imageID = image.ImageID()
s.operatingSystem = image.OperatingSystem()
if !system.IsOSSupported(s.operatingSystem) {
return system.ErrNotSupportedOperatingSystem
s.imageID = img.ImageID()
s.operatingSystem = img.OperatingSystem()
if err := image.CheckOS(s.operatingSystem); err != nil {
return err
}
if image.RunConfig() != nil {
if img.RunConfig() != nil {
// copy avoids referencing the same instance when 2 stages have the same base
s.runConfig = copyRunConfig(image.RunConfig())
s.runConfig = copyRunConfig(img.RunConfig())
} else {
s.runConfig = &container.Config{}
}
s.baseImage = image
s.baseImage = img
s.setDefaultPath()
s.runConfig.OpenStdin = false
s.runConfig.StdinOnce = false

View file

@ -31,7 +31,6 @@ import (
"github.com/docker/docker/pkg/progress"
"github.com/docker/docker/pkg/streamformatter"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/pkg/system"
"github.com/opencontainers/go-digest"
"github.com/opencontainers/image-spec/identity"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
@ -49,8 +48,8 @@ func (i *ImageService) GetImageAndReleasableLayer(ctx context.Context, refOrID s
if opts.Platform != nil {
imgOS = opts.Platform.OS
}
if !system.IsOSSupported(imgOS) {
return nil, nil, system.ErrNotSupportedOperatingSystem
if err := dimage.CheckOS(imgOS); err != nil {
return nil, nil, err
}
return nil, &rolayer{
key: "",
@ -72,8 +71,8 @@ func (i *ImageService) GetImageAndReleasableLayer(ctx context.Context, refOrID s
return nil, nil, err
}
if img != nil {
if !system.IsOSSupported(img.OperatingSystem()) {
return nil, nil, system.ErrNotSupportedOperatingSystem
if err := dimage.CheckOS(img.OperatingSystem()); err != nil {
return nil, nil, err
}
roLayer, err := newROLayerForImage(ctx, &imgDesc, i, opts.Platform)
@ -161,8 +160,8 @@ Please notify the image author to correct the configuration.`,
}
}
if !system.IsOSSupported(img.OperatingSystem()) {
return nil, system.ErrNotSupportedOperatingSystem
if err := dimage.CheckOS(img.OperatingSystem()); err != nil {
return nil, err
}
imgDesc, err := i.resolveDescriptor(ctx, name)

View file

@ -18,7 +18,6 @@ import (
"github.com/docker/docker/pkg/progress"
"github.com/docker/docker/pkg/streamformatter"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/pkg/system"
registrypkg "github.com/docker/docker/registry"
"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
@ -208,8 +207,8 @@ func (i *ImageService) GetImageAndReleasableLayer(ctx context.Context, refOrID s
if opts.Platform != nil {
os = opts.Platform.OS
}
if !system.IsOSSupported(os) {
return nil, nil, system.ErrNotSupportedOperatingSystem
if err := image.CheckOS(os); err != nil {
return nil, nil, err
}
lyr, err := newROLayerForImage(nil, i.layerStore)
return nil, lyr, err
@ -224,8 +223,8 @@ func (i *ImageService) GetImageAndReleasableLayer(ctx context.Context, refOrID s
return nil, nil, err
}
if img != nil {
if !system.IsOSSupported(img.OperatingSystem()) {
return nil, nil, system.ErrNotSupportedOperatingSystem
if err := image.CheckOS(img.OperatingSystem()); err != nil {
return nil, nil, err
}
lyr, err := newROLayerForImage(img, i.layerStore)
return img, lyr, err
@ -236,8 +235,8 @@ func (i *ImageService) GetImageAndReleasableLayer(ctx context.Context, refOrID s
if err != nil {
return nil, nil, err
}
if !system.IsOSSupported(img.OperatingSystem()) {
return nil, nil, system.ErrNotSupportedOperatingSystem
if err := image.CheckOS(img.OperatingSystem()); err != nil {
return nil, nil, err
}
lyr, err := newROLayerForImage(img, i.layerStore)
return img, lyr, err

View file

@ -16,7 +16,6 @@ import (
"github.com/docker/docker/image"
"github.com/docker/docker/layer"
"github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/system"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
@ -32,8 +31,8 @@ func (i *ImageService) ImportImage(ctx context.Context, newRef reference.Named,
def := platforms.DefaultSpec()
platform = &def
}
if !system.IsOSSupported(platform.OS) {
return "", errdefs.InvalidParameter(system.ErrNotSupportedOperatingSystem)
if err := image.CheckOS(platform.OS); err != nil {
return "", err
}
config, err := dockerfile.BuildFromConfig(ctx, &container.Config{}, changes, platform.OS)

View file

@ -13,7 +13,6 @@ import (
"github.com/docker/docker/container"
"github.com/docker/docker/image"
"github.com/docker/docker/layer"
"github.com/docker/docker/pkg/system"
)
var acceptedImageFilterTags = map[string]bool{
@ -116,7 +115,7 @@ func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions)
// Skip any images with an unsupported operating system to avoid a potential
// panic when indexing through the layerstore. Don't error as we want to list
// the other images. This should never happen, but here as a safety precaution.
if !system.IsOSSupported(img.OperatingSystem()) {
if err := image.CheckOS(img.OperatingSystem()); err != nil {
continue
}

View file

@ -5,7 +5,6 @@ import (
"github.com/docker/docker/image"
"github.com/docker/docker/layer"
"github.com/docker/docker/pkg/system"
"github.com/pkg/errors"
)
@ -22,8 +21,8 @@ func (i *ImageService) GetLayerFolders(img *image.Image, rwLayer layer.RWLayer)
for index := 1; index <= rd; index++ {
// FIXME: why does this mutate the RootFS?
img.RootFS.DiffIDs = img.RootFS.DiffIDs[:index]
if !system.IsOSSupported(img.OperatingSystem()) {
return nil, errors.Wrapf(system.ErrNotSupportedOperatingSystem, "cannot get layerpath for ImageID %s", img.RootFS.ChainID())
if err := image.CheckOS(img.OperatingSystem()); err != nil {
return nil, errors.Wrapf(err, "cannot get layerpath for ImageID %s", img.RootFS.ChainID())
}
layerPath, err := layer.GetLayerPath(i.layerStore, img.RootFS.ChainID())
if err != nil {

View file

@ -15,6 +15,7 @@ import (
"github.com/docker/docker/container"
"github.com/docker/docker/daemon/config"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/image"
"github.com/docker/docker/oci"
"github.com/docker/docker/pkg/sysinfo"
"github.com/docker/docker/pkg/system"
@ -33,8 +34,8 @@ func (daemon *Daemon) createSpec(ctx context.Context, daemonCfg *configStore, c
if err != nil {
return nil, err
}
if !system.IsOSSupported(img.OperatingSystem()) {
return nil, system.ErrNotSupportedOperatingSystem
if err := image.CheckOS(img.OperatingSystem()); err != nil {
return nil, err
}
s := oci.DefaultSpec()

View file

@ -16,7 +16,6 @@ import (
"github.com/docker/docker/image"
"github.com/docker/docker/layer"
"github.com/docker/docker/pkg/progress"
"github.com/docker/docker/pkg/system"
refstore "github.com/docker/docker/reference"
registrypkg "github.com/docker/docker/registry"
"github.com/opencontainers/go-digest"
@ -152,8 +151,8 @@ func platformFromConfig(c []byte) (*ocispec.Platform, error) {
if os == "" {
os = runtime.GOOS
}
if !system.IsOSSupported(os) {
return nil, errors.Wrapf(system.ErrNotSupportedOperatingSystem, "image operating system %q cannot be used on this platform", os)
if err := image.CheckOS(os); err != nil {
return nil, errors.Wrapf(err, "image operating system %q cannot be used on this platform", os)
}
return &ocispec.Platform{
OS: os,

View file

@ -27,7 +27,6 @@ import (
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/progress"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/pkg/system"
refstore "github.com/docker/docker/reference"
"github.com/docker/docker/registry"
"github.com/opencontainers/go-digest"
@ -517,7 +516,7 @@ func (p *puller) pullSchema1(ctx context.Context, ref reference.Reference, unver
if platform != nil {
// Early bath if the requested OS doesn't match that of the configuration.
// This avoids doing the download, only to potentially fail later.
if !system.IsOSSupported(platform.OS) {
if err := image.CheckOS(platform.OS); err != nil {
return "", "", fmt.Errorf("cannot download image with operating system %q when requesting %q", runtime.GOOS, platform.OS)
}
}
@ -701,7 +700,7 @@ func (p *puller) pullSchema2Layers(ctx context.Context, target distribution.Desc
if platform == nil {
// Early bath if the requested OS doesn't match that of the configuration.
// This avoids doing the download, only to potentially fail later.
if !system.IsOSSupported(configPlatform.OS) {
if err := image.CheckOS(configPlatform.OS); err != nil {
return "", fmt.Errorf("cannot download image with operating system %q when requesting %q", configPlatform.OS, layerStoreOS)
}
layerStoreOS = configPlatform.OS
@ -716,8 +715,10 @@ func (p *puller) pullSchema2Layers(ctx context.Context, target distribution.Desc
// Assume that the operating system is the host OS if blank, and validate it
// to ensure we don't cause a panic by an invalid index into the layerstores.
if layerStoreOS != "" && !system.IsOSSupported(layerStoreOS) {
return "", system.ErrNotSupportedOperatingSystem
if layerStoreOS != "" {
if err := image.CheckOS(layerStoreOS); err != nil {
return "", err
}
}
if p.config.DownloadManager != nil {

View file

@ -18,7 +18,7 @@ import (
"github.com/docker/distribution/manifest/manifestlist"
"github.com/docker/distribution/manifest/schema2"
"github.com/docker/distribution/registry/client/transport"
"github.com/docker/docker/pkg/system"
"github.com/docker/docker/image"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
@ -86,7 +86,7 @@ func filterManifests(manifests []manifestlist.ManifestDescriptor, p ocispec.Plat
// Explicit user request for an OS
os = p.OS
}
if !system.IsOSSupported(os) {
if err := image.CheckOS(os); err != nil {
skip()
continue
}

18
image/image_os.go Normal file
View file

@ -0,0 +1,18 @@
package image
import (
"errors"
"runtime"
"strings"
"github.com/docker/docker/errdefs"
)
// CheckOS checks if the given OS matches the host's platform, and
// returns an error otherwise.
func CheckOS(os string) error {
if !strings.EqualFold(runtime.GOOS, os) {
return errdefs.InvalidParameter(errors.New("operating system is not supported"))
}
return nil
}

View file

@ -9,7 +9,6 @@ import (
"github.com/containerd/containerd/log"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/layer"
"github.com/docker/docker/pkg/system"
"github.com/opencontainers/go-digest"
"github.com/opencontainers/go-digest/digestset"
"github.com/pkg/errors"
@ -83,7 +82,7 @@ func (is *store) restore() error {
}
var l layer.Layer
if chainID := img.RootFS.ChainID(); chainID != "" {
if !system.IsOSSupported(img.OperatingSystem()) {
if err := CheckOS(img.OperatingSystem()); err != nil {
log.G(context.TODO()).WithFields(f{"chainID": chainID, "os": img.OperatingSystem()}).Error("not restoring image with unsupported operating system")
return nil
}
@ -164,8 +163,8 @@ func (is *store) Create(config []byte) (ID, error) {
var l layer.Layer
if layerID != "" {
if !system.IsOSSupported(img.OperatingSystem()) {
return "", errdefs.InvalidParameter(system.ErrNotSupportedOperatingSystem)
if err := CheckOS(img.OperatingSystem()); err != nil {
return "", err
}
l, err = is.lss.Get(layerID)
if err != nil {

View file

@ -23,7 +23,6 @@ import (
"github.com/docker/docker/pkg/progress"
"github.com/docker/docker/pkg/streamformatter"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/pkg/system"
"github.com/moby/sys/sequential"
"github.com/moby/sys/symlink"
"github.com/opencontainers/go-digest"
@ -85,7 +84,7 @@ func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer, quiet bool)
if err != nil {
return err
}
if !system.IsOSSupported(img.OperatingSystem()) {
if err := image.CheckOS(img.OperatingSystem()); err != nil {
return fmt.Errorf("cannot load %s image on %s", img.OperatingSystem(), runtime.GOOS)
}
rootFS := *img.RootFS
@ -297,7 +296,7 @@ func (l *tarexporter) legacyLoadImage(oldID, sourceDir string, loadedMap map[str
if img.OS == "" {
img.OS = runtime.GOOS
}
if !system.IsOSSupported(img.OS) {
if err := image.CheckOS(img.OS); err != nil {
return fmt.Errorf("cannot load %s image on %s", img.OS, runtime.GOOS)
}

View file

@ -151,8 +151,8 @@ func (l *tarexporter) takeLayerReference(id image.ID, imgDescr *imageDescriptor)
if err != nil {
return err
}
if os := img.OperatingSystem(); !system.IsOSSupported(os) {
return fmt.Errorf("os %q is not supported", os)
if err := image.CheckOS(img.OperatingSystem()); err != nil {
return fmt.Errorf("os %q is not supported", img.OperatingSystem())
}
imgDescr.image = img
topLayerID := img.RootFS.ChainID()

View file

@ -7,9 +7,13 @@ import (
)
// ErrNotSupportedOperatingSystem means the operating system is not supported.
//
// Deprecated: use [github.com/docker/docker/image.CheckOS] and check the error returned.
var ErrNotSupportedOperatingSystem = errors.New("operating system is not supported")
// IsOSSupported determines if an operating system is supported by the host.
//
// Deprecated: use [github.com/docker/docker/image.CheckOS] and check the error returned.
func IsOSSupported(os string) bool {
return strings.EqualFold(runtime.GOOS, os)
}