From 5e0b4497365f9b3c2d795e5771a3abec7cd24cbb Mon Sep 17 00:00:00 2001 From: Brent Baude Date: Sat, 4 Apr 2020 08:35:23 -0500 Subject: podmanv2 start add the ability to start containers Signed-off-by: Brent Baude --- pkg/domain/entities/containers.go | 21 +++++++ pkg/domain/entities/engine_container.go | 1 + pkg/domain/infra/abi/containers.go | 108 ++++++++++++++++++++++++++++++++ pkg/domain/infra/tunnel/containers.go | 4 ++ 4 files changed, 134 insertions(+) (limited to 'pkg') diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go index cf907eb1b..6b4bb9ba2 100644 --- a/pkg/domain/entities/containers.go +++ b/pkg/domain/entities/containers.go @@ -186,3 +186,24 @@ type ExecOptions struct { User string WorkDir string } + +// ContainerStartOptions describes the val from the +// CLI needed to start a container +type ContainerStartOptions struct { + Attach bool + DetachKeys string + Interactive bool + Latest bool + SigProxy bool + Stdout *os.File + Stderr *os.File + Stdin *os.File +} + +// ContainerStartReport describes the response from starting +// containers from the cli +type ContainerStartReport struct { + Id string + Err error + ExitCode int +} diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go index 9bf3d51de..264780771 100644 --- a/pkg/domain/entities/engine_container.go +++ b/pkg/domain/entities/engine_container.go @@ -21,6 +21,7 @@ type ContainerEngine interface { ContainerPause(ctx context.Context, namesOrIds []string, options PauseUnPauseOptions) ([]*PauseUnpauseReport, error) ContainerRestart(ctx context.Context, namesOrIds []string, options RestartOptions) ([]*RestartReport, error) ContainerRm(ctx context.Context, namesOrIds []string, options RmOptions) ([]*RmReport, error) + ContainerStart(ctx context.Context, namesOrIds []string, options ContainerStartOptions) ([]*ContainerStartReport, error) ContainerStop(ctx context.Context, namesOrIds []string, options StopOptions) ([]*StopReport, error) ContainerTop(ctx context.Context, options TopOptions) (*StringSliceReport, error) ContainerUnpause(ctx context.Context, namesOrIds []string, options PauseUnPauseOptions) ([]*PauseUnpauseReport, error) diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index b93e7665a..929c3f335 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -12,6 +12,7 @@ import ( "github.com/containers/image/v5/manifest" "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/define" + "github.com/containers/libpod/libpod/events" "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/checkpoint" "github.com/containers/libpod/pkg/domain/entities" @@ -509,3 +510,110 @@ func (ic *ContainerEngine) ContainerExec(ctx context.Context, nameOrId string, o ec, err = terminal.ExecAttachCtr(ctx, ctr, options.Tty, options.Privileged, options.Envs, options.Cmd, options.User, options.WorkDir, &options.Streams, options.PreserveFDs, options.DetachKeys) return define.TranslateExecErrorToExitCode(ec, err), err } + +func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []string, options entities.ContainerStartOptions) ([]*entities.ContainerStartReport, error) { + var reports []*entities.ContainerStartReport + var exitCode = define.ExecErrorCodeGeneric + ctrs, err := getContainersByContext(false, options.Latest, namesOrIds, ic.Libpod) + if err != nil { + return nil, err + } + // There can only be one container if attach was used + for _, ctr := range ctrs { + ctrState, err := ctr.State() + if err != nil { + return nil, err + } + ctrRunning := ctrState == define.ContainerStateRunning + + if options.Attach { + err = terminal.StartAttachCtr(ctx, ctr, options.Stdout, options.Stderr, options.Stdin, options.DetachKeys, options.SigProxy, !ctrRunning, ctr.PodID() != "") + if errors.Cause(err) == define.ErrDetach { + // User manually detached + // Exit cleanly immediately + reports = append(reports, &entities.ContainerStartReport{ + Id: ctr.ID(), + Err: nil, + ExitCode: 0, + }) + return reports, nil + } + + if errors.Cause(err) == define.ErrWillDeadlock { + logrus.Debugf("Deadlock error: %v", err) + reports = append(reports, &entities.ContainerStartReport{ + Id: ctr.ID(), + Err: err, + ExitCode: define.ExitCode(err), + }) + return reports, errors.Errorf("attempting to start container %s would cause a deadlock; please run 'podman system renumber' to resolve", ctr.ID()) + } + + if ctrRunning { + reports = append(reports, &entities.ContainerStartReport{ + Id: ctr.ID(), + Err: nil, + ExitCode: 0, + }) + return reports, err + } + + if err != nil { + reports = append(reports, &entities.ContainerStartReport{ + Id: ctr.ID(), + Err: err, + ExitCode: exitCode, + }) + return reports, errors.Wrapf(err, "unable to start container %s", ctr.ID()) + } + + if ecode, err := ctr.Wait(); err != nil { + if errors.Cause(err) == define.ErrNoSuchCtr { + // Check events + event, err := ic.Libpod.GetLastContainerEvent(ctr.ID(), events.Exited) + if err != nil { + logrus.Errorf("Cannot get exit code: %v", err) + exitCode = define.ExecErrorCodeNotFound + } else { + exitCode = event.ContainerExitCode + } + } + } else { + exitCode = int(ecode) + } + reports = append(reports, &entities.ContainerStartReport{ + Id: ctr.ID(), + Err: err, + ExitCode: exitCode, + }) + return reports, nil + } // end attach + + // Start the container if it's not running already. + if !ctrRunning { + // Handle non-attach start + // If the container is in a pod, also set to recursively start dependencies + report := &entities.ContainerStartReport{ + Id: ctr.ID(), + ExitCode: 125, + } + if err := ctr.Start(ctx, ctr.PodID() != ""); err != nil { + //if lastError != nil { + // fmt.Fprintln(os.Stderr, lastError) + //} + report.Err = err + if errors.Cause(err) == define.ErrWillDeadlock { + report.Err = errors.Wrapf(err, "please run 'podman system renumber' to resolve deadlocks") + reports = append(reports, report) + continue + } + report.Err = errors.Wrapf(err, "unable to start container %q", ctr.ID()) + reports = append(reports, report) + continue + } + report.ExitCode = 0 + reports = append(reports, report) + } + } + return reports, nil +} diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index 1e71cba2c..4101068ba 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -313,3 +313,7 @@ func (ic *ContainerEngine) ContainerAttach(ctx context.Context, nameOrId string, func (ic *ContainerEngine) ContainerExec(ctx context.Context, nameOrId string, options entities.ExecOptions) (int, error) { return 125, errors.New("not implemented") } + +func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []string, options entities.ContainerStartOptions) ([]*entities.ContainerStartReport, error) { + return nil, errors.New("not implemented") +} -- cgit v1.2.3-54-g00ecf