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> @jfrazelle <no-reply@butts.com>
COMMANDS: COMMANDS:
delete delete a specific reference of a repository
list, ls list all repositories list, ls list all repositories
tags get the tags for a repository
manifest get the json manifest for the specific reference of 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 help, h Shows a list of commands or help for one command
GLOBAL OPTIONS: GLOBAL OPTIONS:

100
main.go
View file

@ -2,6 +2,7 @@ package main
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"os" "os"
"strings" "strings"
@ -34,6 +35,7 @@ func preload(c *cli.Context) (err error) {
} }
if len(c.Args()) > 0 { if len(c.Args()) > 0 {
if c.Args()[0] != "help" {
auth, err = getAuthConfig(c) auth, err = getAuthConfig(c)
if err != nil { if err != nil {
return err return err
@ -45,6 +47,7 @@ func preload(c *cli.Context) (err error) {
return err return err
} }
} }
}
return nil return nil
} }
@ -76,6 +79,22 @@ func main() {
}, },
} }
app.Commands = []cli.Command{ 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", Name: "list",
Aliases: []string{"ls"}, Aliases: []string{"ls"},
@ -109,45 +128,13 @@ func main() {
return nil 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", Name: "manifest",
Usage: "get the json manifest for the specific reference of a repository", Usage: "get the json manifest for the specific reference of a repository",
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
if len(c.Args()) < 1 { repo, ref, err := getRepoAndRef(c)
return fmt.Errorf("pass the name of the repository") if err != nil {
} return err
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]
} }
manifest, err := r.Manifest(repo, ref) manifest, err := r.Manifest(repo, ref)
@ -163,6 +150,25 @@ func main() {
// print the tags // print the tags
fmt.Println(string(b)) 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 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") 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) r.Logf("registry.catalog url=%s", url)
var response catalogResponse var response catalogResponse
if err := r.getJSON(url, &response); err != nil { if _, err := r.getJSON(url, &response); err != nil {
return nil, err return nil, err
} }

View file

@ -1,6 +1,9 @@
package registry package registry
import ( import (
"log"
"strings"
"github.com/docker/distribution/manifest/schema1" "github.com/docker/distribution/manifest/schema1"
"github.com/docker/distribution/manifest/schema2" "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) r.Logf("registry.manifests url=%s repository=%s ref=%s", url, repository, ref)
var m schema2.Manifest var m schema2.Manifest
if err := r.getJSON(url, &m); err != nil { h, err := r.getJSON(url, &m)
if err != nil {
return m, err 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 { if m.Versioned.SchemaVersion == 1 {
return r.v1Manifest(repository, ref) 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) r.Logf("registry.manifests url=%s repository=%s ref=%s", url, repository, ref)
var m schema1.SignedManifest var m schema1.SignedManifest
if err := r.getJSON(url, &m); err != nil { if _, err := r.getJSON(url, &m); err != nil {
return m, err return m, err
} }

View file

@ -93,16 +93,16 @@ func (r *Registry) url(pathTemplate string, args ...interface{}) string {
return url 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) resp, err := r.Client.Get(url)
if err != nil { if err != nil {
return err return nil, err
} }
defer resp.Body.Close() defer resp.Body.Close()
if err := json.NewDecoder(resp.Body).Decode(response); err != nil { 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) r.Logf("registry.tags url=%s repository=%s", url, repository)
var response tagsResponse var response tagsResponse
if err := r.getJSON(url, &response); err != nil { if _, err := r.getJSON(url, &response); err != nil {
return nil, err return nil, err
} }