a3c97beee0
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>
90 lines
2.5 KiB
Go
90 lines
2.5 KiB
Go
package images // import "github.com/docker/docker/daemon/images"
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"io"
|
|
"time"
|
|
|
|
"github.com/containerd/containerd/platforms"
|
|
"github.com/distribution/reference"
|
|
"github.com/docker/docker/api/types/container"
|
|
"github.com/docker/docker/api/types/events"
|
|
"github.com/docker/docker/builder/dockerfile"
|
|
"github.com/docker/docker/dockerversion"
|
|
"github.com/docker/docker/errdefs"
|
|
"github.com/docker/docker/image"
|
|
"github.com/docker/docker/layer"
|
|
"github.com/docker/docker/pkg/archive"
|
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
|
)
|
|
|
|
// ImportImage imports an image, getting the archived layer data from layerReader.
|
|
// Uncompressed layer archive is passed to the layerStore and handled by the
|
|
// underlying graph driver.
|
|
// Image is tagged with the given reference.
|
|
// If the platform is nil, the default host platform is used.
|
|
// Message is used as the image's history comment.
|
|
// Image configuration is derived from the dockerfile instructions in changes.
|
|
func (i *ImageService) ImportImage(ctx context.Context, newRef reference.Named, platform *ocispec.Platform, msg string, layerReader io.Reader, changes []string) (image.ID, error) {
|
|
if platform == nil {
|
|
def := platforms.DefaultSpec()
|
|
platform = &def
|
|
}
|
|
if err := image.CheckOS(platform.OS); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
config, err := dockerfile.BuildFromConfig(ctx, &container.Config{}, changes, platform.OS)
|
|
if err != nil {
|
|
return "", errdefs.InvalidParameter(err)
|
|
}
|
|
|
|
inflatedLayerData, err := archive.DecompressStream(layerReader)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
l, err := i.layerStore.Register(inflatedLayerData, "")
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer layer.ReleaseAndLog(i.layerStore, l)
|
|
|
|
created := time.Now().UTC()
|
|
imgConfig, err := json.Marshal(&image.Image{
|
|
V1Image: image.V1Image{
|
|
DockerVersion: dockerversion.Version,
|
|
Config: config,
|
|
Architecture: platform.Architecture,
|
|
Variant: platform.Variant,
|
|
OS: platform.OS,
|
|
Created: &created,
|
|
Comment: msg,
|
|
},
|
|
RootFS: &image.RootFS{
|
|
Type: "layers",
|
|
DiffIDs: []layer.DiffID{l.DiffID()},
|
|
},
|
|
History: []image.History{{
|
|
Created: &created,
|
|
Comment: msg,
|
|
}},
|
|
})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
id, err := i.imageStore.Create(imgConfig)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if newRef != nil {
|
|
if err := i.TagImage(ctx, id, newRef); err != nil {
|
|
return "", err
|
|
}
|
|
}
|
|
|
|
i.LogImageEvent(id.String(), id.String(), events.ActionImport)
|
|
return id, nil
|
|
}
|