summaryrefslogtreecommitdiff
path: root/pkg/adapter/containers.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/adapter/containers.go')
-rw-r--r--pkg/adapter/containers.go131
1 files changed, 106 insertions, 25 deletions
diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go
index 40b1e6b43..10720886b 100644
--- a/pkg/adapter/containers.go
+++ b/pkg/adapter/containers.go
@@ -20,8 +20,11 @@ import (
"github.com/containers/image/manifest"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/shared"
+ "github.com/containers/libpod/cmd/podman/shared/parse"
"github.com/containers/libpod/libpod"
+ "github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/libpod/image"
+ "github.com/containers/libpod/libpod/logs"
"github.com/containers/libpod/pkg/adapter/shortcuts"
"github.com/containers/libpod/pkg/systemdgen"
"github.com/containers/psgo"
@@ -96,10 +99,10 @@ func (r *LocalRuntime) StopContainers(ctx context.Context, cli *cliconfig.StopVa
func() error {
err := c.StopWithTimeout(*timeout)
if err != nil {
- if errors.Cause(err) == libpod.ErrCtrStopped {
+ if errors.Cause(err) == define.ErrCtrStopped {
logrus.Debugf("Container %s is already stopped", c.ID())
return nil
- } else if cli.All && errors.Cause(err) == libpod.ErrCtrStateInvalid {
+ } else if cli.All && errors.Cause(err) == define.ErrCtrStateInvalid {
logrus.Debugf("Container %s is not running, could not stop", c.ID())
return nil
}
@@ -165,7 +168,7 @@ func (r *LocalRuntime) InitContainers(ctx context.Context, cli *cliconfig.InitVa
err := ctr.Init(ctx)
if err != nil {
// If we're initializing all containers, ignore invalid state errors
- if cli.All && errors.Cause(err) == libpod.ErrCtrStateInvalid {
+ if cli.All && errors.Cause(err) == define.ErrCtrStateInvalid {
return nil
}
return err
@@ -241,7 +244,7 @@ func (r *LocalRuntime) UmountRootFilesystems(ctx context.Context, cli *cliconfig
logrus.Debugf("Error umounting container %s state: %s", ctr.ID(), err.Error())
continue
}
- if state == libpod.ContainerStateRunning {
+ if state == define.ContainerStateRunning {
logrus.Debugf("Error umounting container %s, is running", ctr.ID())
continue
}
@@ -282,13 +285,14 @@ func (r *LocalRuntime) WaitOnContainers(ctx context.Context, cli *cliconfig.Wait
}
// Log logs one or more containers
-func (r *LocalRuntime) Log(c *cliconfig.LogsValues, options *libpod.LogOptions) error {
+func (r *LocalRuntime) Log(c *cliconfig.LogsValues, options *logs.LogOptions) error {
+
var wg sync.WaitGroup
options.WaitGroup = &wg
if len(c.InputArgs) > 1 {
options.Multi = true
}
- logChannel := make(chan *libpod.LogLine, int(c.Tail)*len(c.InputArgs)+1)
+ logChannel := make(chan *logs.LogLine, int(c.Tail)*len(c.InputArgs)+1)
containers, err := shortcuts.GetContainersByContext(false, c.Latest, c.InputArgs, r.Runtime)
if err != nil {
return err
@@ -376,16 +380,26 @@ func (r *LocalRuntime) Run(ctx context.Context, c *cliconfig.RunValues, exitCode
case "stdin":
inputStream = os.Stdin
default:
- return exitCode, errors.Wrapf(libpod.ErrInvalidArg, "invalid stream %q for --attach - must be one of stdin, stdout, or stderr", stream)
+ return exitCode, errors.Wrapf(define.ErrInvalidArg, "invalid stream %q for --attach - must be one of stdin, stdout, or stderr", stream)
}
}
}
+
+ config, err := r.Runtime.GetConfig()
+ if err != nil {
+ return exitCode, err
+ }
+ detachKeys := c.String("detach-keys")
+ if detachKeys == "" {
+ detachKeys = config.DetachKeys
+ }
+
// if the container was created as part of a pod, also start its dependencies, if any.
- if err := StartAttachCtr(ctx, ctr, outputStream, errorStream, inputStream, c.String("detach-keys"), c.Bool("sig-proxy"), true, c.IsSet("pod")); err != nil {
+ if err := StartAttachCtr(ctx, ctr, outputStream, errorStream, inputStream, detachKeys, c.Bool("sig-proxy"), true, c.IsSet("pod")); err != nil {
// We've manually detached from the container
// Do not perform cleanup, or wait for container exit code
// Just exit immediately
- if errors.Cause(err) == libpod.ErrDetach {
+ if errors.Cause(err) == define.ErrDetach {
exitCode = 0
return exitCode, nil
}
@@ -403,13 +417,9 @@ func (r *LocalRuntime) Run(ctx context.Context, c *cliconfig.RunValues, exitCode
}
if ecode, err := ctr.Wait(); err != nil {
- if errors.Cause(err) == libpod.ErrNoSuchCtr {
+ if errors.Cause(err) == define.ErrNoSuchCtr {
// The container may have been removed
// Go looking for an exit file
- config, err := r.Runtime.GetConfig()
- if err != nil {
- return exitCode, err
- }
ctrExitCode, err := ReadExitFile(config.TmpDir, ctr.ID())
if err != nil {
logrus.Errorf("Cannot get exit code: %v", err)
@@ -487,7 +497,7 @@ func (r *LocalRuntime) Attach(ctx context.Context, c *cliconfig.AttachValues) er
if err != nil {
return errors.Wrapf(err, "unable to determine state of %s", ctr.ID())
}
- if conState != libpod.ContainerStateRunning {
+ if conState != define.ContainerStateRunning {
return errors.Errorf("you can only attach to running containers")
}
@@ -496,19 +506,25 @@ func (r *LocalRuntime) Attach(ctx context.Context, c *cliconfig.AttachValues) er
inputStream = nil
}
// If the container is in a pod, also set to recursively start dependencies
- if err := StartAttachCtr(ctx, ctr, os.Stdout, os.Stderr, inputStream, c.DetachKeys, c.SigProxy, false, ctr.PodID() != ""); err != nil && errors.Cause(err) != libpod.ErrDetach {
+ if err := StartAttachCtr(ctx, ctr, os.Stdout, os.Stderr, inputStream, c.DetachKeys, c.SigProxy, false, ctr.PodID() != ""); err != nil && errors.Cause(err) != define.ErrDetach {
return errors.Wrapf(err, "error attaching to container %s", ctr.ID())
}
return nil
}
// Checkpoint one or more containers
-func (r *LocalRuntime) Checkpoint(c *cliconfig.CheckpointValues, options libpod.ContainerCheckpointOptions) error {
+func (r *LocalRuntime) Checkpoint(c *cliconfig.CheckpointValues) error {
var (
containers []*libpod.Container
err, lastError error
)
+ options := libpod.ContainerCheckpointOptions{
+ Keep: c.Keep,
+ KeepRunning: c.LeaveRunning,
+ TCPEstablished: c.TcpEstablished,
+ TargetFile: c.Export,
+ }
if c.All {
containers, err = r.Runtime.GetRunningContainers()
} else {
@@ -532,16 +548,23 @@ func (r *LocalRuntime) Checkpoint(c *cliconfig.CheckpointValues, options libpod.
}
// Restore one or more containers
-func (r *LocalRuntime) Restore(ctx context.Context, c *cliconfig.RestoreValues, options libpod.ContainerCheckpointOptions) error {
+func (r *LocalRuntime) Restore(ctx context.Context, c *cliconfig.RestoreValues) error {
var (
containers []*libpod.Container
err, lastError error
filterFuncs []libpod.ContainerFilter
)
+ options := libpod.ContainerCheckpointOptions{
+ Keep: c.Keep,
+ TCPEstablished: c.TcpEstablished,
+ TargetFile: c.Import,
+ Name: c.Name,
+ }
+
filterFuncs = append(filterFuncs, func(c *libpod.Container) bool {
state, _ := c.State()
- return state == libpod.ContainerStateExited
+ return state == define.ContainerStateExited
})
if c.Import != "" {
@@ -599,7 +622,7 @@ func (r *LocalRuntime) Start(ctx context.Context, c *cliconfig.StartValues, sigP
return exitCode, errors.Wrapf(err, "unable to get container state")
}
- ctrRunning := ctrState == libpod.ContainerStateRunning
+ ctrRunning := ctrState == define.ContainerStateRunning
if c.Attach {
inputStream := os.Stdin
@@ -610,7 +633,7 @@ func (r *LocalRuntime) Start(ctx context.Context, c *cliconfig.StartValues, sigP
// attach to the container and also start it not already running
// If the container is in a pod, also set to recursively start dependencies
err = StartAttachCtr(ctx, ctr.Container, os.Stdout, os.Stderr, inputStream, c.DetachKeys, sigProxy, !ctrRunning, ctr.PodID() != "")
- if errors.Cause(err) == libpod.ErrDetach {
+ if errors.Cause(err) == define.ErrDetach {
// User manually detached
// Exit cleanly immediately
exitCode = 0
@@ -626,7 +649,7 @@ func (r *LocalRuntime) Start(ctx context.Context, c *cliconfig.StartValues, sigP
}
if ecode, err := ctr.Wait(); err != nil {
- if errors.Cause(err) == libpod.ErrNoSuchCtr {
+ if errors.Cause(err) == define.ErrNoSuchCtr {
// The container may have been removed
// Go looking for an exit file
rtc, err := r.GetConfig()
@@ -725,7 +748,7 @@ func (r *LocalRuntime) UnpauseContainers(ctx context.Context, cli *cliconfig.Unp
var filterFuncs []libpod.ContainerFilter
filterFuncs = append(filterFuncs, func(c *libpod.Container) bool {
state, _ := c.State()
- return state == libpod.ContainerStatePaused
+ return state == define.ContainerStatePaused
})
ctrs, err = r.GetContainers(filterFuncs...)
} else {
@@ -922,7 +945,7 @@ func (r *LocalRuntime) Prune(ctx context.Context, maxWorkers int, force bool) ([
if c.PodID() != "" {
return false
}
- if state == libpod.ContainerStateStopped || state == libpod.ContainerStateExited {
+ if state == define.ContainerStateStopped || state == define.ContainerStateExited {
return true
}
return false
@@ -1013,7 +1036,7 @@ func (r *LocalRuntime) Port(c *cliconfig.PortValues) ([]*Container, error) {
//Convert libpod containers to adapter Containers
for _, con := range containers {
- if state, _ := con.State(); state != libpod.ContainerStateRunning {
+ if state, _ := con.State(); state != define.ContainerStateRunning {
continue
}
portContainers = append(portContainers, &Container{con})
@@ -1094,3 +1117,61 @@ func (r *LocalRuntime) Commit(ctx context.Context, c *cliconfig.CommitValues, co
}
return newImage.ID(), nil
}
+
+// Exec a command in a container
+func (r *LocalRuntime) Exec(c *cliconfig.ExecValues, cmd []string) error {
+ var ctr *Container
+ var err error
+
+ if c.Latest {
+ ctr, err = r.GetLatestContainer()
+ } else {
+ ctr, err = r.LookupContainer(c.InputArgs[0])
+ }
+ if err != nil {
+ return errors.Wrapf(err, "unable to exec into %s", c.InputArgs[0])
+ }
+
+ if c.PreserveFDs > 0 {
+ entries, err := ioutil.ReadDir("/proc/self/fd")
+ if err != nil {
+ return errors.Wrapf(err, "unable to read /proc/self/fd")
+ }
+ m := make(map[int]bool)
+ for _, e := range entries {
+ i, err := strconv.Atoi(e.Name())
+ if err != nil {
+ if err != nil {
+ return errors.Wrapf(err, "cannot parse %s in /proc/self/fd", e.Name())
+ }
+ }
+ m[i] = true
+ }
+ for i := 3; i < 3+c.PreserveFDs; i++ {
+ if _, found := m[i]; !found {
+ return errors.New("invalid --preserve-fds=N specified. Not enough FDs available")
+ }
+ }
+ }
+
+ // ENVIRONMENT VARIABLES
+ env := map[string]string{}
+
+ if err := parse.ReadKVStrings(env, []string{}, c.Env); err != nil {
+ return errors.Wrapf(err, "unable to process environment variables")
+ }
+ envs := []string{}
+ for k, v := range env {
+ envs = append(envs, fmt.Sprintf("%s=%s", k, v))
+ }
+
+ streams := new(libpod.AttachStreams)
+ streams.OutputStream = os.Stdout
+ streams.ErrorStream = os.Stderr
+ streams.InputStream = os.Stdin
+ streams.AttachOutput = true
+ streams.AttachError = true
+ streams.AttachInput = true
+
+ return ctr.Exec(c.Tty, c.Privileged, envs, cmd, c.User, c.Workdir, streams, c.PreserveFDs)
+}