Browse Source

Improve (drastically) the push

creack 12 years ago
parent
commit
1ed78ee160
2 changed files with 36 additions and 13 deletions
  1. 24 7
      commands.go
  2. 12 6
      registry.go

+ 24 - 7
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 <user>/<repo> 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")

+ 12 - 6
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 '<user>/<repo>
+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 '<user>/<repo>
+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
 		}
 	}