Signed-off-by: Jess Frazelle <me@jessfraz.com>
This commit is contained in:
Jess Frazelle 2016-09-20 18:16:34 -07:00
parent 7515aa6513
commit 5bb5c33bdf
No known key found for this signature in database
GPG key ID: 18F3685C0022BFF3
6 changed files with 92 additions and 52 deletions

View file

@ -50,9 +50,10 @@ AUTHOR(S):
@jfrazelle <no-reply@butts.com>
COMMANDS:
delete delete a specific reference of a repository
list, ls list all repositories
tags get the tags for a repository
manifest get the json manifest for the specific reference of a repository
tags get the tags for a repository
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:

116
main.go
View file

@ -2,6 +2,7 @@ package main
import (
"encoding/json"
"errors"
"fmt"
"os"
"strings"
@ -34,15 +35,17 @@ func preload(c *cli.Context) (err error) {
}
if len(c.Args()) > 0 {
auth, err = getAuthConfig(c)
if err != nil {
return err
}
if c.Args()[0] != "help" {
auth, err = getAuthConfig(c)
if err != nil {
return err
}
// create the registry client
r, err = registry.New(auth, c.GlobalBool("debug"))
if err != nil {
return err
// create the registry client
r, err = registry.New(auth, c.GlobalBool("debug"))
if err != nil {
return err
}
}
}
@ -76,6 +79,22 @@ func main() {
},
}
app.Commands = []cli.Command{
{
Name: "delete",
Usage: "delete a specific reference of a repository",
Action: func(c *cli.Context) error {
repo, ref, err := getRepoAndRef(c)
if err != nil {
return err
}
if err := r.Delete(repo, ref); err != nil {
return err
}
return nil
},
},
{
Name: "list",
Aliases: []string{"ls"},
@ -109,45 +128,13 @@ func main() {
return nil
},
},
{
Name: "tags",
Usage: "get the tags for a repository",
Action: func(c *cli.Context) error {
if len(c.Args()) < 1 {
return fmt.Errorf("pass the name of the repository")
}
tags, err := r.Tags(c.Args()[0])
if err != nil {
return err
}
// print the tags
fmt.Println(strings.Join(tags, "\n"))
return nil
},
},
{
Name: "manifest",
Usage: "get the json manifest for the specific reference of a repository",
Action: func(c *cli.Context) error {
if len(c.Args()) < 1 {
return fmt.Errorf("pass the name of the repository")
}
arg := c.Args()[0]
parts := []string{}
if strings.Contains(arg, "@") {
parts = strings.Split(c.Args()[0], "@")
} else if strings.Contains(arg, ":") {
parts = strings.Split(c.Args()[0], ":")
}
repo := parts[0]
ref := "latest"
if len(parts) > 1 {
ref = parts[1]
repo, ref, err := getRepoAndRef(c)
if err != nil {
return err
}
manifest, err := r.Manifest(repo, ref)
@ -163,6 +150,25 @@ func main() {
// print the tags
fmt.Println(string(b))
return nil
},
},
{
Name: "tags",
Usage: "get the tags for a repository",
Action: func(c *cli.Context) error {
if len(c.Args()) < 1 {
return fmt.Errorf("pass the name of the repository")
}
tags, err := r.Tags(c.Args()[0])
if err != nil {
return err
}
// print the tags
fmt.Println(strings.Join(tags, "\n"))
return nil
},
},
@ -210,3 +216,27 @@ func getAuthConfig(c *cli.Context) (types.AuthConfig, error) {
return types.AuthConfig{}, fmt.Errorf("Could not find any authentication credentials")
}
func getRepoAndRef(c *cli.Context) (repo, ref string, err error) {
if len(c.Args()) < 1 {
return "", "", errors.New("pass the name of the repository")
}
arg := c.Args()[0]
parts := []string{}
if strings.Contains(arg, "@") {
parts = strings.Split(c.Args()[0], "@")
} else if strings.Contains(arg, ":") {
parts = strings.Split(c.Args()[0], ":")
} else {
parts = []string{arg}
}
repo = parts[0]
ref = "latest"
if len(parts) > 1 {
ref = parts[1]
}
return
}

View file

@ -10,7 +10,7 @@ func (r *Registry) Catalog() ([]string, error) {
r.Logf("registry.catalog url=%s", url)
var response catalogResponse
if err := r.getJSON(url, &response); err != nil {
if _, err := r.getJSON(url, &response); err != nil {
return nil, err
}

View file

@ -1,6 +1,9 @@
package registry
import (
"log"
"strings"
"github.com/docker/distribution/manifest/schema1"
"github.com/docker/distribution/manifest/schema2"
)
@ -11,10 +14,16 @@ func (r *Registry) Manifest(repository, ref string) (interface{}, error) {
r.Logf("registry.manifests url=%s repository=%s ref=%s", url, repository, ref)
var m schema2.Manifest
if err := r.getJSON(url, &m); err != nil {
h, err := r.getJSON(url, &m)
if err != nil {
return m, err
}
if !strings.Contains(ref, ":") {
// we got a tag, get the manifest for the ref
log.Printf("ref: %s", h.Get("Docker-Content-Digest"))
}
if m.Versioned.SchemaVersion == 1 {
return r.v1Manifest(repository, ref)
}
@ -27,7 +36,7 @@ func (r *Registry) v1Manifest(repository, ref string) (schema1.SignedManifest, e
r.Logf("registry.manifests url=%s repository=%s ref=%s", url, repository, ref)
var m schema1.SignedManifest
if err := r.getJSON(url, &m); err != nil {
if _, err := r.getJSON(url, &m); err != nil {
return m, err
}

View file

@ -93,16 +93,16 @@ func (r *Registry) url(pathTemplate string, args ...interface{}) string {
return url
}
func (r *Registry) getJSON(url string, response interface{}) error {
func (r *Registry) getJSON(url string, response interface{}) (http.Header, error) {
resp, err := r.Client.Get(url)
if err != nil {
return err
return nil, err
}
defer resp.Body.Close()
if err := json.NewDecoder(resp.Body).Decode(response); err != nil {
return err
return nil, err
}
return nil
return resp.Header, nil
}

View file

@ -10,7 +10,7 @@ func (r *Registry) Tags(repository string) ([]string, error) {
r.Logf("registry.tags url=%s repository=%s", url, repository)
var response tagsResponse
if err := r.getJSON(url, &response); err != nil {
if _, err := r.getJSON(url, &response); err != nil {
return nil, err
}