Vendor in new new buildah/ci

libpod requires new buildah and container image versions to resolve
bug #1640298

Signed-off-by: baude <bbaude@redhat.com>
This commit is contained in:
baude
2018-10-17 16:42:05 -05:00
parent 19c150bef1
commit bfc473f982
25 changed files with 260 additions and 317 deletions

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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)
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
img, err := is.Transport.GetStoreImage(store, ref)
if err == nil {
return ref, img, nil
}
break
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 {
logrus.Debugf("unable to pull and read image %q: %v", image, err)
failures = append(failures, failure{resolvedImageName: image, err: err})
continue
}
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)
}
}

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -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)
}

View File

@@ -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