Last active
August 29, 2015 14:04
-
-
Save parente/aefabbf2b2c714bc6dfd to your computer and use it in GitHub Desktop.
Docker index/registry repository and image metadata dumper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 = ®istry.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