summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/kpod/export.go62
-rw-r--r--cmd/kpod/rm.go2
-rw-r--r--libpod/container.go38
-rw-r--r--test/kpod_export.bats18
4 files changed, 55 insertions, 65 deletions
diff --git a/cmd/kpod/export.go b/cmd/kpod/export.go
index 94f05ce10..aaa4b2803 100644
--- a/cmd/kpod/export.go
+++ b/cmd/kpod/export.go
@@ -1,13 +1,8 @@
package main
import (
- "io"
"os"
- "fmt"
-
- "github.com/containers/storage"
- "github.com/containers/storage/pkg/archive"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
@@ -40,25 +35,22 @@ var (
// exportCmd saves a container to a tarball on disk
func exportCmd(c *cli.Context) error {
- args := c.Args()
- if len(args) == 0 {
- return errors.Errorf("container id must be specified")
- }
- if len(args) > 1 {
- return errors.Errorf("too many arguments given, need 1 at most.")
- }
- container := args[0]
if err := validateFlags(c, exportFlags); err != nil {
return err
}
- config, err := getConfig(c)
+ runtime, err := getRuntime(c)
if err != nil {
- return errors.Wrapf(err, "could not get config")
+ return errors.Wrapf(err, "could not get runtime")
}
- store, err := getStore(config)
- if err != nil {
- return err
+ defer runtime.Shutdown(false)
+
+ args := c.Args()
+ if len(args) == 0 {
+ return errors.Errorf("container id must be specified")
+ }
+ if len(args) > 1 {
+ return errors.Errorf("too many arguments given, need 1 at most.")
}
output := c.String("output")
@@ -69,38 +61,10 @@ func exportCmd(c *cli.Context) error {
}
}
- opts := exportOptions{
- output: output,
- container: container,
- }
-
- return exportContainer(store, opts)
-}
-
-// exportContainer exports the contents of a container and saves it as
-// a tarball on disk
-func exportContainer(store storage.Store, opts exportOptions) error {
- mountPoint, err := store.Mount(opts.container, "")
- if err != nil {
- return errors.Wrapf(err, "error finding container %q", opts.container)
- }
- defer func() {
- if err := store.Unmount(opts.container); err != nil {
- fmt.Printf("error unmounting container %q: %v\n", opts.container, err)
- }
- }()
-
- input, err := archive.Tar(mountPoint, archive.Uncompressed)
- if err != nil {
- return errors.Wrapf(err, "error reading container directory %q", opts.container)
- }
-
- outFile, err := os.Create(opts.output)
+ ctr, err := runtime.LookupContainer(args[0])
if err != nil {
- return errors.Wrapf(err, "error creating file %q", opts.output)
+ return errors.Wrapf(err, "error looking up container %q", args[0])
}
- defer outFile.Close()
- _, err = io.Copy(outFile, input)
- return err
+ return ctr.Export(output)
}
diff --git a/cmd/kpod/rm.go b/cmd/kpod/rm.go
index c7f5f72b2..86d08f2d3 100644
--- a/cmd/kpod/rm.go
+++ b/cmd/kpod/rm.go
@@ -34,7 +34,7 @@ func rmCmd(c *cli.Context) error {
runtime, err := getRuntime(c)
if err != nil {
- return errors.Wrapf(err, "Could not get runtime")
+ return errors.Wrapf(err, "could not get runtime")
}
defer runtime.Shutdown(false)
diff --git a/libpod/container.go b/libpod/container.go
index f167adc35..9b48d2ca1 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -3,12 +3,15 @@ package libpod
import (
"encoding/json"
"fmt"
+ "io"
"io/ioutil"
+ "os"
"path/filepath"
"sync"
"time"
"github.com/containers/storage"
+ "github.com/containers/storage/pkg/archive"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/pkg/term"
spec "github.com/opencontainers/runtime-spec/specs-go"
@@ -469,7 +472,40 @@ func (c *Container) Unpause() error {
// Export exports a container's root filesystem as a tar archive
// The archive will be saved as a file at the given path
func (c *Container) Export(path string) error {
- return ErrNotImplemented
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ if err := c.syncContainer(); err != nil {
+ return err
+ }
+
+ mountPoint := c.state.Mountpoint
+ if !c.state.Mounted {
+ mount, err := c.runtime.store.Mount(c.ID(), c.config.MountLabel)
+ if err != nil {
+ return errors.Wrapf(err, "error mounting container %q", c.ID())
+ }
+ mountPoint = mount
+ defer func() {
+ if err := c.runtime.store.Unmount(c.ID()); err != nil {
+ logrus.Errorf("error unmounting container %q: %v", c.ID(), err)
+ }
+ }()
+ }
+
+ input, err := archive.Tar(mountPoint, archive.Uncompressed)
+ if err != nil {
+ return errors.Wrapf(err, "error reading container directory %q", c.ID())
+ }
+
+ outFile, err := os.Create(path)
+ if err != nil {
+ return errors.Wrapf(err, "error creating file %q", path)
+ }
+ defer outFile.Close()
+
+ _, err = io.Copy(outFile, input)
+ return err
}
// Commit commits the changes between a container and its image, creating a new
diff --git a/test/kpod_export.bats b/test/kpod_export.bats
index aa577168d..5b8517afc 100644
--- a/test/kpod_export.bats
+++ b/test/kpod_export.bats
@@ -2,7 +2,6 @@
load helpers
-IMAGE="redis:alpine"
function teardown() {
cleanup_test
}
@@ -12,24 +11,15 @@ function setup() {
}
@test "kpod export output flag" {
- skip "Test needs to be converted to kpod run bash -c"
- start_crio
- run bash -c crioctl pod run bash -c --config "$TESTDATA"/sandbox_config.json
+ run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} create $BB ls"
echo "$output"
[ "$status" -eq 0 ]
- pod_id="$output"
- run bash -c crioctl image pull "$IMAGE"
- echo "$output"
- [ "$status" -eq 0 ]
- run bash -c crioctl ctr create --config "$TESTDATA"/container_config.json --pod "$pod_id"
+ ctr_id="$output"
+ run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} export -o container.tar $ctr_id"
echo "$output"
[ "$status" -eq 0 ]
- ctr_id="$output"
- run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} export -o container.tar "$ctr_id"
+ run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} rm $ctr_id"
echo "$output"
[ "$status" -eq 0 ]
- cleanup_ctrs
- cleanup_pods
- stop_crio
rm -f container.tar
}