diff options
Diffstat (limited to 'pkg/domain/infra/tunnel')
-rw-r--r-- | pkg/domain/infra/tunnel/auto-update.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/containers.go | 132 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/helpers.go | 4 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/images.go | 25 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/manifest.go | 31 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/network.go | 27 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/runtime.go | 5 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/system.go | 7 |
8 files changed, 181 insertions, 52 deletions
diff --git a/pkg/domain/infra/tunnel/auto-update.go b/pkg/domain/infra/tunnel/auto-update.go index fac033050..5c2dd360d 100644 --- a/pkg/domain/infra/tunnel/auto-update.go +++ b/pkg/domain/infra/tunnel/auto-update.go @@ -7,6 +7,6 @@ import ( "github.com/pkg/errors" ) -func (ic *ContainerEngine) AutoUpdate(ctx context.Context) (*entities.AutoUpdateReport, []error) { +func (ic *ContainerEngine) AutoUpdate(ctx context.Context, options entities.AutoUpdateOptions) (*entities.AutoUpdateReport, []error) { return nil, []error{errors.New("not implemented")} } diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index 49a3069d6..30c4a8359 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -4,14 +4,17 @@ import ( "context" "io" "os" + "strings" "github.com/containers/common/pkg/config" "github.com/containers/image/v5/docker/reference" "github.com/containers/libpod/libpod/define" + "github.com/containers/libpod/pkg/bindings" "github.com/containers/libpod/pkg/bindings/containers" "github.com/containers/libpod/pkg/domain/entities" "github.com/containers/libpod/pkg/specgen" "github.com/pkg/errors" + "github.com/sirupsen/logrus" ) func (ic *ContainerEngine) ContainerRunlabel(ctx context.Context, label string, image string, args []string, options entities.ContainerRunlabelOptions) error { @@ -84,10 +87,25 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin } 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 + if err = containers.Stop(ic.ClientCxt, c.ID, &options.Timeout); err != nil { + // These first two are considered non-fatal under the right conditions + if errors.Cause(err).Error() == define.ErrCtrStopped.Error() { + logrus.Debugf("Container %s is already stopped", c.ID) + reports = append(reports, &report) + continue + } else if options.All && errors.Cause(err).Error() == define.ErrCtrStateInvalid.Error() { + logrus.Debugf("Container %s is not running, could not stop", c.ID) + reports = append(reports, &report) + continue + } + + // 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 + report.Err = err + reports = append(reports, &report) + continue + } reports = append(reports, &report) } return reports, nil @@ -267,7 +285,7 @@ func (ic *ContainerEngine) ContainerCheckpoint(ctx context.Context, namesOrIds [ } } for _, c := range ctrs { - report, err := containers.Checkpoint(ic.ClientCxt, c.ID, &options.Keep, &options.LeaveRuninng, &options.TCPEstablished, &options.IgnoreRootFS, &options.Export) + report, err := containers.Checkpoint(ic.ClientCxt, c.ID, &options.Keep, &options.LeaveRunning, &options.TCPEstablished, &options.IgnoreRootFS, &options.Export) if err != nil { reports = append(reports, &entities.CheckpointReport{Id: c.ID, Err: err}) } @@ -324,15 +342,59 @@ func (ic *ContainerEngine) ContainerLogs(ctx context.Context, containers []strin } func (ic *ContainerEngine) ContainerAttach(ctx context.Context, nameOrId string, options entities.AttachOptions) error { - return errors.New("not implemented") + return containers.Attach(ic.ClientCxt, nameOrId, &options.DetachKeys, nil, bindings.PTrue, options.Stdin, options.Stdout, options.Stderr, nil) } -func (ic *ContainerEngine) ContainerExec(ctx context.Context, nameOrId string, options entities.ExecOptions) (int, error) { +func (ic *ContainerEngine) ContainerExec(ctx context.Context, nameOrId string, options entities.ExecOptions, streams define.AttachStreams) (int, error) { return 125, errors.New("not implemented") } +func (ic *ContainerEngine) ContainerExecDetached(ctx context.Context, nameOrID string, options entities.ExecOptions) (string, error) { + return "", errors.New("not implemented") +} + +func startAndAttach(ic *ContainerEngine, name string, detachKeys *string, input, output, errput *os.File) error { //nolint + attachErr := make(chan error) + attachReady := make(chan bool) + go func() { + err := containers.Attach(ic.ClientCxt, name, detachKeys, bindings.PFalse, bindings.PTrue, input, output, errput, attachReady) + attachErr <- err + }() + // Wait for the attach to actually happen before starting + // the container. + <-attachReady + if err := containers.Start(ic.ClientCxt, name, detachKeys); err != nil { + return err + } + return <-attachErr +} + func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []string, options entities.ContainerStartOptions) ([]*entities.ContainerStartReport, error) { - return nil, errors.New("not implemented") + var reports []*entities.ContainerStartReport + for _, name := range namesOrIds { + report := entities.ContainerStartReport{ + Id: name, + RawInput: name, + ExitCode: 125, + } + if options.Attach { + report.Err = startAndAttach(ic, name, &options.DetachKeys, options.Stdin, options.Stdout, options.Stderr) + if report.Err == nil { + exitCode, err := containers.Wait(ic.ClientCxt, name, nil) + if err == nil { + report.ExitCode = int(exitCode) + } + } else { + report.ExitCode = define.ExitCode(report.Err) + } + reports = append(reports, &report) + return reports, nil + } + report.Err = containers.Start(ic.ClientCxt, name, &options.DetachKeys) + report.ExitCode = define.ExitCode(report.Err) + reports = append(reports, &report) + } + return reports, nil } func (ic *ContainerEngine) ContainerList(ctx context.Context, options entities.ContainerListOptions) ([]entities.ListContainer, error) { @@ -340,7 +402,30 @@ func (ic *ContainerEngine) ContainerList(ctx context.Context, options entities.C } func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.ContainerRunOptions) (*entities.ContainerRunReport, error) { - return nil, errors.New("not implemented") + if opts.Rm { + logrus.Info("the remote client does not support --rm yet") + } + con, err := containers.CreateWithSpec(ic.ClientCxt, opts.Spec) + if err != nil { + return nil, err + } + report := entities.ContainerRunReport{Id: con.ID} + // Attach + if !opts.Detach { + err = startAndAttach(ic, con.ID, &opts.DetachKeys, opts.InputStream, opts.OutputStream, opts.ErrorStream) + if err == nil { + exitCode, err := containers.Wait(ic.ClientCxt, con.ID, nil) + if err == nil { + report.ExitCode = int(exitCode) + } + } + } else { + err = containers.Start(ic.ClientCxt, con.ID, nil) + } + if err != nil { + report.ExitCode = define.ExitCode(err) + } + return &report, err } func (ic *ContainerEngine) ContainerDiff(ctx context.Context, nameOrId string, _ entities.DiffOptions) (*entities.DiffReport, error) { @@ -360,6 +445,11 @@ func (ic *ContainerEngine) ContainerInit(ctx context.Context, namesOrIds []strin } for _, ctr := range ctrs { err := containers.ContainerInit(ic.ClientCxt, ctr.ID) + // When using all, it is NOT considered an error if a container + // has already been init'd. + if err != nil && options.All && strings.Contains(errors.Cause(err).Error(), define.ErrCtrStateInvalid.Error()) { + err = nil + } reports = append(reports, &entities.ContainerInitReport{ Err: err, Id: ctr.ID, @@ -381,7 +471,29 @@ func (ic *ContainerEngine) Config(_ context.Context) (*config.Config, error) { } func (ic *ContainerEngine) ContainerPort(ctx context.Context, nameOrId string, options entities.ContainerPortOptions) ([]*entities.ContainerPortReport, error) { - return nil, errors.New("not implemented") + var ( + reports []*entities.ContainerPortReport + namesOrIds []string + ) + if len(nameOrId) > 0 { + namesOrIds = append(namesOrIds, nameOrId) + } + ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds) + if err != nil { + return nil, err + } + for _, con := range ctrs { + if con.State != define.ContainerStateRunning.String() { + continue + } + if len(con.Ports) > 0 { + reports = append(reports, &entities.ContainerPortReport{ + Id: con.ID, + Ports: con.Ports, + }) + } + } + return reports, nil } func (ic *ContainerEngine) ContainerCp(ctx context.Context, source, dest string, options entities.ContainerCpOptions) (*entities.ContainerCpReport, error) { diff --git a/pkg/domain/infra/tunnel/helpers.go b/pkg/domain/infra/tunnel/helpers.go index 682d60d6a..862c7a5d6 100644 --- a/pkg/domain/infra/tunnel/helpers.go +++ b/pkg/domain/infra/tunnel/helpers.go @@ -20,7 +20,7 @@ func getContainersByContext(contextWithConnection context.Context, all bool, nam 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) + c, err := containers.List(contextWithConnection, nil, bindings.PTrue, nil, nil, nil, bindings.PTrue) if err != nil { return nil, err } @@ -37,7 +37,7 @@ func getContainersByContext(contextWithConnection context.Context, all bool, nam } } if !found { - return nil, errors.Errorf("unable to find container %q", id) + return nil, errors.Wrapf(define.ErrNoSuchCtr, "unable to find container %q", id) } } return cons, nil diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go index 00893194c..3d5626c45 100644 --- a/pkg/domain/infra/tunnel/images.go +++ b/pkg/domain/infra/tunnel/images.go @@ -4,6 +4,7 @@ import ( "context" "io/ioutil" "os" + "strings" "github.com/containers/common/pkg/config" "github.com/containers/image/v5/docker/reference" @@ -25,8 +26,13 @@ func (ir *ImageEngine) Remove(ctx context.Context, imagesArg []string, opts enti } func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions) ([]*entities.ImageSummary, error) { - images, err := images.List(ir.ClientCxt, &opts.All, opts.Filters) + filters := make(map[string][]string, len(opts.Filter)) + for _, filter := range opts.Filter { + f := strings.Split(filter, "=") + filters[f[0]] = f[1:] + } + images, err := images.List(ir.ClientCxt, &opts.All, filters) if err != nil { return nil, err } @@ -61,7 +67,13 @@ 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, &opts.All, opts.Filters) + filters := make(map[string][]string, len(opts.Filter)) + for _, filter := range opts.Filter { + f := strings.Split(filter, "=") + filters[f[0]] = f[1:] + } + + results, err := images.Prune(ir.ClientCxt, &opts.All, filters) if err != nil { return nil, err } @@ -112,7 +124,7 @@ func (ir *ImageEngine) Tag(ctx context.Context, nameOrId string, tags []string, func (ir *ImageEngine) Untag(ctx context.Context, nameOrId string, tags []string, options entities.ImageUntagOptions) error { // Remove all tags if none are provided if len(tags) == 0 { - newImage, err := images.GetImage(ir.ClientCxt, nameOrId, &bindings.PFalse) + newImage, err := images.GetImage(ir.ClientCxt, nameOrId, bindings.PFalse) if err != nil { return err } @@ -190,7 +202,6 @@ func (ir *ImageEngine) Save(ctx context.Context, nameOrId string, tags []string, f *os.File err error ) - switch options.Format { case "oci-dir", "docker-dir": f, err = ioutil.TempFile("", "podman_save") @@ -258,9 +269,13 @@ func (ir *ImageEngine) Build(ctx context.Context, containerFiles []string, opts } func (ir *ImageEngine) Tree(ctx context.Context, nameOrId string, opts entities.ImageTreeOptions) (*entities.ImageTreeReport, error) { - return nil, errors.New("not implemented yet") + return images.Tree(ir.ClientCxt, nameOrId, &opts.WhatRequires) } // Shutdown Libpod engine func (ir *ImageEngine) Shutdown(_ context.Context) { } + +func (ir *ImageEngine) Sign(ctx context.Context, names []string, options entities.SignOptions) (*entities.SignReport, error) { + return nil, errors.New("not implemented yet") +} diff --git a/pkg/domain/infra/tunnel/manifest.go b/pkg/domain/infra/tunnel/manifest.go index 9c1f5349a..beac378fe 100644 --- a/pkg/domain/infra/tunnel/manifest.go +++ b/pkg/domain/infra/tunnel/manifest.go @@ -57,46 +57,21 @@ func (ir *ImageEngine) ManifestAdd(ctx context.Context, opts entities.ManifestAd } manifestAddOpts.Annotation = annotations } - listID, err := manifests.Add(ctx, opts.Images[1], manifestAddOpts) + listID, err := manifests.Add(ir.ClientCxt, opts.Images[1], manifestAddOpts) if err != nil { return listID, errors.Wrapf(err, "error adding to manifest list %s", opts.Images[1]) } return listID, nil } -// FIXME There is no endpoint for annotate and therefor this code is currently invalid // ManifestAnnotate updates an entry of the manifest list func (ir *ImageEngine) ManifestAnnotate(ctx context.Context, names []string, opts entities.ManifestAnnotateOptions) (string, error) { return "", errors.New("not implemented") - // manifestAnnotateOpts := image.ManifestAnnotateOpts{ - // Arch: opts.Arch, - // Features: opts.Features, - // OS: opts.OS, - // OSFeatures: opts.OSFeatures, - // OSVersion: opts.OSVersion, - // Variant: opts.Variant, - // } - // if len(opts.Annotation) > 0 { - // annotations := make(map[string]string) - // for _, annotationSpec := range opts.Annotation { - // spec := strings.SplitN(annotationSpec, "=", 2) - // if len(spec) != 2 { - // return "", errors.Errorf("no value given for annotation %q", spec[0]) - // } - // annotations[spec[0]] = spec[1] - // } - // manifestAnnotateOpts.Annotation = annotations - // } - // updatedListID, err := manifests.Annotate(ctx, names[0], names[1], manifestAnnotateOpts) - // if err != nil { - // return updatedListID, errors.Wrapf(err, "error annotating %s of manifest list %s", names[1], names[0]) - // } - // return fmt.Sprintf("%s :%s", updatedListID, names[1]), nil } // ManifestRemove removes the digest from manifest list func (ir *ImageEngine) ManifestRemove(ctx context.Context, names []string) (string, error) { - updatedListID, err := manifests.Remove(ctx, names[0], names[1]) + updatedListID, err := manifests.Remove(ir.ClientCxt, names[0], names[1]) if err != nil { return updatedListID, errors.Wrapf(err, "error removing from manifest %s", names[0]) } @@ -105,6 +80,6 @@ func (ir *ImageEngine) ManifestRemove(ctx context.Context, names []string) (stri // ManifestPush pushes a manifest list or image index to the destination func (ir *ImageEngine) ManifestPush(ctx context.Context, names []string, opts entities.ManifestPushOptions) error { - _, err := manifests.Push(ctx, names[0], &names[1], &opts.All) + _, err := manifests.Push(ir.ClientCxt, names[0], &names[1], &opts.All) return err } diff --git a/pkg/domain/infra/tunnel/network.go b/pkg/domain/infra/tunnel/network.go index 4ff72dcfc..7725d8257 100644 --- a/pkg/domain/infra/tunnel/network.go +++ b/pkg/domain/infra/tunnel/network.go @@ -2,22 +2,39 @@ package tunnel import ( "context" - "errors" + "github.com/containers/libpod/pkg/bindings/network" "github.com/containers/libpod/pkg/domain/entities" ) func (ic *ContainerEngine) NetworkList(ctx context.Context, options entities.NetworkListOptions) ([]*entities.NetworkListReport, error) { - return nil, errors.New("not implemented") + return network.List(ic.ClientCxt) } func (ic *ContainerEngine) NetworkInspect(ctx context.Context, namesOrIds []string, options entities.NetworkInspectOptions) ([]entities.NetworkInspectReport, error) { - return nil, errors.New("not implemented") + var reports []entities.NetworkInspectReport + for _, name := range namesOrIds { + report, err := network.Inspect(ic.ClientCxt, name) + if err != nil { + return nil, err + } + reports = append(reports, report...) + } + return reports, nil } + func (ic *ContainerEngine) NetworkRm(ctx context.Context, namesOrIds []string, options entities.NetworkRmOptions) ([]*entities.NetworkRmReport, error) { - return nil, errors.New("not implemented") + var reports []*entities.NetworkRmReport + for _, name := range namesOrIds { + report, err := network.Remove(ic.ClientCxt, name, &options.Force) + if err != nil { + report[0].Err = err + } + reports = append(reports, report...) + } + return reports, nil } func (ic *ContainerEngine) NetworkCreate(ctx context.Context, name string, options entities.NetworkCreateOptions) (*entities.NetworkCreateReport, error) { - return nil, errors.New("not implemented") + return network.Create(ic.ClientCxt, options, &name) } diff --git a/pkg/domain/infra/tunnel/runtime.go b/pkg/domain/infra/tunnel/runtime.go index c111f99e9..357e2c390 100644 --- a/pkg/domain/infra/tunnel/runtime.go +++ b/pkg/domain/infra/tunnel/runtime.go @@ -13,3 +13,8 @@ type ImageEngine struct { type ContainerEngine struct { ClientCxt context.Context } + +// Container-related runtime using an ssh-tunnel to utilize Podman service +type SystemEngine struct { + ClientCxt context.Context +} diff --git a/pkg/domain/infra/tunnel/system.go b/pkg/domain/infra/tunnel/system.go index dafada805..829af31f6 100644 --- a/pkg/domain/infra/tunnel/system.go +++ b/pkg/domain/infra/tunnel/system.go @@ -27,8 +27,13 @@ func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.Sys return system.Prune(ic.ClientCxt, &options.All, &options.Volume) } +// Reset removes all storage +func (ic *SystemEngine) Reset(ctx context.Context) error { + return system.Reset(ic.ClientCxt) +} + func (ic *ContainerEngine) SystemDf(ctx context.Context, options entities.SystemDfOptions) (*entities.SystemDfReport, error) { - panic(errors.New("system df is not supported on remote clients")) + return system.DiskUsage(ic.ClientCxt) } func (ic *ContainerEngine) Unshare(ctx context.Context, args []string) error { |