diff options
author | Matthew Heon <matthew.heon@gmail.com> | 2018-10-17 18:44:56 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-17 18:44:56 -0400 |
commit | d01382aed1429d5aa2dea77fb15569b03f45e9a1 (patch) | |
tree | c2c4992606864554b346ebbfa7bddc5061bd3bcc | |
parent | 19c150bef12ff08abc8249cc21275266a7ac74a3 (diff) | |
parent | bfc473f982ecdbfbe885d104036ecf9f70f3cd0f (diff) | |
download | podman-d01382aed1429d5aa2dea77fb15569b03f45e9a1.tar.gz podman-d01382aed1429d5aa2dea77fb15569b03f45e9a1.tar.bz2 podman-d01382aed1429d5aa2dea77fb15569b03f45e9a1.zip |
Merge pull request #1676 from baude/updatebuildah
Vendor in new new buildah/ci
25 files changed, 259 insertions, 316 deletions
diff --git a/.papr_prepare.sh b/.papr_prepare.sh index b15884478..fbb3647ce 100644 --- a/.papr_prepare.sh +++ b/.papr_prepare.sh @@ -14,4 +14,4 @@ fi ${CONTAINER_RUNTIME} build -t ${IMAGE} -f Dockerfile.${DIST} . 2>build.log # Run the tests -${CONTAINER_RUNTIME} run --rm --cap-add all --security-opt seccomp:unconfined --security-opt label:disabled --net=host -v $PWD:/go/src/github.com/containers/libpod:Z --workdir /go/src/github.com/containers/libpod -e CGROUP_MANAGER=cgroupfs -e PYTHON=$PYTHON -e STORAGE_OPTIONS="--storage-driver=vfs" -e CRIO_ROOT="/go/src/github.com/containers/libpod" -e PODMAN_BINARY="/usr/bin/podman" -e CONMON_BINARY="/usr/libexec/podman/conmon" -e DIST=$DIST -e CONTAINER_RUNTIME=$CONTAINER_RUNTIME $IMAGE sh ./.papr.sh -b -i -t +${CONTAINER_RUNTIME} run --rm --cap-add all --security-opt seccomp=unconfined --security-opt label=disable --net=host -v $PWD:/go/src/github.com/containers/libpod:Z --workdir /go/src/github.com/containers/libpod -e CGROUP_MANAGER=cgroupfs -e PYTHON=$PYTHON -e STORAGE_OPTIONS="--storage-driver=vfs" -e CRIO_ROOT="/go/src/github.com/containers/libpod" -e PODMAN_BINARY="/usr/bin/podman" -e CONMON_BINARY="/usr/libexec/podman/conmon" -e DIST=$DIST -e CONTAINER_RUNTIME=$CONTAINER_RUNTIME $IMAGE sh ./.papr.sh -b -i -t diff --git a/libpod/container_commit.go b/libpod/container_commit.go index 7b6266d97..dabd224d5 100644 --- a/libpod/container_commit.go +++ b/libpod/container_commit.go @@ -161,7 +161,7 @@ func (c *Container) Commit(ctx context.Context, destImage string, options Contai importBuilder.SetWorkDir(splitChange[1]) } } - candidates, err := util.ResolveName(destImage, "", sc, c.runtime.store) + candidates, _, err := util.ResolveName(destImage, "", sc, c.runtime.store) if err != nil { return nil, errors.Wrapf(err, "error resolving name %q", destImage) } @@ -172,7 +172,7 @@ func (c *Container) Commit(ctx context.Context, destImage string, options Contai if err != nil { return nil, errors.Wrapf(err, "error parsing target image name %q", destImage) } - id, err := importBuilder.Commit(ctx, imageRef, commitOptions) + id, _, _, err := importBuilder.Commit(ctx, imageRef, commitOptions) if err != nil { return nil, err } diff --git a/libpod/image/image.go b/libpod/image/image.go index f39b1d78d..7e520d97e 100644 --- a/libpod/image/image.go +++ b/libpod/image/image.go @@ -552,7 +552,7 @@ func (i *Image) PushImageToReference(ctx context.Context, dest types.ImageRefere } } // Copy the image to the remote destination - err = cp.Image(ctx, policyContext, dest, src, copyOptions) + _, err = cp.Image(ctx, policyContext, dest, src, copyOptions) if err != nil { return errors.Wrapf(err, "Error copying image to the remote destination") } @@ -912,7 +912,8 @@ func (ir *Runtime) Import(ctx context.Context, path, reference string, writer io if err != nil { errors.Wrapf(err, "error getting image reference for %q", reference) } - if err = cp.Image(ctx, policyContext, dest, src, copyOptions); err != nil { + _, err = cp.Image(ctx, policyContext, dest, src, copyOptions) + if err != nil { return nil, err } return ir.NewFromLocal(reference) diff --git a/libpod/image/pull.go b/libpod/image/pull.go index 9eac2b988..bfa04d069 100644 --- a/libpod/image/pull.go +++ b/libpod/image/pull.go @@ -255,7 +255,8 @@ func (ir *Runtime) doPullImage(ctx context.Context, sc *types.SystemContext, goa if writer != nil && (imageInfo.srcRef.Transport().Name() == DockerTransport || imageInfo.srcRef.Transport().Name() == AtomicTransport) { io.WriteString(writer, fmt.Sprintf("Trying to pull %s...", imageInfo.image)) } - if err = cp.Image(ctx, policyContext, imageInfo.dstRef, imageInfo.srcRef, copyOptions); err != nil { + _, err = cp.Image(ctx, policyContext, imageInfo.dstRef, imageInfo.srcRef, copyOptions) + if err != nil { pullErrors = multierror.Append(pullErrors, err) logrus.Debugf("Error pulling image ref %s: %v", imageInfo.srcRef.StringWithinTransport(), err) if writer != nil { diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go index a21ea7673..be8711734 100644 --- a/libpod/runtime_img.go +++ b/libpod/runtime_img.go @@ -164,5 +164,6 @@ func removeStorageContainers(ctrIDs []string, store storage.Store) error { // Build adds the runtime to the imagebuildah call func (r *Runtime) Build(ctx context.Context, options imagebuildah.BuildOptions, dockerfiles ...string) error { - return imagebuildah.BuildDockerfiles(ctx, r.store, options, dockerfiles...) + _, _, err := imagebuildah.BuildDockerfiles(ctx, r.store, options, dockerfiles...) + return err } diff --git a/test/copyimg/copyimg.go b/test/copyimg/copyimg.go index 26100beea..da00964fa 100644 --- a/test/copyimg/copyimg.go +++ b/test/copyimg/copyimg.go @@ -160,7 +160,7 @@ func main() { ctx := context.TODO() if imageName != "" { if importFrom != "" { - err = copy.Image(ctx, policyContext, ref, importRef, options) + _, err = copy.Image(ctx, policyContext, ref, importRef, options) if err != nil { logrus.Errorf("error importing %s: %v", importFrom, err) os.Exit(1) @@ -180,7 +180,7 @@ func main() { } } if exportTo != "" { - err = copy.Image(ctx, policyContext, exportRef, ref, options) + _, err = copy.Image(ctx, policyContext, exportRef, ref, options) if err != nil { logrus.Errorf("error exporting %s: %v", exportTo, err) os.Exit(1) @@ -188,7 +188,7 @@ func main() { } } else { if importFrom != "" && exportTo != "" { - err = copy.Image(ctx, policyContext, exportRef, importRef, options) + _, err = copy.Image(ctx, policyContext, exportRef, importRef, options) if err != nil { logrus.Errorf("error copying %s to %s: %v", importFrom, exportTo, err) os.Exit(1) diff --git a/vendor.conf b/vendor.conf index a74953e37..2e6925e5e 100644 --- a/vendor.conf +++ b/vendor.conf @@ -10,7 +10,7 @@ github.com/containerd/cgroups 58556f5ad8448d99a6f7bea69ea4bdb7747cfeb0 github.com/containerd/continuity master github.com/containernetworking/cni v0.7.0-alpha1 github.com/containernetworking/plugins 1562a1e60ed101aacc5e08ed9dbeba8e9f3d4ec1 -github.com/containers/image 918dbb93e6e099b196b498c38d079f6bb924d0c8 +github.com/containers/image bd10b1b53b2976f215b3f2f848fb8e7cad779aeb github.com/containers/storage 41294c85d97bef688e18f710402895dbecde3308 github.com/containers/psgo 5dde6da0bc8831b35243a847625bcf18183bd1ee github.com/coreos/go-systemd v14 @@ -91,7 +91,7 @@ k8s.io/kube-openapi 275e2ce91dec4c05a4094a7b1daee5560b555ac9 https://github.com/ k8s.io/utils 258e2a2fa64568210fbd6267cf1d8fd87c3cb86e https://github.com/kubernetes/utils github.com/mrunalp/fileutils master github.com/varlink/go master -github.com/containers/buildah 9d50d04b9324a22bbb64df9e66b5d9d53ed3daae +github.com/containers/buildah 46c577c87d5a7ab30ef40cfa695cd2b96b32b117 github.com/Nvveen/Gotty master github.com/fsouza/go-dockerclient master github.com/openshift/imagebuilder master diff --git a/vendor/github.com/containers/buildah/buildah.go b/vendor/github.com/containers/buildah/buildah.go index f94c5cc08..9994d6cd0 100644 --- a/vendor/github.com/containers/buildah/buildah.go +++ b/vendor/github.com/containers/buildah/buildah.go @@ -457,6 +457,10 @@ func OpenBuilderByPath(store storage.Store, path string) (*Builder, error) { } buildstate, err := ioutil.ReadFile(filepath.Join(cdir, stateFile)) if err != nil { + if os.IsNotExist(err) { + logrus.Debugf("error reading %q: %v, ignoring container %q", filepath.Join(cdir, stateFile), err, container.ID) + continue + } return nil, errors.Wrapf(err, "error reading %q", filepath.Join(cdir, stateFile)) } b := &Builder{} @@ -488,9 +492,12 @@ func OpenAllBuilders(store storage.Store) (builders []*Builder, err error) { return nil, err } buildstate, err := ioutil.ReadFile(filepath.Join(cdir, stateFile)) - if err != nil && os.IsNotExist(err) { - logrus.Debugf("error reading %q: %v", filepath.Join(cdir, stateFile), err) - continue + if err != nil { + if os.IsNotExist(err) { + logrus.Debugf("error reading %q: %v, ignoring container %q", filepath.Join(cdir, stateFile), err, container.ID) + continue + } + return nil, errors.Wrapf(err, "error reading %q", filepath.Join(cdir, stateFile)) } b := &Builder{} err = json.Unmarshal(buildstate, &b) diff --git a/vendor/github.com/containers/buildah/commit.go b/vendor/github.com/containers/buildah/commit.go index 28dc4ec7c..71696b432 100644 --- a/vendor/github.com/containers/buildah/commit.go +++ b/vendor/github.com/containers/buildah/commit.go @@ -9,12 +9,15 @@ import ( "github.com/containers/buildah/util" cp "github.com/containers/image/copy" + "github.com/containers/image/docker/reference" + "github.com/containers/image/manifest" "github.com/containers/image/signature" is "github.com/containers/image/storage" "github.com/containers/image/transports" "github.com/containers/image/types" "github.com/containers/storage" "github.com/containers/storage/pkg/archive" + digest "github.com/opencontainers/go-digest" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -88,26 +91,26 @@ type PushOptions struct { // configuration, to a new image in the specified location, and if we know how, // add any additional tags that were specified. Returns the ID of the new image // if commit was successful and the image destination was local -func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options CommitOptions) (string, error) { +func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options CommitOptions) (string, reference.Canonical, digest.Digest, error) { var imgID string systemContext := getSystemContext(options.SystemContext, options.SignaturePolicyPath) blocked, err := isReferenceBlocked(dest, systemContext) if err != nil { - return "", errors.Wrapf(err, "error checking if committing to registry for %q is blocked", transports.ImageName(dest)) + return "", nil, "", errors.Wrapf(err, "error checking if committing to registry for %q is blocked", transports.ImageName(dest)) } if blocked { - return "", errors.Errorf("commit access to registry for %q is blocked by configuration", transports.ImageName(dest)) + return "", nil, "", errors.Errorf("commit access to registry for %q is blocked by configuration", transports.ImageName(dest)) } policy, err := signature.DefaultPolicy(systemContext) if err != nil { - return imgID, errors.Wrapf(err, "error obtaining default signature policy") + return imgID, nil, "", errors.Wrapf(err, "error obtaining default signature policy") } policyContext, err := signature.NewPolicyContext(policy) if err != nil { - return imgID, errors.Wrapf(err, "error creating new signature policy context") + return imgID, nil, "", errors.Wrapf(err, "error creating new signature policy context") } defer func() { if err2 := policyContext.Destroy(); err2 != nil { @@ -127,21 +130,22 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options } src, err := b.makeImageRef(options.PreferredManifestType, options.Parent, exportBaseLayers, options.Squash, options.Compression, options.HistoryTimestamp) if err != nil { - return imgID, errors.Wrapf(err, "error computing layer digests and building metadata for container %q", b.ContainerID) + return imgID, nil, "", errors.Wrapf(err, "error computing layer digests and building metadata for container %q", b.ContainerID) } // "Copy" our image to where it needs to be. - if err = cp.Image(ctx, policyContext, dest, src, getCopyOptions(options.ReportWriter, src, nil, dest, systemContext, "")); err != nil { - return imgID, errors.Wrapf(err, "error copying layers and metadata for container %q", b.ContainerID) + var manifestBytes []byte + if manifestBytes, err = cp.Image(ctx, policyContext, dest, src, getCopyOptions(options.ReportWriter, src, nil, dest, systemContext, "")); err != nil { + return imgID, nil, "", errors.Wrapf(err, "error copying layers and metadata for container %q", b.ContainerID) } if len(options.AdditionalTags) > 0 { switch dest.Transport().Name() { case is.Transport.Name(): img, err := is.Transport.GetStoreImage(b.store, dest) if err != nil { - return imgID, errors.Wrapf(err, "error locating just-written image %q", transports.ImageName(dest)) + return imgID, nil, "", errors.Wrapf(err, "error locating just-written image %q", transports.ImageName(dest)) } if err = util.AddImageNames(b.store, "", systemContext, img, options.AdditionalTags); err != nil { - return imgID, errors.Wrapf(err, "error setting image names to %v", append(img.Names, options.AdditionalTags...)) + return imgID, nil, "", errors.Wrapf(err, "error setting image names to %v", append(img.Names, options.AdditionalTags...)) } logrus.Debugf("assigned names %v to image %q", img.Names, img.ID) default: @@ -151,7 +155,7 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options img, err := is.Transport.GetStoreImage(b.store, dest) if err != nil && err != storage.ErrImageUnknown { - return imgID, errors.Wrapf(err, "error locating image %q in local storage", transports.ImageName(dest)) + return imgID, nil, "", errors.Wrapf(err, "error locating image %q in local storage", transports.ImageName(dest)) } if err == nil { @@ -159,47 +163,71 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options if options.IIDFile != "" { if err = ioutil.WriteFile(options.IIDFile, []byte(img.ID), 0644); err != nil { - return imgID, errors.Wrapf(err, "failed to write image ID to file %q", options.IIDFile) + return imgID, nil, "", errors.Wrapf(err, "failed to write image ID to file %q", options.IIDFile) } } } - return imgID, nil + manifestDigest, err := manifest.Digest(manifestBytes) + if err != nil { + return imgID, nil, "", errors.Wrapf(err, "error computing digest of manifest of new image %q", transports.ImageName(dest)) + } + + var ref reference.Canonical + if name := dest.DockerReference(); name != nil { + ref, err = reference.WithDigest(name, manifestDigest) + if err != nil { + logrus.Warnf("error generating canonical reference with name %q and digest %s: %v", name, manifestDigest.String(), err) + } + } + + return imgID, ref, manifestDigest, nil } // Push copies the contents of the image to a new location. -func Push(ctx context.Context, image string, dest types.ImageReference, options PushOptions) error { +func Push(ctx context.Context, image string, dest types.ImageReference, options PushOptions) (reference.Canonical, digest.Digest, error) { systemContext := getSystemContext(options.SystemContext, options.SignaturePolicyPath) blocked, err := isReferenceBlocked(dest, systemContext) if err != nil { - return errors.Wrapf(err, "error checking if pushing to registry for %q is blocked", transports.ImageName(dest)) + return nil, "", errors.Wrapf(err, "error checking if pushing to registry for %q is blocked", transports.ImageName(dest)) } if blocked { - return errors.Errorf("push access to registry for %q is blocked by configuration", transports.ImageName(dest)) + return nil, "", errors.Errorf("push access to registry for %q is blocked by configuration", transports.ImageName(dest)) } policy, err := signature.DefaultPolicy(systemContext) if err != nil { - return errors.Wrapf(err, "error obtaining default signature policy") + return nil, "", errors.Wrapf(err, "error obtaining default signature policy") } policyContext, err := signature.NewPolicyContext(policy) if err != nil { - return errors.Wrapf(err, "error creating new signature policy context") + return nil, "", errors.Wrapf(err, "error creating new signature policy context") } // Look up the image. - src, img, err := util.FindImage(options.Store, "", systemContext, image) + src, _, err := util.FindImage(options.Store, "", systemContext, image) if err != nil { - return err + return nil, "", err } // Copy everything. - if err = cp.Image(ctx, policyContext, dest, src, getCopyOptions(options.ReportWriter, src, nil, dest, systemContext, options.ManifestType)); err != nil { - return errors.Wrapf(err, "error copying layers and metadata from %q to %q", transports.ImageName(src), transports.ImageName(dest)) + var manifestBytes []byte + if manifestBytes, err = cp.Image(ctx, policyContext, dest, src, getCopyOptions(options.ReportWriter, src, nil, dest, systemContext, options.ManifestType)); err != nil { + return nil, "", errors.Wrapf(err, "error copying layers and metadata from %q to %q", transports.ImageName(src), transports.ImageName(dest)) } if options.ReportWriter != nil { fmt.Fprintf(options.ReportWriter, "") } - digest := "@" + img.Digest.Hex() - fmt.Printf("Successfully pushed %s%s\n", dest.StringWithinTransport(), digest) - return nil + manifestDigest, err := manifest.Digest(manifestBytes) + if err != nil { + return nil, "", errors.Wrapf(err, "error computing digest of manifest of new image %q", transports.ImageName(dest)) + } + var ref reference.Canonical + if name := dest.DockerReference(); name != nil { + ref, err = reference.WithDigest(name, manifestDigest) + if err != nil { + logrus.Warnf("error generating canonical reference with name %q and digest %s: %v", name, manifestDigest.String(), err) + } + } + fmt.Printf("Successfully pushed %s@%s\n", dest.StringWithinTransport(), manifestDigest.String()) + return ref, manifestDigest, nil } diff --git a/vendor/github.com/containers/buildah/imagebuildah/build.go b/vendor/github.com/containers/buildah/imagebuildah/build.go index 3d644dfbd..41d85cbc6 100644 --- a/vendor/github.com/containers/buildah/imagebuildah/build.go +++ b/vendor/github.com/containers/buildah/imagebuildah/build.go @@ -17,6 +17,7 @@ import ( "github.com/containers/buildah" "github.com/containers/buildah/util" cp "github.com/containers/image/copy" + "github.com/containers/image/docker/reference" is "github.com/containers/image/storage" "github.com/containers/image/transports" "github.com/containers/image/transports/alltransports" @@ -761,7 +762,7 @@ func (b *Executor) resolveNameToImageRef() (types.ImageReference, error) { if b.output != "" { imageRef, err = alltransports.ParseImageName(b.output) if err != nil { - candidates, err := util.ResolveName(b.output, "", b.systemContext, b.store) + candidates, _, err := util.ResolveName(b.output, "", b.systemContext, b.store) if err != nil { return nil, errors.Wrapf(err, "error parsing target image name %q: %v", b.output) } @@ -860,7 +861,7 @@ func (b *Executor) Execute(ctx context.Context, stage imagebuilder.Stage) error // Commit if no cache is found if cacheID == "" { - imgID, err = b.Commit(ctx, ib, getCreatedBy(node)) + imgID, _, err = b.Commit(ctx, ib, getCreatedBy(node)) if err != nil { return errors.Wrapf(err, "error committing container for step %+v", *step) } @@ -903,7 +904,7 @@ func (b *Executor) copyExistingImage(ctx context.Context, cacheID string) error if err != nil { return errors.Wrapf(err, "error getting source imageReference for %q", cacheID) } - if err := cp.Image(ctx, policyContext, dest, src, nil); err != nil { + if _, err := cp.Image(ctx, policyContext, dest, src, nil); err != nil { return errors.Wrapf(err, "error copying image %q", cacheID) } b.log("COMMIT %s", b.output) @@ -1083,10 +1084,10 @@ func urlContentModified(url string, historyTime *time.Time) (bool, error) { // Commit writes the container's contents to an image, using a passed-in tag as // the name if there is one, generating a unique ID-based one otherwise. -func (b *Executor) Commit(ctx context.Context, ib *imagebuilder.Builder, createdBy string) (string, error) { +func (b *Executor) Commit(ctx context.Context, ib *imagebuilder.Builder, createdBy string) (string, reference.Canonical, error) { imageRef, err := b.resolveNameToImageRef() if err != nil { - return "", err + return "", nil, err } if ib.Author != "" { @@ -1165,19 +1166,19 @@ func (b *Executor) Commit(ctx context.Context, ib *imagebuilder.Builder, created Squash: b.squash, Parent: b.builder.FromImageID, } - imgID, err := b.builder.Commit(ctx, imageRef, options) + imgID, ref, _, err := b.builder.Commit(ctx, imageRef, options) if err != nil { - return "", err + return "", nil, err } if options.IIDFile == "" && imgID != "" { fmt.Fprintf(b.out, "--> %s\n", imgID) } - return imgID, nil + return imgID, ref, nil } // Build takes care of the details of running Prepare/Execute/Commit/Delete // over each of the one or more parsed Dockerfiles and stages. -func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) error { +func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (string, reference.Canonical, error) { if len(stages) == 0 { errors.New("error building: no stages to build") } @@ -1190,7 +1191,7 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) error for _, stage := range stages { stageExecutor = b.withName(stage.Name, stage.Position) if err := stageExecutor.Prepare(ctx, stage, ""); err != nil { - return err + return "", nil, err } // Always remove the intermediate/build containers, even if the build was unsuccessful. // If building with layers, remove all intermediate/build containers if b.forceRmIntermediateCtrs @@ -1208,7 +1209,7 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) error if b.removeIntermediateCtrs { stageExecutor.deleteSuccessfulIntermediateCtrs() } - return lastErr + return "", nil, lastErr } b.containerIDs = append(b.containerIDs, stageExecutor.containerIDs...) // If we've a stage.Name with alpha and not numeric, we've an @@ -1216,20 +1217,24 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) error // stage to be used by other FROM statements that will want // to use it later in the Dockerfile. Note the id in our map. if _, err := strconv.Atoi(stage.Name); err != nil { - imgID, err := stageExecutor.Commit(ctx, stages[stageCount].Builder, "") + imgID, _, err := stageExecutor.Commit(ctx, stages[stageCount].Builder, "") if err != nil { - return err + return "", nil, err } b.imageMap[stage.Name] = imgID } stageCount++ } + var imageRef reference.Canonical + imageID := "" if !b.layers && !b.noCache { - _, err := stageExecutor.Commit(ctx, stages[len(stages)-1].Builder, "") + imgID, ref, err := stageExecutor.Commit(ctx, stages[len(stages)-1].Builder, "") if err != nil { - return err + return "", nil, err } + imageID = imgID + imageRef = ref } // If building with layers and b.removeIntermediateCtrs is true // only remove intermediate container for each step if an error @@ -1241,7 +1246,7 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) error // defer statement above. if b.removeIntermediateCtrs && (b.layers || b.noCache) { if err := b.deleteSuccessfulIntermediateCtrs(); err != nil { - return errors.Errorf("Failed to cleanup intermediate containers") + return "", nil, errors.Errorf("Failed to cleanup intermediate containers") } } // Remove intermediate images that we created for AS clause handling @@ -1250,15 +1255,15 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) error logrus.Debugf("unable to remove intermediate image %q: %v", value, err) } } - return nil + return imageID, imageRef, nil } // BuildDockerfiles parses a set of one or more Dockerfiles (which may be // URLs), creates a new Executor, and then runs Prepare/Execute/Commit/Delete // over the entire set of instructions. -func BuildDockerfiles(ctx context.Context, store storage.Store, options BuildOptions, paths ...string) error { +func BuildDockerfiles(ctx context.Context, store storage.Store, options BuildOptions, paths ...string) (string, reference.Canonical, error) { if len(paths) == 0 { - return errors.Errorf("error building: no dockerfiles specified") + return "", nil, errors.Errorf("error building: no dockerfiles specified") } var dockerfiles []io.ReadCloser defer func(dockerfiles ...io.ReadCloser) { @@ -1274,11 +1279,11 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options BuildOpt logrus.Debugf("reading remote Dockerfile %q", dfile) resp, err := http.Get(dfile) if err != nil { - return errors.Wrapf(err, "error getting %q", dfile) + return "", nil, errors.Wrapf(err, "error getting %q", dfile) } if resp.ContentLength == 0 { resp.Body.Close() - return errors.Errorf("no contents in %q", dfile) + return "", nil, errors.Errorf("no contents in %q", dfile) } data = resp.Body } else { @@ -1290,16 +1295,16 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options BuildOpt logrus.Debugf("reading local Dockerfile %q", dfile) contents, err := os.Open(dfile) if err != nil { - return errors.Wrapf(err, "error reading %q", dfile) + return "", nil, errors.Wrapf(err, "error reading %q", dfile) } dinfo, err := contents.Stat() if err != nil { contents.Close() - return errors.Wrapf(err, "error reading info about %q", dfile) + return "", nil, errors.Wrapf(err, "error reading info about %q", dfile) } if dinfo.Mode().IsRegular() && dinfo.Size() == 0 { contents.Close() - return errors.Wrapf(err, "no contents in %q", dfile) + return "", nil, errors.Wrapf(err, "no contents in %q", dfile) } data = contents } @@ -1308,7 +1313,7 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options BuildOpt if strings.HasSuffix(dfile, ".in") { pData, err := preprocessDockerfileContents(data, options.ContextDirectory) if err != nil { - return err + return "", nil, err } data = *pData } @@ -1317,18 +1322,18 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options BuildOpt } mainNode, err := imagebuilder.ParseDockerfile(dockerfiles[0]) if err != nil { - return errors.Wrapf(err, "error parsing main Dockerfile") + return "", nil, errors.Wrapf(err, "error parsing main Dockerfile") } for _, d := range dockerfiles[1:] { additionalNode, err := imagebuilder.ParseDockerfile(d) if err != nil { - return errors.Wrapf(err, "error parsing additional Dockerfile") + return "", nil, errors.Wrapf(err, "error parsing additional Dockerfile") } mainNode.Children = append(mainNode.Children, additionalNode.Children...) } exec, err := NewExecutor(store, options) if err != nil { - return errors.Wrapf(err, "error creating build executor") + return "", nil, errors.Wrapf(err, "error creating build executor") } b := imagebuilder.NewBuilder(options.Args) stages := imagebuilder.NewStages(mainNode, b) diff --git a/vendor/github.com/containers/buildah/new.go b/vendor/github.com/containers/buildah/new.go index e271d2b4d..8b0e774ba 100644 --- a/vendor/github.com/containers/buildah/new.go +++ b/vendor/github.com/containers/buildah/new.go @@ -12,7 +12,6 @@ import ( "github.com/containers/image/transports/alltransports" "github.com/containers/image/types" "github.com/containers/storage" - multierror "github.com/hashicorp/go-multierror" "github.com/opencontainers/selinux/go-selinux/label" "github.com/openshift/imagebuilder" "github.com/pkg/errors" @@ -107,41 +106,46 @@ func newContainerIDMappingOptions(idmapOptions *IDMappingOptions) storage.IDMapp } func resolveImage(ctx context.Context, systemContext *types.SystemContext, store storage.Store, options BuilderOptions) (types.ImageReference, *storage.Image, error) { - var ref types.ImageReference - var img *storage.Image - images, err := util.ResolveName(options.FromImage, options.Registry, systemContext, store) + type failure struct { + resolvedImageName string + err error + } + + candidates, searchRegistriesWereUsedButEmpty, err := util.ResolveName(options.FromImage, options.Registry, systemContext, store) if err != nil { return nil, nil, errors.Wrapf(err, "error parsing reference to image %q", options.FromImage) } - var pullErrors *multierror.Error - for _, image := range images { + failures := []failure{} + for _, image := range candidates { var err error if len(image) >= minimumTruncatedIDLength { - if img, err = store.Image(image); err == nil && img != nil && strings.HasPrefix(img.ID, image) { - if ref, err = is.Transport.ParseStoreReference(store, img.ID); err != nil { + if img, err := store.Image(image); err == nil && img != nil && strings.HasPrefix(img.ID, image) { + ref, err := is.Transport.ParseStoreReference(store, img.ID) + if err != nil { return nil, nil, errors.Wrapf(err, "error parsing reference to image %q", img.ID) } - break + return ref, img, nil } } if options.PullPolicy == PullAlways { pulledImg, pulledReference, err := pullAndFindImage(ctx, store, image, options, systemContext) if err != nil { - pullErrors = multierror.Append(pullErrors, err) logrus.Debugf("unable to pull and read image %q: %v", image, err) + failures = append(failures, failure{resolvedImageName: image, err: err}) continue } - ref = pulledReference - img = pulledImg - break + return pulledReference, pulledImg, nil } srcRef, err := alltransports.ParseImageName(image) if err != nil { if options.Transport == "" { - pullErrors = multierror.Append(pullErrors, err) logrus.Debugf("error parsing image name %q: %v", image, err) + failures = append(failures, failure{ + resolvedImageName: image, + err: errors.Wrapf(err, "error parsing image name"), + }) continue } logrus.Debugf("error parsing image name %q as given, trying with transport %q: %v", image, options.Transport, err) @@ -151,8 +155,11 @@ func resolveImage(ctx context.Context, systemContext *types.SystemContext, store } srcRef2, err := alltransports.ParseImageName(transport + image) if err != nil { - pullErrors = multierror.Append(pullErrors, err) logrus.Debugf("error parsing image name %q: %v", transport+image, err) + failures = append(failures, failure{ + resolvedImageName: image, + err: errors.Wrapf(err, "error parsing attempted image name %q", transport+image), + }) continue } srcRef = srcRef2 @@ -166,34 +173,63 @@ func resolveImage(ctx context.Context, systemContext *types.SystemContext, store return nil, nil, errors.Errorf("error computing local image name for %q", transports.ImageName(srcRef)) } - ref, err = is.Transport.ParseStoreReference(store, destImage) + ref, err := is.Transport.ParseStoreReference(store, destImage) if err != nil { return nil, nil, errors.Wrapf(err, "error parsing reference to image %q", destImage) } - img, err = is.Transport.GetStoreImage(store, ref) + img, err := is.Transport.GetStoreImage(store, ref) + if err == nil { + return ref, img, nil + } + + if errors.Cause(err) == storage.ErrImageUnknown && options.PullPolicy != PullIfMissing { + logrus.Debugf("no such image %q: %v", transports.ImageName(ref), err) + failures = append(failures, failure{ + resolvedImageName: image, + err: fmt.Errorf("no such image %q", transports.ImageName(ref)), + }) + continue + } + + pulledImg, pulledReference, err := pullAndFindImage(ctx, store, image, options, systemContext) if err != nil { - if errors.Cause(err) == storage.ErrImageUnknown && options.PullPolicy != PullIfMissing { - pullErrors = multierror.Append(pullErrors, err) - logrus.Debugf("no such image %q: %v", transports.ImageName(ref), err) - continue - } - pulledImg, pulledReference, err := pullAndFindImage(ctx, store, image, options, systemContext) - if err != nil { - pullErrors = multierror.Append(pullErrors, err) - logrus.Debugf("unable to pull and read image %q: %v", image, err) - continue - } - ref = pulledReference - img = pulledImg + logrus.Debugf("unable to pull and read image %q: %v", image, err) + failures = append(failures, failure{resolvedImageName: image, err: err}) + continue } - break + return pulledReference, pulledImg, nil } - if img == nil && pullErrors != nil { - return nil, nil, pullErrors + if len(failures) != len(candidates) { + return nil, nil, fmt.Errorf("internal error: %d candidates (%#v) vs. %d failures (%#v)", len(candidates), candidates, len(failures), failures) } - return ref, img, nil + registriesConfPath := sysregistries.RegistriesConfPath(systemContext) + switch len(failures) { + case 0: + if searchRegistriesWereUsedButEmpty { + return nil, nil, errors.Errorf("image name %q is a short name and no search registries are defined in %s.", options.FromImage, registriesConfPath) + } + return nil, nil, fmt.Errorf("internal error: no pull candidates were available for %q for an unknown reason", options.FromImage) + + case 1: + err := failures[0].err + if failures[0].resolvedImageName != options.FromImage { + err = errors.Wrapf(err, "while pulling %q as %q", options.FromImage, failures[0].resolvedImageName) + } + if searchRegistriesWereUsedButEmpty { + err = errors.Wrapf(err, "(image name %q is a short name and no search registries are defined in %s)", options.FromImage, registriesConfPath) + } + return nil, nil, err + + default: + // NOTE: a multi-line error string: + e := fmt.Sprintf("The following failures happened while trying to pull image specified by %q based on search registries in %s:", options.FromImage, registriesConfPath) + for _, f := range failures { + e = e + fmt.Sprintf("\n* %q: %s", f.resolvedImageName, f.err.Error()) + } + return nil, nil, errors.New(e) + } } func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions) (*Builder, error) { @@ -210,17 +246,11 @@ func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions systemContext := getSystemContext(options.SystemContext, options.SignaturePolicyPath) - if options.FromImage != "scratch" { + if options.FromImage != "" && options.FromImage != "scratch" { ref, img, err = resolveImage(ctx, systemContext, store, options) if err != nil { return nil, err } - if options.FromImage != "" && (ref == nil || img == nil) { - // If options.FromImage is set but we ended up - // with nil in ref or in img then there was an error that - // we should return. - return nil, errors.Wrapf(storage.ErrImageUnknown, "image %q not found in %s registries", options.FromImage, sysregistries.RegistriesConfPath(systemContext)) - } } image := options.FromImage imageID := "" @@ -266,7 +296,7 @@ func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions defer func() { if err != nil { - if err2 := store.DeleteContainer(container.ID); err != nil { + if err2 := store.DeleteContainer(container.ID); err2 != nil { logrus.Errorf("error deleting container %q: %v", container.ID, err2) } } diff --git a/vendor/github.com/containers/buildah/pull.go b/vendor/github.com/containers/buildah/pull.go index 3cf5c6343..52269541a 100644 --- a/vendor/github.com/containers/buildah/pull.go +++ b/vendor/github.com/containers/buildah/pull.go @@ -10,7 +10,6 @@ import ( "github.com/containers/image/docker/reference" tarfile "github.com/containers/image/docker/tarfile" ociarchive "github.com/containers/image/oci/archive" - "github.com/containers/image/pkg/sysregistries" "github.com/containers/image/signature" is "github.com/containers/image/storage" "github.com/containers/image/transports" @@ -201,28 +200,10 @@ func pullImage(ctx context.Context, store storage.Store, imageName string, optio }() logrus.Debugf("copying %q to %q", spec, destName) - pullError := cp.Image(ctx, policyContext, destRef, srcRef, getCopyOptions(options.ReportWriter, srcRef, sc, destRef, nil, "")) - if pullError == nil { - return destRef, nil + if _, err := cp.Image(ctx, policyContext, destRef, srcRef, getCopyOptions(options.ReportWriter, srcRef, sc, destRef, nil, "")); err != nil { + return nil, err } - - // If no image was found, we should handle. Lets be nicer to the user and see if we can figure out why. - registryPath := sysregistries.RegistriesConfPath(sc) - searchRegistries, err := getRegistries(sc) - if err != nil { - logrus.Debugf("error getting list of registries: %v", err) - return nil, errors.Wrapf(pullError, "error copying image from %q to %q", transports.ImageName(srcRef), transports.ImageName(destRef)) - } - hasRegistryInName, err := hasRegistry(imageName) - if err != nil { - logrus.Debugf("error checking if image name %q includes a registry component: %v", imageName, err) - return nil, errors.Wrapf(pullError, "error copying image from %q to %q", transports.ImageName(srcRef), transports.ImageName(destRef)) - } - if !hasRegistryInName && len(searchRegistries) == 0 { - logrus.Debugf("copying %q to %q failed: %v", pullError) - return nil, errors.Errorf("image name provided does not include a registry name and no search registries are defined in %s: %s", registryPath, pullError) - } - return nil, pullError + return destRef, nil } // getImageDigest creates an image object and uses the hex value of the digest as the image ID diff --git a/vendor/github.com/containers/buildah/run.go b/vendor/github.com/containers/buildah/run.go index 4f39b4625..718ef4e36 100644 --- a/vendor/github.com/containers/buildah/run.go +++ b/vendor/github.com/containers/buildah/run.go @@ -38,8 +38,6 @@ import ( ) const ( - // DefaultWorkingDir is used if none was specified. - DefaultWorkingDir = "/" // runUsingRuntimeCommand is a command we use as a key for reexec runUsingRuntimeCommand = Package + "-oci-runtime" ) @@ -146,6 +144,8 @@ type RunOptions struct { Runtime string // Args adds global arguments for the runtime. Args []string + // NoPivot adds the --no-pivot runtime flag. + NoPivot bool // Mounts are additional mount points which we want to provide. Mounts []specs.Mount // Env is additional environment variables to set. @@ -520,7 +520,7 @@ func runSetupBuiltinVolumes(mountLabel, mountPoint, containerDir string, copyWit if err = os.Chown(volumePath, int(stat.Sys().(*syscall.Stat_t).Uid), int(stat.Sys().(*syscall.Stat_t).Gid)); err != nil { return nil, errors.Wrapf(err, "error chowning directory %q for volume %q", volumePath, volume) } - if err = copyWithTar(srcPath, volumePath); err != nil && !os.IsNotExist(err) { + if err = copyWithTar(srcPath, volumePath); err != nil && !os.IsNotExist(errors.Cause(err)) { return nil, errors.Wrapf(err, "error populating directory %q for volume %q using contents of %q", volumePath, volume, srcPath) } } @@ -1025,10 +1025,6 @@ func (b *Builder) Run(command []string, options RunOptions) error { spec := g.Spec() g = nil - // Set the working directory, creating it if we must. - if spec.Process.Cwd == "" { - spec.Process.Cwd = DefaultWorkingDir - } logrus.Debugf("ensuring working directory %q exists", filepath.Join(mountPoint, spec.Process.Cwd)) if err = os.MkdirAll(filepath.Join(mountPoint, spec.Process.Cwd), 0755); err != nil { return errors.Wrapf(err, "error ensuring working directory %q exists", spec.Process.Cwd) @@ -1093,7 +1089,13 @@ func (b *Builder) Run(command []string, options RunOptions) error { // } // } // options.Args = append(options.Args, rootlessFlag...) - err = b.runUsingRuntimeSubproc(options, configureNetwork, configureNetworks, nil, spec, mountPoint, path, Package+"-"+filepath.Base(path)) + var moreCreateArgs []string + if options.NoPivot { + moreCreateArgs = []string{"--no-pivot"} + } else { + moreCreateArgs = nil + } + err = b.runUsingRuntimeSubproc(options, configureNetwork, configureNetworks, moreCreateArgs, spec, mountPoint, path, Package+"-"+filepath.Base(path)) case IsolationChroot: err = chroot.RunUsingChroot(spec, path, options.Stdin, options.Stdout, options.Stderr) case IsolationOCIRootless: diff --git a/vendor/github.com/containers/buildah/util.go b/vendor/github.com/containers/buildah/util.go index 697f98779..09aa7e1eb 100644 --- a/vendor/github.com/containers/buildah/util.go +++ b/vendor/github.com/containers/buildah/util.go @@ -173,21 +173,6 @@ func (b *Builder) tarPath() func(path string) (io.ReadCloser, error) { } } -// getRegistries obtains the list of search registries defined in the global registries file. -func getRegistries(sc *types.SystemContext) ([]string, error) { - var searchRegistries []string - registries, err := sysregistriesv2.GetRegistries(sc) - if err != nil { - return nil, errors.Wrapf(err, "unable to parse the registries.conf file") - } - for _, registry := range sysregistriesv2.FindUnqualifiedSearchRegistries(registries) { - if !registry.Blocked { - searchRegistries = append(searchRegistries, registry.URL) - } - } - return searchRegistries, nil -} - // isRegistryInsecure checks if the named registry is marked as not secure func isRegistryInsecure(registry string, sc *types.SystemContext) (bool, error) { registries, err := sysregistriesv2.GetRegistries(sc) @@ -252,20 +237,6 @@ func isReferenceBlocked(ref types.ImageReference, sc *types.SystemContext) (bool return false, nil } -// hasRegistry returns a bool/err response if the image has a registry in its -// name -func hasRegistry(imageName string) (bool, error) { - imgRef, err := reference.Parse(imageName) - if err != nil { - return false, errors.Wrapf(err, "error parsing image name %q", imageName) - } - registry := reference.Domain(imgRef.(reference.Named)) - if registry != "" { - return true, nil - } - return false, nil -} - // ReserveSELinuxLabels reads containers storage and reserves SELinux containers // fall all existing buildah containers func ReserveSELinuxLabels(store storage.Store, id string) error { @@ -281,7 +252,7 @@ func ReserveSELinuxLabels(store storage.Store, id string) error { } else { b, err := OpenBuilder(store, c.ID) if err != nil { - if os.IsNotExist(err) { + if os.IsNotExist(errors.Cause(err)) { // Ignore not exist errors since containers probably created by other tool // TODO, we need to read other containers json data to reserve their SELinux labels continue diff --git a/vendor/github.com/containers/buildah/util/util.go b/vendor/github.com/containers/buildah/util/util.go index 887004ba4..3a415a7f3 100644 --- a/vendor/github.com/containers/buildah/util/util.go +++ b/vendor/github.com/containers/buildah/util/util.go @@ -63,10 +63,13 @@ var ( // ResolveName checks if name is a valid image name, and if that name doesn't // include a domain portion, returns a list of the names which it might -// correspond to in the set of configured registries. -func ResolveName(name string, firstRegistry string, sc *types.SystemContext, store storage.Store) ([]string, error) { +// correspond to in the set of configured registries, +// and a boolean which is true iff 1) the list of search registries was used, and 2) it was empty. +// NOTE: The "list of search registries is empty" check does not count blocked registries, +// and neither the implied "localhost" nor a possible firstRegistry are counted +func ResolveName(name string, firstRegistry string, sc *types.SystemContext, store storage.Store) ([]string, bool, error) { if name == "" { - return nil, nil + return nil, false, nil } // Maybe it's a truncated image ID. Don't prepend a registry name, then. @@ -74,7 +77,7 @@ func ResolveName(name string, firstRegistry string, sc *types.SystemContext, sto if img, err := store.Image(name); err == nil && img != nil && strings.HasPrefix(img.ID, name) { // It's a truncated version of the ID of an image that's present in local storage; // we need only expand the ID. - return []string{img.ID}, nil + return []string{img.ID}, false, nil } } @@ -82,18 +85,18 @@ func ResolveName(name string, firstRegistry string, sc *types.SystemContext, sto split := strings.SplitN(name, ":", 2) if len(split) == 2 { if _, ok := Transports[split[0]]; ok { - return []string{split[1]}, nil + return []string{split[1]}, false, nil } } // If the image name already included a domain component, we're done. named, err := reference.ParseNormalizedNamed(name) if err != nil { - return nil, errors.Wrapf(err, "error parsing image name %q", name) + return nil, false, errors.Wrapf(err, "error parsing image name %q", name) } if named.String() == name { // Parsing produced the same result, so there was a domain name in there to begin with. - return []string{name}, nil + return []string{name}, false, nil } if reference.Domain(named) != "" && RegistryDefaultPathPrefix[reference.Domain(named)] != "" { // If this domain can cause us to insert something in the middle, check if that happened. @@ -110,7 +113,7 @@ func ResolveName(name string, firstRegistry string, sc *types.SystemContext, sto defaultPrefix := RegistryDefaultPathPrefix[reference.Domain(named)] + "/" if strings.HasPrefix(repoPath, defaultPrefix) && path.Join(domain, repoPath[len(defaultPrefix):])+tag+digest == name { // Yup, parsing just inserted a bit in the middle, so there was a domain name there to begin with. - return []string{name}, nil + return []string{name}, false, nil } } @@ -126,6 +129,7 @@ func ResolveName(name string, firstRegistry string, sc *types.SystemContext, sto registries = append(registries, registry.URL) } } + searchRegistriesAreEmpty := len(registries) == 0 // Create all of the combinations. Some registries need an additional component added, so // use our lookaside map to keep track of them. If there are no configured registries, we'll @@ -146,7 +150,7 @@ func ResolveName(name string, firstRegistry string, sc *types.SystemContext, sto candidate := path.Join(registry, middle, name) candidates = append(candidates, candidate) } - return candidates, nil + return candidates, searchRegistriesAreEmpty, nil } // ExpandNames takes unqualified names, parses them as image names, and returns @@ -157,7 +161,7 @@ func ExpandNames(names []string, firstRegistry string, systemContext *types.Syst expanded := make([]string, 0, len(names)) for _, n := range names { var name reference.Named - nameList, err := ResolveName(n, firstRegistry, systemContext, store) + nameList, _, err := ResolveName(n, firstRegistry, systemContext, store) if err != nil { return nil, errors.Wrapf(err, "error parsing name %q", n) } @@ -193,7 +197,7 @@ func FindImage(store storage.Store, firstRegistry string, systemContext *types.S var ref types.ImageReference var img *storage.Image var err error - names, err := ResolveName(image, firstRegistry, systemContext, store) + names, _, err := ResolveName(image, firstRegistry, systemContext, store) if err != nil { return nil, nil, errors.Wrapf(err, "error parsing name %q", image) } diff --git a/vendor/github.com/containers/buildah/vendor.conf b/vendor/github.com/containers/buildah/vendor.conf index 6ab583f51..d79412afc 100644 --- a/vendor/github.com/containers/buildah/vendor.conf +++ b/vendor/github.com/containers/buildah/vendor.conf @@ -3,7 +3,7 @@ github.com/blang/semver master github.com/BurntSushi/toml master github.com/containerd/continuity master github.com/containernetworking/cni v0.7.0-alpha1 -github.com/containers/image 918dbb93e6e099b196b498c38d079f6bb924d0c8 +github.com/containers/image 5e5b67d6b1cf43cc349128ec3ed7d5283a6cc0d1 github.com/containers/libpod 2afadeec6696fefac468a49c8ba24b0bc275aa75 github.com/containers/storage 41294c85d97bef688e18f710402895dbecde3308 github.com/docker/distribution 5f6282db7d65e6d72ad7c2cc66310724a57be716 diff --git a/vendor/github.com/containers/image/README.md b/vendor/github.com/containers/image/README.md index 4ed8c93b7..8fd6e513e 100644 --- a/vendor/github.com/containers/image/README.md +++ b/vendor/github.com/containers/image/README.md @@ -53,7 +53,7 @@ are also available This library, by default, also depends on the GpgME and libostree C libraries. Either install them: ```sh -Fedora$ dnf install gpgme-devel libassuan-devel libostree-devel +Fedora$ dnf install gpgme-devel libassuan-devel ostree-devel macOS$ brew install gpgme ``` or use the build tags described below to avoid the dependencies (e.g. using `go build -tags …`) diff --git a/vendor/github.com/containers/image/copy/copy.go b/vendor/github.com/containers/image/copy/copy.go index 59354ea38..313d802b3 100644 --- a/vendor/github.com/containers/image/copy/copy.go +++ b/vendor/github.com/containers/image/copy/copy.go @@ -102,8 +102,9 @@ type Options struct { } // Image copies image from srcRef to destRef, using policyContext to validate -// source image admissibility. -func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef, srcRef types.ImageReference, options *Options) (retErr error) { +// source image admissibility. It returns the manifest which was written to +// the new copy of the image. +func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef, srcRef types.ImageReference, options *Options) (manifest []byte, retErr error) { // NOTE this function uses an output parameter for the error return value. // Setting this and returning is the ideal way to return an error. // @@ -121,7 +122,7 @@ func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef, dest, err := destRef.NewImageDestination(ctx, options.DestinationCtx) if err != nil { - return errors.Wrapf(err, "Error initializing destination %s", transports.ImageName(destRef)) + return nil, errors.Wrapf(err, "Error initializing destination %s", transports.ImageName(destRef)) } defer func() { if err := dest.Close(); err != nil { @@ -131,7 +132,7 @@ func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef, rawSource, err := srcRef.NewImageSource(ctx, options.SourceCtx) if err != nil { - return errors.Wrapf(err, "Error initializing source %s", transports.ImageName(srcRef)) + return nil, errors.Wrapf(err, "Error initializing source %s", transports.ImageName(srcRef)) } defer func() { if err := rawSource.Close(); err != nil { @@ -151,63 +152,63 @@ func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef, unparsedToplevel := image.UnparsedInstance(rawSource, nil) multiImage, err := isMultiImage(ctx, unparsedToplevel) if err != nil { - return errors.Wrapf(err, "Error determining manifest MIME type for %s", transports.ImageName(srcRef)) + return nil, errors.Wrapf(err, "Error determining manifest MIME type for %s", transports.ImageName(srcRef)) } if !multiImage { // The simple case: Just copy a single image. - if err := c.copyOneImage(ctx, policyContext, options, unparsedToplevel); err != nil { - return err + if manifest, err = c.copyOneImage(ctx, policyContext, options, unparsedToplevel); err != nil { + return nil, err } } else { // This is a manifest list. Choose a single image and copy it. // FIXME: Copy to destinations which support manifest lists, one image at a time. instanceDigest, err := image.ChooseManifestInstanceFromManifestList(ctx, options.SourceCtx, unparsedToplevel) if err != nil { - return errors.Wrapf(err, "Error choosing an image from manifest list %s", transports.ImageName(srcRef)) + return nil, errors.Wrapf(err, "Error choosing an image from manifest list %s", transports.ImageName(srcRef)) } logrus.Debugf("Source is a manifest list; copying (only) instance %s", instanceDigest) unparsedInstance := image.UnparsedInstance(rawSource, &instanceDigest) - if err := c.copyOneImage(ctx, policyContext, options, unparsedInstance); err != nil { - return err + if manifest, err = c.copyOneImage(ctx, policyContext, options, unparsedInstance); err != nil { + return nil, err } } if err := c.dest.Commit(ctx); err != nil { - return errors.Wrap(err, "Error committing the finished image") + return nil, errors.Wrap(err, "Error committing the finished image") } - return nil + return manifest, nil } // Image copies a single (on-manifest-list) image unparsedImage, using policyContext to validate // source image admissibility. -func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.PolicyContext, options *Options, unparsedImage *image.UnparsedImage) (retErr error) { +func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.PolicyContext, options *Options, unparsedImage *image.UnparsedImage) (manifest []byte, retErr error) { // The caller is handling manifest lists; this could happen only if a manifest list contains a manifest list. // Make sure we fail cleanly in such cases. multiImage, err := isMultiImage(ctx, unparsedImage) if err != nil { // FIXME FIXME: How to name a reference for the sub-image? - return errors.Wrapf(err, "Error determining manifest MIME type for %s", transports.ImageName(unparsedImage.Reference())) + return nil, errors.Wrapf(err, "Error determining manifest MIME type for %s", transports.ImageName(unparsedImage.Reference())) } if multiImage { - return fmt.Errorf("Unexpectedly received a manifest list instead of a manifest for a single image") + return nil, fmt.Errorf("Unexpectedly received a manifest list instead of a manifest for a single image") } // Please keep this policy check BEFORE reading any other information about the image. // (the multiImage check above only matches the MIME type, which we have received anyway. // Actual parsing of anything should be deferred.) if allowed, err := policyContext.IsRunningImageAllowed(ctx, unparsedImage); !allowed || err != nil { // Be paranoid and fail if either return value indicates so. - return errors.Wrap(err, "Source image rejected") + return nil, errors.Wrap(err, "Source image rejected") } src, err := image.FromUnparsedImage(ctx, options.SourceCtx, unparsedImage) if err != nil { - return errors.Wrapf(err, "Error initializing image from source %s", transports.ImageName(c.rawSource.Reference())) + return nil, errors.Wrapf(err, "Error initializing image from source %s", transports.ImageName(c.rawSource.Reference())) } if err := checkImageDestinationForCurrentRuntimeOS(ctx, options.DestinationCtx, src, c.dest); err != nil { - return err + return nil, err } var sigs [][]byte @@ -217,14 +218,14 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli c.Printf("Getting image source signatures\n") s, err := src.Signatures(ctx) if err != nil { - return errors.Wrap(err, "Error reading signatures") + return nil, errors.Wrap(err, "Error reading signatures") } sigs = s } if len(sigs) != 0 { c.Printf("Checking if image destination supports signatures\n") if err := c.dest.SupportsSignatures(ctx); err != nil { - return errors.Wrap(err, "Can not copy signatures") + return nil, errors.Wrap(err, "Can not copy signatures") } } @@ -237,28 +238,28 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli } if err := ic.updateEmbeddedDockerReference(); err != nil { - return err + return nil, err } // We compute preferredManifestMIMEType only to show it in error messages. // Without having to add this context in an error message, we would be happy enough to know only that no conversion is needed. preferredManifestMIMEType, otherManifestMIMETypeCandidates, err := ic.determineManifestConversion(ctx, c.dest.SupportedManifestMIMETypes(), options.ForceManifestMIMEType) if err != nil { - return err + return nil, err } // If src.UpdatedImageNeedsLayerDiffIDs(ic.manifestUpdates) will be true, it needs to be true by the time we get here. ic.diffIDsAreNeeded = src.UpdatedImageNeedsLayerDiffIDs(*ic.manifestUpdates) if err := ic.copyLayers(ctx); err != nil { - return err + return nil, err } // With docker/distribution registries we do not know whether the registry accepts schema2 or schema1 only; // and at least with the OpenShift registry "acceptschema2" option, there is no way to detect the support // without actually trying to upload something and getting a types.ManifestTypeRejectedError. // So, try the preferred manifest MIME type. If the process succeeds, fine… - manifest, err := ic.copyUpdatedConfigAndManifest(ctx) + manifest, err = ic.copyUpdatedConfigAndManifest(ctx) if err != nil { logrus.Debugf("Writing manifest using preferred type %s failed: %v", preferredManifestMIMEType, err) // … if it fails, _and_ the failure is because the manifest is rejected, we may have other options. @@ -266,14 +267,14 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli // We don’t have other options. // In principle the code below would handle this as well, but the resulting error message is fairly ugly. // Don’t bother the user with MIME types if we have no choice. - return err + return nil, err } // If the original MIME type is acceptable, determineManifestConversion always uses it as preferredManifestMIMEType. // So if we are here, we will definitely be trying to convert the manifest. // With !ic.canModifyManifest, that would just be a string of repeated failures for the same reason, // so let’s bail out early and with a better error message. if !ic.canModifyManifest { - return errors.Wrap(err, "Writing manifest failed (and converting it is not possible)") + return nil, errors.Wrap(err, "Writing manifest failed (and converting it is not possible)") } // errs is a list of errors when trying various manifest types. Also serves as an "upload succeeded" flag when set to nil. @@ -294,24 +295,24 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli break } if errs != nil { - return fmt.Errorf("Uploading manifest failed, attempted the following formats: %s", strings.Join(errs, ", ")) + return nil, fmt.Errorf("Uploading manifest failed, attempted the following formats: %s", strings.Join(errs, ", ")) } } if options.SignBy != "" { newSig, err := c.createSignature(manifest, options.SignBy) if err != nil { - return err + return nil, err } sigs = append(sigs, newSig) } c.Printf("Storing signatures\n") if err := c.dest.PutSignatures(ctx, sigs); err != nil { - return errors.Wrap(err, "Error writing signatures") + return nil, errors.Wrap(err, "Error writing signatures") } - return nil + return manifest, nil } // Printf writes a formatted string to c.reportWriter. diff --git a/vendor/github.com/containers/image/manifest/docker_schema1.go b/vendor/github.com/containers/image/manifest/docker_schema1.go index 234c8e63f..1ba65d5be 100644 --- a/vendor/github.com/containers/image/manifest/docker_schema1.go +++ b/vendor/github.com/containers/image/manifest/docker_schema1.go @@ -275,7 +275,7 @@ func (m *Schema1) ToSchema2Config(diffIDs []digest.Digest) ([]byte, error) { raw := make(map[string]*json.RawMessage) err = json.Unmarshal(config, &raw) if err != nil { - return nil, errors.Wrapf(err, "error re-decoding compat image config %#v: %v", s1) + return nil, errors.Wrapf(err, "error re-decoding compat image config %#v", s1) } // Drop some fields. delete(raw, "id") diff --git a/vendor/github.com/containers/image/oci/archive/oci_dest.go b/vendor/github.com/containers/image/oci/archive/oci_dest.go index 93f3f80f9..3c6b7dffa 100644 --- a/vendor/github.com/containers/image/oci/archive/oci_dest.go +++ b/vendor/github.com/containers/image/oci/archive/oci_dest.go @@ -25,7 +25,7 @@ func newImageDestination(ctx context.Context, sys *types.SystemContext, ref ociA unpackedDest, err := tempDirRef.ociRefExtracted.NewImageDestination(ctx, sys) if err != nil { if err := tempDirRef.deleteTempDir(); err != nil { - return nil, errors.Wrapf(err, "error deleting temp directory", tempDirRef.tempDirectory) + return nil, errors.Wrapf(err, "error deleting temp directory %q", tempDirRef.tempDirectory) } return nil, err } diff --git a/vendor/github.com/containers/image/oci/archive/oci_src.go b/vendor/github.com/containers/image/oci/archive/oci_src.go index f4d82bbe7..d04773c1f 100644 --- a/vendor/github.com/containers/image/oci/archive/oci_src.go +++ b/vendor/github.com/containers/image/oci/archive/oci_src.go @@ -28,7 +28,7 @@ func newImageSource(ctx context.Context, sys *types.SystemContext, ref ociArchiv unpackedSrc, err := tempDirRef.ociRefExtracted.NewImageSource(ctx, sys) if err != nil { if err := tempDirRef.deleteTempDir(); err != nil { - return nil, errors.Wrapf(err, "error deleting temp directory", tempDirRef.tempDirectory) + return nil, errors.Wrapf(err, "error deleting temp directory %q", tempDirRef.tempDirectory) } return nil, err } diff --git a/vendor/github.com/containers/image/openshift/openshift.go b/vendor/github.com/containers/image/openshift/openshift.go index a8d5072d9..dbd04f10b 100644 --- a/vendor/github.com/containers/image/openshift/openshift.go +++ b/vendor/github.com/containers/image/openshift/openshift.go @@ -96,7 +96,7 @@ func (c *openshiftClient) doRequest(ctx context.Context, method, path string, re req.Header.Set("Content-Type", "application/json") } - logrus.Debugf("%s %s", method, url) + logrus.Debugf("%s %s", method, url.String()) res, err := c.httpClient.Do(req) if err != nil { return nil, err diff --git a/vendor/github.com/containers/image/pkg/sysregistriesv2/system_registries_v2.go b/vendor/github.com/containers/image/pkg/sysregistriesv2/system_registries_v2.go index 9509c6024..067f512ad 100644 --- a/vendor/github.com/containers/image/pkg/sysregistriesv2/system_registries_v2.go +++ b/vendor/github.com/containers/image/pkg/sysregistriesv2/system_registries_v2.go @@ -141,6 +141,10 @@ func parseURL(input string) (string, error) { // registries of type Registry. func getV1Registries(config *tomlConfig) ([]Registry, error) { regMap := make(map[string]*Registry) + // We must preserve the order of config.V1Registries.Search.Registries at least. The order of the + // other registries is not really important, but make it deterministic (the same for the same config file) + // to minimize behavior inconsistency and not contribute to difficult-to-reproduce situations. + registryOrder := []string{} getRegistry := func(url string) (*Registry, error) { // Note: _pointer_ to a long-lived object var err error @@ -156,10 +160,13 @@ func getV1Registries(config *tomlConfig) ([]Registry, error) { Prefix: url, } regMap[url] = reg + registryOrder = append(registryOrder, url) } return reg, nil } + // Note: config.V1Registries.Search needs to be processed first to ensure registryOrder is populated in the right order + // if one of the search registries is also in one of the other lists. for _, search := range config.V1Registries.Search.Registries { reg, err := getRegistry(search) if err != nil { @@ -183,7 +190,8 @@ func getV1Registries(config *tomlConfig) ([]Registry, error) { } registries := []Registry{} - for _, reg := range regMap { + for _, url := range registryOrder { + reg := regMap[url] registries = append(registries, *reg) } return registries, nil diff --git a/vendor/github.com/containers/image/storage/storage_transport.go b/vendor/github.com/containers/image/storage/storage_transport.go index 8886f9250..b53c389bd 100644 --- a/vendor/github.com/containers/image/storage/storage_transport.go +++ b/vendor/github.com/containers/image/storage/storage_transport.go @@ -107,7 +107,7 @@ func (s *storageTransport) DefaultGIDMap() []idtools.IDMap { // relative to the given store, and returns it in a reference object. func (s storageTransport) ParseStoreReference(store storage.Store, ref string) (*storageReference, error) { if ref == "" { - return nil, errors.Wrapf(ErrInvalidReference, "%q is an empty reference") + return nil, errors.Wrapf(ErrInvalidReference, "%q is an empty reference", ref) } if ref[0] == '[' { // Ignore the store specifier. diff --git a/vendor/github.com/containers/storage/pkg/archive/example_changes.go b/vendor/github.com/containers/storage/pkg/archive/example_changes.go deleted file mode 100644 index 70f9c5564..000000000 --- a/vendor/github.com/containers/storage/pkg/archive/example_changes.go +++ /dev/null @@ -1,97 +0,0 @@ -// +build ignore - -// Simple tool to create an archive stream from an old and new directory -// -// By default it will stream the comparison of two temporary directories with junk files -package main - -import ( - "flag" - "fmt" - "io" - "io/ioutil" - "os" - "path" - - "github.com/containers/storage/pkg/archive" - "github.com/sirupsen/logrus" -) - -var ( - flDebug = flag.Bool("D", false, "debugging output") - flNewDir = flag.String("newdir", "", "") - flOldDir = flag.String("olddir", "", "") - log = logrus.New() -) - -func main() { - flag.Usage = func() { - fmt.Println("Produce a tar from comparing two directory paths. By default a demo tar is created of around 200 files (including hardlinks)") - fmt.Printf("%s [OPTIONS]\n", os.Args[0]) - flag.PrintDefaults() - } - flag.Parse() - log.Out = os.Stderr - if (len(os.Getenv("DEBUG")) > 0) || *flDebug { - logrus.SetLevel(logrus.DebugLevel) - } - var newDir, oldDir string - - if len(*flNewDir) == 0 { - var err error - newDir, err = ioutil.TempDir("", "storage-test-newDir") - if err != nil { - log.Fatal(err) - } - defer os.RemoveAll(newDir) - if _, err := prepareUntarSourceDirectory(100, newDir, true); err != nil { - log.Fatal(err) - } - } else { - newDir = *flNewDir - } - - if len(*flOldDir) == 0 { - oldDir, err := ioutil.TempDir("", "storage-test-oldDir") - if err != nil { - log.Fatal(err) - } - defer os.RemoveAll(oldDir) - } else { - oldDir = *flOldDir - } - - changes, err := archive.ChangesDirs(newDir, oldDir) - if err != nil { - log.Fatal(err) - } - - a, err := archive.ExportChanges(newDir, changes) - if err != nil { - log.Fatal(err) - } - defer a.Close() - - i, err := io.Copy(os.Stdout, a) - if err != nil && err != io.EOF { - log.Fatal(err) - } - fmt.Fprintf(os.Stderr, "wrote archive of %d bytes", i) -} - -func prepareUntarSourceDirectory(numberOfFiles int, targetPath string, makeLinks bool) (int, error) { - fileData := []byte("fooo") - for n := 0; n < numberOfFiles; n++ { - fileName := fmt.Sprintf("file-%d", n) - if err := ioutil.WriteFile(path.Join(targetPath, fileName), fileData, 0700); err != nil { - return 0, err - } - if makeLinks { - if err := os.Link(path.Join(targetPath, fileName), path.Join(targetPath, fileName+"-link")); err != nil { - return 0, err - } - } - } - totalSize := numberOfFiles * len(fileData) - return totalSize, nil -} |