diff options
author | baude <bbaude@redhat.com> | 2018-03-22 10:17:50 -0500 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2018-03-23 15:35:37 +0000 |
commit | f7c8dd5836002f3bf85a7bbe6c949cdece5194df (patch) | |
tree | 6cee5a91ff32b016efcf8e9dbcff398b42ce5c4a | |
parent | 8ca3bcc85d6bbf05e7838b20bfb1ae74afa8d35d (diff) | |
download | podman-f7c8dd5836002f3bf85a7bbe6c949cdece5194df.tar.gz podman-f7c8dd5836002f3bf85a7bbe6c949cdece5194df.tar.bz2 podman-f7c8dd5836002f3bf85a7bbe6c949cdece5194df.zip |
Stage 4 Image cleanup
Cull funcs from runtime_img.go which are no longer needed. Also, fix any remaining
spots that use the old image technique.
Signed-off-by: baude <bbaude@redhat.com>
Closes: #532
Approved by: mheon
-rw-r--r-- | cmd/podman/images.go | 20 | ||||
-rw-r--r-- | cmd/podman/import.go | 2 | ||||
-rw-r--r-- | cmd/podman/load.go | 15 | ||||
-rw-r--r-- | cmd/podman/pull.go | 25 | ||||
-rw-r--r-- | cmd/podman/push.go | 36 | ||||
-rw-r--r-- | cmd/podman/rmi.go | 3 | ||||
-rw-r--r-- | cmd/podman/save.go | 14 | ||||
-rw-r--r-- | libpod/container_api.go | 2 | ||||
-rw-r--r-- | libpod/diff.go | 4 | ||||
-rw-r--r-- | libpod/image/filters.go | 82 | ||||
-rw-r--r-- | libpod/image/image.go | 6 | ||||
-rw-r--r-- | libpod/runtime_img.go | 1142 | ||||
-rw-r--r-- | libpod/util.go | 5 |
13 files changed, 155 insertions, 1201 deletions
diff --git a/cmd/podman/images.go b/cmd/podman/images.go index 67f7920f2..4e2114705 100644 --- a/cmd/podman/images.go +++ b/cmd/podman/images.go @@ -82,7 +82,7 @@ var ( func imagesCmd(c *cli.Context) error { var ( - filterFuncs []libpod.ImageResultFilter + filterFuncs []image.ResultFilter newImage *image.Image ) if err := validateFlags(c, imagesFlags); err != nil { @@ -136,7 +136,7 @@ func imagesCmd(c *cli.Context) error { var filteredImages []*image.Image // filter the images if len(c.StringSlice("filter")) > 0 || newImage != nil { - filteredImages = libpod.FilterImages(images, filterFuncs) + filteredImages = image.FilterImages(images, filterFuncs) } else { filteredImages = images } @@ -266,8 +266,8 @@ func (i *imagesTemplateParams) HeaderMap() map[string]string { // CreateFilterFuncs returns an array of filter functions based on the user inputs // and is later used to filter images for output -func CreateFilterFuncs(r *libpod.Runtime, c *cli.Context, image *image.Image) ([]libpod.ImageResultFilter, error) { - var filterFuncs []libpod.ImageResultFilter +func CreateFilterFuncs(r *libpod.Runtime, c *cli.Context, img *image.Image) ([]image.ResultFilter, error) { + var filterFuncs []image.ResultFilter for _, filter := range c.StringSlice("filter") { splitFilter := strings.Split(filter, "=") switch splitFilter[0] { @@ -276,24 +276,24 @@ func CreateFilterFuncs(r *libpod.Runtime, c *cli.Context, image *image.Image) ([ if err != nil { return nil, errors.Wrapf(err, "unable to find image % in local stores", splitFilter[1]) } - filterFuncs = append(filterFuncs, libpod.ImageCreatedBefore(before.Created())) + filterFuncs = append(filterFuncs, image.CreatedBeforeFilter(before.Created())) case "after": after, err := r.ImageRuntime().NewFromLocal(splitFilter[1]) if err != nil { return nil, errors.Wrapf(err, "unable to find image % in local stores", splitFilter[1]) } - filterFuncs = append(filterFuncs, libpod.ImageCreatedAfter(after.Created())) + filterFuncs = append(filterFuncs, image.CreatedAfterFilter(after.Created())) case "dangling": - filterFuncs = append(filterFuncs, libpod.ImageDangling()) + filterFuncs = append(filterFuncs, image.DanglingFilter()) case "label": labelFilter := strings.Join(splitFilter[1:], "=") - filterFuncs = append(filterFuncs, libpod.ImageLabel(labelFilter)) + filterFuncs = append(filterFuncs, image.LabelFilter(labelFilter)) default: return nil, errors.Errorf("invalid filter %s ", splitFilter[0]) } } - if image != nil { - filterFuncs = append(filterFuncs, libpod.OutputImageFilter(image)) + if img != nil { + filterFuncs = append(filterFuncs, image.OutputImageFilter(img)) } return filterFuncs, nil } diff --git a/cmd/podman/import.go b/cmd/podman/import.go index 6f7565b4b..bebd4486c 100644 --- a/cmd/podman/import.go +++ b/cmd/podman/import.go @@ -107,7 +107,7 @@ func importCmd(c *cli.Context) error { source = file } - newImage, err := runtime.Import(source, reference, writer, image.SigningOptions{}, config) + newImage, err := runtime.ImageRuntime().Import(source, reference, writer, image.SigningOptions{}, config) if err == nil { fmt.Println(newImage.ID()) } diff --git a/cmd/podman/load.go b/cmd/podman/load.go index d3a15a2ae..8146f4c5d 100644 --- a/cmd/podman/load.go +++ b/cmd/podman/load.go @@ -8,6 +8,7 @@ import ( "github.com/pkg/errors" "github.com/projectatomic/libpod/libpod" + libpodImage "github.com/projectatomic/libpod/libpod/image" "github.com/urfave/cli" ) @@ -44,6 +45,7 @@ func loadCmd(c *cli.Context) error { args := c.Args() var image string + if len(args) == 1 { image = args[0] } @@ -96,28 +98,23 @@ func loadCmd(c *cli.Context) error { writer = os.Stderr } - options := libpod.CopyOptions{ - SignaturePolicyPath: c.String("signature-policy"), - Writer: writer, - } - src := libpod.DockerArchive + ":" + input - imgName, err := runtime.PullImage(src, options) + newImage, err := runtime.ImageRuntime().New(src, c.String("signature-policy"), "", writer, &libpodImage.DockerRegistryOptions{}, libpodImage.SigningOptions{}) if err != nil { // generate full src name with specified image:tag fullSrc := libpod.OCIArchive + ":" + input if image != "" { fullSrc = fullSrc + ":" + image } - imgName, err = runtime.PullImage(fullSrc, options) + newImage, err = runtime.ImageRuntime().New(fullSrc, c.String("signature-policy"), "", writer, &libpodImage.DockerRegistryOptions{}, libpodImage.SigningOptions{}) if err != nil { src = libpod.DirTransport + ":" + input - imgName, err = runtime.PullImage(src, options) + newImage, err = runtime.ImageRuntime().New(src, c.String("signature-policy"), "", writer, &libpodImage.DockerRegistryOptions{}, libpodImage.SigningOptions{}) if err != nil { return errors.Wrapf(err, "error pulling %q", src) } } } - fmt.Println("Loaded image: ", imgName) + fmt.Println("Loaded image: ", newImage.InputName) return nil } diff --git a/cmd/podman/pull.go b/cmd/podman/pull.go index 5dc9ef2d4..28d69cfdd 100644 --- a/cmd/podman/pull.go +++ b/cmd/podman/pull.go @@ -8,8 +8,7 @@ import ( "github.com/containers/image/types" "github.com/pkg/errors" - "github.com/projectatomic/libpod/libpod" - "github.com/projectatomic/libpod/libpod/common" + image2 "github.com/projectatomic/libpod/libpod/image" "github.com/projectatomic/libpod/pkg/util" "github.com/sirupsen/logrus" "github.com/urfave/cli" @@ -94,27 +93,19 @@ func pullCmd(c *cli.Context) error { writer = os.Stderr } - options := libpod.CopyOptions{ - SignaturePolicyPath: c.String("signature-policy"), - AuthFile: c.String("authfile"), - DockerRegistryOptions: common.DockerRegistryOptions{ - DockerRegistryCreds: registryCreds, - DockerCertPath: c.String("cert-dir"), - DockerInsecureSkipTLSVerify: !c.BoolT("tls-verify"), - }, - Writer: writer, + dockerRegistryOptions := image2.DockerRegistryOptions{ + DockerRegistryCreds: registryCreds, + DockerCertPath: c.String("cert-dir"), + DockerInsecureSkipTLSVerify: !c.BoolT("tls-verify"), } - if _, err := runtime.PullImage(image, options); err != nil { + newImage, err := runtime.ImageRuntime().New(image, c.String("signature-policy"), c.String("authfile"), writer, &dockerRegistryOptions, image2.SigningOptions{}) + if err != nil { return errors.Wrapf(err, "error pulling image %q", image) } - newImage := runtime.NewImage(image) - iid, err := newImage.GetImageID() // Intentially choosing to ignore if there is an error because // outputting the image ID is a NTH and not integral to the pull - if err == nil { - fmt.Println(iid) - } + fmt.Println(newImage.ID()) return nil } diff --git a/cmd/podman/push.go b/cmd/podman/push.go index e16b91611..3a39a1a0e 100644 --- a/cmd/podman/push.go +++ b/cmd/podman/push.go @@ -8,11 +8,10 @@ import ( "github.com/containers/image/manifest" "github.com/containers/image/types" - "github.com/containers/storage/pkg/archive" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" "github.com/projectatomic/libpod/libpod" - "github.com/projectatomic/libpod/libpod/common" + "github.com/projectatomic/libpod/libpod/image" "github.com/projectatomic/libpod/pkg/util" "github.com/urfave/cli" ) @@ -135,23 +134,22 @@ func pushCmd(c *cli.Context) error { } } - options := libpod.CopyOptions{ - Compression: archive.Uncompressed, - SignaturePolicyPath: c.String("signature-policy"), - DockerRegistryOptions: common.DockerRegistryOptions{ - DockerRegistryCreds: registryCreds, - DockerCertPath: certPath, - DockerInsecureSkipTLSVerify: skipVerify, - }, - SigningOptions: common.SigningOptions{ - RemoveSignatures: removeSignatures, - SignBy: signBy, - }, - AuthFile: c.String("authfile"), - Writer: writer, - ManifestMIMEType: manifestType, - ForceCompress: c.Bool("compress"), + dockerRegistryOptions := image.DockerRegistryOptions{ + DockerRegistryCreds: registryCreds, + DockerCertPath: certPath, + DockerInsecureSkipTLSVerify: skipVerify, + } + + so := image.SigningOptions{ + RemoveSignatures: removeSignatures, + SignBy: signBy, + } + + newImage, err := runtime.ImageRuntime().NewFromLocal(srcName) + if err != nil { + return err } - return runtime.PushImage(srcName, destName, options) + //return runtime.PushImage(srcName, destName, options) + return newImage.PushImage(destName, manifestType, c.String("authfile"), c.String("signature-policy"), writer, c.Bool("compress"), so, &dockerRegistryOptions) } diff --git a/cmd/podman/rmi.go b/cmd/podman/rmi.go index cc902cdbe..244e07a06 100644 --- a/cmd/podman/rmi.go +++ b/cmd/podman/rmi.go @@ -5,7 +5,6 @@ import ( "os" "github.com/pkg/errors" - "github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod/image" "github.com/urfave/cli" ) @@ -56,7 +55,7 @@ func rmiCmd(c *cli.Context) error { var lastError error var imagesToDelete []*image.Image if removeAll { - imagesToDelete, err = runtime.GetImages(&libpod.ImageFilterParams{}) + imagesToDelete, err = runtime.ImageRuntime().GetImages() if err != nil { return errors.Wrapf(err, "unable to query local images") } diff --git a/cmd/podman/save.go b/cmd/podman/save.go index 5ceb456f4..009984640 100644 --- a/cmd/podman/save.go +++ b/cmd/podman/save.go @@ -9,6 +9,7 @@ import ( imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" "github.com/projectatomic/libpod/libpod" + libpodImage "github.com/projectatomic/libpod/libpod/image" "github.com/sirupsen/logrus" "github.com/urfave/cli" ) @@ -104,13 +105,6 @@ func saveCmd(c *cli.Context) error { return errors.Errorf("unknown format option %q", c.String("format")) } - saveOpts := libpod.CopyOptions{ - SignaturePolicyPath: "", - Writer: writer, - ManifestMIMEType: manifestType, - ForceCompress: c.Bool("compress"), - } - // only one image is supported for now // future pull requests will fix this for _, image := range args { @@ -119,7 +113,11 @@ func saveCmd(c *cli.Context) error { if strings.Contains(dst, libpod.OCIArchive) || strings.Contains(dst, libpod.DockerArchive) { dest = dst + ":" + image } - if err := runtime.PushImage(image, dest, saveOpts); err != nil { + newImage, err := runtime.ImageRuntime().NewFromLocal(image) + if err != nil { + return err + } + if err := newImage.PushImage(dest, manifestType, "", "", writer, c.Bool("compress"), libpodImage.SigningOptions{}, &libpodImage.DockerRegistryOptions{}); err != nil { if err2 := os.Remove(output); err2 != nil { logrus.Errorf("error deleting %q: %v", output, err) } diff --git a/libpod/container_api.go b/libpod/container_api.go index 27c7994f4..6b30141a5 100644 --- a/libpod/container_api.go +++ b/libpod/container_api.go @@ -565,7 +565,7 @@ func (c *Container) Commit(pause bool, reference string, writer io.Writer, signi if err := c.export(tempFile.Name()); err != nil { return nil, err } - return image.Import(tempFile.Name(), reference, writer, signingOptions, imageConfig, c.runtime.imageRuntime) + return c.runtime.imageRuntime.Import(tempFile.Name(), reference, writer, signingOptions, imageConfig) } // Wait blocks on a container to exit and returns its exit code diff --git a/libpod/diff.go b/libpod/diff.go index 3d95a8e41..6e07f3049 100644 --- a/libpod/diff.go +++ b/libpod/diff.go @@ -27,7 +27,7 @@ func (r *Runtime) GetDiff(from, to string) ([]archive.Change, error) { // If the id matches a layer, the top layer id is returned func (r *Runtime) getLayerID(id string) (string, error) { var toLayer string - toImage, err := r.GetImage(id) + toImage, err := r.imageRuntime.NewFromLocal(id) if err != nil { toCtr, err := r.store.Container(id) if err != nil { @@ -39,7 +39,7 @@ func (r *Runtime) getLayerID(id string) (string, error) { toLayer = toCtr.LayerID } } else { - toLayer = toImage.TopLayer + toLayer = toImage.TopLayer() } return toLayer, nil } diff --git a/libpod/image/filters.go b/libpod/image/filters.go new file mode 100644 index 000000000..20a9efc97 --- /dev/null +++ b/libpod/image/filters.go @@ -0,0 +1,82 @@ +package image + +import ( + "strings" + "time" + + "github.com/projectatomic/libpod/pkg/inspect" +) + +// ResultFilter is a mock function for image filtering +type ResultFilter func(*Image) bool + +// Filter is a function to determine whether an image is included in +// command output. Images to be outputted are tested using the function. A true +// return will include the image, a false return will exclude it. +type Filter func(*Image, *inspect.ImageData) bool + +// CreatedBeforeFilter allows you to filter on images created before +// the given time.Time +func CreatedBeforeFilter(createTime time.Time) ResultFilter { + return func(i *Image) bool { + return i.Created().Before(createTime) + } +} + +// CreatedAfterFilter allows you to filter on images created after +// the given time.Time +func CreatedAfterFilter(createTime time.Time) ResultFilter { + return func(i *Image) bool { + return i.Created().After(createTime) + } +} + +// DanglingFilter allows you to filter images for dangling images +func DanglingFilter() ResultFilter { + return func(i *Image) bool { + return i.Dangling() + } +} + +// LabelFilter allows you to filter by images labels key and/or value +func LabelFilter(labelfilter string) ResultFilter { + // We need to handle both label=key and label=key=value + return func(i *Image) bool { + var value string + splitFilter := strings.Split(labelfilter, "=") + key := splitFilter[0] + if len(splitFilter) > 1 { + value = splitFilter[1] + } + labels, err := i.Labels() + if err != nil { + return false + } + if len(strings.TrimSpace(labels[key])) > 0 && len(strings.TrimSpace(value)) == 0 { + return true + } + return labels[key] == value + } +} + +// OutputImageFilter allows you to filter by an a specific image name +func OutputImageFilter(userImage *Image) ResultFilter { + return func(i *Image) bool { + return userImage.ID() == i.ID() + } +} + +// FilterImages filters images using a set of predefined fitler funcs +func FilterImages(images []*Image, filters []ResultFilter) []*Image { + var filteredImages []*Image + for _, image := range images { + include := true + for _, filter := range filters { + include = include && filter(image) + } + if include { + filteredImages = append(filteredImages, image) + } + } + return filteredImages +} diff --git a/libpod/image/image.go b/libpod/image/image.go index b6e15e361..ac2431a56 100644 --- a/libpod/image/image.go +++ b/libpod/image/image.go @@ -641,7 +641,7 @@ func (i *Image) Inspect() (*inspect.ImageData, error) { } // Import imports and image into the store and returns an image -func Import(path, reference string, writer io.Writer, signingOptions SigningOptions, imageConfig ociv1.Image, runtime *Runtime) (*Image, error) { +func (ir *Runtime) Import(path, reference string, writer io.Writer, signingOptions SigningOptions, imageConfig ociv1.Image) (*Image, error) { file := TarballTransport + ":" + path src, err := alltransports.ParseImageName(file) if err != nil { @@ -676,14 +676,14 @@ func Import(path, reference string, writer io.Writer, signingOptions SigningOpti } defer policyContext.Destroy() copyOptions := getCopyOptions(writer, "", nil, nil, signingOptions, "", "", false) - dest, err := is.Transport.ParseStoreReference(runtime.store, reference) + dest, err := is.Transport.ParseStoreReference(ir.store, reference) if err != nil { errors.Wrapf(err, "error getting image reference for %q", reference) } if err = cp.Image(policyContext, dest, src, copyOptions); err != nil { return nil, err } - return runtime.NewFromLocal(reference) + return ir.NewFromLocal(reference) } // MatchRepoTag takes a string and tries to match it against an diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go index c830304ae..215c0afed 100644 --- a/libpod/runtime_img.go +++ b/libpod/runtime_img.go @@ -3,33 +3,20 @@ package libpod import ( "fmt" "io" - "net" "os" - "strings" - "syscall" - "time" - cp "github.com/containers/image/copy" "github.com/containers/image/directory" "github.com/containers/image/docker" dockerarchive "github.com/containers/image/docker/archive" - "github.com/containers/image/docker/reference" - "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/tarball" - "github.com/containers/image/transports/alltransports" "github.com/containers/image/types" - "github.com/containers/storage" "github.com/containers/storage/pkg/archive" ociv1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" "github.com/projectatomic/libpod/libpod/common" "github.com/projectatomic/libpod/libpod/image" - "github.com/projectatomic/libpod/pkg/inspect" - "github.com/projectatomic/libpod/pkg/util" ) // Runtime API @@ -86,752 +73,6 @@ type CopyOptions struct { ForceCompress bool } -// Image API - -// ImageFilterParams contains the filter options that may be given when outputting images -type ImageFilterParams struct { - Dangling string - Label string - BeforeImage time.Time - SinceImage time.Time - ReferencePattern string - ImageName string - ImageInput string -} - -// struct for when a user passes a short or incomplete -// image name -type imageDecomposeStruct struct { - imageName string - tag string - registry string - hasRegistry bool - transport string -} - -// ImageResultFilter is a mock function for image filtering -type ImageResultFilter func(*image.Image) bool - -func (k *Image) assembleFqName() string { - return fmt.Sprintf("%s/%s:%s", k.Registry, k.ImageName, k.Tag) -} - -func (k *Image) assembleFqNameTransport() string { - return fmt.Sprintf("%s%s/%s:%s", k.Transport, k.Registry, k.ImageName, k.Tag) -} - -//Image describes basic attributes of an image -type Image struct { - Name string - ID string - fqname string - runtime *Runtime - Registry string - ImageName string - Tag string - HasRegistry bool - Transport string - beenDecomposed bool - PullName string - LocalName string -} - -// NewImage creates a new image object based on its name -func (r *Runtime) NewImage(name string) Image { - return Image{ - Name: name, - runtime: r, - } -} - -// IsImageID determines if the input is a valid image ID. -// The input can be a full or partial image ID -func (r *Runtime) IsImageID(input string) (bool, error) { - images, err := r.GetImages(&ImageFilterParams{}) - if err != nil { - return false, errors.Wrapf(err, "unable to get images") - } - for _, image := range images { - if strings.HasPrefix(image.ID(), input) { - return true, nil - } - } - return false, nil -} - -// GetNameByID returns the name of the image when supplied -// the full or partion ID -func (k *Image) GetNameByID() (string, error) { - images, err := k.runtime.GetImages(&ImageFilterParams{}) - if err != nil { - return "", errors.Wrapf(err, "unable to get images") - } - for _, image := range images { - if strings.HasPrefix(image.ID(), k.Name) { - return image.Names()[0], nil - } - } - return "", errors.Errorf("unable to determine image for %s", k.Name) -} - -// GetImageID returns the image ID of the image -func (k *Image) GetImageID() (string, error) { - // If the ID field is already populated, then - // return it. - if k.ID != "" { - return k.ID, nil - } - // If we have the name of the image locally, then - // get the image and returns its ID - if k.LocalName != "" { - img, err := k.runtime.GetImage(k.LocalName) - if err == nil { - return img.ID, nil - } - } - // If the user input is an ID - images, err := k.runtime.GetImages(&ImageFilterParams{}) - if err != nil { - return "", errors.Wrapf(err, "unable to get images") - } - for _, image := range images { - // Check if we have an ID match - if strings.HasPrefix(image.ID(), k.Name) { - return image.ID(), nil - } - // Check if we have a name match, perhaps a tagged name - for _, name := range image.Names() { - if k.Name == name { - return image.ID(), nil - } - } - } - - // If neither the ID is known and no local name - // is know, we search it out. - image, _ := k.GetFQName() - img, err := k.runtime.GetImage(image) - if err != nil { - return "", err - } - return img.ID, nil -} - -// GetFQName returns the fully qualified image name if it can be determined -func (k *Image) GetFQName() (string, error) { - // Check if the fqname has already been found - if k.fqname != "" { - return k.fqname, nil - } - if err := k.Decompose(); err != nil { - return "", err - } - k.fqname = k.assembleFqName() - return k.fqname, nil -} - -func (k *Image) findImageOnRegistry() error { - searchRegistries, err := GetRegistries() - - if err != nil { - return errors.Wrapf(err, " the image name '%s' is incomplete.", k.Name) - } - - for _, searchRegistry := range searchRegistries { - k.Registry = searchRegistry - err = k.GetManifest() - if err == nil { - k.fqname = k.assembleFqName() - return nil - - } - } - return errors.Errorf("unable to find image on any configured registries") - -} - -// GetManifest tries to GET an images manifest, returns nil on success and err on failure -func (k *Image) GetManifest() error { - pullRef, err := alltransports.ParseImageName(k.assembleFqNameTransport()) - if err != nil { - return errors.Errorf("unable to parse1 '%s'", k.assembleFqName()) - } - imageSource, err := pullRef.NewImageSource(nil) - if err != nil { - return errors.Wrapf(err, "unable to create new image source") - } - _, _, err = imageSource.GetManifest(nil) - if err == nil { - return nil - } - return err -} - -//Decompose breaks up an image name into its parts -func (k *Image) Decompose() error { - if k.beenDecomposed { - return nil - } - k.beenDecomposed = true - k.Transport = k.runtime.config.ImageDefaultTransport - decomposeName := k.Name - for _, transport := range TransportNames { - if strings.HasPrefix(k.Name, transport) { - k.Transport = transport - decomposeName = strings.Replace(k.Name, transport, "", -1) - break - } - } - if k.Transport == "dir:" { - return nil - } - var imageError = fmt.Sprintf("unable to parse '%s'\n", decomposeName) - imgRef, err := reference.Parse(decomposeName) - if err != nil { - return errors.Wrapf(err, imageError) - } - tagged, isTagged := imgRef.(reference.NamedTagged) - k.Tag = "latest" - if isTagged { - k.Tag = tagged.Tag() - } - k.HasRegistry = true - registry := reference.Domain(imgRef.(reference.Named)) - if registry == "" { - k.HasRegistry = false - } - k.ImageName = reference.Path(imgRef.(reference.Named)) - - // account for image names with directories in them like - // umohnani/get-started:part1 - if k.HasRegistry { - k.Registry = registry - k.fqname = k.assembleFqName() - k.PullName = k.assembleFqName() - - registries, err := getRegistries() - if err != nil { - return nil - } - if util.StringInSlice(k.Registry, registries) { - return nil - } - // We need to check if the registry name is legit - _, err = net.LookupHost(k.Registry) - if err == nil { - return nil - } - // Combine the Registry and Image Name together and blank out the Registry Name - k.ImageName = fmt.Sprintf("%s/%s", k.Registry, k.ImageName) - k.Registry = "" - - } - // No Registry means we check the globals registries configuration file - // and assemble a list of candidate sources to try - //searchRegistries, err := GetRegistries() - err = k.findImageOnRegistry() - k.PullName = k.assembleFqName() - if err != nil { - return errors.Wrapf(err, " the image name '%s' is incomplete.", k.Name) - } - return nil -} - -func getTags(nameInput string) (reference.NamedTagged, bool, error) { - inputRef, err := reference.Parse(nameInput) - if err != nil { - return nil, false, errors.Wrapf(err, "unable to obtain tag from input name") - } - tagged, isTagged := inputRef.(reference.NamedTagged) - - return tagged, isTagged, nil -} - -// GetLocalImageName returns the name of the image if it is local as well -// as the image's ID. It will return an empty strings and error if not found. -func (k *Image) GetLocalImageName() (string, string, error) { - localImage, err := k.runtime.GetImage(k.Name) - if err == nil { - k.LocalName = k.Name - return k.Name, localImage.ID, nil - } - localImages, err := k.runtime.GetImages(&ImageFilterParams{}) - if err != nil { - return "", "", errors.Wrapf(err, "unable to find local images") - } - _, isTagged, err := getTags(k.Name) - if err != nil { - return "", "", err - } - for _, image := range localImages { - for _, name := range image.Names() { - imgRef, err := reference.Parse(name) - if err != nil { - continue - } - var imageName string - imageNameOnly := reference.Path(imgRef.(reference.Named)) - if isTagged { - imageNameTag, _, err := getTags(name) - if err != nil { - continue - } - imageName = fmt.Sprintf("%s:%s", imageNameOnly, imageNameTag.Tag()) - } else { - imageName = imageNameOnly - } - - if imageName == k.Name { - k.LocalName = name - return name, image.ID(), nil - } - imageSplit := strings.Split(imageName, "/") - baseName := imageSplit[len(imageSplit)-1] - if baseName == k.Name { - k.LocalName = name - return name, image.ID(), nil - } - } - } - return "", "", errors.Wrapf(storage.ErrImageUnknown, "unable to find image locally") -} - -// HasLatest determines if we have the latest image local -func (k *Image) HasLatest() (bool, error) { - localName, _, err := k.GetLocalImageName() - if err != nil { - return false, err - } - if localName == "" { - return false, nil - } - - fqname, err := k.GetFQName() - if err != nil { - return false, err - } - pullRef, err := alltransports.ParseImageName(fqname) - if err != nil { - return false, err - } - _, _, err = pullRef.(types.ImageSource).GetManifest(nil) - return false, err -} - -// Pull is a wrapper function to pull and image -func (k *Image) Pull(writer io.Writer) error { - // If the image hasn't been decomposed yet - if !k.beenDecomposed { - err := k.Decompose() - if err != nil { - return err - } - } - k.runtime.PullImage(k.PullName, CopyOptions{Writer: writer, SignaturePolicyPath: k.runtime.config.SignaturePolicyPath}) - return nil -} - -// GetRegistries gets the searchable registries from the global registration file. -func GetRegistries() ([]string, error) { - registryConfigPath := "" - envOverride := os.Getenv("REGISTRIES_CONFIG_PATH") - if len(envOverride) > 0 { - registryConfigPath = envOverride - } - searchRegistries, err := sysregistries.GetRegistries(&types.SystemContext{SystemRegistriesConfPath: registryConfigPath}) - if err != nil { - return nil, errors.Errorf("unable to parse the registries.conf file") - } - return searchRegistries, nil -} - -// GetInsecureRegistries obtains the list of inseure registries from the global registration file. -func GetInsecureRegistries() ([]string, error) { - registryConfigPath := "" - envOverride := os.Getenv("REGISTRIES_CONFIG_PATH") - if len(envOverride) > 0 { - registryConfigPath = envOverride - } - registries, err := sysregistries.GetInsecureRegistries(&types.SystemContext{SystemRegistriesConfPath: registryConfigPath}) - if err != nil { - return nil, errors.Errorf("unable to parse the registries.conf file") - } - return registries, nil -} - -// getRegistries returns both searchable and insecure registries from the global conf file. -func getRegistries() ([]string, error) { - var r []string - registries, err := GetRegistries() - if err != nil { - return r, err - } - insecureRegistries, err := GetInsecureRegistries() - if err != nil { - return r, err - } - r = append(registries, insecureRegistries...) - return r, nil -} - -// ImageFilter is a function to determine whether an image is included in -// command output. Images to be outputted are tested using the function. A true -// return will include the image, a false return will exclude it. -type ImageFilter func(*image.Image, *inspect.ImageData) bool - -func (ips imageDecomposeStruct) returnFQName() string { - return fmt.Sprintf("%s%s/%s:%s", ips.transport, ips.registry, ips.imageName, ips.tag) -} - -func getRegistriesToTry(image string, store storage.Store, defaultTransport string) ([]*pullStruct, error) { - var pStructs []*pullStruct - var imageError = fmt.Sprintf("unable to parse '%s'\n", image) - imgRef, err := reference.Parse(image) - if err != nil { - return nil, errors.Wrapf(err, imageError) - } - tagged, isTagged := imgRef.(reference.NamedTagged) - tag := "latest" - if isTagged { - tag = tagged.Tag() - } - hasDomain := true - registry := reference.Domain(imgRef.(reference.Named)) - if registry == "" { - hasDomain = false - } - imageName := reference.Path(imgRef.(reference.Named)) - pImage := imageDecomposeStruct{ - imageName, - tag, - registry, - hasDomain, - defaultTransport, - } - if pImage.hasRegistry { - // If input has a registry, we have to assume they included an image - // name but maybe not a tag - srcRef, err := alltransports.ParseImageName(pImage.returnFQName()) - if err != nil { - return nil, errors.Errorf(imageError) - } - pStruct := &pullStruct{ - image: srcRef.DockerReference().String(), - srcRef: srcRef, - } - pStructs = append(pStructs, pStruct) - } else { - // No registry means we check the globals registries configuration file - // and assemble a list of candidate sources to try - registryConfigPath := "" - envOverride := os.Getenv("REGISTRIES_CONFIG_PATH") - if len(envOverride) > 0 { - registryConfigPath = envOverride - } - searchRegistries, err := sysregistries.GetRegistries(&types.SystemContext{SystemRegistriesConfPath: registryConfigPath}) - if err != nil { - return nil, errors.Wrapf(err, "unable to parse the registries.conf file and"+ - " the image name '%s' is incomplete.", imageName) - } - for _, searchRegistry := range searchRegistries { - pImage.registry = searchRegistry - srcRef, err := alltransports.ParseImageName(pImage.returnFQName()) - if err != nil { - return nil, errors.Errorf("unable to parse '%s'", pImage.returnFQName()) - } - pStruct := &pullStruct{ - image: srcRef.DockerReference().String(), - srcRef: srcRef, - } - pStructs = append(pStructs, pStruct) - } - } - - for _, pStruct := range pStructs { - destRef, err := is.Transport.ParseStoreReference(store, pStruct.image) - if err != nil { - return nil, errors.Errorf("error parsing dest reference name: %v", err) - } - pStruct.dstRef = destRef - } - return pStructs, nil -} - -type pullStruct struct { - image string - srcRef types.ImageReference - dstRef types.ImageReference -} - -func (r *Runtime) getPullStruct(srcRef types.ImageReference, destName string) (*pullStruct, error) { - reference := destName - if srcRef.DockerReference() != nil { - reference = srcRef.DockerReference().String() - } - destRef, err := is.Transport.ParseStoreReference(r.store, reference) - if err != nil { - return nil, errors.Errorf("error parsing dest reference name: %v", err) - } - return &pullStruct{ - image: destName, - srcRef: srcRef, - dstRef: destRef, - }, nil -} - -// returns a list of pullStruct with the srcRef and DstRef based on the transport being used -func (r *Runtime) getPullListFromRef(srcRef types.ImageReference, imgName string, sc *types.SystemContext) ([]*pullStruct, error) { - var pullStructs []*pullStruct - splitArr := strings.Split(imgName, ":") - archFile := splitArr[len(splitArr)-1] - - // supports pulling from docker-archive, oci, and registries - if srcRef.Transport().Name() == DockerArchive { - tarSource, err := tarfile.NewSourceFromFile(archFile) - if err != nil { - return nil, err - } - manifest, err := tarSource.LoadTarManifest() - if err != nil { - return nil, errors.Errorf("error retrieving manifest.json: %v", err) - } - // to pull the first image stored in the tar file - if len(manifest) == 0 { - // use the hex of the digest if no manifest is found - reference, err := getImageDigest(srcRef, sc) - if err != nil { - return nil, err - } - pullInfo, err := r.getPullStruct(srcRef, reference) - if err != nil { - return nil, err - } - pullStructs = append(pullStructs, pullInfo) - } else { - var dest string - if len(manifest[0].RepoTags) > 0 { - dest = manifest[0].RepoTags[0] - } else { - // If the input image has no repotags, we need to feed it a dest anyways - dest, err = getImageDigest(srcRef, sc) - if err != nil { - return nil, err - } - } - pullInfo, err := r.getPullStruct(srcRef, dest) - if err != nil { - return nil, err - } - pullStructs = append(pullStructs, pullInfo) - } - } else if srcRef.Transport().Name() == OCIArchive { - // retrieve the manifest from index.json to access the image name - manifest, err := ociarchive.LoadManifestDescriptor(srcRef) - if err != nil { - return nil, errors.Wrapf(err, "error loading manifest for %q", srcRef) - } - - if manifest.Annotations == nil || manifest.Annotations["org.opencontainers.image.ref.name"] == "" { - return nil, errors.Errorf("error, archive doesn't have a name annotation. Cannot store image with no name") - } - pullInfo, err := r.getPullStruct(srcRef, manifest.Annotations["org.opencontainers.image.ref.name"]) - if err != nil { - return nil, err - } - pullStructs = append(pullStructs, pullInfo) - } else if srcRef.Transport().Name() == DirTransport { - // supports pull from a directory - image := splitArr[1] - // remove leading "/" - if image[:1] == "/" { - image = image[1:] - } - pullInfo, err := r.getPullStruct(srcRef, image) - if err != nil { - return nil, err - } - pullStructs = append(pullStructs, pullInfo) - } else { - pullInfo, err := r.getPullStruct(srcRef, imgName) - if err != nil { - return nil, err - } - pullStructs = append(pullStructs, pullInfo) - } - return pullStructs, nil -} - -// PullImage pulls an image from configured registries -// By default, only the latest tag (or a specific tag if requested) will be -// pulled. If allTags is true, all tags for the requested image will be pulled. -// Signature validation will be performed if the Runtime has been appropriately -// configured -func (r *Runtime) PullImage(imgName string, options CopyOptions) (string, error) { - r.lock.Lock() - defer r.lock.Unlock() - - if !r.valid { - return "", ErrRuntimeStopped - } - - // PullImage copies the image from the source to the destination - var pullStructs []*pullStruct - - signaturePolicyPath := r.config.SignaturePolicyPath - if options.SignaturePolicyPath != "" { - signaturePolicyPath = options.SignaturePolicyPath - } - - sc := common.GetSystemContext(signaturePolicyPath, options.AuthFile, false) - - srcRef, err := alltransports.ParseImageName(imgName) - if err != nil { - // could be trying to pull from registry with short name - pullStructs, err = getRegistriesToTry(imgName, r.store, r.config.ImageDefaultTransport) - if err != nil { - return "", errors.Wrap(err, "error getting default registries to try") - } - } else { - pullStructs, err = r.getPullListFromRef(srcRef, imgName, sc) - if err != nil { - return "", errors.Wrapf(err, "error getting pullStruct info to pull image %q", imgName) - } - } - policyContext, err := getPolicyContext(sc) - if err != nil { - return "", err - } - defer policyContext.Destroy() - - copyOptions := common.GetCopyOptions(options.Writer, signaturePolicyPath, &options.DockerRegistryOptions, nil, options.SigningOptions, options.AuthFile, "", false) - - for _, imageInfo := range pullStructs { - // Print the following statement only when pulling from a docker or atomic registry - if options.Writer != nil && (imageInfo.srcRef.Transport().Name() == Docker || imageInfo.srcRef.Transport().Name() == Atomic) { - io.WriteString(options.Writer, fmt.Sprintf("Trying to pull %s...\n", imageInfo.image)) - } - if err = cp.Image(policyContext, imageInfo.dstRef, imageInfo.srcRef, copyOptions); err != nil { - if options.Writer != nil { - io.WriteString(options.Writer, "Failed\n") - } - } else { - return imageInfo.image, nil - } - } - return "", errors.Wrapf(err, "error pulling image from %q", imgName) -} - -// PushImage pushes the given image to a location described by the given path -func (r *Runtime) PushImage(source string, destination string, options CopyOptions) error { - r.lock.Lock() - defer r.lock.Unlock() - - if !r.valid { - return ErrRuntimeStopped - } - - // PushImage pushes the src image to the destination - //func PushImage(source, destination string, options CopyOptions) error { - if source == "" || destination == "" { - return errors.Wrapf(syscall.EINVAL, "source and destination image names must be specified") - } - - // Get the destination Image Reference - dest, err := alltransports.ParseImageName(destination) - if err != nil { - if hasTransport(destination) { - return errors.Wrapf(err, "error getting destination imageReference for %q", destination) - } - // Try adding the images default transport - destination2 := r.config.ImageDefaultTransport + destination - dest, err = alltransports.ParseImageName(destination2) - if err != nil { - // One last try with docker:// as the transport - destination2 = DefaultTransport + destination - dest, err = alltransports.ParseImageName(destination2) - if err != nil { - return errors.Wrapf(err, "error getting destination imageReference for %q", destination) - } - } - } - - signaturePolicyPath := r.config.SignaturePolicyPath - if options.SignaturePolicyPath != "" { - signaturePolicyPath = options.SignaturePolicyPath - } - - sc := common.GetSystemContext(signaturePolicyPath, options.AuthFile, options.ForceCompress) - - policyContext, err := getPolicyContext(sc) - if err != nil { - return err - } - defer policyContext.Destroy() - - // Look up the source image, expecting it to be in local storage - src, err := is.Transport.ParseStoreReference(r.store, source) - if err != nil { - return errors.Wrapf(err, "error getting source imageReference for %q", source) - } - - copyOptions := common.GetCopyOptions(options.Writer, signaturePolicyPath, nil, &options.DockerRegistryOptions, options.SigningOptions, options.AuthFile, options.ManifestMIMEType, options.ForceCompress) - - // Copy the image to the remote destination - err = cp.Image(policyContext, dest, src, copyOptions) - if err != nil { - return errors.Wrapf(err, "Error copying image to the remote destination") - } - return nil -} - -// TagImage adds a tag to the given image -func (r *Runtime) TagImage(image *storage.Image, tag string) error { - r.lock.Lock() - defer r.lock.Unlock() - - if !r.valid { - return ErrRuntimeStopped - } - - tags, err := r.store.Names(image.ID) - if err != nil { - return err - } - for _, key := range tags { - if key == tag { - return nil - } - } - tags = append(tags, tag) - return r.store.SetNames(image.ID, tags) -} - -// UntagImage removes a tag from the given image -func (r *Runtime) UntagImage(image *storage.Image, tag string) (string, error) { - r.lock.Lock() - defer r.lock.Unlock() - - if !r.valid { - return "", ErrRuntimeStopped - } - - tags, err := r.store.Names(image.ID) - if err != nil { - return "", err - } - for i, key := range tags { - if key == tag { - tags[i] = tags[len(tags)-1] - tags = tags[:len(tags)-1] - break - } - } - if err = r.store.SetNames(image.ID, tags); err != nil { - return "", err - } - return tag, nil -} - // RemoveImage deletes an image from local storage // Images being used by running containers can only be removed if force=true func (r *Runtime) RemoveImage(image *image.Image, force bool) (string, error) { @@ -886,377 +127,30 @@ func (r *Runtime) RemoveImage(image *image.Image, force bool) (string, error) { return image.ID(), image.Remove(force) } -// GetImage retrieves an image matching the given name or hash from system -// storage -// If no matching image can be found, an error is returned -func (r *Runtime) GetImage(image string) (*storage.Image, error) { - r.lock.Lock() - defer r.lock.Unlock() - - if !r.valid { - return nil, ErrRuntimeStopped - } - return r.getImage(image) -} - -func (r *Runtime) getImage(image string) (*storage.Image, error) { - var img *storage.Image - ref, err := is.Transport.ParseStoreReference(r.store, image) - if err == nil { - img, err = is.Transport.GetStoreImage(r.store, ref) - } - if err != nil { - img2, err2 := r.store.Image(image) - 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 - } - return img, nil -} - -// GetImageRef searches for and returns a new types.Image matching the given name or ID in the given store. -func (r *Runtime) GetImageRef(image string) (types.Image, error) { - r.lock.Lock() - defer r.lock.Unlock() - - if !r.valid { - return nil, ErrRuntimeStopped - } - return r.getImageRef(image) - -} - -func (r *Runtime) getImageRef(image string) (types.Image, error) { - img, err := r.getImage(image) - if err != nil { - return nil, errors.Wrapf(err, "unable to locate image %q", image) - } - ref, err := is.Transport.ParseStoreReference(r.store, "@"+img.ID) - if err != nil { - return nil, errors.Wrapf(err, "error parsing reference to image %q", img.ID) - } - imgRef, err := ref.NewImage(nil) - if err != nil { - return nil, errors.Wrapf(err, "error reading image %q", img.ID) - } - return imgRef, nil -} - -// GetImages retrieves all images present in storage -// Filters can be provided which will determine which images are included in the -// output. Multiple filters are handled by ANDing their output, so only images -// matching all filters are included -func (r *Runtime) GetImages(params *ImageFilterParams, filters ...ImageFilter) ([]*image.Image, error) { - r.lock.RLock() - defer r.lock.RUnlock() - - if !r.valid { - return nil, ErrRuntimeStopped - } - - images, err := r.imageRuntime.GetImages() - if err != nil { - return nil, err - } - var imagesFiltered []*image.Image - - for _, img := range images { - info, err := img.Inspect() - - if err != nil { - return nil, err - } - var names []string - if len(img.Names()) > 0 { - names = img.Names() - } else { - names = append(names, "<none>") - } - for _, name := range names { - include := true - if params != nil { - params.ImageName = name - } - for _, filter := range filters { - include = include && filter(img, info) - } - - if include { - newImage := img - imagesFiltered = append(imagesFiltered, newImage) - } - } - } - - return imagesFiltered, nil -} - -// GetHistory gets the history of an image and information about its layers -func (r *Runtime) GetHistory(image string) ([]ociv1.History, []types.BlobInfo, string, error) { - r.lock.RLock() - defer r.lock.RUnlock() - - if !r.valid { - return nil, nil, "", ErrRuntimeStopped - } - - img, err := r.getImage(image) - if err != nil { - return nil, nil, "", errors.Wrapf(err, "no such image %q", image) - } - - src, err := r.getImageRef(image) - if err != nil { - return nil, nil, "", errors.Wrapf(err, "error instantiating image %q", image) - } - - oci, err := src.OCIConfig() - if err != nil { - return nil, nil, "", err - } - - return oci.History, src.LayerInfos(), img.ID, nil -} - -//Import imports an oci format image archive into storage as an image -func (r *Runtime) Import(path, reference string, writer io.Writer, signingOptions image.SigningOptions, imageConfig ociv1.Image) (*image.Image, error) { - return image.Import(path, reference, writer, signingOptions, imageConfig, r.imageRuntime) -} - -// ParseImageFilter takes a set of images and a filter string as input, and returns the libpod.ImageFilterParams struct -func (r *Runtime) ParseImageFilter(imageInput, filter string) (*ImageFilterParams, error) { - r.lock.RLock() - defer r.lock.RUnlock() - - if !r.valid { - return nil, ErrRuntimeStopped - } - - if filter == "" && imageInput == "" { - return nil, nil - } - - var params ImageFilterParams - params.ImageInput = imageInput - - if filter == "" && imageInput != "" { - return ¶ms, nil - } - - images, err := r.imageRuntime.GetImages() - if err != nil { - return nil, err - } - - filterStrings := strings.Split(filter, ",") - for _, param := range filterStrings { - pair := strings.SplitN(param, "=", 2) - switch strings.TrimSpace(pair[0]) { - case "dangling": - if common.IsValidBool(pair[1]) { - params.Dangling = pair[1] - } else { - return nil, fmt.Errorf("invalid filter: '%s=[%s]'", pair[0], pair[1]) - } - case "label": - params.Label = pair[1] - case "before": - if img, err := findImageInSlice(images, pair[1]); err == nil { - info, err := img.Inspect() - if err != nil { - return nil, err - } - params.BeforeImage = *info.Created - } else { - return nil, fmt.Errorf("no such id: %s", pair[0]) - } - case "since": - if img, err := findImageInSlice(images, pair[1]); err == nil { - info, err := img.Inspect() - if err != nil { - return nil, err - } - params.SinceImage = *info.Created - } else { - return nil, fmt.Errorf("no such id: %s``", pair[0]) - } - case "reference": - params.ReferencePattern = pair[1] - default: - return nil, fmt.Errorf("invalid filter: '%s'", pair[0]) - } - } - return ¶ms, nil -} - -// MatchesID returns true if argID is a full or partial match for id -func MatchesID(id, argID string) bool { - return strings.HasPrefix(argID, id) -} - -// MatchesReference returns true if argName is a full or partial match for name -// Partial matches will register only if they match the most specific part of the name available -// For example, take the image docker.io/library/redis:latest -// redis, library/redis, docker.io/library/redis, redis:latest, etc. will match -// But redis:alpine, ry/redis, library, and io/library/redis will not -func MatchesReference(name, argName string) bool { - if argName == "" { - return false - } - splitName := strings.Split(name, ":") - // If the arg contains a tag, we handle it differently than if it does not - if strings.Contains(argName, ":") { - splitArg := strings.Split(argName, ":") - return strings.HasSuffix(splitName[0], splitArg[0]) && (splitName[1] == splitArg[1]) - } - return strings.HasSuffix(splitName[0], argName) -} - -// ParseImageNames parses the names we've stored with an image into a list of -// tagged references and a list of references which contain digests. -func ParseImageNames(names []string) (tags, digests []string, err error) { - for _, name := range names { - if named, err := reference.ParseNamed(name); err == nil { - if digested, ok := named.(reference.Digested); ok { - canonical, err := reference.WithDigest(named, digested.Digest()) - if err == nil { - digests = append(digests, canonical.String()) - } - } else { - if reference.IsNameOnly(named) { - named = reference.TagNameOnly(named) - } - if tagged, ok := named.(reference.Tagged); ok { - namedTagged, err := reference.WithTag(named, tagged.Tag()) - if err == nil { - tags = append(tags, namedTagged.String()) - } - } - } - } - } - return tags, digests, nil -} - -func findImageInSlice(images []*image.Image, ref string) (*image.Image, error) { - for _, image := range images { - if MatchesID(image.ID(), ref) { - return image, nil - } - for _, name := range image.Names() { - if MatchesReference(name, ref) { - return image, nil - } - } +// GetRegistries gets the searchable registries from the global registration file. +func GetRegistries() ([]string, error) { + registryConfigPath := "" + envOverride := os.Getenv("REGISTRIES_CONFIG_PATH") + if len(envOverride) > 0 { + registryConfigPath = envOverride } - return nil, errors.New("could not find image") -} - -// getImageDigest creates an image object and uses the hex value of the digest as the image ID -// for parsing the store reference -func getImageDigest(src types.ImageReference, ctx *types.SystemContext) (string, error) { - newImg, err := src.NewImage(ctx) + searchRegistries, err := sysregistries.GetRegistries(&types.SystemContext{SystemRegistriesConfPath: registryConfigPath}) if err != nil { - return "", err - } - defer newImg.Close() - - digest := newImg.ConfigInfo().Digest - if err = digest.Validate(); err != nil { - return "", errors.Wrapf(err, "error getting config info") + return nil, errors.Errorf("unable to parse the registries.conf file") } - return "@" + digest.Hex(), nil + return searchRegistries, nil } -// getPolicyContext sets up, intializes and returns a new context for the specified policy -func getPolicyContext(ctx *types.SystemContext) (*signature.PolicyContext, error) { - policy, err := signature.DefaultPolicy(ctx) - if err != nil { - return nil, err +// GetInsecureRegistries obtains the list of inseure registries from the global registration file. +func GetInsecureRegistries() ([]string, error) { + registryConfigPath := "" + envOverride := os.Getenv("REGISTRIES_CONFIG_PATH") + if len(envOverride) > 0 { + registryConfigPath = envOverride } - - policyContext, err := signature.NewPolicyContext(policy) + registries, err := sysregistries.GetInsecureRegistries(&types.SystemContext{SystemRegistriesConfPath: registryConfigPath}) if err != nil { - return nil, err - } - return policyContext, nil -} - -// ImageCreatedBefore allows you to filter on images created before -// the given time.Time -func ImageCreatedBefore(createTime time.Time) ImageResultFilter { - return func(i *image.Image) bool { - if i.Created().Before(createTime) { - return true - } - return false - } -} - -// ImageCreatedAfter allows you to filter on images created after -// the given time.Time -func ImageCreatedAfter(createTime time.Time) ImageResultFilter { - return func(i *image.Image) bool { - if i.Created().After(createTime) { - return true - } - return false - } -} - -// ImageDangling allows you to filter images for dangling images -func ImageDangling() ImageResultFilter { - return func(i *image.Image) bool { - if i.Dangling() { - return true - } - return false - } -} - -// ImageLabel allows you to filter by images labels key and/or value -func ImageLabel(labelfilter string) ImageResultFilter { - // We need to handle both label=key and label=key=value - return func(i *image.Image) bool { - var value string - splitFilter := strings.Split(labelfilter, "=") - key := splitFilter[0] - if len(splitFilter) > 1 { - value = splitFilter[1] - } - labels, err := i.Labels() - if err != nil { - return false - } - if len(strings.TrimSpace(labels[key])) > 0 && len(strings.TrimSpace(value)) == 0 { - return true - } - return labels[key] == value - } -} - -// OutputImageFilter allows you to filter by an a specific image name -func OutputImageFilter(userImage *image.Image) ImageResultFilter { - return func(i *image.Image) bool { - return userImage.ID() == i.ID() - } -} - -// FilterImages filters images using a set of predefined fitler funcs -func FilterImages(images []*image.Image, filters []ImageResultFilter) []*image.Image { - var filteredImages []*image.Image - for _, image := range images { - include := true - for _, filter := range filters { - include = include && filter(image) - } - if include { - filteredImages = append(filteredImages, image) - } + return nil, errors.Errorf("unable to parse the registries.conf file") } - return filteredImages + return registries, nil } diff --git a/libpod/util.go b/libpod/util.go index c258af307..106dd4666 100644 --- a/libpod/util.go +++ b/libpod/util.go @@ -47,11 +47,6 @@ func FuncTimer(funcName string) { fmt.Printf("%s executed in %d ms\n", funcName, elapsed) } -// hasTransport determines if the image string contains '://', returns bool -func hasTransport(image string) bool { - return strings.Contains(image, "://") -} - // CopyStringStringMap deep copies a map[string]string and returns the result func CopyStringStringMap(m map[string]string) map[string]string { n := map[string]string{} |