summaryrefslogtreecommitdiff
path: root/pkg/domain
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/domain')
-rw-r--r--pkg/domain/entities/container_ps.go174
-rw-r--r--pkg/domain/entities/containers.go59
-rw-r--r--pkg/domain/entities/engine_container.go5
-rw-r--r--pkg/domain/infra/abi/containers.go187
-rw-r--r--pkg/domain/infra/abi/pods.go5
-rw-r--r--pkg/domain/infra/abi/system.go13
-rw-r--r--pkg/domain/infra/tunnel/containers.go17
-rw-r--r--pkg/domain/infra/tunnel/helpers.go5
-rw-r--r--pkg/domain/infra/tunnel/system.go11
9 files changed, 468 insertions, 8 deletions
diff --git a/pkg/domain/entities/container_ps.go b/pkg/domain/entities/container_ps.go
new file mode 100644
index 000000000..ceafecebc
--- /dev/null
+++ b/pkg/domain/entities/container_ps.go
@@ -0,0 +1,174 @@
+package entities
+
+import (
+ "sort"
+ "strings"
+
+ "github.com/containers/libpod/cmd/podman/shared"
+ "github.com/containers/libpod/libpod"
+ "github.com/cri-o/ocicni/pkg/ocicni"
+ "github.com/pkg/errors"
+)
+
+// Listcontainer describes a container suitable for listing
+type ListContainer struct {
+ // Container command
+ Command []string
+ // Container creation time
+ Created int64
+ // If container has exited/stopped
+ Exited bool
+ // Time container exited
+ ExitedAt int64
+ // If container has exited, the return code from the command
+ ExitCode int32
+ // The unique identifier for the container
+ ID string `json:"Id"`
+ // Container image
+ Image string
+ // If this container is a Pod infra container
+ IsInfra bool
+ // Labels for container
+ Labels map[string]string
+ // User volume mounts
+ Mounts []string
+ // The names assigned to the container
+ Names []string
+ // Namespaces the container belongs to. Requires the
+ // namespace boolean to be true
+ Namespaces ListContainerNamespaces
+ // The process id of the container
+ Pid int
+ // If the container is part of Pod, the Pod ID. Requires the pod
+ // boolean to be set
+ Pod string
+ // If the container is part of Pod, the Pod name. Requires the pod
+ // boolean to be set
+ PodName string
+ // Port mappings
+ Ports []ocicni.PortMapping
+ // Size of the container rootfs. Requires the size boolean to be true
+ Size *shared.ContainerSize
+ // Time when container started
+ StartedAt int64
+ // State of container
+ State string
+}
+
+// ListContainer Namespaces contains the identifiers of the container's Linux namespaces
+type ListContainerNamespaces struct {
+ // Mount namespace
+ MNT string `json:"Mnt,omitempty"`
+ // Cgroup namespace
+ Cgroup string `json:"Cgroup,omitempty"`
+ // IPC namespace
+ IPC string `json:"Ipc,omitempty"`
+ // Network namespace
+ NET string `json:"Net,omitempty"`
+ // PID namespace
+ PIDNS string `json:"Pidns,omitempty"`
+ // UTS namespace
+ UTS string `json:"Uts,omitempty"`
+ // User namespace
+ User string `json:"User,omitempty"`
+}
+
+// SortContainers helps us set-up ability to sort by createTime
+type SortContainers []*libpod.Container
+
+func (a SortContainers) Len() int { return len(a) }
+func (a SortContainers) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+
+type SortCreateTime struct{ SortContainers }
+
+func (a SortCreateTime) Less(i, j int) bool {
+ return a.SortContainers[i].CreatedTime().Before(a.SortContainers[j].CreatedTime())
+}
+
+type SortListContainers []ListContainer
+
+func (a SortListContainers) Len() int { return len(a) }
+func (a SortListContainers) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+
+type psSortedCommand struct{ SortListContainers }
+
+func (a psSortedCommand) Less(i, j int) bool {
+ return strings.Join(a.SortListContainers[i].Command, " ") < strings.Join(a.SortListContainers[j].Command, " ")
+}
+
+type psSortedId struct{ SortListContainers }
+
+func (a psSortedId) Less(i, j int) bool {
+ return a.SortListContainers[i].ID < a.SortListContainers[j].ID
+}
+
+type psSortedImage struct{ SortListContainers }
+
+func (a psSortedImage) Less(i, j int) bool {
+ return a.SortListContainers[i].Image < a.SortListContainers[j].Image
+}
+
+type psSortedNames struct{ SortListContainers }
+
+func (a psSortedNames) Less(i, j int) bool {
+ return a.SortListContainers[i].Names[0] < a.SortListContainers[j].Names[0]
+}
+
+type psSortedPod struct{ SortListContainers }
+
+func (a psSortedPod) Less(i, j int) bool {
+ return a.SortListContainers[i].Pod < a.SortListContainers[j].Pod
+}
+
+type psSortedRunningFor struct{ SortListContainers }
+
+func (a psSortedRunningFor) Less(i, j int) bool {
+ return a.SortListContainers[i].StartedAt < a.SortListContainers[j].StartedAt
+}
+
+type psSortedStatus struct{ SortListContainers }
+
+func (a psSortedStatus) Less(i, j int) bool {
+ return a.SortListContainers[i].State < a.SortListContainers[j].State
+}
+
+type psSortedSize struct{ SortListContainers }
+
+func (a psSortedSize) Less(i, j int) bool {
+ if a.SortListContainers[i].Size == nil || a.SortListContainers[j].Size == nil {
+ return false
+ }
+ return a.SortListContainers[i].Size.RootFsSize < a.SortListContainers[j].Size.RootFsSize
+}
+
+type PsSortedCreateTime struct{ SortListContainers }
+
+func (a PsSortedCreateTime) Less(i, j int) bool {
+ return a.SortListContainers[i].Created < a.SortListContainers[j].Created
+}
+
+func SortPsOutput(sortBy string, psOutput SortListContainers) (SortListContainers, error) {
+ switch sortBy {
+ case "id":
+ sort.Sort(psSortedId{psOutput})
+ case "image":
+ sort.Sort(psSortedImage{psOutput})
+ case "command":
+ sort.Sort(psSortedCommand{psOutput})
+ case "runningfor":
+ sort.Sort(psSortedRunningFor{psOutput})
+ case "status":
+ sort.Sort(psSortedStatus{psOutput})
+ case "size":
+ sort.Sort(psSortedSize{psOutput})
+ case "names":
+ sort.Sort(psSortedNames{psOutput})
+ case "created":
+ sort.Sort(PsSortedCreateTime{psOutput})
+ case "pod":
+ sort.Sort(psSortedPod{psOutput})
+ default:
+ return nil, errors.Errorf("invalid option for --sort, options are: command, created, id, image, names, runningfor, size, or status")
+ }
+ return psOutput, nil
+}
diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go
index cf907eb1b..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 {
@@ -186,3 +187,61 @@ 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
+}
+
+// ContainerListOptions describes the CLI options
+// for listing containers
+type ContainerListOptions struct {
+ All bool
+ Filters map[string][]string
+ Format string
+ Last int
+ Latest bool
+ Namespace bool
+ Pod bool
+ Quiet bool
+ Size bool
+ Sort string
+ 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 9bf3d51de..0fc390ea2 100644
--- a/pkg/domain/entities/engine_container.go
+++ b/pkg/domain/entities/engine_container.go
@@ -19,8 +19,11 @@ type ContainerEngine interface {
ContainerExport(ctx context.Context, nameOrId string, options ContainerExportOptions) error
ContainerKill(ctx context.Context, namesOrIds []string, options KillOptions) ([]*KillReport, error)
ContainerPause(ctx context.Context, namesOrIds []string, options PauseUnPauseOptions) ([]*PauseUnpauseReport, error)
+ ContainerList(ctx context.Context, options ContainerListOptions) ([]ListContainer, 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)
+ 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)
@@ -45,4 +48,6 @@ type ContainerEngine interface {
VolumeList(ctx context.Context, opts VolumeListOptions) ([]*VolumeListReport, error)
VolumePrune(ctx context.Context, opts VolumePruneOptions) ([]*VolumePruneReport, error)
VolumeRm(ctx context.Context, namesOrIds []string, opts VolumeRmOptions) ([]*VolumeRmReport, error)
+
+ Info(ctx context.Context) (*define.Info, error)
}
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index b93e7665a..828ee56f0 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -12,10 +12,12 @@ 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"
"github.com/containers/libpod/pkg/domain/infra/abi/terminal"
+ "github.com/containers/libpod/pkg/ps"
"github.com/containers/libpod/pkg/signal"
"github.com/containers/libpod/pkg/specgen"
"github.com/containers/libpod/pkg/specgen/generate"
@@ -509,3 +511,188 @@ 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
+}
+
+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/abi/pods.go b/pkg/domain/infra/abi/pods.go
index 073cd8d5c..c3e5d59bc 100644
--- a/pkg/domain/infra/abi/pods.go
+++ b/pkg/domain/infra/abi/pods.go
@@ -5,9 +5,10 @@ package abi
import (
"context"
+ lpfilters "github.com/containers/libpod/libpod/filters"
+
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define"
- "github.com/containers/libpod/libpod/podfilters"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/pkg/signal"
"github.com/containers/libpod/pkg/specgen"
@@ -281,7 +282,7 @@ func (ic *ContainerEngine) PodPs(ctx context.Context, options entities.PodPSOpti
)
for k, v := range options.Filters {
for _, filter := range v {
- f, err := podfilters.GeneratePodFilterFunc(k, filter)
+ f, err := lpfilters.GeneratePodFilterFunc(k, filter)
if err != nil {
return nil, err
}
diff --git a/pkg/domain/infra/abi/system.go b/pkg/domain/infra/abi/system.go
new file mode 100644
index 000000000..8aaa69847
--- /dev/null
+++ b/pkg/domain/infra/abi/system.go
@@ -0,0 +1,13 @@
+// +build ABISupport
+
+package abi
+
+import (
+ "context"
+
+ "github.com/containers/libpod/libpod/define"
+)
+
+func (ic *ContainerEngine) Info(ctx context.Context) (*define.Info, error) {
+ return ic.Libpod.Info()
+}
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index 1e71cba2c..e96200c5b 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -7,7 +7,6 @@ import (
"github.com/containers/image/v5/docker/reference"
"github.com/containers/libpod/libpod/define"
- "github.com/containers/libpod/pkg/api/handlers/libpod"
"github.com/containers/libpod/pkg/bindings/containers"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/pkg/specgen"
@@ -233,7 +232,7 @@ func (ic *ContainerEngine) ContainerCheckpoint(ctx context.Context, namesOrIds [
var (
reports []*entities.CheckpointReport
err error
- ctrs []libpod.ListContainer
+ ctrs []entities.ListContainer
)
if options.All {
@@ -268,7 +267,7 @@ func (ic *ContainerEngine) ContainerRestore(ctx context.Context, namesOrIds []st
var (
reports []*entities.RestoreReport
err error
- ctrs []libpod.ListContainer
+ ctrs []entities.ListContainer
)
if options.All {
allCtrs, err := getContainersByContext(ic.ClientCxt, true, []string{})
@@ -313,3 +312,15 @@ 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")
+}
+
+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")
+}
diff --git a/pkg/domain/infra/tunnel/helpers.go b/pkg/domain/infra/tunnel/helpers.go
index f9183c955..682d60d6a 100644
--- a/pkg/domain/infra/tunnel/helpers.go
+++ b/pkg/domain/infra/tunnel/helpers.go
@@ -5,7 +5,6 @@ import (
"strings"
"github.com/containers/libpod/libpod/define"
- "github.com/containers/libpod/pkg/api/handlers/libpod"
"github.com/containers/libpod/pkg/bindings"
"github.com/containers/libpod/pkg/bindings/containers"
"github.com/containers/libpod/pkg/bindings/pods"
@@ -14,9 +13,9 @@ import (
"github.com/pkg/errors"
)
-func getContainersByContext(contextWithConnection context.Context, all bool, namesOrIds []string) ([]libpod.ListContainer, error) {
+func getContainersByContext(contextWithConnection context.Context, all bool, namesOrIds []string) ([]entities.ListContainer, error) {
var (
- cons []libpod.ListContainer
+ cons []entities.ListContainer
)
if all && len(namesOrIds) > 0 {
return nil, errors.New("cannot lookup containers and all")
diff --git a/pkg/domain/infra/tunnel/system.go b/pkg/domain/infra/tunnel/system.go
index 5bafef1fe..5d6346234 100644
--- a/pkg/domain/infra/tunnel/system.go
+++ b/pkg/domain/infra/tunnel/system.go
@@ -1 +1,12 @@
package tunnel
+
+import (
+ "context"
+
+ "github.com/containers/libpod/libpod/define"
+ "github.com/containers/libpod/pkg/bindings/system"
+)
+
+func (ic *ContainerEngine) Info(ctx context.Context) (*define.Info, error) {
+ return system.Info(ic.ClientCxt)
+}