From fb4271d9afc3cdbb5a0c7cc318e4547cd2876d19 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 24 Apr 2019 15:33:31 +0000 Subject: [PATCH] Don't use `skopeo inspect` for canonical (digested) pull specs `skopeo inspect` hits the `/tags` API which can be expensive for registries to compute. Quay.io recently changed how they do rate limiting, and we started hitting this in OpenShift CI jobs. Since the machine-config-operator always provides canonical/digested pull specs, the non-digested support is just for local developer convenience. This PR changes things so we don't use `skopeo` at all anymore, rather we `podman inspect` after we pull. Basically this PR ends up in a place where the non-canonical path only loses out on the optimization of avoiding pulling the image in the case where we already have that target. --- cmd/root.go | 66 ++++++++++++++++++++++++---------------- types/imageinspection.go | 2 +- 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 4149e94..bf9fc5f 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -8,6 +8,7 @@ import ( "io/ioutil" "os" "strings" + // Enable sha256 in container image references _ "crypto/sha256" @@ -46,11 +47,11 @@ var tuneableArgsWhitelist = map[string]bool{ // RootCmd houses the cobra config for the main command var RootCmd = &cobra.Command{ - Use: "pivot [FLAGS] [IMAGE_PULLSPEC]", + Use: "pivot [FLAGS] [IMAGE_PULLSPEC]", DisableFlagsInUseLine: true, - Short: "Allows moving from one OSTree deployment to another", - Args: cobra.MaximumNArgs(1), - Run: Execute, + Short: "Allows moving from one OSTree deployment to another", + Args: cobra.MaximumNArgs(1), + Run: Execute, } // init executes upon import @@ -268,31 +269,44 @@ func pullAndRebase(container string) (imgid string, changed bool) { authArgs = append(authArgs, "--authfile", kubeletAuthFile) } - // Use skopeo to canonicalize to $name@$digest, so we can refer to it reliably - skopeoArgs := []string{"inspect"} - skopeoArgs = append(skopeoArgs, authArgs...) - skopeoArgs = append(skopeoArgs, fmt.Sprintf("docker://%s", container)) - output := utils.RunExt(true, numRetriesNetCommands, "skopeo", skopeoArgs...) - - var imagedata types.ImageInspection - json.Unmarshal([]byte(output), &imagedata) - imgid = fmt.Sprintf("%s@%s", imagedata.Name, imagedata.Digest) - glog.Infof("Resolved to: %s", imgid) + // If we're passed a non-canonical image, resolve it to its sha256 now + isCanonicalForm := true + if _, err := getRefDigest(container); err != nil { + isCanonicalForm = false + // In non-canonical form, we pull unconditionally right now + args := []string{"pull", "-q"} + args = append(args, authArgs...) + args = append(args, container) + utils.RunExt(false, numRetriesNetCommands, "podman", args...) + } else { + targetMatched, err := compareOSImageURL(previousPivot, container) + if err != nil { + glog.Fatalf("%v", err) + } + if targetMatched { + changed = false + return + } - targetMatched, err := compareOSImageURL(previousPivot, imgid) - if err != nil { - glog.Fatalf("%v", err) - } - if targetMatched { - changed = false - return + // Pull the image + args := []string{"pull", "-q"} + args = append(args, authArgs...) + args = append(args, container) + utils.RunExt(false, numRetriesNetCommands, "podman", args...) } - // Pull the image - podmanArgs := []string{"pull", "-q"} - podmanArgs = append(podmanArgs, authArgs...) - podmanArgs = append(podmanArgs, imgid) - utils.RunExt(false, numRetriesNetCommands, "podman", podmanArgs...) + inspectArgs := []string{"inspect", "--type=image"} + inspectArgs = append(inspectArgs, fmt.Sprintf("%s", container)) + output := utils.RunExt(true, 1, "podman", inspectArgs...) + var imagedataArray []types.ImageInspection + json.Unmarshal([]byte(output), &imagedataArray) + imagedata := imagedataArray[0] + if !isCanonicalForm { + imgid = imagedata.RepoDigests[0] + glog.Infof("Resolved to: %s", imgid) + } else { + imgid = container + } // Clean up a previous container podmanRemove(types.PivotName) diff --git a/types/imageinspection.go b/types/imageinspection.go index a4bd9ca..62dd71a 100644 --- a/types/imageinspection.go +++ b/types/imageinspection.go @@ -17,7 +17,7 @@ type ImageInspection struct { Name string `json:",omitempty"` Tag string `json:",omitempty"` Digest digest.Digest - RepoTags []string + RepoDigests []string Created *time.Time DockerVersion string Labels map[string]string