diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/api/handlers/libpod/system.go | 23 | ||||
-rw-r--r-- | pkg/api/server/register_system.go | 31 | ||||
-rw-r--r-- | pkg/api/server/swagger.go | 18 | ||||
-rw-r--r-- | pkg/autoupdate/autoupdate.go | 25 | ||||
-rw-r--r-- | pkg/bindings/system/system.go | 28 | ||||
-rw-r--r-- | pkg/bindings/test/system_test.go | 42 | ||||
-rw-r--r-- | pkg/domain/entities/auto-update.go | 6 | ||||
-rw-r--r-- | pkg/domain/entities/engine_container.go | 2 | ||||
-rw-r--r-- | pkg/domain/entities/engine_image.go | 1 | ||||
-rw-r--r-- | pkg/domain/entities/engine_system.go | 2 | ||||
-rw-r--r-- | pkg/domain/entities/images.go | 10 | ||||
-rw-r--r-- | pkg/domain/infra/abi/auto-update.go | 8 | ||||
-rw-r--r-- | pkg/domain/infra/abi/images.go | 154 | ||||
-rw-r--r-- | pkg/domain/infra/abi/system.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/auto-update.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/containers.go | 24 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/images.go | 4 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/runtime.go | 5 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/system.go | 7 |
19 files changed, 374 insertions, 20 deletions
diff --git a/pkg/api/handlers/libpod/system.go b/pkg/api/handlers/libpod/system.go index 98e33bf10..81ed37b4a 100644 --- a/pkg/api/handlers/libpod/system.go +++ b/pkg/api/handlers/libpod/system.go @@ -7,6 +7,7 @@ import ( "github.com/containers/libpod/pkg/api/handlers/compat" "github.com/containers/libpod/pkg/api/handlers/utils" "github.com/containers/libpod/pkg/domain/entities" + "github.com/containers/libpod/pkg/domain/infra/abi" "github.com/gorilla/schema" "github.com/pkg/errors" ) @@ -69,3 +70,25 @@ func SystemPrune(w http.ResponseWriter, r *http.Request) { } utils.WriteResponse(w, http.StatusOK, systemPruneReport) } + +// SystemReset Resets podman storage back to default state +func SystemReset(w http.ResponseWriter, r *http.Request) { + err := r.Context().Value("runtime").(*libpod.Runtime).Reset(r.Context()) + if err != nil { + utils.InternalServerError(w, err) + return + } + utils.WriteResponse(w, http.StatusOK, nil) +} + +func DiskUsage(w http.ResponseWriter, r *http.Request) { + // Options are only used by the CLI + options := entities.SystemDfOptions{} + runtime := r.Context().Value("runtime").(*libpod.Runtime) + ic := abi.ContainerEngine{Libpod: runtime} + response, err := ic.SystemDf(r.Context(), options) + if err != nil { + utils.InternalServerError(w, err) + } + utils.WriteResponse(w, http.StatusOK, response) +} diff --git a/pkg/api/server/register_system.go b/pkg/api/server/register_system.go index 7375a75c1..8a942a888 100644 --- a/pkg/api/server/register_system.go +++ b/pkg/api/server/register_system.go @@ -12,7 +12,7 @@ func (s *APIServer) registerSystemHandlers(r *mux.Router) error { r.Handle(VersionedPath("/system/df"), s.APIHandler(compat.GetDiskUsage)).Methods(http.MethodGet) // Added non version path to URI to support docker non versioned paths r.Handle("/system/df", s.APIHandler(compat.GetDiskUsage)).Methods(http.MethodGet) - // Swagger:operation POST /libpod/system/prune libpod pruneSystem + // swagger:operation POST /libpod/system/prune libpod pruneSystem // --- // tags: // - system @@ -27,6 +27,33 @@ func (s *APIServer) registerSystemHandlers(r *mux.Router) error { // 500: // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/system/prune"), s.APIHandler(libpod.SystemPrune)).Methods(http.MethodPost) - + // swagger:operation POST /libpod/system/reset libpod resetSystem + // --- + // tags: + // - system + // summary: Reset podman storage + // description: All containers will be stopped and removed, and all images, volumes and container content will be removed. + // produces: + // - application/json + // responses: + // 200: + // description: no error + // 500: + // $ref: "#/responses/InternalError" + r.Handle(VersionedPath("/libpod/system/reset"), s.APIHandler(libpod.SystemReset)).Methods(http.MethodPost) + // swagger:operation GET /libpod/system/df libpod df + // --- + // tags: + // - system + // summary: Show disk usage + // description: Return information about disk usage for containers, images, and volumes + // produces: + // - application/json + // responses: + // 200: + // $ref: '#/responses/SystemDiskUse' + // 500: + // $ref: "#/responses/InternalError" + r.Handle(VersionedPath("/libpod/system/df"), s.APIHandler(libpod.DiskUsage)).Methods(http.MethodGet) return nil } diff --git a/pkg/api/server/swagger.go b/pkg/api/server/swagger.go index e47f2cc2f..7776d0e79 100644 --- a/pkg/api/server/swagger.go +++ b/pkg/api/server/swagger.go @@ -190,3 +190,21 @@ type swagVersion struct { entities.SystemVersionReport } } + +// Disk usage +// swagger:response SystemDiskUse +type swagDiskUseResponse struct { + // in:body + Body struct { + entities.SystemDfReport + } +} + +// Prune report +// swagger:response SystemPruneReport +type swagSystemPruneReport struct { + // in:body + Body struct { + entities.SystemPruneReport + } +} diff --git a/pkg/autoupdate/autoupdate.go b/pkg/autoupdate/autoupdate.go index 78d5ac474..1b0419892 100644 --- a/pkg/autoupdate/autoupdate.go +++ b/pkg/autoupdate/autoupdate.go @@ -63,6 +63,12 @@ func LookupPolicy(s string) (Policy, error) { return "", errors.Errorf("invalid auto-update policy %q: valid policies are %+q", s, keys) } +// Options include parameters for auto updates. +type Options struct { + // Authfile to use when contacting registries. + Authfile string +} + // ValidateImageReference checks if the specified imageName is a fully-qualified // image reference to the docker transport (without digest). Such a reference // includes a domain, name and tag (e.g., quay.io/podman/stable:latest). The @@ -96,7 +102,7 @@ func ValidateImageReference(imageName string) error { // // It returns a slice of successfully restarted systemd units and a slice of // errors encountered during auto update. -func AutoUpdate(runtime *libpod.Runtime) ([]string, []error) { +func AutoUpdate(runtime *libpod.Runtime, options Options) ([]string, []error) { // Create a map from `image ID -> []*Container`. containerMap, errs := imageContainersMap(runtime) if len(containerMap) == 0 { @@ -138,7 +144,7 @@ func AutoUpdate(runtime *libpod.Runtime) ([]string, []error) { if rawImageName == "" { errs = append(errs, errors.Errorf("error auto-updating container %q: raw-image name is empty", ctr.ID())) } - needsUpdate, err := newerImageAvailable(runtime, image, rawImageName) + needsUpdate, err := newerImageAvailable(runtime, image, rawImageName, options) if err != nil { errs = append(errs, errors.Wrapf(err, "error auto-updating container %q: image check for %q failed", ctr.ID(), rawImageName)) continue @@ -148,7 +154,7 @@ func AutoUpdate(runtime *libpod.Runtime) ([]string, []error) { } logrus.Infof("Auto-updating container %q using image %q", ctr.ID(), rawImageName) if _, updated := updatedRawImages[rawImageName]; !updated { - _, err = updateImage(runtime, rawImageName) + _, err = updateImage(runtime, rawImageName, options) if err != nil { errs = append(errs, errors.Wrapf(err, "error auto-updating container %q: image update for %q failed", ctr.ID(), rawImageName)) continue @@ -230,13 +236,15 @@ func imageContainersMap(runtime *libpod.Runtime) (map[string][]*libpod.Container // newerImageAvailable returns true if there corresponding image on the remote // registry is newer. -func newerImageAvailable(runtime *libpod.Runtime, img *image.Image, origName string) (bool, error) { +func newerImageAvailable(runtime *libpod.Runtime, img *image.Image, origName string, options Options) (bool, error) { remoteRef, err := docker.ParseReference("//" + origName) if err != nil { return false, err } - remoteImg, err := remoteRef.NewImage(context.Background(), runtime.SystemContext()) + sys := runtime.SystemContext() + sys.AuthFilePath = options.Authfile + remoteImg, err := remoteRef.NewImage(context.Background(), sys) if err != nil { return false, err } @@ -255,25 +263,22 @@ func newerImageAvailable(runtime *libpod.Runtime, img *image.Image, origName str } // updateImage pulls the specified image. -func updateImage(runtime *libpod.Runtime, name string) (*image.Image, error) { +func updateImage(runtime *libpod.Runtime, name string, options Options) (*image.Image, error) { sys := runtime.SystemContext() registryOpts := image.DockerRegistryOptions{} signaturePolicyPath := "" - authFilePath := "" if sys != nil { registryOpts.OSChoice = sys.OSChoice registryOpts.ArchitectureChoice = sys.OSChoice registryOpts.DockerCertPath = sys.DockerCertPath - signaturePolicyPath = sys.SignaturePolicyPath - authFilePath = sys.AuthFilePath } newImage, err := runtime.ImageRuntime().New(context.Background(), docker.Transport.Name()+"://"+name, signaturePolicyPath, - authFilePath, + options.Authfile, os.Stderr, ®istryOpts, image.SigningOptions{}, diff --git a/pkg/bindings/system/system.go b/pkg/bindings/system/system.go index caef6af6f..e567e7a86 100644 --- a/pkg/bindings/system/system.go +++ b/pkg/bindings/system/system.go @@ -121,3 +121,31 @@ func Version(ctx context.Context) (*entities.SystemVersionReport, error) { } return &report, err } + +// Reset removes all unused system data. +func Reset(ctx context.Context) error { + conn, err := bindings.GetClient(ctx) + if err != nil { + return err + } + response, err := conn.DoRequest(nil, http.MethodPost, "/system/reset", nil) + if err != nil { + return err + } + return response.Process(response) +} + +// DiskUsage returns information about image, container, and volume disk +// consumption +func DiskUsage(ctx context.Context) (*entities.SystemDfReport, error) { + var report entities.SystemDfReport + conn, err := bindings.GetClient(ctx) + if err != nil { + return nil, err + } + response, err := conn.DoRequest(nil, http.MethodGet, "/system/df", nil) + if err != nil { + return nil, err + } + return &report, response.Process(&report) +} diff --git a/pkg/bindings/test/system_test.go b/pkg/bindings/test/system_test.go index 62ea32377..76f0b074b 100644 --- a/pkg/bindings/test/system_test.go +++ b/pkg/bindings/test/system_test.go @@ -5,6 +5,7 @@ import ( "github.com/containers/libpod/pkg/bindings" "github.com/containers/libpod/pkg/bindings/containers" + "github.com/containers/libpod/pkg/bindings/images" "github.com/containers/libpod/pkg/bindings/pods" "github.com/containers/libpod/pkg/bindings/system" "github.com/containers/libpod/pkg/bindings/volumes" @@ -149,4 +150,45 @@ var _ = Describe("Podman system", func() { // Volume should be pruned now as flag set true Expect(len(systemPruneResponse.VolumePruneReport)).To(Equal(1)) }) + + It("podman system reset", func() { + // Adding an unused volume should work + _, err := volumes.Create(bt.conn, entities.VolumeCreateOptions{}) + Expect(err).To(BeNil()) + + vols, err := volumes.List(bt.conn, nil) + Expect(err).To(BeNil()) + Expect(len(vols)).To(Equal(1)) + + // Start a pod and leave it running + _, err = pods.Start(bt.conn, newpod) + Expect(err).To(BeNil()) + + imageSummary, err := images.List(bt.conn, nil, nil) + Expect(err).To(BeNil()) + // Since in the begin context images are created + Expect(len(imageSummary)).To(Equal(3)) + + err = system.Reset(bt.conn) + Expect(err).To(BeNil()) + + // re-establish connection + s = bt.startAPIService() + time.Sleep(1 * time.Second) + + // No pods + podSummary, err := pods.List(bt.conn, nil) + Expect(err).To(BeNil()) + Expect(len(podSummary)).To(Equal(0)) + + // No images + imageSummary, err = images.List(bt.conn, &bindings.PTrue, nil) + Expect(err).To(BeNil()) + Expect(len(imageSummary)).To(Equal(0)) + + // no volumes + vols, err = volumes.List(bt.conn, nil) + Expect(err).To(BeNil()) + Expect(len(vols)).To(BeZero()) + }) }) diff --git a/pkg/domain/entities/auto-update.go b/pkg/domain/entities/auto-update.go index aef8fc46b..c51158816 100644 --- a/pkg/domain/entities/auto-update.go +++ b/pkg/domain/entities/auto-update.go @@ -1,5 +1,11 @@ package entities +// AutoUpdateOptions are the options for running auto-update. +type AutoUpdateOptions struct { + // Authfile to use when contacting registries. + Authfile string +} + // AutoUpdateReport contains the results from running auto-update. type AutoUpdateReport struct { // Units - the restarted systemd units during auto-update. diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go index 719ac3f9e..e77f0758b 100644 --- a/pkg/domain/entities/engine_container.go +++ b/pkg/domain/entities/engine_container.go @@ -10,7 +10,7 @@ import ( ) type ContainerEngine interface { - AutoUpdate(ctx context.Context) (*AutoUpdateReport, []error) + AutoUpdate(ctx context.Context, options AutoUpdateOptions) (*AutoUpdateReport, []error) Config(ctx context.Context) (*config.Config, error) ContainerAttach(ctx context.Context, nameOrId string, options AttachOptions) error ContainerCheckpoint(ctx context.Context, namesOrIds []string, options CheckpointOptions) ([]*CheckpointReport, error) diff --git a/pkg/domain/entities/engine_image.go b/pkg/domain/entities/engine_image.go index ffa71abd6..7d7099838 100644 --- a/pkg/domain/entities/engine_image.go +++ b/pkg/domain/entities/engine_image.go @@ -34,4 +34,5 @@ type ImageEngine interface { ManifestAnnotate(ctx context.Context, names []string, opts ManifestAnnotateOptions) (string, error) ManifestRemove(ctx context.Context, names []string) (string, error) ManifestPush(ctx context.Context, names []string, manifestPushOpts ManifestPushOptions) error + Sign(ctx context.Context, names []string, options SignOptions) (*SignReport, error) } diff --git a/pkg/domain/entities/engine_system.go b/pkg/domain/entities/engine_system.go index e2000f5cb..a0ecfe9ea 100644 --- a/pkg/domain/entities/engine_system.go +++ b/pkg/domain/entities/engine_system.go @@ -9,6 +9,6 @@ import ( type SystemEngine interface { Renumber(ctx context.Context, flags *pflag.FlagSet, config *PodmanConfig) error Migrate(ctx context.Context, flags *pflag.FlagSet, config *PodmanConfig, options SystemMigrateOptions) error - Reset(ctx context.Context, options SystemResetOptions) error + Reset(ctx context.Context) error Shutdown(ctx context.Context) } diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go index e116a90b9..cce3001eb 100644 --- a/pkg/domain/entities/images.go +++ b/pkg/domain/entities/images.go @@ -309,3 +309,13 @@ type SetTrustOptions struct { PubKeysFile []string Type string } + +// SignOptions describes input options for the CLI signing +type SignOptions struct { + Directory string + SignBy string + CertDir string +} + +// SignReport describes the result of signing +type SignReport struct{} diff --git a/pkg/domain/infra/abi/auto-update.go b/pkg/domain/infra/abi/auto-update.go index aa20664b4..9fcc451fd 100644 --- a/pkg/domain/infra/abi/auto-update.go +++ b/pkg/domain/infra/abi/auto-update.go @@ -7,7 +7,11 @@ import ( "github.com/containers/libpod/pkg/domain/entities" ) -func (ic *ContainerEngine) AutoUpdate(ctx context.Context) (*entities.AutoUpdateReport, []error) { - units, failures := autoupdate.AutoUpdate(ic.Libpod) +func (ic *ContainerEngine) AutoUpdate(ctx context.Context, options entities.AutoUpdateOptions) (*entities.AutoUpdateReport, []error) { + // Convert the entities options to the autoupdate ones. We can't use + // them in the entities package as low-level packages must not leak + // into the remote client. + autoOpts := autoupdate.Options{Authfile: options.Authfile} + units, failures := autoupdate.AutoUpdate(ic.Libpod, autoOpts) return &entities.AutoUpdateReport{Units: units}, failures } diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go index 7ab5131f0..6e774df8e 100644 --- a/pkg/domain/infra/abi/images.go +++ b/pkg/domain/infra/abi/images.go @@ -4,14 +4,22 @@ import ( "context" "fmt" "io" + "io/ioutil" + "net/url" "os" + "path/filepath" + "strconv" "strings" + "github.com/containers/libpod/pkg/rootless" + "github.com/containers/common/pkg/config" "github.com/containers/image/v5/docker" dockerarchive "github.com/containers/image/v5/docker/archive" "github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/manifest" + "github.com/containers/image/v5/signature" + "github.com/containers/image/v5/transports" "github.com/containers/image/v5/transports/alltransports" "github.com/containers/image/v5/types" "github.com/containers/libpod/libpod/define" @@ -19,6 +27,7 @@ import ( libpodImage "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/domain/entities" domainUtils "github.com/containers/libpod/pkg/domain/utils" + "github.com/containers/libpod/pkg/trust" "github.com/containers/libpod/pkg/util" "github.com/containers/storage" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" @@ -26,6 +35,9 @@ import ( "github.com/sirupsen/logrus" ) +// SignatureStoreDir defines default directory to store signatures +const SignatureStoreDir = "/var/lib/containers/sigstore" + func (ir *ImageEngine) Exists(_ context.Context, nameOrId string) (*entities.BoolReport, error) { _, err := ir.Libpod.ImageRuntime().NewFromLocal(nameOrId) if err != nil && errors.Cause(err) != define.ErrNoSuchImage { @@ -549,3 +561,145 @@ func (ir *ImageEngine) Shutdown(_ context.Context) { _ = ir.Libpod.Shutdown(false) }) } + +func (ir *ImageEngine) Sign(ctx context.Context, names []string, options entities.SignOptions) (*entities.SignReport, error) { + dockerRegistryOptions := image.DockerRegistryOptions{ + DockerCertPath: options.CertDir, + } + + mech, err := signature.NewGPGSigningMechanism() + if err != nil { + return nil, errors.Wrap(err, "error initializing GPG") + } + defer mech.Close() + if err := mech.SupportsSigning(); err != nil { + return nil, errors.Wrap(err, "signing is not supported") + } + sc := ir.Libpod.SystemContext() + sc.DockerCertPath = options.CertDir + + systemRegistriesDirPath := trust.RegistriesDirPath(sc) + registryConfigs, err := trust.LoadAndMergeConfig(systemRegistriesDirPath) + if err != nil { + return nil, errors.Wrapf(err, "error reading registry configuration") + } + + for _, signimage := range names { + var sigStoreDir string + srcRef, err := alltransports.ParseImageName(signimage) + if err != nil { + return nil, errors.Wrapf(err, "error parsing image name") + } + rawSource, err := srcRef.NewImageSource(ctx, sc) + if err != nil { + return nil, errors.Wrapf(err, "error getting image source") + } + err = rawSource.Close() + if err != nil { + logrus.Errorf("unable to close new image source %q", err) + } + getManifest, _, err := rawSource.GetManifest(ctx, nil) + if err != nil { + return nil, errors.Wrapf(err, "error getting getManifest") + } + dockerReference := rawSource.Reference().DockerReference() + if dockerReference == nil { + return nil, errors.Errorf("cannot determine canonical Docker reference for destination %s", transports.ImageName(rawSource.Reference())) + } + + // create the signstore file + rtc, err := ir.Libpod.GetConfig() + if err != nil { + return nil, err + } + newImage, err := ir.Libpod.ImageRuntime().New(ctx, signimage, rtc.Engine.SignaturePolicyPath, "", os.Stderr, &dockerRegistryOptions, image.SigningOptions{SignBy: options.SignBy}, nil, util.PullImageMissing) + if err != nil { + return nil, errors.Wrapf(err, "error pulling image %s", signimage) + } + if sigStoreDir == "" { + if rootless.IsRootless() { + sigStoreDir = filepath.Join(filepath.Dir(ir.Libpod.StorageConfig().GraphRoot), "sigstore") + } else { + registryInfo := trust.HaveMatchRegistry(rawSource.Reference().DockerReference().String(), registryConfigs) + if registryInfo != nil { + if sigStoreDir = registryInfo.SigStoreStaging; sigStoreDir == "" { + sigStoreDir = registryInfo.SigStore + + } + } + } + } + sigStoreDir, err = isValidSigStoreDir(sigStoreDir) + if err != nil { + return nil, errors.Wrapf(err, "invalid signature storage %s", sigStoreDir) + } + repos, err := newImage.RepoDigests() + if err != nil { + return nil, errors.Wrapf(err, "error calculating repo digests for %s", signimage) + } + if len(repos) == 0 { + logrus.Errorf("no repodigests associated with the image %s", signimage) + continue + } + + // create signature + newSig, err := signature.SignDockerManifest(getManifest, dockerReference.String(), mech, options.SignBy) + if err != nil { + return nil, errors.Wrapf(err, "error creating new signature") + } + + trimmedDigest := strings.TrimPrefix(repos[0], strings.Split(repos[0], "/")[0]) + sigStoreDir = filepath.Join(sigStoreDir, strings.Replace(trimmedDigest, ":", "=", 1)) + if err := os.MkdirAll(sigStoreDir, 0751); err != nil { + // The directory is allowed to exist + if !os.IsExist(err) { + logrus.Errorf("error creating directory %s: %s", sigStoreDir, err) + continue + } + } + sigFilename, err := getSigFilename(sigStoreDir) + if err != nil { + logrus.Errorf("error creating sigstore file: %v", err) + continue + } + err = ioutil.WriteFile(filepath.Join(sigStoreDir, sigFilename), newSig, 0644) + if err != nil { + logrus.Errorf("error storing signature for %s", rawSource.Reference().DockerReference().String()) + continue + } + } + return nil, nil +} + +func getSigFilename(sigStoreDirPath string) (string, error) { + sigFileSuffix := 1 + sigFiles, err := ioutil.ReadDir(sigStoreDirPath) + if err != nil { + return "", err + } + sigFilenames := make(map[string]bool) + for _, file := range sigFiles { + sigFilenames[file.Name()] = true + } + for { + sigFilename := "signature-" + strconv.Itoa(sigFileSuffix) + if _, exists := sigFilenames[sigFilename]; !exists { + return sigFilename, nil + } + sigFileSuffix++ + } +} + +func isValidSigStoreDir(sigStoreDir string) (string, error) { + writeURIs := map[string]bool{"file": true} + url, err := url.Parse(sigStoreDir) + if err != nil { + return sigStoreDir, errors.Wrapf(err, "invalid directory %s", sigStoreDir) + } + _, exists := writeURIs[url.Scheme] + if !exists { + return sigStoreDir, errors.Errorf("writing to %s is not supported. Use a supported scheme", sigStoreDir) + } + sigStoreDir = url.Path + return sigStoreDir, nil +} diff --git a/pkg/domain/infra/abi/system.go b/pkg/domain/infra/abi/system.go index d701d65de..af2ec5f7b 100644 --- a/pkg/domain/infra/abi/system.go +++ b/pkg/domain/infra/abi/system.go @@ -375,7 +375,7 @@ func sizeOfPath(path string) (int64, error) { return size, err } -func (se *SystemEngine) Reset(ctx context.Context, options entities.SystemResetOptions) error { +func (se *SystemEngine) Reset(ctx context.Context) error { return se.Libpod.Reset(ctx) } 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..028e3bc5f 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -381,7 +381,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/images.go b/pkg/domain/infra/tunnel/images.go index 00893194c..788752fd8 100644 --- a/pkg/domain/infra/tunnel/images.go +++ b/pkg/domain/infra/tunnel/images.go @@ -264,3 +264,7 @@ func (ir *ImageEngine) Tree(ctx context.Context, nameOrId string, opts entities. // 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/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 { |