github.com/moby/docker@v26.1.3+incompatible/daemon/images/image_import.go (about)

     1  package images // import "github.com/docker/docker/daemon/images"
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"io"
     7  	"time"
     8  
     9  	"github.com/containerd/containerd/platforms"
    10  	"github.com/distribution/reference"
    11  	"github.com/docker/docker/api/types/container"
    12  	"github.com/docker/docker/api/types/events"
    13  	"github.com/docker/docker/builder/dockerfile"
    14  	"github.com/docker/docker/dockerversion"
    15  	"github.com/docker/docker/errdefs"
    16  	"github.com/docker/docker/image"
    17  	"github.com/docker/docker/layer"
    18  	"github.com/docker/docker/pkg/archive"
    19  	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
    20  )
    21  
    22  // ImportImage imports an image, getting the archived layer data from layerReader.
    23  // Uncompressed layer archive is passed to the layerStore and handled by the
    24  // underlying graph driver.
    25  // Image is tagged with the given reference.
    26  // If the platform is nil, the default host platform is used.
    27  // Message is used as the image's history comment.
    28  // Image configuration is derived from the dockerfile instructions in changes.
    29  func (i *ImageService) ImportImage(ctx context.Context, newRef reference.Named, platform *ocispec.Platform, msg string, layerReader io.Reader, changes []string) (image.ID, error) {
    30  	if platform == nil {
    31  		def := platforms.DefaultSpec()
    32  		platform = &def
    33  	}
    34  	if err := image.CheckOS(platform.OS); err != nil {
    35  		return "", err
    36  	}
    37  
    38  	config, err := dockerfile.BuildFromConfig(ctx, &container.Config{}, changes, platform.OS)
    39  	if err != nil {
    40  		return "", errdefs.InvalidParameter(err)
    41  	}
    42  
    43  	inflatedLayerData, err := archive.DecompressStream(layerReader)
    44  	if err != nil {
    45  		return "", err
    46  	}
    47  	l, err := i.layerStore.Register(inflatedLayerData, "")
    48  	if err != nil {
    49  		return "", err
    50  	}
    51  	defer layer.ReleaseAndLog(i.layerStore, l)
    52  
    53  	created := time.Now().UTC()
    54  	imgConfig, err := json.Marshal(&image.Image{
    55  		V1Image: image.V1Image{
    56  			DockerVersion: dockerversion.Version,
    57  			Config:        config,
    58  			Architecture:  platform.Architecture,
    59  			Variant:       platform.Variant,
    60  			OS:            platform.OS,
    61  			Created:       &created,
    62  			Comment:       msg,
    63  		},
    64  		RootFS: &image.RootFS{
    65  			Type:    "layers",
    66  			DiffIDs: []layer.DiffID{l.DiffID()},
    67  		},
    68  		History: []image.History{{
    69  			Created: &created,
    70  			Comment: msg,
    71  		}},
    72  	})
    73  	if err != nil {
    74  		return "", err
    75  	}
    76  
    77  	id, err := i.imageStore.Create(imgConfig)
    78  	if err != nil {
    79  		return "", err
    80  	}
    81  
    82  	if newRef != nil {
    83  		if err := i.TagImage(ctx, id, newRef); err != nil {
    84  			return "", err
    85  		}
    86  	}
    87  
    88  	i.LogImageEvent(id.String(), id.String(), events.ActionImport)
    89  	return id, nil
    90  }