Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions cmd/podman/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ func getMainCommands() []*cobra.Command {
_mountCommand,
_portCommand,
_refreshCommand,
_restartCommand,
_searchCommand,
_statsCommand,
_topCommand,
Expand Down Expand Up @@ -50,7 +49,6 @@ func getContainerSubCommands() []*cobra.Command {
_portCommand,
_pruneContainersCommand,
_refreshCommand,
_restartCommand,
_restoreCommand,
_runlabelCommand,
_statsCommand,
Expand Down
1 change: 1 addition & 0 deletions cmd/podman/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ var (
_listSubCommand,
_logsCommand,
_pauseCommand,
_restartCommand,
_runCommand,
_rmCommand,
_startCommand,
Expand Down
1 change: 1 addition & 0 deletions cmd/podman/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ var mainCommands = []*cobra.Command{
&_psCommand,
_pullCommand,
_pushCommand,
_restartCommand,
_rmCommand,
&_rmiCommand,
_runCommand,
Expand Down
84 changes: 14 additions & 70 deletions cmd/podman/restart.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ package main

import (
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/adapter"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

Expand All @@ -22,7 +20,6 @@ var (
RunE: func(cmd *cobra.Command, args []string) error {
restartCommand.InputArgs = args
restartCommand.GlobalFlags = MainGlobalOpts
restartCommand.Remote = remoteclient
return restartCmd(&restartCommand)
},
Args: func(cmd *cobra.Command, args []string) error {
Expand All @@ -49,83 +46,30 @@ func init() {
}

func restartCmd(c *cliconfig.RestartValues) error {
var (
restartFuncs []shared.ParallelWorkerInput
containers []*libpod.Container
restartContainers []*libpod.Container
)

args := c.InputArgs
runOnly := c.Running
all := c.All
if len(args) < 1 && !c.Latest && !all {
if len(c.InputArgs) < 1 && !c.Latest && !all {
return errors.Wrapf(libpod.ErrInvalidArg, "you must provide at least one container name or ID")
}

runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
runtime, err := adapter.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
defer runtime.Shutdown(false)

timeout := c.Timeout
useTimeout := c.Flag("timeout").Changed || c.Flag("time").Changed

// Handle --latest
if c.Latest {
lastCtr, err := runtime.GetLatestContainer()
if err != nil {
return errors.Wrapf(err, "unable to get latest container")
}
restartContainers = append(restartContainers, lastCtr)
} else if runOnly {
containers, err = getAllOrLatestContainers(&c.PodmanCommand, runtime, libpod.ContainerStateRunning, "running")
if err != nil {
return err
}
restartContainers = append(restartContainers, containers...)
} else if all {
containers, err = runtime.GetAllContainers()
if err != nil {
return err
}
restartContainers = append(restartContainers, containers...)
} else {
for _, id := range args {
ctr, err := runtime.LookupContainer(id)
if err != nil {
return err
ok, failures, err := runtime.Restart(getContext(), c)
if err != nil {
if errors.Cause(err) == libpod.ErrNoSuchCtr {
if len(c.InputArgs) > 1 {
exitCode = 125
} else {
exitCode = 1
}
restartContainers = append(restartContainers, ctr)
}
return err
}

maxWorkers := shared.Parallelize("restart")
if c.GlobalIsSet("max-workers") {
maxWorkers = c.GlobalFlags.MaxWorks
if len(failures) > 0 {
exitCode = 125
}

logrus.Debugf("Setting maximum workers to %d", maxWorkers)

// We now have a slice of all the containers to be restarted. Iterate them to
// create restart Funcs with a timeout as needed
for _, ctr := range restartContainers {
con := ctr
ctrTimeout := ctr.StopTimeout()
if useTimeout {
ctrTimeout = timeout
}

f := func() error {
return con.RestartWithTimeout(getContext(), ctrTimeout)
}

restartFuncs = append(restartFuncs, shared.ParallelWorkerInput{
ContainerID: con.ID(),
ParallelFunc: f,
})
}

restartErrors, errCount := shared.ParallelExecuteWorkerPool(maxWorkers, restartFuncs)
return printParallelOutput(restartErrors, errCount)
return printCmdResults(ok, failures)
}
69 changes: 69 additions & 0 deletions pkg/adapter/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -694,3 +694,72 @@ func (r *LocalRuntime) UnpauseContainers(ctx context.Context, cli *cliconfig.Unp
}
return pool.Run()
}

// Restart containers without or without a timeout
func (r *LocalRuntime) Restart(ctx context.Context, c *cliconfig.RestartValues) ([]string, map[string]error, error) {
var (
containers []*libpod.Container
restartContainers []*libpod.Container
err error
)
useTimeout := c.Flag("timeout").Changed || c.Flag("time").Changed
inputTimeout := c.Timeout

// Handle --latest
if c.Latest {
lastCtr, err := r.Runtime.GetLatestContainer()
if err != nil {
return nil, nil, errors.Wrapf(err, "unable to get latest container")
}
restartContainers = append(restartContainers, lastCtr)
} else if c.Running {
containers, err = r.GetRunningContainers()
if err != nil {
return nil, nil, err
}
restartContainers = append(restartContainers, containers...)
} else if c.All {
containers, err = r.Runtime.GetAllContainers()
if err != nil {
return nil, nil, err
}
restartContainers = append(restartContainers, containers...)
} else {
for _, id := range c.InputArgs {
ctr, err := r.Runtime.LookupContainer(id)
if err != nil {
return nil, nil, err
}
restartContainers = append(restartContainers, ctr)
}
}

maxWorkers := shared.DefaultPoolSize("restart")
if c.GlobalIsSet("max-workers") {
maxWorkers = c.GlobalFlags.MaxWorks
}

logrus.Debugf("Setting maximum workers to %d", maxWorkers)

// We now have a slice of all the containers to be restarted. Iterate them to
// create restart Funcs with a timeout as needed
pool := shared.NewPool("restart", maxWorkers, len(restartContainers))
for _, c := range restartContainers {
ctr := c
timeout := ctr.StopTimeout()
if useTimeout {
timeout = inputTimeout
}
pool.Add(shared.Job{
ID: ctr.ID(),
Fn: func() error {
err := ctr.RestartWithTimeout(ctx, timeout)
if err != nil {
logrus.Debugf("Failed to restart container %s: %s", ctr.ID(), err.Error())
}
return err
},
})
}
return pool.Run()
}
79 changes: 79 additions & 0 deletions pkg/adapter/containers_remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ func (c *Container) ID() string {
return c.config.ID
}

// Restart a single container
func (c *Container) Restart(timeout int64) error {
_, err := iopodman.RestartContainer().Call(c.Runtime.Conn, c.ID(), timeout)
return err
}

// Pause a container
func (c *Container) Pause() error {
_, err := iopodman.PauseContainer().Call(c.Runtime.Conn, c.ID())
Expand Down Expand Up @@ -132,6 +138,23 @@ func (r *LocalRuntime) LookupContainer(idOrName string) (*Container, error) {
}, nil
}

// GetAllContainers returns all containers in a slice
func (r *LocalRuntime) GetAllContainers() ([]*Container, error) {
var containers []*Container
ctrs, err := iopodman.GetContainersByContext().Call(r.Conn, true, false, []string{})
if err != nil {
return nil, err
}
for _, ctr := range ctrs {
container, err := r.LookupContainer(ctr)
if err != nil {
return nil, err
}
containers = append(containers, container)
}
return containers, nil
}

func (r *LocalRuntime) LookupContainersWithStatus(filters []string) ([]*Container, error) {
var containers []*Container
ctrs, err := iopodman.GetContainersByStatus().Call(r.Conn, filters)
Expand Down Expand Up @@ -753,3 +776,59 @@ func (r *LocalRuntime) UnpauseContainers(ctx context.Context, cli *cliconfig.Unp
}
return ok, failures, nil
}

// Restart restarts a container over varlink
func (r *LocalRuntime) Restart(ctx context.Context, c *cliconfig.RestartValues) ([]string, map[string]error, error) {
var (
containers []*Container
restartContainers []*Container
err error
ok = []string{}
failures = map[string]error{}
)
useTimeout := c.Flag("timeout").Changed || c.Flag("time").Changed
inputTimeout := c.Timeout

if c.Latest {
lastCtr, err := r.GetLatestContainer()
if err != nil {
return nil, nil, errors.Wrapf(err, "unable to get latest container")
}
restartContainers = append(restartContainers, lastCtr)
} else if c.Running {
containers, err = r.LookupContainersWithStatus([]string{libpod.ContainerStateRunning.String()})
if err != nil {
return nil, nil, err
}
restartContainers = append(restartContainers, containers...)
} else if c.All {
containers, err = r.GetAllContainers()
if err != nil {
return nil, nil, err
}
restartContainers = append(restartContainers, containers...)
} else {
for _, id := range c.InputArgs {
ctr, err := r.LookupContainer(id)
if err != nil {
return nil, nil, err
}
restartContainers = append(restartContainers, ctr)
}
}

for _, c := range restartContainers {
c := c
timeout := c.config.StopTimeout
if useTimeout {
timeout = inputTimeout
}
err := c.Restart(int64(timeout))
if err != nil {
failures[c.ID()] = err
} else {
ok = append(ok, c.ID())
}
}
return ok, failures, nil
}
2 changes: 0 additions & 2 deletions test/e2e/restart_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// +build !remoteclient

package integration

import (
Expand Down