mirror of
https://github.com/containers/podman.git
synced 2025-06-14 12:28:57 +08:00
Add support for dir transport to kpod save
kpod save can now save images to directories using the dir transport. Manifest conversion is also possible. To save with the oci manifest type set --format to oci-dir and to save with the v2s2(docker) manifest type, set --format to docker-dir. The layers can be compressed as well when saving to a directory using the --compress flag. Added functionality to kpod load to be able to load image from a directory Signed-off-by: umohnani8 <umohnani@redhat.com> Closes: #137 Approved by: rhatdan
This commit is contained in:
@ -104,14 +104,18 @@ func loadCmd(c *cli.Context) error {
|
||||
src := libpod.DockerArchive + ":" + input
|
||||
imgName, err := runtime.PullImage(src, options)
|
||||
if err != nil {
|
||||
src = libpod.OCIArchive + ":" + input
|
||||
// generate full src name with specified image:tag
|
||||
fullSrc := libpod.OCIArchive + ":" + input
|
||||
if image != "" {
|
||||
src = src + ":" + image
|
||||
fullSrc = fullSrc + ":" + image
|
||||
}
|
||||
imgName, err = runtime.PullImage(src, options)
|
||||
imgName, err = runtime.PullImage(fullSrc, options)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error pulling %q", src)
|
||||
src = libpod.DirTransport + ":" + input
|
||||
imgName, err = runtime.PullImage(src, options)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error pulling %q", src)
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Println("Loaded image: ", imgName)
|
||||
|
@ -3,15 +3,27 @@ package main
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/image/manifest"
|
||||
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/projectatomic/libpod/libpod"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
const (
|
||||
ociManifestDir = "oci-dir"
|
||||
v2s2ManifestDir = "docker-dir"
|
||||
)
|
||||
|
||||
var (
|
||||
saveFlags = []cli.Flag{
|
||||
cli.BoolFlag{
|
||||
Name: "compress",
|
||||
Usage: "compress tarball image layers when saving to a directory using the 'dir' transport. (default is same compression type as source)",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "output, o",
|
||||
Usage: "Write to a file, default is STDOUT",
|
||||
@ -23,7 +35,7 @@ var (
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "format",
|
||||
Usage: "Save image to oci-archive",
|
||||
Usage: "Save image to oci-archive, oci-dir (directory with oci manifest type), docker-dir (directory with v2s2 manifest type)",
|
||||
},
|
||||
}
|
||||
saveDescription = `
|
||||
@ -56,6 +68,10 @@ func saveCmd(c *cli.Context) error {
|
||||
}
|
||||
defer runtime.Shutdown(false)
|
||||
|
||||
if c.IsSet("compress") && (c.String("format") != ociManifestDir && c.String("format") != v2s2ManifestDir && c.String("format") == "") {
|
||||
return errors.Errorf("--compress can only be set when --format is either 'oci-dir' or 'docker-dir'")
|
||||
}
|
||||
|
||||
var writer io.Writer
|
||||
if !c.Bool("quiet") {
|
||||
writer = os.Stdout
|
||||
@ -69,10 +85,16 @@ func saveCmd(c *cli.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
var dst string
|
||||
var dst, manifestType string
|
||||
switch c.String("format") {
|
||||
case libpod.OCIArchive:
|
||||
dst = libpod.OCIArchive + ":" + output
|
||||
case "oci-dir":
|
||||
dst = libpod.DirTransport + ":" + output
|
||||
manifestType = imgspecv1.MediaTypeImageManifest
|
||||
case "docker-dir":
|
||||
dst = libpod.DirTransport + ":" + output
|
||||
manifestType = manifest.DockerV2Schema2MediaType
|
||||
case libpod.DockerArchive:
|
||||
fallthrough
|
||||
case "":
|
||||
@ -84,12 +106,18 @@ func saveCmd(c *cli.Context) error {
|
||||
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 {
|
||||
dest := dst + ":" + image
|
||||
dest := dst
|
||||
// need dest to be in the format transport:path:reference for the following transports
|
||||
if strings.Contains(dst, libpod.OCIArchive) || strings.Contains(dst, libpod.DockerArchive) {
|
||||
dest = dst + ":" + image
|
||||
}
|
||||
if err := runtime.PushImage(image, dest, saveOpts); err != nil {
|
||||
if err2 := os.Remove(output); err2 != nil {
|
||||
logrus.Errorf("error deleting %q: %v", output, err)
|
||||
|
@ -1302,6 +1302,7 @@ _kpod_save() {
|
||||
--format
|
||||
"
|
||||
local boolean_options="
|
||||
--compress
|
||||
--quiet -q
|
||||
"
|
||||
_complete_ "$options_with_args" "$boolean_options"
|
||||
|
@ -14,10 +14,10 @@ kpod-save - Save an image to docker-archive or oci-archive
|
||||
[**--help**|**-h**]
|
||||
|
||||
## DESCRIPTION
|
||||
**kpod save** saves an image to either **docker-archive** or **oci-archive**
|
||||
on the local machine, default is **docker-archive**.
|
||||
**kpod save** writes to STDOUT by default and can be redirected to a file using the **output** flag.
|
||||
The **quiet** flag suppresses the output when set.
|
||||
**kpod save** saves an image to either **docker-archive**, **oci-archive**, **oci-dir** (directory
|
||||
with oci manifest type), or **docker-dir** (directory with v2s2 manifest type) on the local machine,
|
||||
default is **docker-archive**. **kpod save** writes to STDOUT by default and can be redirected to a
|
||||
file using the **output** flag. The **quiet** flag suppresses the output when set.
|
||||
|
||||
**kpod [GLOBAL OPTIONS]**
|
||||
|
||||
@ -27,13 +27,20 @@ The **quiet** flag suppresses the output when set.
|
||||
|
||||
## OPTIONS
|
||||
|
||||
**--compress**
|
||||
|
||||
Compress tarball image layers when pushing to a directory using the 'dir' transport. (default is same compression type, compressed or uncompressed, as source)
|
||||
Note: This flag can only be set when using the **dir** transport i.e --format=oci-dir or --format-docker-dir
|
||||
|
||||
**--output, -o**
|
||||
Write to a file, default is STDOUT
|
||||
|
||||
**--format**
|
||||
Save image to **oci-archive**
|
||||
Save image to **oci-archive**, **oci-dir** (directory with oci manifest type), or **docker-dir** (directory with v2s2 manifest type)
|
||||
```
|
||||
--format oci-archive
|
||||
--format oci-dir
|
||||
--format docker-dir
|
||||
```
|
||||
|
||||
**--quiet, -q**
|
||||
@ -53,6 +60,36 @@ Suppress the output
|
||||
# kpod save -o oci-alpine.tar --format oci-archive alpine
|
||||
```
|
||||
|
||||
```
|
||||
# kpod save --compress --format oci-dir -o alp-dir alpine
|
||||
Getting image source signatures
|
||||
Copying blob sha256:2fdfe1cd78c20d05774f0919be19bc1a3e4729bce219968e4188e7e0f1af679d
|
||||
1.97 MB / 1.97 MB [========================================================] 0s
|
||||
Copying config sha256:501d1a8f0487e93128df34ea349795bc324d5e0c0d5112e08386a9dfaff620be
|
||||
584 B / 584 B [============================================================] 0s
|
||||
Writing manifest to image destination
|
||||
Storing signatures
|
||||
```
|
||||
|
||||
```
|
||||
# kpod save --format docker-dir -o ubuntu-dir ubuntu
|
||||
Getting image source signatures
|
||||
Copying blob sha256:660c48dd555dcbfdfe19c80a30f557ac57a15f595250e67bfad1e5663c1725bb
|
||||
45.55 MB / 45.55 MB [======================================================] 8s
|
||||
Copying blob sha256:4c7380416e7816a5ab1f840482c9c3ca8de58c6f3ee7f95e55ad299abbfe599f
|
||||
846 B / 846 B [============================================================] 0s
|
||||
Copying blob sha256:421e436b5f80d876128b74139531693be9b4e59e4f1081c9a3c379c95094e375
|
||||
620 B / 620 B [============================================================] 0s
|
||||
Copying blob sha256:e4ce6c3651b3a090bb43688f512f687ea6e3e533132bcbc4a83fb97e7046cea3
|
||||
849 B / 849 B [============================================================] 0s
|
||||
Copying blob sha256:be588e74bd348ce48bb7161350f4b9d783c331f37a853a80b0b4abc0a33c569e
|
||||
169 B / 169 B [============================================================] 0s
|
||||
Copying config sha256:20c44cd7596ff4807aef84273c99588d22749e2a7e15a7545ac96347baa65eda
|
||||
3.53 KB / 3.53 KB [========================================================] 0s
|
||||
Writing manifest to image destination
|
||||
Storing signatures
|
||||
```
|
||||
|
||||
## SEE ALSO
|
||||
kpod(1), kpod-load(1), crio(8), crio.conf(5)
|
||||
|
||||
|
@ -10,10 +10,10 @@ function teardown() {
|
||||
cleanup_test
|
||||
}
|
||||
@test "kpod load input flag" {
|
||||
run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} save -o alpine.tar $IMAGE
|
||||
run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} save -o alpine.tar $ALPINE
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} rmi $IMAGE
|
||||
run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} rmi $ALPINE
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} load -i alpine.tar
|
||||
@ -23,9 +23,9 @@ function teardown() {
|
||||
}
|
||||
|
||||
@test "kpod load oci-archive image" {
|
||||
run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} save -o alpine.tar --format oci-archive $IMAGE
|
||||
run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} save -o alpine.tar --format oci-archive $ALPINE
|
||||
[ "$status" -eq 0 ]
|
||||
run bash -c ${KPOD_BINARY} $KPOD_OPTIONS rmi $IMAGE
|
||||
run bash -c ${KPOD_BINARY} $KPOD_OPTIONS rmi $ALPINE
|
||||
[ "$status" -eq 0 ]
|
||||
run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} load -i alpine.tar
|
||||
echo "$output"
|
||||
@ -34,9 +34,9 @@ function teardown() {
|
||||
}
|
||||
|
||||
@test "kpod load oci-archive image with signature-policy" {
|
||||
run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} save -o alpine.tar --format oci-archive $IMAGE
|
||||
run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} save -o alpine.tar --format oci-archive $ALPINE
|
||||
[ "$status" -eq 0 ]
|
||||
run bash -c ${KPOD_BINARY} $KPOD_OPTIONS rmi $IMAGE
|
||||
run bash -c ${KPOD_BINARY} $KPOD_OPTIONS rmi $ALPINE
|
||||
[ "$status" -eq 0 ]
|
||||
cp /etc/containers/policy.json /tmp
|
||||
run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} load --signature-policy /tmp/policy.json -i alpine.tar
|
||||
@ -47,10 +47,10 @@ function teardown() {
|
||||
}
|
||||
|
||||
@test "kpod load using quiet flag" {
|
||||
run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} save -o alpine.tar $IMAGE
|
||||
run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} save -o alpine.tar $ALPINE
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} rmi $IMAGE
|
||||
run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} rmi $ALPINE
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} load -q -i alpine.tar
|
||||
@ -59,6 +59,21 @@ function teardown() {
|
||||
rm -f alpine.tar
|
||||
}
|
||||
|
||||
@test "kpod load directory" {
|
||||
run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} save --format oci-dir -o alp-dir $ALPINE
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} rmi $ALPINE
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} load -i alp-dir
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} rmi alp-dir
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "kpod load non-existent file" {
|
||||
run ${KPOD_BINARY} ${KPOD_OPTIONS} load -i alpine.tar
|
||||
echo "$output"
|
||||
|
@ -42,3 +42,17 @@ function setup() {
|
||||
echo "$output"
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
@test "kpod save to directory wit oci format" {
|
||||
run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} save --format oci-dir -o alp-dir $ALPINE"
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
rm -rf alp-dir
|
||||
}
|
||||
|
||||
@test "kpod save to directory wit v2s2 (docker) format" {
|
||||
run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} save --format docker-dir -o alp-dir $ALPINE"
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
rm -rf alp-dir
|
||||
}
|
||||
|
Reference in New Issue
Block a user