Skip to content

Instantly share code, notes, and snippets.

@parente
Last active August 29, 2015 14:04
Show Gist options
  • Select an option

  • Save parente/aefabbf2b2c714bc6dfd to your computer and use it in GitHub Desktop.

Select an option

Save parente/aefabbf2b2c714bc6dfd to your computer and use it in GitHub Desktop.
Docker index/registry repository and image metadata dumper
package main
import (
"os"
"fmt"
"net/http"
"net/http/httputil"
"strings"
"github.com/docker/docker/registry"
"github.com/docker/docker/utils"
)
// Fetches image metadata from a registry endpoint and dumps the entire response
// to a string.
func fetchImageMeta(reqFactory *utils.HTTPRequestFactory, endpoint string, imgId string, tokens []string) (string, error) {
client := &http.Client{}
req, err := reqFactory.NewRequest("GET", endpoint + "images/" + imgId + "/json", nil)
if err != nil {
fmt.Printf("error creating request for /images/%s/json: %v", imgId, err)
return "", err
}
req.Header.Set("Authorization", "Token "+strings.Join(tokens, ","))
resp, err := client.Do(req)
if err != nil {
fmt.Printf("error GET /images/%s/json: %v", imgId, err)
return "", err
}
dump, err := httputil.DumpResponse(resp, true)
if err != nil {
fmt.Printf("error dump GET response: %v", err)
return "", err
}
return string(dump), nil
}
// Uses some of the Docker client's registry functions to resolve a repository
// name, veryify its URL, get its image list, get its tags, and get the metadata
// associated with each image.
func main() {
if len(os.Args) < 2 {
fmt.Printf("usage: %s <repository>\n", os.Args[0])
return
}
var (
localName = os.Args[1]
authConfig = &registry.AuthConfig{}
metaHeaders map[string][]string
)
hostname, remoteName, err := registry.ResolveRepositoryName(localName)
if err != nil {
fmt.Printf("error ResolveRepositoryName: %v", err)
return
}
fmt.Printf("hostname: %s\n", hostname)
fmt.Printf("remoteName: %s\n", remoteName)
endpoint, err := registry.ExpandAndVerifyRegistryUrl(hostname)
if err != nil {
fmt.Printf("error ExpandAndVerifyRegistryUrl: %v", err)
return
}
fmt.Printf("endpoint: %s\n", endpoint)
reqFactory := registry.HTTPRequestFactory(metaHeaders)
reg, err := registry.NewSession(authConfig, reqFactory, endpoint, true)
if err != nil {
fmt.Printf("error NewSession: %v", err)
return
}
repoData, err := reg.GetRepositoryData(remoteName)
if err != nil {
fmt.Printf("error GetRepositoryData: %v", err)
return
}
fmt.Println(repoData)
tagsList, err := reg.GetRemoteTags(repoData.Endpoints, remoteName, repoData.Tokens)
if err != nil {
fmt.Printf("error GetRemoteTags: %v", err)
return
}
fmt.Println(tagsList)
// Fetch the metadata in parallel. Aggregate and print serially.
ch := make(chan string)
for key, _ := range repoData.ImgList {
go func(key string) {
//meta, err := fetchImageMeta(reqFactory, repoData.Endpoints[0], key, repoData.Tokens)
meta, _, err := reg.GetRemoteImageJSON(key, repoData.Endpoints[0], repoData.Tokens)
if err == nil {
ch <- string(meta)
}
}(key)
}
for i:=0; i < len(repoData.ImgList); i++ {
fmt.Println(<-ch + "\n")
}
close(ch)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment