aboutsummaryrefslogtreecommitdiff
path: root/pkg/domain/infra/tunnel
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/domain/infra/tunnel')
-rw-r--r--pkg/domain/infra/tunnel/containers.go179
-rw-r--r--pkg/domain/infra/tunnel/healthcheck.go13
-rw-r--r--pkg/domain/infra/tunnel/helpers.go34
-rw-r--r--pkg/domain/infra/tunnel/images.go201
-rw-r--r--pkg/domain/infra/tunnel/pods.go196
-rw-r--r--pkg/domain/infra/tunnel/system.go1
6 files changed, 605 insertions, 19 deletions
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index a8ecff41b..4101068ba 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -2,9 +2,16 @@ package tunnel
import (
"context"
+ "io"
+ "os"
+ "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"
+ "github.com/pkg/errors"
)
func (ic *ContainerEngine) ContainerExists(ctx context.Context, nameOrId string) (*entities.BoolReport, error) {
@@ -138,3 +145,175 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
}
return reports, nil
}
+
+func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []string, options entities.InspectOptions) ([]*entities.ContainerInspectReport, error) {
+ var (
+ reports []*entities.ContainerInspectReport
+ )
+ ctrs, err := getContainersByContext(ic.ClientCxt, false, namesOrIds)
+ if err != nil {
+ return nil, err
+ }
+ for _, con := range ctrs {
+ data, err := containers.Inspect(ic.ClientCxt, con.ID, &options.Size)
+ if err != nil {
+ return nil, err
+ }
+ reports = append(reports, &entities.ContainerInspectReport{InspectContainerData: data})
+ }
+ return reports, nil
+}
+
+func (ic *ContainerEngine) ContainerTop(ctx context.Context, options entities.TopOptions) (*entities.StringSliceReport, error) {
+ switch {
+ case options.Latest:
+ return nil, errors.New("latest is not supported")
+ case options.NameOrID == "":
+ return nil, errors.New("NameOrID must be specified")
+ }
+
+ topOutput, err := containers.Top(ic.ClientCxt, options.NameOrID, options.Descriptors)
+ if err != nil {
+ return nil, err
+ }
+ return &entities.StringSliceReport{Value: topOutput}, nil
+}
+
+func (ic *ContainerEngine) ContainerCommit(ctx context.Context, nameOrId string, options entities.CommitOptions) (*entities.CommitReport, error) {
+ var (
+ repo string
+ tag string = "latest"
+ )
+ if len(options.ImageName) > 0 {
+ ref, err := reference.Parse(options.ImageName)
+ if err != nil {
+ return nil, err
+ }
+ if t, ok := ref.(reference.Tagged); ok {
+ tag = t.Tag()
+ }
+ if r, ok := ref.(reference.Named); ok {
+ repo = r.Name()
+ }
+ if len(repo) < 1 {
+ return nil, errors.Errorf("invalid image name %q", options.ImageName)
+ }
+ }
+ commitOpts := containers.CommitOptions{
+ Author: &options.Author,
+ Changes: options.Changes,
+ Comment: &options.Message,
+ Format: &options.Format,
+ Pause: &options.Pause,
+ Repo: &repo,
+ Tag: &tag,
+ }
+ response, err := containers.Commit(ic.ClientCxt, nameOrId, commitOpts)
+ if err != nil {
+ return nil, err
+ }
+ return &entities.CommitReport{Id: response.ID}, nil
+}
+
+func (ic *ContainerEngine) ContainerExport(ctx context.Context, nameOrId string, options entities.ContainerExportOptions) error {
+ var (
+ err error
+ w io.Writer
+ )
+ if len(options.Output) > 0 {
+ w, err = os.Create(options.Output)
+ if err != nil {
+ return err
+ }
+ }
+ return containers.Export(ic.ClientCxt, nameOrId, w)
+}
+
+func (ic *ContainerEngine) ContainerCheckpoint(ctx context.Context, namesOrIds []string, options entities.CheckpointOptions) ([]*entities.CheckpointReport, error) {
+ var (
+ reports []*entities.CheckpointReport
+ err error
+ ctrs []libpod.ListContainer
+ )
+
+ if options.All {
+ allCtrs, err := getContainersByContext(ic.ClientCxt, true, []string{})
+ if err != nil {
+ return nil, err
+ }
+ // narrow the list to running only
+ for _, c := range allCtrs {
+ if c.State == define.ContainerStateRunning.String() {
+ ctrs = append(ctrs, c)
+ }
+ }
+
+ } else {
+ ctrs, err = getContainersByContext(ic.ClientCxt, false, namesOrIds)
+ if err != nil {
+ return nil, err
+ }
+ }
+ for _, c := range ctrs {
+ report, err := containers.Checkpoint(ic.ClientCxt, c.ID, &options.Keep, &options.LeaveRuninng, &options.TCPEstablished, &options.IgnoreRootFS, &options.Export)
+ if err != nil {
+ reports = append(reports, &entities.CheckpointReport{Id: c.ID, Err: err})
+ }
+ reports = append(reports, report)
+ }
+ return reports, nil
+}
+
+func (ic *ContainerEngine) ContainerRestore(ctx context.Context, namesOrIds []string, options entities.RestoreOptions) ([]*entities.RestoreReport, error) {
+ var (
+ reports []*entities.RestoreReport
+ err error
+ ctrs []libpod.ListContainer
+ )
+ if options.All {
+ allCtrs, err := getContainersByContext(ic.ClientCxt, true, []string{})
+ if err != nil {
+ return nil, err
+ }
+ // narrow the list to exited only
+ for _, c := range allCtrs {
+ if c.State == define.ContainerStateExited.String() {
+ ctrs = append(ctrs, c)
+ }
+ }
+
+ } else {
+ ctrs, err = getContainersByContext(ic.ClientCxt, false, namesOrIds)
+ if err != nil {
+ return nil, err
+ }
+ }
+ for _, c := range ctrs {
+ report, err := containers.Restore(ic.ClientCxt, c.ID, &options.Keep, &options.TCPEstablished, &options.IgnoreRootFS, &options.IgnoreStaticIP, &options.IgnoreStaticMAC, &options.Name, &options.Import)
+ if err != nil {
+ reports = append(reports, &entities.RestoreReport{Id: c.ID, Err: err})
+ }
+ reports = append(reports, report)
+ }
+ return reports, nil
+}
+
+func (ic *ContainerEngine) ContainerCreate(ctx context.Context, s *specgen.SpecGenerator) (*entities.ContainerCreateReport, error) {
+ response, err := containers.CreateWithSpec(ic.ClientCxt, s)
+ if err != nil {
+ return nil, err
+ }
+ return &entities.ContainerCreateReport{Id: response.ID}, nil
+}
+
+func (ic *ContainerEngine) ContainerAttach(ctx context.Context, nameOrId string, options entities.AttachOptions) error {
+ return errors.New("not implemented")
+}
+
+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")
+}
diff --git a/pkg/domain/infra/tunnel/healthcheck.go b/pkg/domain/infra/tunnel/healthcheck.go
new file mode 100644
index 000000000..e589489b3
--- /dev/null
+++ b/pkg/domain/infra/tunnel/healthcheck.go
@@ -0,0 +1,13 @@
+package tunnel
+
+import (
+ "context"
+
+ "github.com/containers/libpod/libpod/define"
+ "github.com/containers/libpod/pkg/bindings/containers"
+ "github.com/containers/libpod/pkg/domain/entities"
+)
+
+func (ic *ContainerEngine) HealthCheckRun(ctx context.Context, nameOrId string, options entities.HealthCheckOptions) (*define.HealthCheckResults, error) {
+ return containers.RunHealthCheck(ic.ClientCxt, nameOrId)
+}
diff --git a/pkg/domain/infra/tunnel/helpers.go b/pkg/domain/infra/tunnel/helpers.go
index 11fca5278..f9183c955 100644
--- a/pkg/domain/infra/tunnel/helpers.go
+++ b/pkg/domain/infra/tunnel/helpers.go
@@ -4,9 +4,12 @@ import (
"context"
"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"
+ "github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/pkg/util"
"github.com/pkg/errors"
)
@@ -40,3 +43,34 @@ func getContainersByContext(contextWithConnection context.Context, all bool, nam
}
return cons, nil
}
+
+func getPodsByContext(contextWithConnection context.Context, all bool, namesOrIds []string) ([]*entities.ListPodsReport, error) {
+ var (
+ sPods []*entities.ListPodsReport
+ )
+ if all && len(namesOrIds) > 0 {
+ return nil, errors.New("cannot lookup specific pods and all")
+ }
+
+ fPods, err := pods.List(contextWithConnection, nil)
+ if err != nil {
+ return nil, err
+ }
+ if all {
+ return fPods, nil
+ }
+ for _, nameOrId := range namesOrIds {
+ var found bool
+ for _, f := range fPods {
+ if f.Name == nameOrId || strings.HasPrefix(f.Id, nameOrId) {
+ sPods = append(sPods, f)
+ found = true
+ break
+ }
+ }
+ if !found {
+ return nil, errors.Wrapf(define.ErrNoSuchPod, "unable to find pod %q", nameOrId)
+ }
+ }
+ return sPods, nil
+}
diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go
index 60df40498..516914a68 100644
--- a/pkg/domain/infra/tunnel/images.go
+++ b/pkg/domain/infra/tunnel/images.go
@@ -2,34 +2,41 @@ package tunnel
import (
"context"
- "net/url"
+ "io/ioutil"
+ "os"
+ "github.com/containers/image/v5/docker/reference"
images "github.com/containers/libpod/pkg/bindings/images"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/pkg/domain/utils"
+ utils2 "github.com/containers/libpod/utils"
+ "github.com/pkg/errors"
)
-func (ir *ImageEngine) Delete(ctx context.Context, nameOrId string, opts entities.ImageDeleteOptions) (*entities.ImageDeleteReport, error) {
- results, err := images.Remove(ir.ClientCxt, nameOrId, &opts.Force)
- if err != nil {
- return nil, err
- }
+func (ir *ImageEngine) Exists(_ context.Context, nameOrId string) (*entities.BoolReport, error) {
+ found, err := images.Exists(ir.ClientCxt, nameOrId)
+ return &entities.BoolReport{Value: found}, err
+}
- report := entities.ImageDeleteReport{
- Untagged: nil,
- Deleted: "",
- }
+func (ir *ImageEngine) Delete(ctx context.Context, nameOrId []string, opts entities.ImageDeleteOptions) (*entities.ImageDeleteReport, error) {
+ report := entities.ImageDeleteReport{}
- for _, e := range results {
- if a, ok := e["Deleted"]; ok {
- report.Deleted = a
+ for _, id := range nameOrId {
+ results, err := images.Remove(ir.ClientCxt, id, &opts.Force)
+ if err != nil {
+ return nil, err
}
+ for _, e := range results {
+ if a, ok := e["Deleted"]; ok {
+ report.Deleted = append(report.Deleted, a)
+ }
- if a, ok := e["Untagged"]; ok {
- report.Untagged = append(report.Untagged, a)
+ if a, ok := e["Untagged"]; ok {
+ report.Untagged = append(report.Untagged, a)
+ }
}
}
- return &report, err
+ return &report, nil
}
func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions) ([]*entities.ImageSummary, error) {
@@ -69,12 +76,168 @@ func (ir *ImageEngine) History(ctx context.Context, nameOrId string, opts entiti
}
func (ir *ImageEngine) Prune(ctx context.Context, opts entities.ImagePruneOptions) (*entities.ImagePruneReport, error) {
- results, err := images.Prune(ir.ClientCxt, url.Values{})
+ results, err := images.Prune(ir.ClientCxt, &opts.All, opts.Filters)
+ if err != nil {
+ return nil, err
+ }
+
+ report := entities.ImagePruneReport{
+ Report: entities.Report{
+ Id: results,
+ Err: nil,
+ },
+ Size: 0,
+ }
+ return &report, nil
+}
+
+func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entities.ImagePullOptions) (*entities.ImagePullReport, error) {
+ pulledImages, err := images.Pull(ir.ClientCxt, rawImage, options)
if err != nil {
return nil, err
}
+ return &entities.ImagePullReport{Images: pulledImages}, nil
+}
+
+func (ir *ImageEngine) Tag(ctx context.Context, nameOrId string, tags []string, options entities.ImageTagOptions) error {
+ for _, newTag := range tags {
+ var (
+ tag, repo string
+ )
+ ref, err := reference.Parse(newTag)
+ if err != nil {
+ return err
+ }
+ if t, ok := ref.(reference.Tagged); ok {
+ tag = t.Tag()
+ }
+ if r, ok := ref.(reference.Named); ok {
+ repo = r.Name()
+ }
+ if len(repo) < 1 {
+ return errors.Errorf("invalid image name %q", nameOrId)
+ }
+ if err := images.Tag(ir.ClientCxt, nameOrId, tag, repo); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (ir *ImageEngine) Untag(ctx context.Context, nameOrId string, tags []string, options entities.ImageUntagOptions) error {
+ for _, newTag := range tags {
+ var (
+ tag, repo string
+ )
+ ref, err := reference.Parse(newTag)
+ if err != nil {
+ return err
+ }
+ if t, ok := ref.(reference.Tagged); ok {
+ tag = t.Tag()
+ }
+ if r, ok := ref.(reference.Named); ok {
+ repo = r.Name()
+ }
+ if len(repo) < 1 {
+ return errors.Errorf("invalid image name %q", nameOrId)
+ }
+ if err := images.Untag(ir.ClientCxt, nameOrId, tag, repo); err != nil {
+ return err
+ }
+ }
+ return nil
+}
- report := entities.ImagePruneReport{}
- copy(report.Report.Id, results)
+func (ir *ImageEngine) Inspect(_ context.Context, names []string, opts entities.InspectOptions) (*entities.ImageInspectReport, error) {
+ report := entities.ImageInspectReport{}
+ for _, id := range names {
+ r, err := images.GetImage(ir.ClientCxt, id, &opts.Size)
+ if err != nil {
+ report.Errors[id] = err
+ }
+ report.Images = append(report.Images, r)
+ }
return &report, nil
}
+
+func (ir *ImageEngine) Load(ctx context.Context, opts entities.ImageLoadOptions) (*entities.ImageLoadReport, error) {
+ f, err := os.Open(opts.Input)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+ return images.Load(ir.ClientCxt, f, &opts.Name)
+}
+
+func (ir *ImageEngine) Import(ctx context.Context, opts entities.ImageImportOptions) (*entities.ImageImportReport, error) {
+ var (
+ err error
+ sourceURL *string
+ f *os.File
+ )
+ if opts.SourceIsURL {
+ sourceURL = &opts.Source
+ } else {
+ f, err = os.Open(opts.Source)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return images.Import(ir.ClientCxt, opts.Changes, &opts.Message, &opts.Reference, sourceURL, f)
+}
+
+func (ir *ImageEngine) Push(ctx context.Context, source string, destination string, options entities.ImagePushOptions) error {
+ return images.Push(ir.ClientCxt, source, destination, options)
+}
+
+func (ir *ImageEngine) Save(ctx context.Context, nameOrId string, tags []string, options entities.ImageSaveOptions) error {
+ var (
+ f *os.File
+ err error
+ )
+
+ switch options.Format {
+ case "oci-dir", "docker-dir":
+ f, err = ioutil.TempFile("", "podman_save")
+ if err == nil {
+ defer func() { _ = os.Remove(f.Name()) }()
+ }
+ default:
+ f, err = os.Create(options.Output)
+ }
+ if err != nil {
+ return err
+ }
+
+ exErr := images.Export(ir.ClientCxt, nameOrId, f, &options.Format, &options.Compress)
+ if err := f.Close(); err != nil {
+ return err
+ }
+ if exErr != nil {
+ return exErr
+ }
+
+ if options.Format != "oci-dir" && options.Format != "docker-dir" {
+ return nil
+ }
+
+ f, err = os.Open(f.Name())
+ if err != nil {
+ return err
+ }
+ info, err := os.Stat(options.Output)
+ switch {
+ case err == nil:
+ if info.Mode().IsRegular() {
+ return errors.Errorf("%q already exists as a regular file", options.Output)
+ }
+ case os.IsNotExist(err):
+ if err := os.Mkdir(options.Output, 0755); err != nil {
+ return err
+ }
+ default:
+ return err
+ }
+ return utils2.UntarToFileSystem(options.Output, f, nil)
+}
diff --git a/pkg/domain/infra/tunnel/pods.go b/pkg/domain/infra/tunnel/pods.go
index 500069d51..dad77284f 100644
--- a/pkg/domain/infra/tunnel/pods.go
+++ b/pkg/domain/infra/tunnel/pods.go
@@ -5,9 +5,205 @@ import (
"github.com/containers/libpod/pkg/bindings/pods"
"github.com/containers/libpod/pkg/domain/entities"
+ "github.com/containers/libpod/pkg/specgen"
+ "github.com/pkg/errors"
)
func (ic *ContainerEngine) PodExists(ctx context.Context, nameOrId string) (*entities.BoolReport, error) {
exists, err := pods.Exists(ic.ClientCxt, nameOrId)
return &entities.BoolReport{Value: exists}, err
}
+
+func (ic *ContainerEngine) PodKill(ctx context.Context, namesOrIds []string, options entities.PodKillOptions) ([]*entities.PodKillReport, error) {
+ var (
+ reports []*entities.PodKillReport
+ )
+ foundPods, err := getPodsByContext(ic.ClientCxt, options.All, namesOrIds)
+ if err != nil {
+ return nil, err
+ }
+ for _, p := range foundPods {
+ response, err := pods.Kill(ic.ClientCxt, p.Id, &options.Signal)
+ if err != nil {
+ report := entities.PodKillReport{
+ Errs: []error{err},
+ Id: p.Id,
+ }
+ reports = append(reports, &report)
+ continue
+ }
+ reports = append(reports, response)
+ }
+ return reports, nil
+}
+
+func (ic *ContainerEngine) PodPause(ctx context.Context, namesOrIds []string, options entities.PodPauseOptions) ([]*entities.PodPauseReport, error) {
+ var (
+ reports []*entities.PodPauseReport
+ )
+ foundPods, err := getPodsByContext(ic.ClientCxt, options.All, namesOrIds)
+ if err != nil {
+ return nil, err
+ }
+ for _, p := range foundPods {
+ response, err := pods.Pause(ic.ClientCxt, p.Id)
+ if err != nil {
+ report := entities.PodPauseReport{
+ Errs: []error{err},
+ Id: p.Id,
+ }
+ reports = append(reports, &report)
+ continue
+ }
+ reports = append(reports, response)
+ }
+ return reports, nil
+}
+
+func (ic *ContainerEngine) PodUnpause(ctx context.Context, namesOrIds []string, options entities.PodunpauseOptions) ([]*entities.PodUnpauseReport, error) {
+ var (
+ reports []*entities.PodUnpauseReport
+ )
+ foundPods, err := getPodsByContext(ic.ClientCxt, options.All, namesOrIds)
+ if err != nil {
+ return nil, err
+ }
+ for _, p := range foundPods {
+ response, err := pods.Unpause(ic.ClientCxt, p.Id)
+ if err != nil {
+ report := entities.PodUnpauseReport{
+ Errs: []error{err},
+ Id: p.Id,
+ }
+ reports = append(reports, &report)
+ continue
+ }
+ reports = append(reports, response)
+ }
+ return reports, nil
+}
+
+func (ic *ContainerEngine) PodStop(ctx context.Context, namesOrIds []string, options entities.PodStopOptions) ([]*entities.PodStopReport, error) {
+ var (
+ reports []*entities.PodStopReport
+ timeout int = -1
+ )
+ foundPods, err := getPodsByContext(ic.ClientCxt, options.All, namesOrIds)
+ if err != nil {
+ return nil, err
+ }
+ if options.Timeout != -1 {
+ timeout = options.Timeout
+ }
+ for _, p := range foundPods {
+ response, err := pods.Stop(ic.ClientCxt, p.Id, &timeout)
+ if err != nil {
+ report := entities.PodStopReport{
+ Errs: []error{err},
+ Id: p.Id,
+ }
+ reports = append(reports, &report)
+ continue
+ }
+ reports = append(reports, response)
+ }
+ return reports, nil
+}
+
+func (ic *ContainerEngine) PodRestart(ctx context.Context, namesOrIds []string, options entities.PodRestartOptions) ([]*entities.PodRestartReport, error) {
+ var reports []*entities.PodRestartReport
+ foundPods, err := getPodsByContext(ic.ClientCxt, options.All, namesOrIds)
+ if err != nil {
+ return nil, err
+ }
+ for _, p := range foundPods {
+ response, err := pods.Restart(ic.ClientCxt, p.Id)
+ if err != nil {
+ report := entities.PodRestartReport{
+ Errs: []error{err},
+ Id: p.Id,
+ }
+ reports = append(reports, &report)
+ continue
+ }
+ reports = append(reports, response)
+ }
+ return reports, nil
+}
+
+func (ic *ContainerEngine) PodStart(ctx context.Context, namesOrIds []string, options entities.PodStartOptions) ([]*entities.PodStartReport, error) {
+ var reports []*entities.PodStartReport
+ foundPods, err := getPodsByContext(ic.ClientCxt, options.All, namesOrIds)
+ if err != nil {
+ return nil, err
+ }
+ for _, p := range foundPods {
+ response, err := pods.Start(ic.ClientCxt, p.Id)
+ if err != nil {
+ report := entities.PodStartReport{
+ Errs: []error{err},
+ Id: p.Id,
+ }
+ reports = append(reports, &report)
+ continue
+ }
+ reports = append(reports, response)
+ }
+ return reports, nil
+}
+
+func (ic *ContainerEngine) PodRm(ctx context.Context, namesOrIds []string, options entities.PodRmOptions) ([]*entities.PodRmReport, error) {
+ var reports []*entities.PodRmReport
+ foundPods, err := getPodsByContext(ic.ClientCxt, options.All, namesOrIds)
+ if err != nil {
+ return nil, err
+ }
+ for _, p := range foundPods {
+ response, err := pods.Remove(ic.ClientCxt, p.Id, &options.Force)
+ if err != nil {
+ report := entities.PodRmReport{
+ Err: err,
+ Id: p.Id,
+ }
+ reports = append(reports, &report)
+ continue
+ }
+ reports = append(reports, response)
+ }
+ return reports, nil
+}
+
+func (ic *ContainerEngine) PodCreate(ctx context.Context, opts entities.PodCreateOptions) (*entities.PodCreateReport, error) {
+ podSpec := specgen.NewPodSpecGenerator()
+ opts.ToPodSpecGen(podSpec)
+ return pods.CreatePodFromSpec(ic.ClientCxt, podSpec)
+}
+
+func (ic *ContainerEngine) PodTop(ctx context.Context, options entities.PodTopOptions) (*entities.StringSliceReport, error) {
+ switch {
+ case options.Latest:
+ return nil, errors.New("latest is not supported")
+ case options.NameOrID == "":
+ return nil, errors.New("NameOrID must be specified")
+ }
+
+ topOutput, err := pods.Top(ic.ClientCxt, options.NameOrID, options.Descriptors)
+ if err != nil {
+ return nil, err
+ }
+ return &entities.StringSliceReport{Value: topOutput}, nil
+}
+
+func (ic *ContainerEngine) PodPs(ctx context.Context, options entities.PodPSOptions) ([]*entities.ListPodsReport, error) {
+ return pods.List(ic.ClientCxt, options.Filters)
+}
+
+func (ic *ContainerEngine) PodInspect(ctx context.Context, options entities.PodInspectOptions) (*entities.PodInspectReport, error) {
+ switch {
+ case options.Latest:
+ return nil, errors.New("latest is not supported")
+ case options.NameOrID == "":
+ return nil, errors.New("NameOrID must be specified")
+ }
+ return pods.Inspect(ic.ClientCxt, options.NameOrID)
+}
diff --git a/pkg/domain/infra/tunnel/system.go b/pkg/domain/infra/tunnel/system.go
new file mode 100644
index 000000000..5bafef1fe
--- /dev/null
+++ b/pkg/domain/infra/tunnel/system.go
@@ -0,0 +1 @@
+package tunnel