diff options
author | Urvashi Mohnani <umohnani@redhat.com> | 2017-11-02 15:31:49 -0400 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2017-11-07 19:16:31 +0000 |
commit | 23979f8e0644cd1e05e05b0fc9bcb4a1fe42bb82 (patch) | |
tree | dc018440069dece8df8f57de65cdbb46bb06350d /libpod | |
parent | d086beb7abc5ed002fe699ab02792aa47d50d581 (diff) | |
download | podman-23979f8e0644cd1e05e05b0fc9bcb4a1fe42bb82.tar.gz podman-23979f8e0644cd1e05e05b0fc9bcb4a1fe42bb82.tar.bz2 podman-23979f8e0644cd1e05e05b0fc9bcb4a1fe42bb82.zip |
Add 'kpod import' command
Imports a tarball and saves it as a filesystem image
Signed-off-by: Urvashi Mohnani <umohnani@redhat.com>
Closes: #12
Approved by: rhatdan
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/runtime_img.go | 125 |
1 files changed, 97 insertions, 28 deletions
diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go index a57aec86c..8a5258e75 100644 --- a/libpod/runtime_img.go +++ b/libpod/runtime_img.go @@ -18,6 +18,7 @@ import ( "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" "github.com/containers/image/transports/alltransports" "github.com/containers/image/types" @@ -49,6 +50,9 @@ var ( DirTransport = "dir" // TransportNames are the supported transports in string form TransportNames = [...]string{DefaultRegistry, DockerArchive, OCIArchive, "ostree:", "dir:"} + // TarballTransport is the transport for importing a tar archive + // and creating a filesystem image + TarballTransport = "tarball" ) // CopyOptions contains the options given when pushing or pulling images @@ -72,6 +76,10 @@ type CopyOptions struct { AuthFile string // Writer is the reportWriter for the output Writer io.Writer + // Reference is the name for the image created when a tar archive is imported + Reference string + // ImageConfig is the Image spec for the image created when a tar archive is imported + ImageConfig ociv1.Image } // Image API @@ -473,23 +481,16 @@ func (r *Runtime) getPullListFromRef(srcRef types.ImageReference, imgName string } // to pull the first image stored in the tar file if len(manifest) == 0 { - // create an image object and use the hex value of the digest as the image ID - // for parsing the store reference - newImg, err := srcRef.NewImage(sc) + // use the hex of the digest if no manifest is found + reference, err := getImageDigest(srcRef, sc) if err != nil { return nil, err } - defer newImg.Close() - digest := newImg.ConfigInfo().Digest - if err := digest.Validate(); err == nil { - pullInfo, err := r.getPullStruct(srcRef, "@"+digest.Hex()) - if err != nil { - return nil, err - } - pullStructs = append(pullStructs, pullInfo) - } else { - return nil, errors.Wrapf(err, "error getting config info") + pullInfo, err := r.getPullStruct(srcRef, reference) + if err != nil { + return nil, err } + pullStructs = append(pullStructs, pullInfo) } else { pullInfo, err := r.getPullStruct(srcRef, manifest[0].RepoTags[0]) if err != nil { @@ -497,7 +498,6 @@ func (r *Runtime) getPullListFromRef(srcRef types.ImageReference, imgName string } 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) @@ -572,12 +572,7 @@ func (r *Runtime) PullImage(imgName string, options CopyOptions) error { } } - policy, err := signature.DefaultPolicy(sc) - if err != nil { - return err - } - - policyContext, err := signature.NewPolicyContext(policy) + policyContext, err := getPolicyContext(sc) if err != nil { return err } @@ -628,12 +623,7 @@ func (r *Runtime) PushImage(source string, destination string, options CopyOptio sc := common.GetSystemContext(signaturePolicyPath, options.AuthFile) - policy, err := signature.DefaultPolicy(sc) - if err != nil { - return err - } - - policyContext, err := signature.NewPolicyContext(policy) + policyContext, err := getPolicyContext(sc) if err != nil { return err } @@ -880,8 +870,57 @@ func (r *Runtime) GetHistory(image string) ([]ociv1.History, []types.BlobInfo, s } // ImportImage imports an OCI format image archive into storage as an image -func (r *Runtime) ImportImage(path string) (*storage.Image, error) { - return nil, ErrNotImplemented +func (r *Runtime) ImportImage(path string, options CopyOptions) error { + r.lock.RLock() + defer r.lock.RUnlock() + + if !r.valid { + return ErrRuntimeStopped + } + + file := TarballTransport + ":" + path + src, err := alltransports.ParseImageName(file) + if err != nil { + return errors.Wrapf(err, "error parsing image name %q", path) + } + + updater, ok := src.(tarball.ConfigUpdater) + if !ok { + return errors.Wrapf(err, "unexpected type, a tarball reference should implement tarball.ConfigUpdater") + } + + annotations := make(map[string]string) + + err = updater.ConfigUpdate(options.ImageConfig, annotations) + if err != nil { + return errors.Wrapf(err, "error updating image config") + } + + var reference = options.Reference + sc := common.GetSystemContext("", "") + + // if reference not given, get the image digest + if reference == "" { + reference, err = getImageDigest(src, sc) + if err != nil { + return err + } + } + + policyContext, err := getPolicyContext(sc) + if err != nil { + return err + } + defer policyContext.Destroy() + + copyOptions := common.GetCopyOptions(os.Stdout, "", nil, nil, common.SigningOptions{}, "") + + dest, err := is.Transport.ParseStoreReference(r.store, reference) + if err != nil { + errors.Wrapf(err, "error getting image reference for %q", options.Reference) + } + + return cp.Image(policyContext, dest, src, copyOptions) } // GetImageInspectInfo returns the inspect information of an image @@ -1083,3 +1122,33 @@ func findImageInSlice(images []storage.Image, ref string) (storage.Image, error) } return storage.Image{}, 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) + 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 "@" + digest.Hex(), 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 + } + + policyContext, err := signature.NewPolicyContext(policy) + if err != nil { + return nil, err + } + return policyContext, nil +} |