diff options
-rw-r--r-- | cmd/kpod/export.go | 62 | ||||
-rw-r--r-- | cmd/kpod/rm.go | 2 | ||||
-rw-r--r-- | libpod/container.go | 38 | ||||
-rw-r--r-- | test/kpod_export.bats | 18 |
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 } |