diff options
-rw-r--r-- | cmd/kpod/pause.go | 38 | ||||
-rw-r--r-- | cmd/kpod/unpause.go | 38 | ||||
-rw-r--r-- | libkpod/pause.go | 46 | ||||
-rw-r--r-- | libpod/container.go | 55 | ||||
-rw-r--r-- | libpod/oci.go | 10 | ||||
-rw-r--r-- | test/kpod_pause.bats | 133 |
6 files changed, 132 insertions, 188 deletions
diff --git a/cmd/kpod/pause.go b/cmd/kpod/pause.go index 094013e6d..dede89443 100644 --- a/cmd/kpod/pause.go +++ b/cmd/kpod/pause.go @@ -2,10 +2,10 @@ package main import ( "fmt" + "os" + "github.com/pkg/errors" - "github.com/projectatomic/libpod/libkpod" "github.com/urfave/cli" - "os" ) var ( @@ -24,35 +24,35 @@ var ( ) func pauseCmd(c *cli.Context) error { + runtime, err := getRuntime(c) + if err != nil { + return errors.Wrapf(err, "could not get runtime") + } + defer runtime.Shutdown(false) + args := c.Args() if len(args) < 1 { return errors.Errorf("you must provide at least one container name or id") } - config, err := getConfig(c) - if err != nil { - return errors.Wrapf(err, "could not get config") - } - server, err := libkpod.New(config) - if err != nil { - return errors.Wrapf(err, "could not get container server") - } - defer server.Shutdown() - if err := server.Update(); err != nil { - return errors.Wrapf(err, "could not update list of containers") - } var lastError error - for _, container := range c.Args() { - cid, err := server.ContainerPause(container) + for _, arg := range args { + ctr, err := runtime.LookupContainer(arg) if err != nil { if lastError != nil { fmt.Fprintln(os.Stderr, lastError) } - lastError = errors.Wrapf(err, "failed to pause container %v", container) + lastError = errors.Wrapf(err, "error looking up container %q", arg) + continue + } + if err = ctr.Pause(); err != nil { + if lastError != nil { + fmt.Fprintln(os.Stderr, lastError) + } + lastError = errors.Wrapf(err, "failed to pause container %v", ctr.ID()) } else { - fmt.Println(cid) + fmt.Println(ctr.ID()) } } - return lastError } diff --git a/cmd/kpod/unpause.go b/cmd/kpod/unpause.go index 47a2e3778..6deed7e77 100644 --- a/cmd/kpod/unpause.go +++ b/cmd/kpod/unpause.go @@ -2,10 +2,10 @@ package main import ( "fmt" + "os" + "github.com/pkg/errors" - "github.com/projectatomic/libpod/libkpod" "github.com/urfave/cli" - "os" ) var ( @@ -24,35 +24,35 @@ var ( ) func unpauseCmd(c *cli.Context) error { + runtime, err := getRuntime(c) + if err != nil { + return errors.Wrapf(err, "could not get runtime") + } + defer runtime.Shutdown(false) + args := c.Args() if len(args) < 1 { return errors.Errorf("you must provide at least one container name or id") } - config, err := getConfig(c) - if err != nil { - return errors.Wrapf(err, "could not get config") - } - server, err := libkpod.New(config) - if err != nil { - return errors.Wrapf(err, "could not get container server") - } - defer server.Shutdown() - if err := server.Update(); err != nil { - return errors.Wrapf(err, "could not update list of containers") - } var lastError error - for _, container := range c.Args() { - cid, err := server.ContainerUnpause(container) + for _, arg := range args { + ctr, err := runtime.LookupContainer(arg) if err != nil { if lastError != nil { fmt.Fprintln(os.Stderr, lastError) } - lastError = errors.Wrapf(err, "failed to unpause container %v", container) + lastError = errors.Wrapf(err, "error looking up container %q", arg) + continue + } + if err = ctr.Unpause(); err != nil { + if lastError != nil { + fmt.Fprintln(os.Stderr, lastError) + } + lastError = errors.Wrapf(err, "failed to unpause container %v", ctr.ID()) } else { - fmt.Println(cid) + fmt.Println(ctr.ID()) } } - return lastError } diff --git a/libkpod/pause.go b/libkpod/pause.go deleted file mode 100644 index e2e844b58..000000000 --- a/libkpod/pause.go +++ /dev/null @@ -1,46 +0,0 @@ -package libkpod - -import ( - "github.com/pkg/errors" - "github.com/projectatomic/libpod/oci" -) - -// ContainerPause pauses a running container. -func (c *ContainerServer) ContainerPause(container string) (string, error) { - ctr, err := c.LookupContainer(container) - if err != nil { - return "", errors.Wrapf(err, "failed to find container %s", container) - } - - cStatus := c.runtime.ContainerStatus(ctr) - if cStatus.Status != oci.ContainerStatePaused { - if err := c.runtime.PauseContainer(ctr); err != nil { - return "", errors.Wrapf(err, "failed to pause container %s", ctr.ID()) - } - c.ContainerStateToDisk(ctr) - } else { - return "", errors.Wrapf(err, "container %s is already paused", ctr.ID()) - } - - return ctr.ID(), nil -} - -// ContainerUnpause unpauses a running container with a grace period (i.e., timeout). -func (c *ContainerServer) ContainerUnpause(container string) (string, error) { - ctr, err := c.LookupContainer(container) - if err != nil { - return "", errors.Wrapf(err, "failed to find container %s", container) - } - - cStatus := c.runtime.ContainerStatus(ctr) - if cStatus.Status == oci.ContainerStatePaused { - if err := c.runtime.UnpauseContainer(ctr); err != nil { - return "", errors.Wrapf(err, "failed to unpause container %s", ctr.ID()) - } - c.ContainerStateToDisk(ctr) - } else { - return "", errors.Wrapf(err, "the container %s is not paused", ctr.ID()) - } - - return ctr.ID(), nil -} diff --git a/libpod/container.go b/libpod/container.go index f0a6d58eb..8bd1a0abf 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -536,12 +536,63 @@ func (c *Container) Unmount() error { // Pause pauses a container func (c *Container) Pause() error { - return ErrNotImplemented + c.lock.Lock() + defer c.lock.Unlock() + + if err := c.syncContainer(); err != nil { + return err + } + + if c.state.State == ContainerStatePaused { + return errors.Wrapf(ErrCtrStateInvalid, "%q is already paused", c.ID()) + } + if c.state.State != ContainerStateRunning && c.state.State != ContainerStateCreated { + return errors.Wrapf(ErrCtrStateInvalid, "%q is not running/created, can't pause", c.state.State) + } + if err := c.runtime.ociRuntime.pauseContainer(c); err != nil { + return err + } + + logrus.Debugf("Paused container %s", c.ID()) + + // Update container's state as it should be ContainerStatePaused now + if err := c.runtime.ociRuntime.updateContainerStatus(c); err != nil { + return err + } + + if err := c.runtime.state.SaveContainer(c); err != nil { + return errors.Wrapf(err, "error saving container %s state", c.ID()) + } + return nil } // Unpause unpauses a container func (c *Container) Unpause() error { - return ErrNotImplemented + c.lock.Lock() + defer c.lock.Unlock() + + if err := c.syncContainer(); err != nil { + return err + } + + if c.state.State != ContainerStatePaused { + return errors.Wrapf(ErrCtrStateInvalid, "%q is not paused, can't unpause", c.ID()) + } + if err := c.runtime.ociRuntime.unpauseContainer(c); err != nil { + return err + } + + logrus.Debugf("Unpaused container %s", c.ID()) + + // Update container's state as it should be ContainerStateRunning now + if err := c.runtime.ociRuntime.updateContainerStatus(c); err != nil { + return err + } + + if err := c.runtime.state.SaveContainer(c); err != nil { + return errors.Wrapf(err, "error saving container %s state", c.ID()) + } + return nil } // Export exports a container's root filesystem as a tar archive diff --git a/libpod/oci.go b/libpod/oci.go index ddbd2f606..eb8bd0d93 100644 --- a/libpod/oci.go +++ b/libpod/oci.go @@ -345,3 +345,13 @@ func (r *OCIRuntime) startContainer(ctr *Container) error { return nil } + +// pauseContainer pauses the given container +func (r *OCIRuntime) pauseContainer(ctr *Container) error { + return utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, r.path, "pause", ctr.ID()) +} + +// unpauseContainer unpauses the given container +func (r *OCIRuntime) unpauseContainer(ctr *Container) error { + return utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, r.path, "resume", ctr.ID()) +} diff --git a/test/kpod_pause.bats b/test/kpod_pause.bats index 0cd22f469..23c27ae71 100644 --- a/test/kpod_pause.bats +++ b/test/kpod_pause.bats @@ -2,8 +2,6 @@ load helpers -IMAGE="redis:alpine" - function setup() { copy_images } @@ -13,166 +11,97 @@ function teardown() { } @test "pause a bogus container" { - run ${KPOD_BINARY} ${KPOD_OPTIONS} pause foobar + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} pause foobar" echo "$output" [ "$status" -eq 1 ] } @test "unpause a bogus container" { - run ${KPOD_BINARY} ${KPOD_OPTIONS} unpause foobar + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} unpause foobar" echo "$output" [ "$status" -eq 1 ] } @test "pause a created container by id" { - skip "Test needs to be converted to kpod run" - start_crio - run crioctl pod run --config "$TESTDATA"/sandbox_config.json - echo "$output" - [ "$status" -eq 0 ] - pod_id="$output" - run crioctl image pull "$IMAGE" - [ "$status" -eq 0 ] - run crioctl ctr create --config "$TESTDATA"/container_config.json --pod "$pod_id" + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} create $BB ls" echo "$output" [ "$status" -eq 0 ] ctr_id="$output" - run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} pause "$ctr_id" - echo "$output" - [ "$status" -eq 0 ] - run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} unpause "$ctr_id" + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} pause $ctr_id" echo "$output" - [ "$status" -eq 0 ] - run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} ps -a --filter id="$ctr_id" + [ "$status" -eq 1 ] + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} rm $ctr_id" echo "$output" [ "$status" -eq 0 ] - cleanup_pods - stop_crio } @test "pause a running container by id" { - skip "Test needs to be converted to kpod run" - start_crio - run crioctl pod run --config "$TESTDATA"/sandbox_config.json - echo "$output" - [ "$status" -eq 0 ] - pod_id="$output" - run crioctl image pull "$IMAGE" - [ "$status" -eq 0 ] - run crioctl ctr create --config "$TESTDATA"/container_redis.json --pod "$pod_id" + skip "Test needs to wait for --force to work for kpod rm" + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} run -d $BB sleep 60" echo "$output" [ "$status" -eq 0 ] ctr_id="$output" - run crioctl ctr start --id "$ctr_id" - echo "$output" - [ "$status" -eq 0 ] - id="$output" - run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} pause "$id" + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} pause $ctr_id" echo "$output" [ "$status" -eq 0 ] - run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} unpause "$id" + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} unpause $ctr_id" echo "$output" [ "$status" -eq 0 ] - run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} ps -a --filter id="$ctr_id" + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} rm -f $ctr_id" echo "$output" [ "$status" -eq 0 ] - cleanup_pods - stop_crio } -@test "pause a running container by name" { - skip "Test needs to be converted to kpod run" - start_crio - run crioctl pod run --config "$TESTDATA"/sandbox_config.json - echo "$output" - [ "$status" -eq 0 ] - pod_id="$output" - run crioctl image pull "$IMAGE" - [ "$status" -eq 0 ] - run crioctl ctr create --config "$TESTDATA"/container_redis.json --pod "$pod_id" +@test "unpause a running container" { + skip "Test needs to wait for --force to work for kpod rm" + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} run -d $BB sleep 60" echo "$output" [ "$status" -eq 0 ] ctr_id="$output" - run crioctl ctr start --id "$ctr_id" - echo "$output" - [ "$status" -eq 0 ] - run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} pause "k8s_podsandbox1-redis_podsandbox1_redhat.test.crio_redhat-test-crio_0" - echo "$output" - [ "$status" -eq 0 ] - run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} unpause "k8s_podsandbox1-redis_podsandbox1_redhat.test.crio_redhat-test-crio_0" + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} unpause $ctr_id" echo "$output" - [ "$status" -eq 0 ] - run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} ps -a --filter id="k8s_podsandbox1-redis_podsandbox1_redhat.test.crio_redhat-test-crio_0" + [ "$status" -eq 1 ] + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} rm -f $ctr_id" echo "$output" [ "$status" -eq 0 ] - cleanup_pods - stop_crio } @test "remove a paused container by id" { - skip "Test needs to be converted to kpod run" - start_crio - run crioctl pod run --config "$TESTDATA"/sandbox_config.json - echo "$output" - [ "$status" -eq 0 ] - pod_id="$output" - run crioctl image pull "$IMAGE" - [ "$status" -eq 0 ] - run crioctl ctr create --config "$TESTDATA"/container_redis.json --pod "$pod_id" + skip "Test needs to wait for --force to work for kpod rm" + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} run -d $BB sleep 60" echo "$output" [ "$status" -eq 0 ] ctr_id="$output" - run crioctl ctr start --id "$ctr_id" - echo "$output" - id="$output" - [ "$status" -eq 0 ] - run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} pause "$id" + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} pause $ctr_id" echo "$output" [ "$status" -eq 0 ] - run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} rm "$id" - echo "$output" - [ "$status" -eq 1 ] - run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} rm --force "$id" + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} rm $ctr_id" echo "$output" [ "$status" -eq 1 ] - run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} unpause "$id" + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} rm --force $ctr_id" echo "$output" [ "$status" -eq 0 ] - run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} stop "$ctr_id" - echo "$output" - [ "$status" -eq 0 ] - run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} rm "$ctr_id" - echo "$output" - [ "$status" -eq 0 ] - cleanup_pods - stop_crio } @test "stop a paused container created by id" { - skip "Test needs to be converted to kpod run" - start_crio - run crioctl pod run --config "$TESTDATA"/sandbox_config.json - echo "$output" - [ "$status" -eq 0 ] - pod_id="$output" - run crioctl image pull "$IMAGE" - [ "$status" -eq 0 ] - run crioctl ctr create --config "$TESTDATA"/container_config.json --pod "$pod_id" + skip "Test needs to wait for kpod stop to be implemented" + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} run -d $BB sleep 60" echo "$output" [ "$status" -eq 0 ] ctr_id="$output" - run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} pause "$ctr_id" + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} pause $ctr_id" echo "$output" [ "$status" -eq 0 ] - run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} stop "$ctr_id" + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} stop $ctr_id" echo "$output" [ "$status" -eq 1 ] - run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} unpause "$ctr_id" + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} unpause $ctr_id" + echo "$output" + [ "$status" -eq 0 ] + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} ps -a --filter id=$ctr_id" echo "$output" [ "$status" -eq 0 ] - run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} ps -a --filter id="$ctr_id" + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} rm $ctr_id" echo "$output" [ "$status" -eq 0 ] - cleanup_pods - stop_crio } |