github.com/rumpl/bof@v23.0.0-rc.2+incompatible/daemon/images/image_import.go (about) 1 package images // import "github.com/docker/docker/daemon/images" 2 3 import ( 4 "encoding/json" 5 "io" 6 "net/http" 7 "net/url" 8 "strings" 9 "time" 10 11 "github.com/containerd/containerd/platforms" 12 "github.com/docker/distribution/reference" 13 "github.com/docker/docker/api/types/container" 14 "github.com/docker/docker/builder/dockerfile" 15 "github.com/docker/docker/builder/remotecontext" 16 "github.com/docker/docker/dockerversion" 17 "github.com/docker/docker/errdefs" 18 "github.com/docker/docker/image" 19 "github.com/docker/docker/layer" 20 "github.com/docker/docker/pkg/archive" 21 "github.com/docker/docker/pkg/progress" 22 "github.com/docker/docker/pkg/streamformatter" 23 "github.com/docker/docker/pkg/system" 24 specs "github.com/opencontainers/image-spec/specs-go/v1" 25 "github.com/pkg/errors" 26 ) 27 28 // ImportImage imports an image, getting the archived layer data either from 29 // inConfig (if src is "-"), or from a URI specified in src. Progress output is 30 // written to outStream. Repository and tag names can optionally be given in 31 // the repo and tag arguments, respectively. 32 func (i *ImageService) ImportImage(src string, repository string, platform *specs.Platform, tag string, msg string, inConfig io.ReadCloser, outStream io.Writer, changes []string) error { 33 var ( 34 rc io.ReadCloser 35 resp *http.Response 36 newRef reference.Named 37 ) 38 39 if repository != "" { 40 var err error 41 newRef, err = reference.ParseNormalizedNamed(repository) 42 if err != nil { 43 return errdefs.InvalidParameter(err) 44 } 45 if _, isCanonical := newRef.(reference.Canonical); isCanonical { 46 return errdefs.InvalidParameter(errors.New("cannot import digest reference")) 47 } 48 49 if tag != "" { 50 newRef, err = reference.WithTag(newRef, tag) 51 if err != nil { 52 return errdefs.InvalidParameter(err) 53 } 54 } 55 } 56 57 // Normalize platform - default to the operating system and architecture if not supplied. 58 if platform == nil { 59 p := platforms.DefaultSpec() 60 platform = &p 61 } 62 if !system.IsOSSupported(platform.OS) { 63 return errdefs.InvalidParameter(system.ErrNotSupportedOperatingSystem) 64 } 65 config, err := dockerfile.BuildFromConfig(&container.Config{}, changes, platform.OS) 66 if err != nil { 67 return err 68 } 69 if src == "-" { 70 rc = inConfig 71 } else { 72 inConfig.Close() 73 if len(strings.Split(src, "://")) == 1 { 74 src = "http://" + src 75 } 76 u, err := url.Parse(src) 77 if err != nil { 78 return errdefs.InvalidParameter(err) 79 } 80 81 resp, err = remotecontext.GetWithStatusError(u.String()) 82 if err != nil { 83 return err 84 } 85 outStream.Write(streamformatter.FormatStatus("", "Downloading from %s", u)) 86 progressOutput := streamformatter.NewJSONProgressOutput(outStream, true) 87 rc = progress.NewProgressReader(resp.Body, progressOutput, resp.ContentLength, "", "Importing") 88 } 89 90 defer rc.Close() 91 if len(msg) == 0 { 92 msg = "Imported from " + src 93 } 94 95 inflatedLayerData, err := archive.DecompressStream(rc) 96 if err != nil { 97 return err 98 } 99 l, err := i.layerStore.Register(inflatedLayerData, "") 100 if err != nil { 101 return err 102 } 103 defer layer.ReleaseAndLog(i.layerStore, l) 104 105 created := time.Now().UTC() 106 imgConfig, err := json.Marshal(&image.Image{ 107 V1Image: image.V1Image{ 108 DockerVersion: dockerversion.Version, 109 Config: config, 110 Architecture: platform.Architecture, 111 Variant: platform.Variant, 112 OS: platform.OS, 113 Created: created, 114 Comment: msg, 115 }, 116 RootFS: &image.RootFS{ 117 Type: "layers", 118 DiffIDs: []layer.DiffID{l.DiffID()}, 119 }, 120 History: []image.History{{ 121 Created: created, 122 Comment: msg, 123 }}, 124 }) 125 if err != nil { 126 return err 127 } 128 129 id, err := i.imageStore.Create(imgConfig) 130 if err != nil { 131 return err 132 } 133 134 // FIXME: connect with commit code and call refstore directly 135 if newRef != nil { 136 if err := i.TagImageWithReference(id, newRef); err != nil { 137 return err 138 } 139 } 140 141 i.LogImageEvent(id.String(), id.String(), "import") 142 outStream.Write(streamformatter.FormatStatus("", id.String())) 143 return nil 144 }