diff options
author | Paweł Gronowski <pawel.gronowski@docker.com> | 2022-12-12 16:30:04 +0100 |
---|---|---|
committer | Paweł Gronowski <pawel.gronowski@docker.com> | 2023-01-11 13:53:40 +0100 |
commit | 28327f10a2216681061307fae566a6c913442f45 (patch) | |
tree | 3ed83a098ae9bbaf9dd73b560e5101d023a35cc1 /api/server | |
parent | b139a7636f3b6a3d9ad0e2d6dc8bcb687ba2f2cc (diff) | |
download | docker-28327f10a2216681061307fae566a6c913442f45.tar.gz |
daemon/import: Extract common logic to api
Extract logic that would need to be duplicated in both implementations
of ImageService.
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
Diffstat (limited to 'api/server')
-rw-r--r-- | api/server/router/image/backend.go | 3 | ||||
-rw-r--r-- | api/server/router/image/image_routes.go | 62 |
2 files changed, 62 insertions, 3 deletions
diff --git a/api/server/router/image/backend.go b/api/server/router/image/backend.go index 7ec0dc59c9..221d12e241 100644 --- a/api/server/router/image/backend.go +++ b/api/server/router/image/backend.go @@ -4,6 +4,7 @@ import ( "context" "io" + "github.com/docker/distribution/reference" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/image" @@ -31,7 +32,7 @@ type imageBackend interface { type importExportBackend interface { LoadImage(ctx context.Context, inTar io.ReadCloser, outStream io.Writer, quiet bool) error - ImportImage(ctx context.Context, src string, repository string, platform *specs.Platform, tag string, msg string, inConfig io.ReadCloser, outStream io.Writer, changes []string) error + ImportImage(ctx context.Context, ref reference.Named, platform *specs.Platform, msg string, layerReader io.Reader, changes []string) (dockerimage.ID, error) ExportImage(ctx context.Context, names []string, outStream io.Writer) error } diff --git a/api/server/router/image/image_routes.go b/api/server/router/image/image_routes.go index ab64b1511a..c49cd102b0 100644 --- a/api/server/router/image/image_routes.go +++ b/api/server/router/image/image_routes.go @@ -2,7 +2,9 @@ package image // import "github.com/docker/docker/api/server/router/image" import ( "context" + "io" "net/http" + "net/url" "strconv" "strings" "time" @@ -15,9 +17,11 @@ import ( opts "github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/registry" "github.com/docker/docker/api/types/versions" + "github.com/docker/docker/builder/remotecontext" "github.com/docker/docker/errdefs" "github.com/docker/docker/image" "github.com/docker/docker/pkg/ioutils" + "github.com/docker/docker/pkg/progress" "github.com/docker/docker/pkg/streamformatter" specs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" @@ -33,7 +37,7 @@ func (ir *imageRouter) postImagesCreate(ctx context.Context, w http.ResponseWrit img = r.Form.Get("fromImage") repo = r.Form.Get("repo") tag = r.Form.Get("tag") - message = r.Form.Get("message") + comment = r.Form.Get("message") progressErr error output = ioutils.NewWriteFlusher(w) platform *specs.Platform @@ -67,7 +71,61 @@ func (ir *imageRouter) postImagesCreate(ctx context.Context, w http.ResponseWrit progressErr = ir.backend.PullImage(ctx, img, tag, platform, metaHeaders, authConfig, output) } else { // import src := r.Form.Get("fromSrc") - progressErr = ir.backend.ImportImage(ctx, src, repo, platform, tag, message, r.Body, output, r.Form["changes"]) + + var ref reference.Named + if repo != "" { + var err error + ref, err = reference.ParseNormalizedNamed(repo) + if err != nil { + return errdefs.InvalidParameter(err) + } + if _, isCanonical := ref.(reference.Canonical); isCanonical { + return errdefs.InvalidParameter(errors.New("cannot import digest reference")) + } + + if tag != "" { + ref, err = reference.WithTag(ref, tag) + if err != nil { + return errdefs.InvalidParameter(err) + } + } else { + ref = reference.TagNameOnly(ref) + } + } + + if len(comment) == 0 { + comment = "Imported from " + src + } + + var layerReader io.ReadCloser + defer r.Body.Close() + if src == "-" { + layerReader = r.Body + } else { + if len(strings.Split(src, "://")) == 1 { + src = "http://" + src + } + u, err := url.Parse(src) + if err != nil { + return errdefs.InvalidParameter(err) + } + + resp, err := remotecontext.GetWithStatusError(u.String()) + if err != nil { + return err + } + output.Write(streamformatter.FormatStatus("", "Downloading from %s", u)) + progressOutput := streamformatter.NewJSONProgressOutput(output, true) + layerReader = progress.NewProgressReader(resp.Body, progressOutput, resp.ContentLength, "", "Importing") + defer layerReader.Close() + } + + var id image.ID + id, progressErr = ir.backend.ImportImage(ctx, ref, platform, comment, layerReader, r.Form["changes"]) + + if progressErr == nil { + output.Write(streamformatter.FormatStatus("", id.String())) + } } if progressErr != nil { if !output.Flushed() { |