4352da78 |
package daemon
import (
"encoding/json"
"io"
"net/http"
"net/url"
"runtime" |
e050f176 |
"strings" |
4352da78 |
"time"
|
3a127939 |
"github.com/docker/distribution/reference" |
91e197d6 |
"github.com/docker/docker/api/types/container" |
93e02efa |
"github.com/docker/docker/builder/dockerfile" |
4060d6ee |
"github.com/docker/docker/builder/remotecontext" |
4352da78 |
"github.com/docker/docker/dockerversion"
"github.com/docker/docker/image"
"github.com/docker/docker/layer" |
e1c2eb0d |
"github.com/docker/docker/pkg/archive" |
572ce802 |
"github.com/docker/docker/pkg/progress" |
4352da78 |
"github.com/docker/docker/pkg/streamformatter" |
3a127939 |
"github.com/pkg/errors" |
4352da78 |
)
// ImportImage imports an image, getting the archived layer data either from
// inConfig (if src is "-"), or from a URI specified in src. Progress output is
// written to outStream. Repository and tag names can optionally be given in
// the repo and tag arguments, respectively. |
0380fbff |
func (daemon *Daemon) ImportImage(src string, repository, os string, tag string, msg string, inConfig io.ReadCloser, outStream io.Writer, changes []string) error { |
4352da78 |
var ( |
47afe6bd |
rc io.ReadCloser
resp *http.Response
newRef reference.Named |
4352da78 |
)
|
0380fbff |
// Default the operating system if not supplied.
if os == "" {
os = runtime.GOOS |
3d5cec70 |
}
|
47afe6bd |
if repository != "" {
var err error |
3a127939 |
newRef, err = reference.ParseNormalizedNamed(repository) |
47afe6bd |
if err != nil { |
ebcb7d6b |
return validationError{err} |
47afe6bd |
}
if _, isCanonical := newRef.(reference.Canonical); isCanonical { |
ebcb7d6b |
return validationError{errors.New("cannot import digest reference")} |
47afe6bd |
}
if tag != "" {
newRef, err = reference.WithTag(newRef, tag)
if err != nil { |
ebcb7d6b |
return validationError{err} |
47afe6bd |
}
}
}
|
93e02efa |
config, err := dockerfile.BuildFromConfig(&container.Config{}, changes)
if err != nil {
return err
} |
4352da78 |
if src == "-" { |
e1c2eb0d |
rc = inConfig |
4352da78 |
} else {
inConfig.Close() |
e050f176 |
if len(strings.Split(src, "://")) == 1 {
src = "http://" + src
} |
4352da78 |
u, err := url.Parse(src)
if err != nil { |
ebcb7d6b |
return validationError{err} |
4352da78 |
} |
e050f176 |
|
4060d6ee |
resp, err = remotecontext.GetWithStatusError(u.String()) |
4352da78 |
if err != nil {
return err
} |
c87d67b0 |
outStream.Write(streamformatter.FormatStatus("", "Downloading from %s", u))
progressOutput := streamformatter.NewJSONProgressOutput(outStream, true) |
e1c2eb0d |
rc = progress.NewProgressReader(resp.Body, progressOutput, resp.ContentLength, "", "Importing") |
4352da78 |
}
|
e1c2eb0d |
defer rc.Close() |
4352da78 |
if len(msg) == 0 {
msg = "Imported from " + src
} |
e1c2eb0d |
inflatedLayerData, err := archive.DecompressStream(rc)
if err != nil {
return err
} |
0380fbff |
l, err := daemon.stores[os].layerStore.Register(inflatedLayerData, "", layer.OS(os)) |
4352da78 |
if err != nil {
return err
} |
0380fbff |
defer layer.ReleaseAndLog(daemon.stores[os].layerStore, l) |
4352da78 |
created := time.Now().UTC()
imgConfig, err := json.Marshal(&image.Image{
V1Image: image.V1Image{
DockerVersion: dockerversion.Version,
Config: config,
Architecture: runtime.GOARCH, |
0380fbff |
OS: os, |
4352da78 |
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
}
|
0380fbff |
id, err := daemon.stores[os].imageStore.Create(imgConfig) |
4352da78 |
if err != nil {
return err
}
|
2655954c |
// FIXME: connect with commit code and call refstore directly |
4352da78 |
if newRef != nil { |
0380fbff |
if err := daemon.TagImageWithReference(id, os, newRef); err != nil { |
4352da78 |
return err
}
}
|
72f1881d |
daemon.LogImageEvent(id.String(), id.String(), "import") |
c87d67b0 |
outStream.Write(streamformatter.FormatStatus("", id.String())) |
4352da78 |
return nil
} |