Docker-DCO-1.1-Signed-off-by: Victor Vieux <victor.vieux@docker.com> (github: vieux)
| ... | ... |
@@ -413,11 +413,11 @@ func postImagesCreate(srv *Server, version float64, w http.ResponseWriter, r *ht |
| 413 | 413 |
return err |
| 414 | 414 |
} |
| 415 | 415 |
|
| 416 |
- src := r.Form.Get("fromSrc")
|
|
| 417 |
- image := r.Form.Get("fromImage")
|
|
| 418 |
- tag := r.Form.Get("tag")
|
|
| 419 |
- repo := r.Form.Get("repo")
|
|
| 420 |
- |
|
| 416 |
+ var ( |
|
| 417 |
+ image = r.Form.Get("fromImage")
|
|
| 418 |
+ tag = r.Form.Get("tag")
|
|
| 419 |
+ job *engine.Job |
|
| 420 |
+ ) |
|
| 421 | 421 |
authEncoded := r.Header.Get("X-Registry-Auth")
|
| 422 | 422 |
authConfig := &auth.AuthConfig{}
|
| 423 | 423 |
if authEncoded != "" {
|
| ... | ... |
@@ -431,7 +431,6 @@ func postImagesCreate(srv *Server, version float64, w http.ResponseWriter, r *ht |
| 431 | 431 |
if version > 1.0 {
|
| 432 | 432 |
w.Header().Set("Content-Type", "application/json")
|
| 433 | 433 |
} |
| 434 |
- sf := utils.NewStreamFormatter(version > 1.0) |
|
| 435 | 434 |
if image != "" { //pull
|
| 436 | 435 |
metaHeaders := map[string][]string{}
|
| 437 | 436 |
for k, v := range r.Header {
|
| ... | ... |
@@ -439,22 +438,25 @@ func postImagesCreate(srv *Server, version float64, w http.ResponseWriter, r *ht |
| 439 | 439 |
metaHeaders[k] = v |
| 440 | 440 |
} |
| 441 | 441 |
} |
| 442 |
- if err := srv.ImagePull(image, tag, w, sf, authConfig, metaHeaders, version > 1.3); err != nil {
|
|
| 443 |
- if sf.Used() {
|
|
| 444 |
- w.Write(sf.FormatError(err)) |
|
| 445 |
- return nil |
|
| 446 |
- } |
|
| 447 |
- return err |
|
| 448 |
- } |
|
| 442 |
+ job = srv.Eng.Job("pull", r.Form.Get("fromImage"), tag)
|
|
| 443 |
+ job.SetenvBool("parallel", version > 1.3)
|
|
| 444 |
+ job.SetenvJson("metaHeaders", metaHeaders)
|
|
| 445 |
+ job.SetenvJson("authConfig", authConfig)
|
|
| 449 | 446 |
} else { //import
|
| 450 |
- if err := srv.ImageImport(src, repo, tag, r.Body, w, sf); err != nil {
|
|
| 451 |
- if sf.Used() {
|
|
| 452 |
- w.Write(sf.FormatError(err)) |
|
| 453 |
- return nil |
|
| 454 |
- } |
|
| 447 |
+ job = srv.Eng.Job("import", r.Form.Get("fromSrc"), r.Form.Get("repo"), tag)
|
|
| 448 |
+ job.Stdin.Add(r.Body) |
|
| 449 |
+ } |
|
| 450 |
+ |
|
| 451 |
+ job.SetenvBool("json", version > 1.0)
|
|
| 452 |
+ job.Stdout.Add(w) |
|
| 453 |
+ if err := job.Run(); err != nil {
|
|
| 454 |
+ if !job.Stdout.Used() {
|
|
| 455 | 455 |
return err |
| 456 | 456 |
} |
| 457 |
+ sf := utils.NewStreamFormatter(version > 1.0) |
|
| 458 |
+ w.Write(sf.FormatError(err)) |
|
| 457 | 459 |
} |
| 460 |
+ |
|
| 458 | 461 |
return nil |
| 459 | 462 |
} |
| 460 | 463 |
|
| ... | ... |
@@ -84,7 +84,12 @@ func (b *buildFile) CmdFrom(name string) error {
|
| 84 | 84 |
resolvedAuth := b.configFile.ResolveAuthConfig(endpoint) |
| 85 | 85 |
pullRegistryAuth = &resolvedAuth |
| 86 | 86 |
} |
| 87 |
- if err := b.srv.ImagePull(remote, tag, b.outOld, b.sf, pullRegistryAuth, nil, true); err != nil {
|
|
| 87 |
+ job := b.srv.Eng.Job("pull", remote, tag)
|
|
| 88 |
+ job.SetenvBool("json", b.sf.Json())
|
|
| 89 |
+ job.SetenvBool("parallel", true)
|
|
| 90 |
+ job.SetenvJson("authConfig", pullRegistryAuth)
|
|
| 91 |
+ job.Stdout.Add(b.outOld) |
|
| 92 |
+ if err := job.Run(); err != nil {
|
|
| 88 | 93 |
return err |
| 89 | 94 |
} |
| 90 | 95 |
image, err = b.runtime.repositories.LookupImage(name) |
| ... | ... |
@@ -137,6 +137,9 @@ func (eng *Engine) Job(name string, args ...string) *Job {
|
| 137 | 137 |
} |
| 138 | 138 |
|
| 139 | 139 |
func (eng *Engine) Logf(format string, args ...interface{}) (n int, err error) {
|
| 140 |
- prefixedFormat := fmt.Sprintf("[%s] %s\n", eng, strings.TrimRight(format, "\n"))
|
|
| 141 |
- return fmt.Fprintf(eng.Stderr, prefixedFormat, args...) |
|
| 140 |
+ if os.Getenv("TEST") == "" {
|
|
| 141 |
+ prefixedFormat := fmt.Sprintf("[%s] %s\n", eng, strings.TrimRight(format, "\n"))
|
|
| 142 |
+ return fmt.Fprintf(eng.Stderr, prefixedFormat, args...) |
|
| 143 |
+ } |
|
| 144 |
+ return 0, nil |
|
| 142 | 145 |
} |
| ... | ... |
@@ -3,6 +3,7 @@ package engine |
| 3 | 3 |
import ( |
| 4 | 4 |
"fmt" |
| 5 | 5 |
"io" |
| 6 |
+ "os" |
|
| 6 | 7 |
"strings" |
| 7 | 8 |
"time" |
| 8 | 9 |
) |
| ... | ... |
@@ -176,8 +177,11 @@ func (job *Job) Environ() map[string]string {
|
| 176 | 176 |
} |
| 177 | 177 |
|
| 178 | 178 |
func (job *Job) Logf(format string, args ...interface{}) (n int, err error) {
|
| 179 |
- prefixedFormat := fmt.Sprintf("[%s] %s\n", job, strings.TrimRight(format, "\n"))
|
|
| 180 |
- return fmt.Fprintf(job.Stderr, prefixedFormat, args...) |
|
| 179 |
+ if os.Getenv("TEST") == "" {
|
|
| 180 |
+ prefixedFormat := fmt.Sprintf("[%s] %s\n", job, strings.TrimRight(format, "\n"))
|
|
| 181 |
+ return fmt.Fprintf(job.Stderr, prefixedFormat, args...) |
|
| 182 |
+ } |
|
| 183 |
+ return 0, nil |
|
| 181 | 184 |
} |
| 182 | 185 |
|
| 183 | 186 |
func (job *Job) Printf(format string, args ...interface{}) (n int, err error) {
|
| ... | ... |
@@ -137,7 +137,9 @@ func setupBaseImage() {
|
| 137 | 137 |
// If the unit test is not found, try to download it. |
| 138 | 138 |
if img, err := srv.ImageInspect(unitTestImageName); err != nil || img.ID != unitTestImageID {
|
| 139 | 139 |
// Retrieve the Image |
| 140 |
- if err := srv.ImagePull(unitTestImageName, "", os.Stdout, utils.NewStreamFormatter(false), nil, nil, true); err != nil {
|
|
| 140 |
+ job = eng.Job("pull", unitTestImageName)
|
|
| 141 |
+ job.Stdout.Add(utils.NopWriteCloser(os.Stdout)) |
|
| 142 |
+ if err := job.Run(); err != nil {
|
|
| 141 | 143 |
log.Fatalf("Unable to pull the test image: %s", err)
|
| 142 | 144 |
} |
| 143 | 145 |
} |
| ... | ... |
@@ -2,8 +2,6 @@ package docker |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"github.com/dotcloud/docker" |
| 5 |
- "github.com/dotcloud/docker/utils" |
|
| 6 |
- "io/ioutil" |
|
| 7 | 5 |
"testing" |
| 8 | 6 |
"time" |
| 9 | 7 |
) |
| ... | ... |
@@ -53,5 +51,8 @@ func generateImage(name string, srv *docker.Server) error {
|
| 53 | 53 |
if err != nil {
|
| 54 | 54 |
return err |
| 55 | 55 |
} |
| 56 |
- return srv.ImageImport("-", "repo", name, archive, ioutil.Discard, utils.NewStreamFormatter(true))
|
|
| 56 |
+ job := srv.Eng.Job("import", "-", "repo", name)
|
|
| 57 |
+ job.Stdin.Add(archive) |
|
| 58 |
+ job.SetenvBool("json", true)
|
|
| 59 |
+ return job.Run() |
|
| 57 | 60 |
} |
| ... | ... |
@@ -97,6 +97,8 @@ func jobInitApi(job *engine.Job) engine.Status {
|
| 97 | 97 |
"top": srv.ContainerTop, |
| 98 | 98 |
"load": srv.ImageLoad, |
| 99 | 99 |
"build": srv.Build, |
| 100 |
+ "pull": srv.ImagePull, |
|
| 101 |
+ "import": srv.ImageImport, |
|
| 100 | 102 |
} {
|
| 101 | 103 |
if err := job.Eng.Register(name, handler); err != nil {
|
| 102 | 104 |
job.Error(err) |
| ... | ... |
@@ -1312,8 +1314,25 @@ func (srv *Server) poolRemove(kind, key string) error {
|
| 1312 | 1312 |
return nil |
| 1313 | 1313 |
} |
| 1314 | 1314 |
|
| 1315 |
-func (srv *Server) ImagePull(localName string, tag string, out io.Writer, sf *utils.StreamFormatter, authConfig *auth.AuthConfig, metaHeaders map[string][]string, parallel bool) error {
|
|
| 1316 |
- out = utils.NewWriteFlusher(out) |
|
| 1315 |
+func (srv *Server) ImagePull(job *engine.Job) engine.Status {
|
|
| 1316 |
+ if n := len(job.Args); n != 1 && n != 2 {
|
|
| 1317 |
+ job.Errorf("Usage: %s IMAGE [TAG]", job.Name)
|
|
| 1318 |
+ return engine.StatusErr |
|
| 1319 |
+ } |
|
| 1320 |
+ var ( |
|
| 1321 |
+ localName = job.Args[0] |
|
| 1322 |
+ tag string |
|
| 1323 |
+ sf = utils.NewStreamFormatter(job.GetenvBool("json"))
|
|
| 1324 |
+ out = utils.NewWriteFlusher(job.Stdout) |
|
| 1325 |
+ authConfig *auth.AuthConfig |
|
| 1326 |
+ metaHeaders map[string][]string |
|
| 1327 |
+ ) |
|
| 1328 |
+ if len(job.Args) > 1 {
|
|
| 1329 |
+ tag = job.Args[1] |
|
| 1330 |
+ } |
|
| 1331 |
+ |
|
| 1332 |
+ job.GetenvJson("authConfig", authConfig)
|
|
| 1333 |
+ job.GetenvJson("metaHeaders", metaHeaders)
|
|
| 1317 | 1334 |
|
| 1318 | 1335 |
c, err := srv.poolAdd("pull", localName+":"+tag)
|
| 1319 | 1336 |
if err != nil {
|
| ... | ... |
@@ -1321,21 +1340,24 @@ func (srv *Server) ImagePull(localName string, tag string, out io.Writer, sf *ut |
| 1321 | 1321 |
// Another pull of the same repository is already taking place; just wait for it to finish |
| 1322 | 1322 |
out.Write(sf.FormatStatus("", "Repository %s already being pulled by another client. Waiting.", localName))
|
| 1323 | 1323 |
<-c |
| 1324 |
- return nil |
|
| 1324 |
+ return engine.StatusOK |
|
| 1325 | 1325 |
} |
| 1326 |
- return err |
|
| 1326 |
+ job.Error(err) |
|
| 1327 |
+ return engine.StatusErr |
|
| 1327 | 1328 |
} |
| 1328 | 1329 |
defer srv.poolRemove("pull", localName+":"+tag)
|
| 1329 | 1330 |
|
| 1330 | 1331 |
// Resolve the Repository name from fqn to endpoint + name |
| 1331 | 1332 |
endpoint, remoteName, err := registry.ResolveRepositoryName(localName) |
| 1332 | 1333 |
if err != nil {
|
| 1333 |
- return err |
|
| 1334 |
+ job.Error(err) |
|
| 1335 |
+ return engine.StatusErr |
|
| 1334 | 1336 |
} |
| 1335 | 1337 |
|
| 1336 | 1338 |
r, err := registry.NewRegistry(authConfig, srv.HTTPRequestFactory(metaHeaders), endpoint) |
| 1337 | 1339 |
if err != nil {
|
| 1338 |
- return err |
|
| 1340 |
+ job.Error(err) |
|
| 1341 |
+ return engine.StatusErr |
|
| 1339 | 1342 |
} |
| 1340 | 1343 |
|
| 1341 | 1344 |
if endpoint == auth.IndexServerAddress() {
|
| ... | ... |
@@ -1343,11 +1365,12 @@ func (srv *Server) ImagePull(localName string, tag string, out io.Writer, sf *ut |
| 1343 | 1343 |
localName = remoteName |
| 1344 | 1344 |
} |
| 1345 | 1345 |
|
| 1346 |
- if err = srv.pullRepository(r, out, localName, remoteName, tag, sf, parallel); err != nil {
|
|
| 1347 |
- return err |
|
| 1346 |
+ if err = srv.pullRepository(r, out, localName, remoteName, tag, sf, job.GetenvBool("parallel")); err != nil {
|
|
| 1347 |
+ job.Error(err) |
|
| 1348 |
+ return engine.StatusErr |
|
| 1348 | 1349 |
} |
| 1349 | 1350 |
|
| 1350 |
- return nil |
|
| 1351 |
+ return engine.StatusOK |
|
| 1351 | 1352 |
} |
| 1352 | 1353 |
|
| 1353 | 1354 |
// Retrieve the all the images to be uploaded in the correct order |
| ... | ... |
@@ -1551,16 +1574,31 @@ func (srv *Server) ImagePush(localName string, out io.Writer, sf *utils.StreamFo |
| 1551 | 1551 |
return nil |
| 1552 | 1552 |
} |
| 1553 | 1553 |
|
| 1554 |
-func (srv *Server) ImageImport(src, repo, tag string, in io.Reader, out io.Writer, sf *utils.StreamFormatter) error {
|
|
| 1555 |
- var archive io.Reader |
|
| 1556 |
- var resp *http.Response |
|
| 1554 |
+func (srv *Server) ImageImport(job *engine.Job) engine.Status {
|
|
| 1555 |
+ if n := len(job.Args); n != 2 && n != 3 {
|
|
| 1556 |
+ job.Errorf("Usage: %s SRC REPO [TAG]", job.Name)
|
|
| 1557 |
+ return engine.StatusErr |
|
| 1558 |
+ } |
|
| 1559 |
+ var ( |
|
| 1560 |
+ src = job.Args[0] |
|
| 1561 |
+ repo = job.Args[1] |
|
| 1562 |
+ tag string |
|
| 1563 |
+ sf = utils.NewStreamFormatter(job.GetenvBool("json"))
|
|
| 1564 |
+ out = utils.NewWriteFlusher(job.Stdout) |
|
| 1565 |
+ archive io.Reader |
|
| 1566 |
+ resp *http.Response |
|
| 1567 |
+ ) |
|
| 1568 |
+ if len(job.Args) > 2 {
|
|
| 1569 |
+ tag = job.Args[2] |
|
| 1570 |
+ } |
|
| 1557 | 1571 |
|
| 1558 | 1572 |
if src == "-" {
|
| 1559 |
- archive = in |
|
| 1573 |
+ archive = job.Stdin |
|
| 1560 | 1574 |
} else {
|
| 1561 | 1575 |
u, err := url.Parse(src) |
| 1562 | 1576 |
if err != nil {
|
| 1563 |
- return err |
|
| 1577 |
+ job.Error(err) |
|
| 1578 |
+ return engine.StatusErr |
|
| 1564 | 1579 |
} |
| 1565 | 1580 |
if u.Scheme == "" {
|
| 1566 | 1581 |
u.Scheme = "http" |
| ... | ... |
@@ -1572,22 +1610,25 @@ func (srv *Server) ImageImport(src, repo, tag string, in io.Reader, out io.Write |
| 1572 | 1572 |
// If curl is not available, fallback to http.Get() |
| 1573 | 1573 |
resp, err = utils.Download(u.String()) |
| 1574 | 1574 |
if err != nil {
|
| 1575 |
- return err |
|
| 1575 |
+ job.Error(err) |
|
| 1576 |
+ return engine.StatusErr |
|
| 1576 | 1577 |
} |
| 1577 | 1578 |
archive = utils.ProgressReader(resp.Body, int(resp.ContentLength), out, sf, true, "", "Importing") |
| 1578 | 1579 |
} |
| 1579 | 1580 |
img, err := srv.runtime.graph.Create(archive, nil, "Imported from "+src, "", nil) |
| 1580 | 1581 |
if err != nil {
|
| 1581 |
- return err |
|
| 1582 |
+ job.Error(err) |
|
| 1583 |
+ return engine.StatusErr |
|
| 1582 | 1584 |
} |
| 1583 | 1585 |
// Optionally register the image at REPO/TAG |
| 1584 | 1586 |
if repo != "" {
|
| 1585 | 1587 |
if err := srv.runtime.repositories.Set(repo, tag, img.ID, true); err != nil {
|
| 1586 |
- return err |
|
| 1588 |
+ job.Error(err) |
|
| 1589 |
+ return engine.StatusErr |
|
| 1587 | 1590 |
} |
| 1588 | 1591 |
} |
| 1589 | 1592 |
out.Write(sf.FormatStatus("", img.ID))
|
| 1590 |
- return nil |
|
| 1593 |
+ return engine.StatusOK |
|
| 1591 | 1594 |
} |
| 1592 | 1595 |
|
| 1593 | 1596 |
func (srv *Server) ContainerCreate(job *engine.Job) engine.Status {
|