Skip to content

Commit

Permalink
Only optionally grab repotags in raw inspect out
Browse files Browse the repository at this point in the history
For images with a lot of tags it can take a significant amount of time to
list tags.  This can often cause timeouts causing the operation to fail
or if ignore-missing is set wrongly skip an image.  This change will only
grab tags during "inspect --raw" and not during non-raw inspect or push.
Since some repos are so large they always timeout a new parameter --tags
has been added to inspect do disable including tags on raw inspect.

Signed-off-by: Darren Shepherd <darren@rancher.com>
  • Loading branch information
ibuildthecloud committed Mar 29, 2020
1 parent 6f48d5f commit bf0ea44
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 17 deletions.
2 changes: 1 addition & 1 deletion docker/createml.go
Expand Up @@ -66,7 +66,7 @@ func PutManifestList(a *types.AuthInfo, yamlInput types.YAMLInput, ignoreMissing
// for the constituent images:
logrus.Info("Retrieving digests of images...")
for _, img := range yamlInput.Manifests {
mfstData, repoInfo, err := GetImageData(a, img.Image, insecure)
mfstData, repoInfo, err := GetImageData(a, img.Image, insecure, false)
if err != nil {
// if ignoreMissing is true, we will skip this error and simply
// log a warning that we couldn't find it in the registry
Expand Down
15 changes: 8 additions & 7 deletions docker/inspect.go
Expand Up @@ -149,7 +149,7 @@ func checkHTTPRedirect(req *http.Request, via []*http.Request) error {
}

// GetImageData takes registry authentication information and a name of the image to return information about
func GetImageData(a *types.AuthInfo, name string, insecure bool) ([]types.ImageInspect, *registry.RepositoryInfo, error) {
func GetImageData(a *types.AuthInfo, name string, insecure, includeTags bool) ([]types.ImageInspect, *registry.RepositoryInfo, error) {
if err := validateName(name); err != nil {
return nil, nil, err
}
Expand Down Expand Up @@ -215,7 +215,7 @@ func GetImageData(a *types.AuthInfo, name string, insecure bool) ([]types.ImageI

logrus.Debugf("Trying to fetch image manifest of %s repository from %s %s", repoInfo.Name.Name(), endpoint.URL, endpoint.Version)

fetcher, err := newManifestFetcher(endpoint, repoInfo, authConfig, registryService)
fetcher, err := newManifestFetcher(endpoint, repoInfo, authConfig, registryService, includeTags)
if err != nil {
lastErr = err
continue
Expand Down Expand Up @@ -263,14 +263,15 @@ func GetImageData(a *types.AuthInfo, name string, insecure bool) ([]types.ImageI
return nil, nil, lastErr
}

func newManifestFetcher(endpoint registry.APIEndpoint, repoInfo *registry.RepositoryInfo, authConfig engineTypes.AuthConfig, registryService registry.Service) (manifestFetcher, error) {
func newManifestFetcher(endpoint registry.APIEndpoint, repoInfo *registry.RepositoryInfo, authConfig engineTypes.AuthConfig, registryService registry.Service, includeTags bool) (manifestFetcher, error) {
switch endpoint.Version {
case registry.APIVersion2:
return &v2ManifestFetcher{
endpoint: endpoint,
authConfig: authConfig,
service: registryService,
repoInfo: repoInfo,
endpoint: endpoint,
authConfig: authConfig,
service: registryService,
repoInfo: repoInfo,
includeTags: includeTags,
}, nil
case registry.APIVersion1:
return &v1ManifestFetcher{
Expand Down
19 changes: 11 additions & 8 deletions docker/inspect_v2.go
Expand Up @@ -29,6 +29,7 @@ type v2ManifestFetcher struct {
repoInfo *registry.RepositoryInfo
repo distribution.Repository
confirmedV2 bool
includeTags bool
authConfig engineTypes.AuthConfig
service registry.Service
}
Expand Down Expand Up @@ -108,14 +109,16 @@ func (mf *v2ManifestFetcher) fetchWithRepository(ctx context.Context, ref refere
// the other side speaks the v2 protocol.
mf.confirmedV2 = true

tagList, err = mf.repo.Tags(ctx).All(ctx)
if err != nil {
// If this repository doesn't exist on V2, we should
// permit a fallback to V1.
if !strings.Contains(err.Error(), "unauthorized") {
// only error out if the the "list all tags" endpoint isn't blocked by the registry
// some registries may have a reason to not allow complete tag list queries
return nil, allowV1Fallback(err)
if mf.includeTags {
tagList, err = mf.repo.Tags(ctx).All(ctx)
if err != nil {
// If this repository doesn't exist on V2, we should
// permit a fallback to V1.
if !strings.Contains(err.Error(), "unauthorized") {
// only error out if the the "list all tags" endpoint isn't blocked by the registry
// some registries may have a reason to not allow complete tag list queries
return nil, allowV1Fallback(err)
}
}
}

Expand Down
6 changes: 5 additions & 1 deletion inspect.go
Expand Up @@ -18,12 +18,16 @@ var inspectCmd = cli.Command{
Name: "raw",
Usage: "raw JSON output",
},
cli.BoolTFlag{
Name: "tags",
Usage: "include RepoTags in raw response",
},
},
Action: func(c *cli.Context) {

name := c.Args().First()
a := getAuthInfo(c)
imgInspect, _, err := docker.GetImageData(a, name, c.GlobalBool("insecure"))
imgInspect, _, err := docker.GetImageData(a, name, c.GlobalBool("insecure"), c.Bool("raw") && c.Bool("tags"))
if err != nil {
logrus.Fatal(err)
}
Expand Down

0 comments on commit bf0ea44

Please sign in to comment.