Skip to content

Commit

Permalink
leverage the Docker API
Browse files Browse the repository at this point in the history
  • Loading branch information
ndegory authored and qube committed Dec 9, 2016
1 parent 8210a9c commit 35cb5dd
Showing 1 changed file with 52 additions and 35 deletions.
87 changes: 52 additions & 35 deletions cmd/amp/registry.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package main

import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"os"
"os/exec"
"strings"

"github.com/appcelerator/amp/api/client"
distreference "github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/reference"
docker "github.com/docker/docker/client"
"github.com/spf13/cobra"
"golang.org/x/net/context"
"io/ioutil"
"net/http"
"regexp"
)

// RegCmd is the main command for attaching registry subcommands.
Expand Down Expand Up @@ -49,46 +53,66 @@ func init() {

// RegistryPush displays resource usage statistics
func RegistryPush(amp *client.AMP, cmd *cobra.Command, args []string) error {
_, err := amp.GetAuthorizedContext()
defaultHeaders := map[string]string{"User-Agent": "amp-cli"}
dclient, err := docker.NewClient(DockerURL, DockerVersion, nil, defaultHeaders)
if err != nil {
return err
}
ctx := context.Background()
_, err = amp.GetAuthorizedContext()
if err != nil {
return err
}
// @todo: read the .dockercfg file for authentication, or use credentials from amp.yaml
ac := types.AuthConfig{Username: "none"}
jsonString, err := json.Marshal(ac)
if err != nil {
return errors.New("Failed to marshal authconfig")
}
dst := make([]byte, base64.URLEncoding.EncodedLen(len(jsonString)))
base64.URLEncoding.Encode(dst, jsonString)
authConfig := string(dst)
imagePushOptions := types.ImagePushOptions{RegistryAuth: authConfig}

image := args[0]
distributionRef, err := distreference.ParseNamed(image)
if err != nil {
return fmt.Errorf("Error parsing reference: %q is not a valid repository/tag", image)
}
if _, isCanonical := distributionRef.(distreference.Canonical); isCanonical {
return errors.New("refusing to create a tag with a digest reference")
}
tag := reference.GetTagFromNamedRef(distributionRef)
hostname, name := distreference.SplitHostname(distributionRef)

if amp.Verbose() {
fmt.Println("Execute registry push command with:")
fmt.Printf("image: %s\n", image)
fmt.Println("Registry push request with:")
fmt.Printf(" image: %s\n", image)
}

if err = validateRegistryImage(image); err != nil {
return err
}
taggedImage := image
if !strings.HasPrefix(image, "registry."+domain) {
nn := strings.Index(image, "/")
if nn < 0 {
return fmt.Errorf("Invalid image name %s", image)
}
taggedImage = "registry." + domain + "/" + image[nn+1:]
if hostname != "registry."+domain {
taggedImage = "registry." + domain + "/" + name + ":" + tag
fmt.Printf("Tag image from %s to %s\n", image, taggedImage)
cmdexe := exec.Command("docker", "tag", image, taggedImage)
cmdexe.Stdout = os.Stdout
cmdexe.Stderr = os.Stderr
err = cmdexe.Run()
if err != nil {
if err := dclient.ImageTag(ctx, image, taggedImage); err != nil {
return err
}
}
fmt.Printf("push image %s\n", taggedImage)
cmdexe := exec.Command("docker", "push", taggedImage)
cmdexe.Stdout = os.Stdout
cmdexe.Stderr = os.Stderr
err = cmdexe.Run()
resp, err := dclient.ImagePush(ctx, taggedImage, imagePushOptions)
if err != nil {
return err
}
return err
body, err := ioutil.ReadAll(resp)
if err != nil {
return err
}
re := regexp.MustCompile(`: digest: sha256:`)
if !re.Match(body) {
fmt.Print(string(body))
return errors.New("Push failed")
}
return nil
}

// RegistryLs lists images
Expand All @@ -106,10 +130,3 @@ func RegistryLs(amp *client.AMP, cmd *cobra.Command, args []string) error {
fmt.Println(string(body))
return err
}

func validateRegistryImage(image string) error {
if image == "" {
return errors.New("Need a valid image name")
}
return nil
}

0 comments on commit 35cb5dd

Please sign in to comment.