diff options
author | Jhon Honce <jhonce@redhat.com> | 2020-03-23 09:04:31 -0700 |
---|---|---|
committer | Jhon Honce <jhonce@redhat.com> | 2020-03-24 16:06:01 -0700 |
commit | 1d7cb7cc48d06631e2bdfd0e25eeccc8e87b042f (patch) | |
tree | a9ce6c3b2e91a797cf8174d7a4e9d62eccb4d1e8 /pkg | |
parent | 0c084d9719772a9b68d5eb67114cf5bf001958b2 (diff) | |
download | podman-1d7cb7cc48d06631e2bdfd0e25eeccc8e87b042f.tar.gz podman-1d7cb7cc48d06631e2bdfd0e25eeccc8e87b042f.tar.bz2 podman-1d7cb7cc48d06631e2bdfd0e25eeccc8e87b042f.zip |
V2 podman images/image list
* Updated entities to support flags/options
* Updated bindings caused by entities changes
* Removed handlers.ImageSummary in favor of entities.ImageSummary
* Introduced StringSet() container object to simply error checking
Signed-off-by: Jhon Honce <jhonce@redhat.com>
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/api/handlers/compat/images.go | 3 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/images.go | 5 | ||||
-rw-r--r-- | pkg/api/handlers/types.go | 70 | ||||
-rw-r--r-- | pkg/api/server/swagger.go | 3 | ||||
-rw-r--r-- | pkg/bindings/images/images.go | 5 | ||||
-rw-r--r-- | pkg/domain/entities/engine_image.go | 2 | ||||
-rw-r--r-- | pkg/domain/entities/images.go | 61 | ||||
-rw-r--r-- | pkg/domain/entities/set.go | 45 | ||||
-rw-r--r-- | pkg/domain/infra/abi/images.go | 29 | ||||
-rw-r--r-- | pkg/domain/infra/abi/images_list.go | 80 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/images.go | 11 |
11 files changed, 201 insertions, 113 deletions
diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go index b18687bf9..cce718f54 100644 --- a/pkg/api/handlers/compat/images.go +++ b/pkg/api/handlers/compat/images.go @@ -15,6 +15,7 @@ import ( image2 "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/api/handlers" "github.com/containers/libpod/pkg/api/handlers/utils" + "github.com/containers/libpod/pkg/domain/entities" "github.com/containers/libpod/pkg/util" "github.com/docker/docker/api/types" "github.com/gorilla/schema" @@ -305,7 +306,7 @@ func GetImages(w http.ResponseWriter, r *http.Request) { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Failed get images")) return } - var summaries = make([]*handlers.ImageSummary, len(images)) + var summaries = make([]*entities.ImageSummary, len(images)) for j, img := range images { is, err := handlers.ImageToImageSummary(img) if err != nil { diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go index b6f2f58e8..f8e666451 100644 --- a/pkg/api/handlers/libpod/images.go +++ b/pkg/api/handlers/libpod/images.go @@ -21,6 +21,7 @@ import ( image2 "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/api/handlers" "github.com/containers/libpod/pkg/api/handlers/utils" + "github.com/containers/libpod/pkg/domain/entities" "github.com/containers/libpod/pkg/util" "github.com/gorilla/schema" "github.com/pkg/errors" @@ -101,7 +102,7 @@ func GetImages(w http.ResponseWriter, r *http.Request) { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Failed get images")) return } - var summaries = make([]*handlers.ImageSummary, len(images)) + var summaries = make([]*entities.ImageSummary, len(images)) for j, img := range images { is, err := handlers.ImageToImageSummary(img) if err != nil { @@ -109,7 +110,7 @@ func GetImages(w http.ResponseWriter, r *http.Request) { return } // libpod has additional fields that we need to populate. - is.CreatedTime = img.Created() + is.Created = img.Created().Unix() is.ReadOnly = img.IsReadOnly() summaries[j] = is } diff --git a/pkg/api/handlers/types.go b/pkg/api/handlers/types.go index c6b70251b..84ca0fbed 100644 --- a/pkg/api/handlers/types.go +++ b/pkg/api/handlers/types.go @@ -13,6 +13,7 @@ import ( "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/events" libpodImage "github.com/containers/libpod/libpod/image" + "github.com/containers/libpod/pkg/domain/entities" docker "github.com/docker/docker/api/types" dockerContainer "github.com/docker/docker/api/types/container" dockerEvents "github.com/docker/docker/api/types/events" @@ -45,12 +46,6 @@ type LibpodImagesPullReport struct { ID string `json:"id"` } -type ImageSummary struct { - docker.ImageSummary - CreatedTime time.Time `json:"CreatedTime,omitempty"` - ReadOnly bool `json:"ReadOnly,omitempty"` -} - type ContainersPruneReport struct { docker.ContainersPruneReport } @@ -195,23 +190,13 @@ func EventToApiEvent(e *events.Event) *Event { }} } -func ImageToImageSummary(l *libpodImage.Image) (*ImageSummary, error) { +func ImageToImageSummary(l *libpodImage.Image) (*entities.ImageSummary, error) { containers, err := l.Containers() if err != nil { return nil, errors.Wrapf(err, "Failed to obtain Containers for image %s", l.ID()) } containerCount := len(containers) - var digests []string - for _, d := range l.Digests() { - digests = append(digests, string(d)) - } - - tags, err := l.RepoTags() - if err != nil { - return nil, errors.Wrapf(err, "Failed to obtain RepoTags for image %s", l.ID()) - } - // FIXME: GetParent() panics // parent, err := l.GetParent(context.TODO()) // if err != nil { @@ -227,20 +212,43 @@ func ImageToImageSummary(l *libpodImage.Image) (*ImageSummary, error) { if err != nil { return nil, errors.Wrapf(err, "Failed to obtain Size for image %s", l.ID()) } - dockerSummary := docker.ImageSummary{ - Containers: int64(containerCount), - Created: l.Created().Unix(), - ID: l.ID(), - Labels: labels, - ParentID: l.Parent, - RepoDigests: digests, - RepoTags: tags, - SharedSize: 0, - Size: int64(*size), - VirtualSize: int64(*size), - } - is := ImageSummary{ - ImageSummary: dockerSummary, + + repoTags, err := l.RepoTags() + if err != nil { + return nil, errors.Wrapf(err, "Failed to obtain RepoTags for image %s", l.ID()) + } + + history, err := l.History(context.TODO()) + if err != nil { + return nil, errors.Wrapf(err, "Failed to obtain History for image %s", l.ID()) + } + historyIds := make([]string, len(history)) + for i, h := range history { + historyIds[i] = h.ID + } + + digests := make([]string, len(l.Digests())) + for i, d := range l.Digests() { + digests[i] = string(d) + } + + is := entities.ImageSummary{ + ID: l.ID(), + ParentId: l.Parent, + RepoTags: repoTags, + Created: l.Created().Unix(), + Size: int64(*size), + SharedSize: 0, + VirtualSize: l.VirtualSize, + Labels: labels, + Containers: containerCount, + ReadOnly: l.IsReadOnly(), + Dangling: l.Dangling(), + Names: l.Names(), + Digest: string(l.Digest()), + Digests: digests, + ConfigDigest: string(l.ConfigDigest), + History: historyIds, } return &is, nil } diff --git a/pkg/api/server/swagger.go b/pkg/api/server/swagger.go index 2e1a269f2..3eee5fda8 100644 --- a/pkg/api/server/swagger.go +++ b/pkg/api/server/swagger.go @@ -2,7 +2,6 @@ package server import ( "github.com/containers/libpod/libpod" - "github.com/containers/libpod/pkg/api/handlers" "github.com/containers/libpod/pkg/api/handlers/utils" "github.com/containers/libpod/pkg/domain/entities" ) @@ -128,7 +127,7 @@ type swagPodAlreadyStopped struct { // swagger:response DockerImageSummary type swagImageSummary struct { // in:body - Body []handlers.ImageSummary + Body []entities.ImageSummary } // List Containers diff --git a/pkg/bindings/images/images.go b/pkg/bindings/images/images.go index c84aa4601..e67965042 100644 --- a/pkg/bindings/images/images.go +++ b/pkg/bindings/images/images.go @@ -10,6 +10,7 @@ import ( "github.com/containers/libpod/pkg/api/handlers" "github.com/containers/libpod/pkg/bindings" + "github.com/containers/libpod/pkg/domain/entities" "github.com/containers/libpod/pkg/inspect" ) @@ -29,8 +30,8 @@ func Exists(ctx context.Context, nameOrID string) (bool, error) { // List returns a list of images in local storage. The all boolean and filters parameters are optional // ways to alter the image query. -func List(ctx context.Context, all *bool, filters map[string][]string) ([]*handlers.ImageSummary, error) { - var imageSummary []*handlers.ImageSummary +func List(ctx context.Context, all *bool, filters map[string][]string) ([]*entities.ImageSummary, error) { + var imageSummary []*entities.ImageSummary conn, err := bindings.GetClient(ctx) if err != nil { return nil, err diff --git a/pkg/domain/entities/engine_image.go b/pkg/domain/entities/engine_image.go index 27676d781..d44fdaf53 100644 --- a/pkg/domain/entities/engine_image.go +++ b/pkg/domain/entities/engine_image.go @@ -7,6 +7,6 @@ import ( type ImageEngine interface { Delete(ctx context.Context, nameOrId string, opts ImageDeleteOptions) (*ImageDeleteReport, error) History(ctx context.Context, nameOrId string, opts ImageHistoryOptions) (*ImageHistoryReport, error) - List(ctx context.Context, opts ImageListOptions) (*ImageListReport, error) + List(ctx context.Context, opts ImageListOptions) ([]*ImageSummary, error) Prune(ctx context.Context, opts ImagePruneOptions) (*ImagePruneReport, error) } diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go index f18ee2651..f04317e37 100644 --- a/pkg/domain/entities/images.go +++ b/pkg/domain/entities/images.go @@ -48,22 +48,24 @@ func (i *Image) Id() string { } type ImageSummary struct { - Identifier - ID string `json:"Id"` - ParentId string `json:",omitempty"` - RepoTags []string `json:",omitempty"` - Created int `json:",omitempty"` - Size int `json:",omitempty"` - SharedSize int `json:",omitempty"` - VirtualSize int `json:",omitempty"` - Labels string `json:",omitempty"` - Containers int `json:",omitempty"` - ReadOnly bool `json:",omitempty"` - Dangling bool `json:",omitempty"` + ID string `json:"Id"` + ParentId string `json:",omitempty"` + RepoTags []string `json:",omitempty"` + Created int64 `json:",omitempty"` + Size int64 `json:",omitempty"` + SharedSize int `json:",omitempty"` + VirtualSize int64 `json:",omitempty"` + Labels map[string]string `json:",omitempty"` + Containers int `json:",omitempty"` + ReadOnly bool `json:",omitempty"` + Dangling bool `json:",omitempty"` // Podman extensions - Digest digest.Digest `json:",omitempty"` - ConfigDigest digest.Digest `json:",omitempty"` + Names []string `json:",omitempty"` + Digest string `json:",omitempty"` + Digests []string `json:",omitempty"` + ConfigDigest string `json:",omitempty"` + History []string `json:",omitempty"` } func (i *ImageSummary) Id() string { @@ -78,18 +80,6 @@ func (i *ImageSummary) IsDangling() bool { return i.Dangling } -type ImageOptions struct { - All bool - Digests bool - Filter []string - Format string - Noheading bool - NoTrunc bool - Quiet bool - Sort string - History bool -} - type ImageDeleteOptions struct { Force bool } @@ -124,21 +114,14 @@ type ImageInspectOptions struct { } type ImageListOptions struct { - All bool `json:"all" schema:"all"` - Digests bool `json:"digests" schema:"digests"` - Filter []string `json:",omitempty"` - Filters url.Values `json:"filters" schema:"filters"` - Format string `json:",omitempty"` - History bool `json:",omitempty"` - Noheading bool `json:",omitempty"` - NoTrunc bool `json:",omitempty"` - Quiet bool `json:",omitempty"` - Sort string `json:",omitempty"` + All bool `json:"all" schema:"all"` + Filter []string `json:",omitempty"` + Filters url.Values `json:"filters" schema:"filters"` } -type ImageListReport struct { - Images []ImageSummary -} +// type ImageListReport struct { +// Images []ImageSummary +// } type ImagePruneOptions struct { All bool diff --git a/pkg/domain/entities/set.go b/pkg/domain/entities/set.go new file mode 100644 index 000000000..c8d6cb1a9 --- /dev/null +++ b/pkg/domain/entities/set.go @@ -0,0 +1,45 @@ +package entities + +import ( + "strings" +) + +type stringSet struct { + m map[string]struct{} +} + +func NewStringSet(elem ...string) *stringSet { + s := &stringSet{} + s.m = make(map[string]struct{}, len(elem)) + for _, e := range elem { + s.Add(e) + } + return s +} + +func (s *stringSet) Add(elem string) { + s.m[elem] = struct{}{} +} + +func (s *stringSet) Remove(elem string) { + delete(s.m, elem) +} + +func (s *stringSet) Contains(elem string) bool { + _, ok := s.m[elem] + return ok +} + +func (s *stringSet) Elements() []string { + keys := make([]string, len(s.m)) + i := 0 + for k := range s.m { + keys[i] = k + i++ + } + return keys +} + +func (s *stringSet) String() string { + return strings.Join(s.Elements(), ", ") +} diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go index 2db08f259..6e9d7f566 100644 --- a/pkg/domain/infra/abi/images.go +++ b/pkg/domain/infra/abi/images.go @@ -39,35 +39,6 @@ func (ir *ImageEngine) Prune(ctx context.Context, opts entities.ImagePruneOption return &report, nil } -func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions) (*entities.ImageListReport, error) { - var ( - images []*libpodImage.Image - err error - ) - - filters := utils.ToLibpodFilters(opts.Filters) - if len(filters) > 0 { - images, err = ir.Libpod.ImageRuntime().GetImagesWithFilters(filters) - } else { - images, err = ir.Libpod.ImageRuntime().GetImages() - } - if err != nil { - return nil, err - } - - report := entities.ImageListReport{ - Images: make([]entities.ImageSummary, len(images)), - } - for i, img := range images { - hold := entities.ImageSummary{} - if err := utils.DeepCopy(&hold, img); err != nil { - return nil, err - } - report.Images[i] = hold - } - return &report, nil -} - func (ir *ImageEngine) History(ctx context.Context, nameOrId string, opts entities.ImageHistoryOptions) (*entities.ImageHistoryReport, error) { image, err := ir.Libpod.ImageRuntime().NewFromLocal(nameOrId) if err != nil { diff --git a/pkg/domain/infra/abi/images_list.go b/pkg/domain/infra/abi/images_list.go new file mode 100644 index 000000000..2f4020374 --- /dev/null +++ b/pkg/domain/infra/abi/images_list.go @@ -0,0 +1,80 @@ +// +build ABISupport + +package abi + +import ( + "context" + + libpodImage "github.com/containers/libpod/libpod/image" + "github.com/containers/libpod/pkg/domain/entities" +) + +func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions) ([]*entities.ImageSummary, error) { + var ( + images []*libpodImage.Image + err error + ) + + // TODO: Future work support for domain.Filters + // filters := utils.ToLibpodFilters(opts.Filters) + + if len(opts.Filter) > 0 { + images, err = ir.Libpod.ImageRuntime().GetImagesWithFilters(opts.Filter) + } else { + images, err = ir.Libpod.ImageRuntime().GetImages() + } + if err != nil { + return nil, err + } + + summaries := make([]*entities.ImageSummary, len(images)) + for i, img := range images { + var repoTags []string + if opts.All { + pairs, err := libpodImage.ReposToMap(img.Names()) + if err != nil { + return nil, err + } + + for repo, tags := range pairs { + for _, tag := range tags { + repoTags = append(repoTags, repo+":"+tag) + } + } + } else { + repoTags, _ = img.RepoTags() + } + + digests := make([]string, len(img.Digests())) + for j, d := range img.Digests() { + digests[j] = string(d) + } + + e := entities.ImageSummary{ + ID: img.ID(), + + ConfigDigest: string(img.ConfigDigest), + Created: img.Created().Unix(), + Dangling: img.Dangling(), + Digest: string(img.Digest()), + Digests: digests, + History: img.NamesHistory(), + Names: img.Names(), + ParentId: img.Parent, + ReadOnly: img.IsReadOnly(), + SharedSize: 0, + VirtualSize: img.VirtualSize, + RepoTags: repoTags, + } + e.Labels, _ = img.Labels(context.TODO()) + + ctnrs, _ := img.Containers() + e.Containers = len(ctnrs) + + sz, _ := img.Size(context.TODO()) + e.Size = int64(*sz) + + summaries[i] = &e + } + return summaries, nil +} diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go index 718685e57..60df40498 100644 --- a/pkg/domain/infra/tunnel/images.go +++ b/pkg/domain/infra/tunnel/images.go @@ -32,23 +32,22 @@ func (ir *ImageEngine) Delete(ctx context.Context, nameOrId string, opts entitie return &report, err } -func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions) (*entities.ImageListReport, error) { +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 } - report := entities.ImageListReport{ - Images: make([]entities.ImageSummary, len(images)), - } + 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 } - report.Images[i] = hold + is[i] = &hold } - return &report, nil + return is, nil } func (ir *ImageEngine) History(ctx context.Context, nameOrId string, opts entities.ImageHistoryOptions) (*entities.ImageHistoryReport, error) { |