summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
authorUrvashi Mohnani <umohnani@redhat.com>2017-11-02 15:31:49 -0400
committerAtomic Bot <atomic-devel@projectatomic.io>2017-11-07 19:16:31 +0000
commit23979f8e0644cd1e05e05b0fc9bcb4a1fe42bb82 (patch)
treedc018440069dece8df8f57de65cdbb46bb06350d /libpod
parentd086beb7abc5ed002fe699ab02792aa47d50d581 (diff)
downloadpodman-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.go125
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
+}