diff --git a/commands.go b/commands.go index a8247855fa..443d192bd2 100644 --- a/commands.go +++ b/commands.go @@ -402,30 +402,47 @@ func (srv *Server) CmdImport(stdin io.ReadCloser, stdout io.Writer, args ...stri } func (srv *Server) CmdPush(stdin io.ReadCloser, stdout io.Writer, args ...string) error { - cmd := rcli.Subcmd(stdout, "push", "[OPTIONS] IMAGE", "Push an image or a repository to the registry") - user := cmd.String("u", "", "specify the user for the repository") + cmd := rcli.Subcmd(stdout, "push", "LOCAL [REMOTE]", "Push an image or a repository to the registry") if err := cmd.Parse(args); err != nil { return nil } - if cmd.NArg() == 0 || *user == "" { + local := cmd.Arg(0) + remote := cmd.Arg(1) + + if local == "" { cmd.Usage() return nil } + // If the login failed, abort if srv.runtime.authConfig == nil { return fmt.Errorf("Please login prior to push. ('docker login')") } + if remote == "" { + tmp := strings.SplitN(local, "/", 2) + if len(tmp) == 1 { + remote = srv.runtime.authConfig.Username + "/" + local + } else { + remote = local + } + } else { + tmp := strings.SplitN(remote, "/", 2) + if len(tmp) == 1 { + return fmt.Errorf("The remote repository needs to be in the / format") + } + } + // Try to get the image // FIXME: Handle lookup // FIXME: Also push the tags in case of ./docker push myrepo:mytag // img, err := srv.runtime.LookupImage(cmd.Arg(0)) - img, err := srv.runtime.graph.Get(cmd.Arg(0)) + img, err := srv.runtime.graph.Get(local) if err != nil { // If it fails, try to get the repository - if repo, exists := srv.runtime.repositories.Repositories[cmd.Arg(0)]; exists { - fmt.Fprintf(stdout, "Pushing %s (%d images) on %s...\n", cmd.Arg(0), len(repo), *user+"/"+cmd.Arg(0)) - if err := srv.runtime.graph.PushRepository(*user, cmd.Arg(0), repo, srv.runtime.authConfig); err != nil { + if localRepo, exists := srv.runtime.repositories.Repositories[local]; exists { + fmt.Fprintf(stdout, "Pushing %s (%d images) on %s...\n", local, len(localRepo), remote) + if err := srv.runtime.graph.PushRepository(remote, localRepo, srv.runtime.authConfig); err != nil { return err } fmt.Fprintf(stdout, "Push completed\n") diff --git a/registry.go b/registry.go index 6cd64ff779..f39aa66552 100644 --- a/registry.go +++ b/registry.go @@ -287,22 +287,26 @@ func (graph *Graph) PushImage(imgOrig *Image, authConfig *auth.AuthConfig) error return nil } -func (graph *Graph) pushTag(user, repo, revision, tag string, authConfig *auth.AuthConfig) error { +// push a tag on the registry. +// Remote has the format '/ +func (graph *Graph) pushTag(remote, revision, tag string, authConfig *auth.AuthConfig) error { + // Keep this for backward compatibility if tag == "" { tag = "lastest" } + // "jsonify" the string revision = "\"" + revision + "\"" client := &http.Client{} - req, err := http.NewRequest("PUT", REGISTRY_ENDPOINT+"/users/"+user+"/"+repo+"/"+tag, strings.NewReader(revision)) + req, err := http.NewRequest("PUT", REGISTRY_ENDPOINT+"/users/"+remote+"/"+tag, strings.NewReader(revision)) req.Header.Add("Content-type", "application/json") req.SetBasicAuth(authConfig.Username, authConfig.Password) res, err := client.Do(req) if err != nil || (res.StatusCode != 200 && res.StatusCode != 201) { if res != nil { - return fmt.Errorf("Internal server error: %d trying to push tag %s on %s/%s", res.StatusCode, tag, user, repo) + return fmt.Errorf("Internal server error: %d trying to push tag %s on %s", res.StatusCode, tag, remote) } return err } @@ -316,8 +320,10 @@ func (graph *Graph) pushTag(user, repo, revision, tag string, authConfig *auth.A return nil } -func (graph *Graph) PushRepository(user, repoName string, repo Repository, authConfig *auth.AuthConfig) error { - for tag, imgId := range repo { +// Push a repository to the registry. +// Remote has the format '/ +func (graph *Graph) PushRepository(remote string, localRepo Repository, authConfig *auth.AuthConfig) error { + for tag, imgId := range localRepo { fmt.Printf("tag: %s, imgId: %s\n", tag, imgId) img, err := graph.Get(imgId) if err != nil { @@ -326,7 +332,7 @@ func (graph *Graph) PushRepository(user, repoName string, repo Repository, authC if err = graph.PushImage(img, authConfig); err != nil { return err } - if err = graph.pushTag(user, repoName, imgId, tag, authConfig); err != nil { + if err = graph.pushTag(remote, imgId, tag, authConfig); err != nil { return err } }