Skip to content

Commit

Permalink
enable managing more containers for some commands
Browse files Browse the repository at this point in the history
Signed-off-by: xiechengsheng <[email protected]>
  • Loading branch information
xiechengsheng committed May 21, 2018
1 parent b8b7c01 commit dfb3444
Show file tree
Hide file tree
Showing 9 changed files with 207 additions and 74 deletions.
40 changes: 27 additions & 13 deletions cli/pause.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@ package main

import (
"context"
"errors"
"fmt"
"strings"

"github.com/spf13/cobra"
)

// pauseDescription is used to describe pause command in detail and auto generate command doc.
var pauseDescription = "Pause a running container object in Pouchd. " +
var pauseDescription = "Pause one or more running containers in Pouchd. " +
"when pausing, the container will pause its running but hold all the relevant resource." +
"This is useful when you wish to pause a container for a while and to restore the running status later." +
"The container you paused will pause without being terminated."

// PauseCommand use to implement 'pause' command, it pauses a container.
// PauseCommand use to implement 'pause' command, it pauses one or more containers.
type PauseCommand struct {
baseCommand
}
Expand All @@ -22,10 +24,10 @@ type PauseCommand struct {
func (p *PauseCommand) Init(c *Cli) {
p.cli = c
p.cmd = &cobra.Command{
Use: "pause CONTAINER",
Short: "Pause a running container",
Use: "pause CONTAINER [CONTAINER...]",
Short: "Pause one or more running containers",
Long: pauseDescription,
Args: cobra.ExactArgs(1),
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return p.runPause(args)
},
Expand All @@ -44,21 +46,33 @@ func (p *PauseCommand) runPause(args []string) error {
ctx := context.Background()
apiClient := p.cli.Client()

container := args[0]
var errs []string
for _, name := range args {
if err := apiClient.ContainerPause(ctx, name); err != nil {
errs = append(errs, err.Error())
continue
}
fmt.Printf("%s\n", name)
}

if err := apiClient.ContainerPause(ctx, container); err != nil {
return fmt.Errorf("failed to pause container %s: %v", container, err)
if len(errs) > 0 {
return errors.New(strings.Join(errs, "\n"))
}

return nil
}

// pauseExample shows examples in pause command, and is used in auto-generated cli docs.
func pauseExample() string {
return `$ pouch ps
Name ID Status Image Runtime
foo 71b9c1 Running docker.io/library/busybox:latest runc
$ pouch pause foo
Name ID Status Created Image Runtime
foo2 87259c Up 25 seconds 26 seconds ago registry.hub.docker.com/library/busybox:latest runc
foo1 77188c Up 46 seconds 47 seconds ago registry.hub.docker.com/library/busybox:latest runc
$ pouch pause foo1 foo2
foo1
foo2
$ pouch ps
Name ID Status Image Runtime
foo 71b9c1 Paused docker.io/library/busybox:latest runc`
Name ID Status Created Image Runtime
foo2 87259c Up 1 minute(paused) 1 minute ago registry.hub.docker.com/library/busybox:latest runc
foo1 77188c Up 1 minute(paused) 1 minute ago registry.hub.docker.com/library/busybox:latest runc`
}
15 changes: 11 additions & 4 deletions cli/restart.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package main

import (
"context"
"strconv"

"errors"
"fmt"
"strconv"
"strings"

"github.com/spf13/cobra"
)
Expand All @@ -23,7 +24,7 @@ func (rc *RestartCommand) Init(c *Cli) {
rc.cli = c

rc.cmd = &cobra.Command{
Use: "restart [OPTION] CONTAINER [CONTAINERS]",
Use: "restart [OPTION] CONTAINER [CONTAINER...]",
Short: "restart one or more containers",
Long: restartDescription,
Args: cobra.MinimumNArgs(1),
Expand All @@ -46,13 +47,19 @@ func (rc *RestartCommand) runRestart(args []string) error {
ctx := context.Background()
apiClient := rc.cli.Client()

var errs []string
for _, name := range args {
if err := apiClient.ContainerRestart(ctx, name, strconv.Itoa(rc.timeout)); err != nil {
return fmt.Errorf("failed to restart container: %v", err)
errs = append(errs, err.Error())
continue
}
fmt.Printf("%s\n", name)
}

if len(errs) > 0 {
return errors.New(strings.Join(errs, "\n"))
}

return nil
}

Expand Down
33 changes: 24 additions & 9 deletions cli/rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@ package main

import (
"context"
"errors"
"fmt"
"strings"

"github.com/alibaba/pouch/apis/types"

"github.com/spf13/cobra"
)

var rmDescription = `
Remove a container object in Pouchd.
Remove one or more containers in Pouchd.
If a container be stopped or created, you can remove it.
If the container be running, you can also remove it with flag force.
When the container be removed, the all resource of the container will
If the container is running, you can also remove it with flag force.
When the container is removed, the all resources of the container will
be released.
`

Expand Down Expand Up @@ -58,20 +60,33 @@ func (r *RmCommand) runRm(args []string) error {
Volumes: r.removeVolumes,
}

var errs []string
for _, name := range args {
if err := apiClient.ContainerRemove(ctx, name, options); err != nil {
return fmt.Errorf("failed to remove container: %v", err)
errs = append(errs, err.Error())
continue
}
fmt.Printf("%s\n", name)
}

if len(errs) > 0 {
return errors.New(strings.Join(errs, "\n"))
}

return nil
}

func rmExample() string {
return `$ pouch rm 5d3152
5d3152
$ pouch rm -f 493028
493028`
return `$ pouch ps -a
Name ID Status Created Image Runtime
foo 03cd58 Exited (0) 25 seconds 26 seconds ago registry.hub.docker.com/library/busybox:latest runc
$ pouch rm foo
foo
$ pouch ps
Name ID Status Created Image Runtime
foo2 1d979d Up 5 seconds 6 seconds ago registry.hub.docker.com/library/busybox:latest runc
foo1 83e3cf Up 9 seconds 10 seconds ago registry.hub.docker.com/library/busybox:latest runc
$ pouch rm -f foo1 foo2
foo1
foo2`
}
14 changes: 12 additions & 2 deletions cli/rmi.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package main

import (
"context"
"errors"
"fmt"
"strings"

"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -43,19 +45,27 @@ func (rmi *RmiCommand) runRmi(args []string) error {
ctx := context.Background()
apiClient := rmi.cli.Client()

var errs []string
for _, name := range args {
if err := apiClient.ImageRemove(ctx, name, rmi.force); err != nil {
return fmt.Errorf("failed to remove image: %v", err)
errs = append(errs, err.Error())
continue
}
fmt.Printf("%s\n", name)
}

if len(errs) > 0 {
return errors.New("failed to remove images: " + strings.Join(errs, ""))
}

return nil
}

// rmiExample shows examples in rmi command, and is used in auto-generated cli docs.
func rmiExample() string {
return `$ pouch rmi registry.hub.docker.com/library/busybox:latest
return `$ pouch rmi registry.hub.docker.com/library/busybox:latest registry.hub.docker.com/library/busybox:1.28
registry.hub.docker.com/library/busybox:latest
registry.hub.docker.com/library/busybox:1.28
$ pouch create --name test registry.hub.docker.com/library/busybox:latest
container ID: e5952417f9ee94621bbeaec532be1803ae2dedeb11a80f578a6d621e04a95afd, name: test
$ pouch rmi registry.hub.docker.com/library/busybox:latest
Expand Down
87 changes: 55 additions & 32 deletions cli/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,23 @@ package main

import (
"context"
"errors"
"fmt"
"io"
"os"
"strings"

"github.com/spf13/cobra"
"golang.org/x/crypto/ssh/terminal"
)

// startDescription is used to describe start command in detail and auto generate command doc.
var startDescription = "Start a created container object in Pouchd. " +
var startDescription = "Start one or more created container objects in Pouchd. " +
"When starting, the relevant resource preserved during creating period comes into use." +
"This is useful when you wish to start a container which has been created in advance." +
"The container you started will be running if no error occurs."

// StartCommand use to implement 'start' command, it start a container.
// StartCommand use to implement 'start' command, it start one or more containers.
type StartCommand struct {
baseCommand
detachKeys string
Expand All @@ -28,10 +30,10 @@ type StartCommand struct {
func (s *StartCommand) Init(c *Cli) {
s.cli = c
s.cmd = &cobra.Command{
Use: "start [OPTIONS] CONTAINER",
Short: "Start a created or stopped container",
Use: "start [OPTIONS] CONTAINER [CONTAINER...]",
Short: "Start one or more created or stopped containers",
Long: startDescription,
Args: cobra.ExactArgs(1),
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return s.runStart(args)
},
Expand All @@ -50,14 +52,17 @@ func (s *StartCommand) addFlags() {

// runStart is the entry of start command.
func (s *StartCommand) runStart(args []string) error {
container := args[0]

// attach to io.
ctx := context.Background()
apiClient := s.cli.Client()

var wait chan struct{}
// attach to io.
if s.attach || s.stdin {
var wait chan struct{}
// If we want to attach to a container, we should make sure we only have one container.
if len(args) > 1 {
return fmt.Errorf("cannot start and attach multiple containers at once")
}

in, out, err := setRawMode(s.stdin, false)
if err != nil {
return fmt.Errorf("failed to set raw mode")
Expand All @@ -68,6 +73,7 @@ func (s *StartCommand) runStart(args []string) error {
}
}()

container := args[0]
conn, br, err := apiClient.ContainerAttach(ctx, container, s.stdin)
if err != nil {
return fmt.Errorf("failed to attach container: %v", err)
Expand All @@ -82,28 +88,41 @@ func (s *StartCommand) runStart(args []string) error {
go func() {
io.Copy(conn, os.Stdin)
}()
}

// start container
if err := apiClient.ContainerStart(ctx, container, s.detachKeys); err != nil {
return fmt.Errorf("failed to start container %s: %v", container, err)
}
// start container
if err := apiClient.ContainerStart(ctx, container, s.detachKeys); err != nil {
return fmt.Errorf("failed to start container %s: %v", container, err)
}

// wait the io to finish.
if s.attach || s.stdin {
<-wait
}
// wait the io to finish.
if s.attach || s.stdin {
<-wait
}

info, err := apiClient.ContainerGet(ctx, container)
if err != nil {
return err
}
info, err := apiClient.ContainerGet(ctx, container)
if err != nil {
return err
}

code := info.State.ExitCode
if code != 0 {
return ExitError{Code: int(code)}
}
code := info.State.ExitCode
if code != 0 {
return ExitError{Code: int(code)}
}
} else {
// We're not going to attach to any container, so we just start as many containers as we want.
var errs []string
for _, name := range args {
if err := apiClient.ContainerStart(ctx, name, s.detachKeys); err != nil {
errs = append(errs, err.Error())
continue
}
fmt.Printf("%s\n", name)
}

if len(errs) > 0 {
return errors.New("failed to start containers: " + strings.Join(errs, ""))
}
}
return nil
}

Expand Down Expand Up @@ -144,11 +163,15 @@ func restoreMode(in, out *terminal.State) error {

// startExample shows examples in start command, and is used in auto-generated cli docs.
func startExample() string {
return `$ pouch ps
Name ID Status Image Runtime
foo 71b9c1 Created docker.io/library/busybox:latest runc
$ pouch start foo
return `$ pouch ps -a
Name ID Status Created Image Runtime
foo2 5a0ede created 1 second ago registry.hub.docker.com/library/busybox:latest runc
foo1 e05637 created 6 seconds ago registry.hub.docker.com/library/busybox:latest runc
$ pouch start foo1 foo2
foo1
foo2
$ pouch ps
Name ID Status Image Runtime
foo 71b9c1 Running docker.io/library/busybox:latest runc`
Name ID Status Created Image Runtime
foo2 5a0ede Up 2 seconds 12 seconds ago registry.hub.docker.com/library/busybox:latest runc
foo1 e05637 Up 3 seconds 17 seconds ago registry.hub.docker.com/library/busybox:latest runc`
}
Loading

0 comments on commit dfb3444

Please sign in to comment.