image_import.go 2.5 KB

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