diff options
Diffstat (limited to 'pkg/domain/infra/abi')
-rw-r--r-- | pkg/domain/infra/abi/manifest.go | 39 | ||||
-rw-r--r-- | pkg/domain/infra/abi/runtime.go | 5 | ||||
-rw-r--r-- | pkg/domain/infra/abi/system.go | 177 |
3 files changed, 220 insertions, 1 deletions
diff --git a/pkg/domain/infra/abi/manifest.go b/pkg/domain/infra/abi/manifest.go index 88331f96c..812507f0a 100644 --- a/pkg/domain/infra/abi/manifest.go +++ b/pkg/domain/infra/abi/manifest.go @@ -14,6 +14,7 @@ import ( libpodImage "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/domain/entities" "github.com/containers/libpod/pkg/util" + "github.com/opencontainers/go-digest" "github.com/pkg/errors" ) @@ -71,7 +72,7 @@ func (ir *ImageEngine) ManifestAdd(ctx context.Context, opts entities.ManifestAd } listImage, err := ir.Libpod.ImageRuntime().NewFromLocal(listImageSpec) if err != nil { - return "", errors.Wrapf(err, "error retriving local image from image name %s", listImageSpec) + return "", errors.Wrapf(err, "error retrieving local image from image name %s", listImageSpec) } manifestAddOpts := libpodImage.ManifestAddOpts{ @@ -100,3 +101,39 @@ func (ir *ImageEngine) ManifestAdd(ctx context.Context, opts entities.ManifestAd } return listID, nil } + +// ManifestAnnotate updates an entry of the manifest list +func (ir *ImageEngine) ManifestAnnotate(ctx context.Context, names []string, opts entities.ManifestAnnotateOptions) (string, error) { + listImage, err := ir.Libpod.ImageRuntime().NewFromLocal(names[0]) + if err != nil { + return "", errors.Wrapf(err, "error retreiving local image from image name %s", names[0]) + } + digest, err := digest.Parse(names[1]) + if err != nil { + return "", errors.Errorf(`invalid image digest "%s": %v`, names[1], err) + } + manifestAnnotateOpts := libpodImage.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 := listImage.AnnotateManifest(*ir.Libpod.SystemContext(), digest, manifestAnnotateOpts) + if err == nil { + return fmt.Sprintf("%s: %s", updatedListID, digest.String()), nil + } + return "", err +} diff --git a/pkg/domain/infra/abi/runtime.go b/pkg/domain/infra/abi/runtime.go index fba422d8e..b9020e9a5 100644 --- a/pkg/domain/infra/abi/runtime.go +++ b/pkg/domain/infra/abi/runtime.go @@ -16,4 +16,9 @@ type ContainerEngine struct { Libpod *libpod.Runtime } +// Container-related runtime linked against libpod library +type SystemEngine struct { + Libpod *libpod.Runtime +} + var shutdownSync sync.Once diff --git a/pkg/domain/infra/abi/system.go b/pkg/domain/infra/abi/system.go index ab1b282d8..692fcfa0f 100644 --- a/pkg/domain/infra/abi/system.go +++ b/pkg/domain/infra/abi/system.go @@ -5,6 +5,7 @@ import ( "fmt" "io/ioutil" "os" + "path/filepath" "strconv" "syscall" @@ -18,9 +19,11 @@ import ( iopodmanAPI "github.com/containers/libpod/pkg/varlinkapi" "github.com/containers/libpod/utils" "github.com/containers/libpod/version" + "github.com/docker/distribution/reference" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" + "github.com/spf13/pflag" "github.com/varlink/go/varlink" ) @@ -213,3 +216,177 @@ func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.Sys } return systemPruneReport, nil } + +func (ic *ContainerEngine) SystemDf(ctx context.Context, options entities.SystemDfOptions) (*entities.SystemDfReport, error) { + var ( + dfImages []*entities.SystemDfImageReport + dfContainers []*entities.SystemDfContainerReport + dfVolumes []*entities.SystemDfVolumeReport + runningContainers []string + ) + + // Get Images and iterate them + imgs, err := ic.Libpod.ImageRuntime().GetImages() + if err != nil { + return nil, err + } + for _, i := range imgs { + var sharedSize uint64 + cons, err := i.Containers() + if err != nil { + return nil, err + } + imageSize, err := i.Size(ctx) + if err != nil { + return nil, err + } + uniqueSize := *imageSize + + parent, err := i.GetParent(ctx) + if err != nil { + return nil, err + } + if parent != nil { + parentSize, err := parent.Size(ctx) + if err != nil { + return nil, err + } + uniqueSize = *parentSize - *imageSize + sharedSize = *imageSize - uniqueSize + } + var name, repository, tag string + for _, n := range i.Names() { + if len(n) > 0 { + name = n + break + } + } + + named, err := reference.ParseNormalizedNamed(name) + if err != nil { + return nil, err + } + repository = named.Name() + if tagged, isTagged := named.(reference.NamedTagged); isTagged { + tag = tagged.Tag() + } + + report := entities.SystemDfImageReport{ + Repository: repository, + Tag: tag, + ImageID: i.ID(), + Created: i.Created(), + Size: int64(*imageSize), + SharedSize: int64(sharedSize), + UniqueSize: int64(uniqueSize), + Containers: len(cons), + } + dfImages = append(dfImages, &report) + } + + // GetContainers and iterate them + cons, err := ic.Libpod.GetAllContainers() + if err != nil { + return nil, err + } + for _, c := range cons { + iid, _ := c.Image() + conSize, err := c.RootFsSize() + if err != nil { + return nil, err + } + state, err := c.State() + if err != nil { + return nil, err + } + rwsize, err := c.RWSize() + if err != nil { + return nil, err + } + report := entities.SystemDfContainerReport{ + ContainerID: c.ID(), + Image: iid, + Command: c.Command(), + LocalVolumes: len(c.UserVolumes()), + RWSize: rwsize, + Size: conSize, + Created: c.CreatedTime(), + Status: state.String(), + Names: c.Name(), + } + dfContainers = append(dfContainers, &report) + } + + // Get volumes and iterate them + vols, err := ic.Libpod.GetAllVolumes() + if err != nil { + return nil, err + } + + running, err := ic.Libpod.GetRunningContainers() + if err != nil { + return nil, err + } + for _, c := range running { + runningContainers = append(runningContainers, c.ID()) + } + + for _, v := range vols { + var consInUse int + volSize, err := sizeOfPath(v.MountPoint()) + if err != nil { + return nil, err + } + inUse, err := v.VolumesInUse() + if err != nil { + return nil, err + } + for _, viu := range inUse { + if util.StringInSlice(viu, runningContainers) { + consInUse += 1 + } + } + report := entities.SystemDfVolumeReport{ + VolumeName: v.Name(), + Links: consInUse, + Size: volSize, + } + dfVolumes = append(dfVolumes, &report) + } + return &entities.SystemDfReport{ + Images: dfImages, + Containers: dfContainers, + Volumes: dfVolumes, + }, nil +} + +// sizeOfPath determines the file usage of a given path. it was called volumeSize in v1 +// and now is made to be generic and take a path instead of a libpod volume +func sizeOfPath(path string) (int64, error) { + var size int64 + err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error { + if err == nil && !info.IsDir() { + size += info.Size() + } + return err + }) + return size, err +} + +func (se *SystemEngine) Reset(ctx context.Context, options entities.SystemResetOptions) error { + return se.Libpod.Reset(ctx) +} + +func (se *SystemEngine) Renumber(ctx context.Context, flags *pflag.FlagSet, config *entities.PodmanConfig) error { + return nil +} + +func (s SystemEngine) Migrate(ctx context.Context, flags *pflag.FlagSet, config *entities.PodmanConfig, options entities.SystemMigrateOptions) error { + return nil +} + +func (s SystemEngine) Shutdown(ctx context.Context) { + if err := s.Libpod.Shutdown(false); err != nil { + logrus.Error(err) + } +} |