summaryrefslogtreecommitdiff
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.go212
-rw-r--r--pkg/domain/infra/tunnel/helpers.go76
-rw-r--r--pkg/domain/infra/tunnel/images.go87
-rw-r--r--pkg/domain/infra/tunnel/pods.go179
-rw-r--r--pkg/domain/infra/tunnel/runtime.go15
-rw-r--r--pkg/domain/infra/tunnel/volumes.go70
6 files changed, 639 insertions, 0 deletions
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
new file mode 100644
index 000000000..3c8be90dc
--- /dev/null
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -0,0 +1,212 @@
+package tunnel
+
+import (
+ "context"
+
+ "github.com/containers/image/v5/docker/reference"
+
+ "github.com/containers/libpod/pkg/bindings/containers"
+ "github.com/containers/libpod/pkg/domain/entities"
+ "github.com/pkg/errors"
+)
+
+func (ic *ContainerEngine) ContainerExists(ctx context.Context, nameOrId string) (*entities.BoolReport, error) {
+ exists, err := containers.Exists(ic.ClientCxt, nameOrId)
+ return &entities.BoolReport{Value: exists}, err
+}
+
+func (ic *ContainerEngine) ContainerWait(ctx context.Context, namesOrIds []string, options entities.WaitOptions) ([]entities.WaitReport, error) {
+ var (
+ responses []entities.WaitReport
+ )
+ cons, err := getContainersByContext(ic.ClientCxt, false, namesOrIds)
+ if err != nil {
+ return nil, err
+ }
+ for _, c := range cons {
+ response := entities.WaitReport{Id: c.ID}
+ exitCode, err := containers.Wait(ic.ClientCxt, c.ID, &options.Condition)
+ if err != nil {
+ response.Error = err
+ } else {
+ response.ExitCode = exitCode
+ }
+ responses = append(responses, response)
+ }
+ return responses, nil
+}
+
+func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []string, options entities.PauseUnPauseOptions) ([]*entities.PauseUnpauseReport, error) {
+ var (
+ reports []*entities.PauseUnpauseReport
+ )
+ ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds)
+ if err != nil {
+ return nil, err
+ }
+ for _, c := range ctrs {
+ err := containers.Pause(ic.ClientCxt, c.ID)
+ reports = append(reports, &entities.PauseUnpauseReport{Id: c.ID, Err: err})
+ }
+ return reports, nil
+}
+
+func (ic *ContainerEngine) ContainerUnpause(ctx context.Context, namesOrIds []string, options entities.PauseUnPauseOptions) ([]*entities.PauseUnpauseReport, error) {
+ var (
+ reports []*entities.PauseUnpauseReport
+ )
+ ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds)
+ if err != nil {
+ return nil, err
+ }
+ for _, c := range ctrs {
+ err := containers.Unpause(ic.ClientCxt, c.ID)
+ reports = append(reports, &entities.PauseUnpauseReport{Id: c.ID, Err: err})
+ }
+ return reports, nil
+}
+
+func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []string, options entities.StopOptions) ([]*entities.StopReport, error) {
+ var (
+ reports []*entities.StopReport
+ )
+ ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds)
+ if err != nil {
+ return nil, err
+ }
+ for _, c := range ctrs {
+ report := entities.StopReport{Id: c.ID}
+ report.Err = containers.Stop(ic.ClientCxt, c.ID, &options.Timeout)
+ // TODO we need to associate errors returned by http with common
+ // define.errors so that we can equity tests. this will allow output
+ // to be the same as the native client
+ reports = append(reports, &report)
+ }
+ return reports, nil
+}
+
+func (ic *ContainerEngine) ContainerKill(ctx context.Context, namesOrIds []string, options entities.KillOptions) ([]*entities.KillReport, error) {
+ var (
+ reports []*entities.KillReport
+ )
+ ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds)
+ if err != nil {
+ return nil, err
+ }
+ for _, c := range ctrs {
+ reports = append(reports, &entities.KillReport{
+ Id: c.ID,
+ Err: containers.Kill(ic.ClientCxt, c.ID, options.Signal),
+ })
+ }
+ return reports, nil
+}
+
+func (ic *ContainerEngine) ContainerRestart(ctx context.Context, namesOrIds []string, options entities.RestartOptions) ([]*entities.RestartReport, error) {
+ var (
+ reports []*entities.RestartReport
+ timeout *int
+ )
+ if options.Timeout != nil {
+ t := int(*options.Timeout)
+ timeout = &t
+ }
+ ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds)
+ if err != nil {
+ return nil, err
+ }
+ for _, c := range ctrs {
+ reports = append(reports, &entities.RestartReport{
+ Id: c.ID,
+ Err: containers.Restart(ic.ClientCxt, c.ID, timeout),
+ })
+ }
+ return reports, nil
+}
+
+func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string, options entities.RmOptions) ([]*entities.RmReport, error) {
+ var (
+ reports []*entities.RmReport
+ )
+ ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds)
+ if err != nil {
+ return nil, err
+ }
+ // TODO there is no endpoint for container eviction. Need to discuss
+ for _, c := range ctrs {
+ reports = append(reports, &entities.RmReport{
+ Id: c.ID,
+ Err: containers.Remove(ic.ClientCxt, c.ID, &options.Force, &options.Volumes),
+ })
+ }
+ return reports, nil
+}
+
+func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []string, options entities.ContainerInspectOptions) ([]*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
+}
diff --git a/pkg/domain/infra/tunnel/helpers.go b/pkg/domain/infra/tunnel/helpers.go
new file mode 100644
index 000000000..f9183c955
--- /dev/null
+++ b/pkg/domain/infra/tunnel/helpers.go
@@ -0,0 +1,76 @@
+package tunnel
+
+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"
+)
+
+func getContainersByContext(contextWithConnection context.Context, all bool, namesOrIds []string) ([]libpod.ListContainer, error) {
+ var (
+ cons []libpod.ListContainer
+ )
+ if all && len(namesOrIds) > 0 {
+ return nil, errors.New("cannot lookup containers and all")
+ }
+ c, err := containers.List(contextWithConnection, nil, &bindings.PTrue, nil, nil, nil, &bindings.PTrue)
+ if err != nil {
+ return nil, err
+ }
+ if all {
+ return c, err
+ }
+ for _, id := range namesOrIds {
+ var found bool
+ for _, con := range c {
+ if id == con.ID || strings.HasPrefix(con.ID, id) || util.StringInSlice(id, con.Names) {
+ cons = append(cons, con)
+ found = true
+ break
+ }
+ }
+ if !found {
+ return nil, errors.Errorf("unable to find container %q", id)
+ }
+ }
+ 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
new file mode 100644
index 000000000..6a3adc9ee
--- /dev/null
+++ b/pkg/domain/infra/tunnel/images.go
@@ -0,0 +1,87 @@
+package tunnel
+
+import (
+ "context"
+
+ images "github.com/containers/libpod/pkg/bindings/images"
+ "github.com/containers/libpod/pkg/domain/entities"
+ "github.com/containers/libpod/pkg/domain/utils"
+)
+
+func (ir *ImageEngine) Exists(_ context.Context, nameOrId string) (*entities.BoolReport, error) {
+ found, err := images.Exists(ir.ClientCxt, nameOrId)
+ return &entities.BoolReport{Value: found}, err
+}
+
+func (ir *ImageEngine) Delete(ctx context.Context, nameOrId []string, opts entities.ImageDeleteOptions) (*entities.ImageDeleteReport, error) {
+ report := entities.ImageDeleteReport{}
+
+ 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)
+ }
+ }
+ }
+ return &report, nil
+}
+
+func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions) ([]*entities.ImageSummary, error) {
+ images, err := images.List(ir.ClientCxt, &opts.All, opts.Filters)
+
+ if err != nil {
+ return nil, err
+ }
+
+ is := make([]*entities.ImageSummary, len(images))
+ for i, img := range images {
+ hold := entities.ImageSummary{}
+ if err := utils.DeepCopy(&hold, img); err != nil {
+ return nil, err
+ }
+ is[i] = &hold
+ }
+ return is, nil
+}
+
+func (ir *ImageEngine) History(ctx context.Context, nameOrId string, opts entities.ImageHistoryOptions) (*entities.ImageHistoryReport, error) {
+ results, err := images.History(ir.ClientCxt, nameOrId)
+ if err != nil {
+ return nil, err
+ }
+
+ history := entities.ImageHistoryReport{
+ Layers: make([]entities.ImageHistoryLayer, len(results)),
+ }
+
+ for i, layer := range results {
+ hold := entities.ImageHistoryLayer{}
+ _ = utils.DeepCopy(&hold, layer)
+ history.Layers[i] = hold
+ }
+ return &history, nil
+}
+
+func (ir *ImageEngine) Prune(ctx context.Context, opts entities.ImagePruneOptions) (*entities.ImagePruneReport, error) {
+ 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
+}
diff --git a/pkg/domain/infra/tunnel/pods.go b/pkg/domain/infra/tunnel/pods.go
new file mode 100644
index 000000000..4894874e5
--- /dev/null
+++ b/pkg/domain/infra/tunnel/pods.go
@@ -0,0 +1,179 @@
+package tunnel
+
+import (
+ "context"
+
+ "github.com/containers/libpod/pkg/bindings/pods"
+ "github.com/containers/libpod/pkg/domain/entities"
+ "github.com/containers/libpod/pkg/specgen"
+)
+
+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)
+}
diff --git a/pkg/domain/infra/tunnel/runtime.go b/pkg/domain/infra/tunnel/runtime.go
new file mode 100644
index 000000000..c111f99e9
--- /dev/null
+++ b/pkg/domain/infra/tunnel/runtime.go
@@ -0,0 +1,15 @@
+package tunnel
+
+import (
+ "context"
+)
+
+// Image-related runtime using an ssh-tunnel to utilize Podman service
+type ImageEngine struct {
+ ClientCxt context.Context
+}
+
+// Container-related runtime using an ssh-tunnel to utilize Podman service
+type ContainerEngine struct {
+ ClientCxt context.Context
+}
diff --git a/pkg/domain/infra/tunnel/volumes.go b/pkg/domain/infra/tunnel/volumes.go
new file mode 100644
index 000000000..e48a7fa7c
--- /dev/null
+++ b/pkg/domain/infra/tunnel/volumes.go
@@ -0,0 +1,70 @@
+package tunnel
+
+import (
+ "context"
+
+ "github.com/containers/libpod/pkg/bindings/volumes"
+ "github.com/containers/libpod/pkg/domain/entities"
+)
+
+func (ic *ContainerEngine) VolumeCreate(ctx context.Context, opts entities.VolumeCreateOptions) (*entities.IdOrNameResponse, error) {
+ response, err := volumes.Create(ic.ClientCxt, opts)
+ if err != nil {
+ return nil, err
+ }
+ return &entities.IdOrNameResponse{IdOrName: response.Name}, nil
+}
+
+func (ic *ContainerEngine) VolumeRm(ctx context.Context, namesOrIds []string, opts entities.VolumeRmOptions) ([]*entities.VolumeRmReport, error) {
+ var (
+ reports []*entities.VolumeRmReport
+ )
+
+ if opts.All {
+ vols, err := volumes.List(ic.ClientCxt, nil)
+ if err != nil {
+ return nil, err
+ }
+ for _, v := range vols {
+ namesOrIds = append(namesOrIds, v.Name)
+ }
+ }
+ for _, id := range namesOrIds {
+ reports = append(reports, &entities.VolumeRmReport{
+ Err: volumes.Remove(ic.ClientCxt, id, &opts.Force),
+ Id: id,
+ })
+ }
+ return reports, nil
+}
+
+func (ic *ContainerEngine) VolumeInspect(ctx context.Context, namesOrIds []string, opts entities.VolumeInspectOptions) ([]*entities.VolumeInspectReport, error) {
+ var (
+ reports []*entities.VolumeInspectReport
+ )
+ if opts.All {
+ vols, err := volumes.List(ic.ClientCxt, nil)
+ if err != nil {
+ return nil, err
+ }
+ for _, v := range vols {
+ namesOrIds = append(namesOrIds, v.Name)
+ }
+ }
+ for _, id := range namesOrIds {
+ data, err := volumes.Inspect(ic.ClientCxt, id)
+ if err != nil {
+ return nil, err
+ }
+ reports = append(reports, &entities.VolumeInspectReport{VolumeConfigResponse: data})
+ }
+ return reports, nil
+}
+
+func (ic *ContainerEngine) VolumePrune(ctx context.Context, opts entities.VolumePruneOptions) ([]*entities.VolumePruneReport, error) {
+ return volumes.Prune(ic.ClientCxt)
+}
+
+func (ic *ContainerEngine) VolumeList(ctx context.Context, opts entities.VolumeListOptions) ([]*entities.VolumeListReport, error) {
+ return volumes.List(ic.ClientCxt, opts.Filter)
+}