From 1bfb96b54010b048e9bea155a75d150f4bf8853c Mon Sep 17 00:00:00 2001 From: Brent Baude Date: Sun, 5 Apr 2020 15:52:59 -0500 Subject: v2podman run add the ability to run a container Signed-off-by: Brent Baude --- pkg/domain/entities/containers.go | 21 ++++++++++ pkg/domain/entities/engine_container.go | 1 + pkg/domain/infra/abi/containers.go | 74 +++++++++++++++++++++++++++++++++ pkg/domain/infra/tunnel/containers.go | 4 ++ 4 files changed, 100 insertions(+) (limited to 'pkg/domain') diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go index 4f94e009f..5d302058b 100644 --- a/pkg/domain/entities/containers.go +++ b/pkg/domain/entities/containers.go @@ -6,6 +6,7 @@ import ( "time" "github.com/containers/libpod/libpod/define" + "github.com/containers/libpod/pkg/specgen" ) type WaitOptions struct { @@ -224,3 +225,23 @@ type ContainerListOptions struct { Sync bool Watch uint } + +// ContainerRunOptions describes the options needed +// to run a container from the CLI +type ContainerRunOptions struct { + Detach bool + DetachKeys string + ErrorStream *os.File + InputStream *os.File + OutputStream *os.File + Rm bool + SigProxy bool + Spec *specgen.SpecGenerator +} + +// ContainerRunReport describes the results of running +//a container +type ContainerRunReport struct { + ExitCode int + Id string +} diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go index 36c20c38d..576ce1658 100644 --- a/pkg/domain/entities/engine_container.go +++ b/pkg/domain/entities/engine_container.go @@ -23,6 +23,7 @@ type ContainerEngine interface { 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) + ContainerRun(ctx context.Context, opts ContainerRunOptions) (*ContainerRunReport, 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 54f91a189..828ee56f0 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -622,3 +622,77 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri func (ic *ContainerEngine) ContainerList(ctx context.Context, options entities.ContainerListOptions) ([]entities.ListContainer, error) { return ps.GetContainerLists(ic.Libpod, options) } + +func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.ContainerRunOptions) (*entities.ContainerRunReport, error) { + var ( + joinPod bool + ) + if err := generate.CompleteSpec(ctx, ic.Libpod, opts.Spec); err != nil { + return nil, err + } + ctr, err := generate.MakeContainer(ic.Libpod, opts.Spec) + if err != nil { + return nil, err + } + + if len(ctr.PodID()) > 0 { + joinPod = true + } + report := entities.ContainerRunReport{Id: ctr.ID()} + + if logrus.GetLevel() == logrus.DebugLevel { + cgroupPath, err := ctr.CGroupPath() + if err == nil { + logrus.Debugf("container %q has CgroupParent %q", ctr.ID(), cgroupPath) + } + } + if opts.Detach { + // if the container was created as part of a pod, also start its dependencies, if any. + if err := ctr.Start(ctx, joinPod); err != nil { + // This means the command did not exist + report.ExitCode = define.ExitCode(err) + return &report, err + } + + return &report, nil + } + + // if the container was created as part of a pod, also start its dependencies, if any. + if err := terminal.StartAttachCtr(ctx, ctr, opts.OutputStream, opts.ErrorStream, opts.InputStream, opts.DetachKeys, opts.SigProxy, true, joinPod); 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) == define.ErrDetach { + report.ExitCode = 0 + return &report, nil + } + if opts.Rm { + if deleteError := ic.Libpod.RemoveContainer(ctx, ctr, true, false); deleteError != nil { + logrus.Debugf("unable to remove container %s after failing to start and attach to it", ctr.ID()) + } + } + if errors.Cause(err) == define.ErrWillDeadlock { + logrus.Debugf("Deadlock error on %q: %v", ctr.ID(), err) + report.ExitCode = define.ExitCode(err) + return &report, errors.Errorf("attempting to start container %s would cause a deadlock; please run 'podman system renumber' to resolve", ctr.ID()) + } + report.ExitCode = define.ExitCode(err) + return &report, err + } + + 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) + report.ExitCode = define.ExecErrorCodeNotFound + } else { + report.ExitCode = event.ContainerExitCode + } + } + } else { + report.ExitCode = int(ecode) + } + return &report, nil +} diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index b6807d5b6..e96200c5b 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -320,3 +320,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri func (ic *ContainerEngine) ContainerList(ctx context.Context, options entities.ContainerListOptions) ([]entities.ListContainer, error) { return containers.List(ic.ClientCxt, options.Filters, &options.All, &options.Last, &options.Pod, &options.Size, &options.Sync) } + +func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.ContainerRunOptions) (*entities.ContainerRunReport, error) { + return nil, errors.New("not implemented") +} -- cgit v1.2.3-54-g00ecf