Make podman commit to localhost rather then docker.io

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>

Closes: 
Approved by: mheon
This commit is contained in:
Daniel J Walsh
2018-05-03 08:59:19 -04:00
committed by Atomic Bot
parent e6ec1aaffe
commit fae5033a01
7 changed files with 124 additions and 91 deletions
docs
libpod
vendor.conf
vendor/github.com/projectatomic/buildah

@ -17,6 +17,8 @@ committed. This minimizes the likelihood of data corruption when creating the ne
image. If this is not desired, the **--pause** flag can be set to false. When the commit image. If this is not desired, the **--pause** flag can be set to false. When the commit
is complete, podman will print out the ID of the new image. is complete, podman will print out the ID of the new image.
If *imageName* does not begin with a registry name component, *localhost* will be added to the name.
## OPTIONS ## OPTIONS
**--author, -a** **--author, -a**

@ -8,6 +8,7 @@ import (
is "github.com/containers/image/storage" is "github.com/containers/image/storage"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/buildah" "github.com/projectatomic/buildah"
"github.com/projectatomic/buildah/util"
"github.com/projectatomic/libpod/libpod/image" "github.com/projectatomic/libpod/libpod/image"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -132,13 +133,18 @@ func (c *Container) Commit(ctx context.Context, destImage string, options Contai
importBuilder.SetWorkDir(splitChange[1]) importBuilder.SetWorkDir(splitChange[1])
} }
} }
imageRef, err := is.Transport.ParseStoreReference(c.runtime.store, destImage) candidates := util.ResolveName(destImage, "", sc, c.runtime.store)
if len(candidates) == 0 {
return nil, errors.Errorf("error parsing target image name %q", destImage)
}
imageRef, err := is.Transport.ParseStoreReference(c.runtime.store, candidates[0])
if err != nil {
return nil, errors.Wrapf(err, "error parsing target image name %q", destImage)
}
id, err := importBuilder.Commit(ctx, imageRef, commitOptions)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err = importBuilder.Commit(ctx, imageRef, commitOptions); err != nil {
return nil, err
}
fmt.Fprintf(commitOptions.ReportWriter, importBuilder.Comment()) fmt.Fprintf(commitOptions.ReportWriter, importBuilder.Comment())
return c.runtime.imageRuntime.NewFromLocal(imageRef.DockerReference().String()) return c.runtime.imageRuntime.NewFromLocal(id)
} }

@ -87,8 +87,8 @@ k8s.io/client-go 7cd1d3291b7d9b1e2d54d4b69eb65995eaf8888e https://github.com/kub
k8s.io/kube-openapi 275e2ce91dec4c05a4094a7b1daee5560b555ac9 https://github.com/kubernetes/kube-openapi k8s.io/kube-openapi 275e2ce91dec4c05a4094a7b1daee5560b555ac9 https://github.com/kubernetes/kube-openapi
k8s.io/utils 258e2a2fa64568210fbd6267cf1d8fd87c3cb86e https://github.com/kubernetes/utils k8s.io/utils 258e2a2fa64568210fbd6267cf1d8fd87c3cb86e https://github.com/kubernetes/utils
github.com/mrunalp/fileutils master github.com/mrunalp/fileutils master
github.com/varlink/go master https://github.com/varlink/go github.com/varlink/go master
github.com/projectatomic/buildah master https://github.com/projectatomic/buildah github.com/projectatomic/buildah master
github.com/Nvveen/Gotty master github.com/Nvveen/Gotty master
github.com/fsouza/go-dockerclient master github.com/fsouza/go-dockerclient master
github.com/openshift/imagebuilder master github.com/openshift/imagebuilder master

@ -78,15 +78,19 @@ type PushOptions struct {
// Commit writes the contents of the container, along with its updated // Commit writes the contents of the container, along with its updated
// configuration, to a new image in the specified location, and if we know how, // configuration, to a new image in the specified location, and if we know how,
// add any additional tags that were specified. // add any additional tags that were specified. Returns the ID of the new image
func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options CommitOptions) error { // if commit was successful and the image destination was local
policy, err := signature.DefaultPolicy(getSystemContext(options.SystemContext, options.SignaturePolicyPath)) func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options CommitOptions) (string, error) {
var imgID string
systemContext := getSystemContext(options.SystemContext, options.SignaturePolicyPath)
policy, err := signature.DefaultPolicy(systemContext)
if err != nil { if err != nil {
return errors.Wrapf(err, "error obtaining default signature policy") return imgID, errors.Wrapf(err, "error obtaining default signature policy")
} }
policyContext, err := signature.NewPolicyContext(policy) policyContext, err := signature.NewPolicyContext(policy)
if err != nil { if err != nil {
return errors.Wrapf(err, "error creating new signature policy context") return imgID, errors.Wrapf(err, "error creating new signature policy context")
} }
defer func() { defer func() {
if err2 := policyContext.Destroy(); err2 != nil { if err2 := policyContext.Destroy(); err2 != nil {
@ -98,23 +102,23 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options
exporting := !destIsStorage exporting := !destIsStorage
src, err := b.makeImageRef(options.PreferredManifestType, exporting, options.Compression, options.HistoryTimestamp) src, err := b.makeImageRef(options.PreferredManifestType, exporting, options.Compression, options.HistoryTimestamp)
if err != nil { if err != nil {
return errors.Wrapf(err, "error computing layer digests and building metadata") return imgID, errors.Wrapf(err, "error computing layer digests and building metadata")
} }
// "Copy" our image to where it needs to be. // "Copy" our image to where it needs to be.
err = cp.Image(ctx, policyContext, dest, src, getCopyOptions(options.ReportWriter, nil, options.SystemContext, "")) err = cp.Image(ctx, policyContext, dest, src, getCopyOptions(options.ReportWriter, nil, systemContext, ""))
if err != nil { if err != nil {
return errors.Wrapf(err, "error copying layers and metadata") return imgID, errors.Wrapf(err, "error copying layers and metadata")
} }
if len(options.AdditionalTags) > 0 { if len(options.AdditionalTags) > 0 {
switch dest.Transport().Name() { switch dest.Transport().Name() {
case is.Transport.Name(): case is.Transport.Name():
img, err := is.Transport.GetStoreImage(b.store, dest) img, err := is.Transport.GetStoreImage(b.store, dest)
if err != nil { if err != nil {
return errors.Wrapf(err, "error locating just-written image %q", transports.ImageName(dest)) return imgID, errors.Wrapf(err, "error locating just-written image %q", transports.ImageName(dest))
} }
err = util.AddImageNames(b.store, img, options.AdditionalTags) err = util.AddImageNames(b.store, "", systemContext, img, options.AdditionalTags)
if err != nil { if err != nil {
return errors.Wrapf(err, "error setting image names to %v", append(img.Names, options.AdditionalTags...)) return imgID, 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) logrus.Debugf("assigned names %v to image %q", img.Names, img.ID)
default: default:
@ -123,16 +127,21 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options
} }
img, err := is.Transport.GetStoreImage(b.store, dest) img, err := is.Transport.GetStoreImage(b.store, dest)
if err != nil && err != storage.ErrImageUnknown {
return imgID, err
}
if err == nil { if err == nil {
imgID = img.ID
if options.IIDFile != "" { if options.IIDFile != "" {
if err := ioutil.WriteFile(options.IIDFile, []byte(img.ID), 0644); err != nil { if err := ioutil.WriteFile(options.IIDFile, []byte(img.ID), 0644); err != nil {
return errors.Wrapf(err, "failed to write Image ID File %q", options.IIDFile) return imgID, errors.Wrapf(err, "failed to write Image ID File %q", options.IIDFile)
} }
} else {
fmt.Printf("%s\n", img.ID)
} }
} }
return nil
return imgID, nil
} }
// Push copies the contents of the image to a new location. // Push copies the contents of the image to a new location.
@ -147,12 +156,12 @@ func Push(ctx context.Context, image string, dest types.ImageReference, options
return errors.Wrapf(err, "error creating new signature policy context") return errors.Wrapf(err, "error creating new signature policy context")
} }
// Look up the image. // Look up the image.
src, err := is.Transport.ParseStoreReference(options.Store, image) src, _, err := util.FindImage(options.Store, "", systemContext, image)
if err != nil { if err != nil {
return errors.Wrapf(err, "error parsing reference to image %q", image) return err
} }
// Copy everything. // Copy everything.
err = cp.Image(ctx, policyContext, dest, src, getCopyOptions(options.ReportWriter, nil, options.SystemContext, options.ManifestType)) err = cp.Image(ctx, policyContext, dest, src, getCopyOptions(options.ReportWriter, nil, systemContext, options.ManifestType))
if err != nil { if err != nil {
return errors.Wrapf(err, "error copying layers and metadata") return errors.Wrapf(err, "error copying layers and metadata")
} }

@ -23,6 +23,7 @@ import (
"github.com/openshift/imagebuilder" "github.com/openshift/imagebuilder"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/buildah" "github.com/projectatomic/buildah"
"github.com/projectatomic/buildah/util"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -623,22 +624,25 @@ func (b *Executor) Execute(ib *imagebuilder.Builder, node *parser.Node) error {
// the name if there is one, generating a unique ID-based one otherwise. // the name if there is one, generating a unique ID-based one otherwise.
func (b *Executor) Commit(ctx context.Context, ib *imagebuilder.Builder) (err error) { func (b *Executor) Commit(ctx context.Context, ib *imagebuilder.Builder) (err error) {
var imageRef types.ImageReference var imageRef types.ImageReference
if b.output != "" { if b.output != "" {
imageRef, err = alltransports.ParseImageName(b.output) imageRef, err = alltransports.ParseImageName(b.output)
if err != nil { if err != nil {
imageRef2, err2 := is.Transport.ParseStoreReference(b.store, b.output) candidates := util.ResolveName(b.output, "", b.systemContext, b.store)
if err2 == nil { if len(candidates) == 0 {
imageRef = imageRef2 return errors.Errorf("error parsing target image name %q", b.output)
err = nil
} else {
err = err2
} }
imageRef2, err2 := is.Transport.ParseStoreReference(b.store, candidates[0])
if err2 != nil {
return errors.Wrapf(err, "error parsing target image name %q", b.output)
}
imageRef = imageRef2
} }
} else { } else {
imageRef, err = is.Transport.ParseStoreReference(b.store, "@"+stringid.GenerateRandomID()) imageRef, err = is.Transport.ParseStoreReference(b.store, "@"+stringid.GenerateRandomID())
} if err != nil {
if err != nil { return errors.Wrapf(err, "error parsing reference for image to be written")
return errors.Wrapf(err, "error parsing reference for image to be written") }
} }
if ib.Author != "" { if ib.Author != "" {
b.builder.SetMaintainer(ib.Author) b.builder.SetMaintainer(ib.Author)
@ -689,7 +693,14 @@ func (b *Executor) Commit(ctx context.Context, ib *imagebuilder.Builder) (err er
PreferredManifestType: b.outputFormat, PreferredManifestType: b.outputFormat,
IIDFile: b.iidfile, IIDFile: b.iidfile,
} }
return b.builder.Commit(ctx, imageRef, options) imgID, err := b.builder.Commit(ctx, imageRef, options)
if err != nil {
return err
}
if options.IIDFile == "" && imgID != "" {
fmt.Printf("%s\n", imgID)
}
return nil
} }
// Build takes care of the details of running Prepare/Execute/Commit/Delete // Build takes care of the details of running Prepare/Execute/Commit/Delete

@ -97,27 +97,21 @@ func importBuilder(ctx context.Context, store storage.Store, options ImportOptio
} }
func importBuilderFromImage(ctx context.Context, store storage.Store, options ImportFromImageOptions) (*Builder, error) { func importBuilderFromImage(ctx context.Context, store storage.Store, options ImportFromImageOptions) (*Builder, error) {
var img *storage.Image
var err error
if options.Image == "" { if options.Image == "" {
return nil, errors.Errorf("image name must be specified") return nil, errors.Errorf("image name must be specified")
} }
systemContext := getSystemContext(options.SystemContext, options.SignaturePolicyPath) systemContext := getSystemContext(options.SystemContext, options.SignaturePolicyPath)
for _, image := range util.ResolveName(options.Image, "", systemContext, store) { _, img, err := util.FindImage(store, "", systemContext, options.Image)
img, err = util.FindImage(store, image) if err != nil {
if err != nil { return nil, errors.Wrapf(err, "error locating image %q for importing settings", options.Image)
continue
}
builder, err2 := importBuilderDataFromImage(ctx, store, systemContext, img.ID, "", "")
if err2 != nil {
return nil, errors.Wrapf(err2, "error importing build settings from image %q", options.Image)
}
return builder, nil
} }
return nil, errors.Wrapf(err, "error locating image %q for importing settings", options.Image)
builder, err := importBuilderDataFromImage(ctx, store, systemContext, img.ID, "", "")
if err != nil {
return nil, errors.Wrapf(err, "error importing build settings from image %q", options.Image)
}
return builder, nil
} }

@ -6,7 +6,6 @@ import (
"net/url" "net/url"
"path" "path"
"strings" "strings"
"time"
"github.com/containers/image/directory" "github.com/containers/image/directory"
dockerarchive "github.com/containers/image/docker/archive" dockerarchive "github.com/containers/image/docker/archive"
@ -54,8 +53,9 @@ var (
TarballTransport = tarball.Transport.Name() TarballTransport = tarball.Transport.Name()
) )
// ResolveName checks if name is a valid image name, and if that name doesn't include a domain // ResolveName checks if name is a valid image name, and if that name doesn't
// portion, returns a list of the names which it might correspond to in the registries. // 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 { func ResolveName(name string, firstRegistry string, sc *types.SystemContext, store storage.Store) []string {
if name == "" { if name == "" {
return nil return nil
@ -101,8 +101,8 @@ func ResolveName(name string, firstRegistry string, sc *types.SystemContext, sto
// Figure out the list of registries. // Figure out the list of registries.
registries, err := sysregistries.GetRegistries(sc) registries, err := sysregistries.GetRegistries(sc)
if err != nil { if err != nil {
logrus.Debugf("unable to complete image name %q: %v", name, err) logrus.Debugf("unable to read configured registries to complete %q: %v", name, err)
return []string{name} registries = []string{}
} }
if sc.DockerInsecureSkipTLSVerify { if sc.DockerInsecureSkipTLSVerify {
if unverifiedRegistries, err := sysregistries.GetInsecureRegistries(sc); err == nil { if unverifiedRegistries, err := sysregistries.GetInsecureRegistries(sc); err == nil {
@ -111,10 +111,14 @@ func ResolveName(name string, firstRegistry string, sc *types.SystemContext, sto
} }
// Create all of the combinations. Some registries need an additional component added, so // 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, at // use our lookaside map to keep track of them. If there are no configured registries, we'll
// least return the name as it was passed to us. // return a name using "localhost" as the registry name.
candidates := []string{} candidates := []string{}
for _, registry := range append([]string{firstRegistry}, registries...) { initRegistries := []string{"localhost"}
if firstRegistry != "" && firstRegistry != "localhost" {
initRegistries = append([]string{firstRegistry}, initRegistries...)
}
for _, registry := range append(initRegistries, registries...) {
if registry == "" { if registry == "" {
continue continue
} }
@ -125,9 +129,6 @@ func ResolveName(name string, firstRegistry string, sc *types.SystemContext, sto
candidate := path.Join(registry, middle, name) candidate := path.Join(registry, middle, name)
candidates = append(candidates, candidate) candidates = append(candidates, candidate)
} }
if len(candidates) == 0 {
candidates = append(candidates, name)
}
return candidates return candidates
} }
@ -135,12 +136,23 @@ func ResolveName(name string, firstRegistry string, sc *types.SystemContext, sto
// the fully expanded result, including a tag. Names which don't include a registry // the fully expanded result, including a tag. Names which don't include a registry
// name will be marked for the most-preferred registry (i.e., the first one in our // name will be marked for the most-preferred registry (i.e., the first one in our
// configuration). // configuration).
func ExpandNames(names []string) ([]string, error) { func ExpandNames(names []string, firstRegistry string, systemContext *types.SystemContext, store storage.Store) ([]string, error) {
expanded := make([]string, 0, len(names)) expanded := make([]string, 0, len(names))
for _, n := range names { for _, n := range names {
name, err := reference.ParseNormalizedNamed(n) var name reference.Named
if err != nil { nameList := ResolveName(n, firstRegistry, systemContext, store)
return nil, errors.Wrapf(err, "error parsing name %q", n) if len(nameList) == 0 {
named, err := reference.ParseNormalizedNamed(n)
if err != nil {
return nil, errors.Wrapf(err, "error parsing name %q", n)
}
name = named
} else {
named, err := reference.ParseNormalizedNamed(nameList[0])
if err != nil {
return nil, errors.Wrapf(err, "error parsing name %q", nameList[0])
}
name = named
} }
name = reference.TagNameOnly(name) name = reference.TagNameOnly(name)
tag := "" tag := ""
@ -157,28 +169,36 @@ func ExpandNames(names []string) ([]string, error) {
} }
// FindImage locates the locally-stored image which corresponds to a given name. // FindImage locates the locally-stored image which corresponds to a given name.
func FindImage(store storage.Store, image string) (*storage.Image, error) { func FindImage(store storage.Store, firstRegistry string, systemContext *types.SystemContext, image string) (types.ImageReference, *storage.Image, error) {
var ref types.ImageReference
var img *storage.Image var img *storage.Image
ref, err := is.Transport.ParseStoreReference(store, image) var err error
if err == nil { for _, name := range ResolveName(image, firstRegistry, systemContext, store) {
img, err = is.Transport.GetStoreImage(store, ref) ref, err = is.Transport.ParseStoreReference(store, name)
} if err != nil {
if err != nil { logrus.Debugf("error parsing reference to image %q: %v", name, err)
img2, err2 := store.Image(image) continue
if err2 != nil {
if ref == nil {
return nil, errors.Wrapf(err, "error parsing reference to image %q", image)
}
return nil, errors.Wrapf(err, "unable to locate image %q", image)
} }
img = img2 img, err = is.Transport.GetStoreImage(store, ref)
if err != nil {
img2, err2 := store.Image(name)
if err2 != nil {
logrus.Debugf("error locating image %q: %v", name, err2)
continue
}
img = img2
}
break
} }
return img, nil if ref == nil || img == nil {
return nil, nil, errors.Wrapf(err, "error locating image with name %q", image)
}
return ref, img, nil
} }
// AddImageNames adds the specified names to the specified image. // AddImageNames adds the specified names to the specified image.
func AddImageNames(store storage.Store, image *storage.Image, addNames []string) error { func AddImageNames(store storage.Store, firstRegistry string, systemContext *types.SystemContext, image *storage.Image, addNames []string) error {
names, err := ExpandNames(addNames) names, err := ExpandNames(addNames, firstRegistry, systemContext, store)
if err != nil { if err != nil {
return err return err
} }
@ -203,15 +223,6 @@ func GetFailureCause(err, defaultError error) error {
} }
} }
// GetLocalTime discover the UTC offset and then add that to the
// passed in time to arrive at the local time.
func GetLocalTime(localTime time.Time) time.Time {
t := time.Now()
_, offset := t.Local().Zone()
localTime = localTime.Add(time.Second * time.Duration(offset))
return localTime
}
// WriteError writes `lastError` into `w` if not nil and return the next error `err` // WriteError writes `lastError` into `w` if not nil and return the next error `err`
func WriteError(w io.Writer, err error, lastError error) error { func WriteError(w io.Writer, err error, lastError error) error {
if lastError != nil { if lastError != nil {