Skip to content

Commit

Permalink
Merge pull request #4568 from openSUSE/history
Browse files Browse the repository at this point in the history
Add support for image name history
  • Loading branch information
openshift-merge-robot authored Nov 27, 2019
2 parents 27a09f8 + 63e46cc commit 2178875
Show file tree
Hide file tree
Showing 24 changed files with 346 additions and 40 deletions.
2 changes: 2 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -1698,6 +1698,8 @@ isParent [bool](https://godoc.org/builtin#bool)
topLayer [string](https://godoc.org/builtin#string)

readOnly [bool](https://godoc.org/builtin#bool)

history [[]string](#[]string)
### <a name="ImageHistory"></a>type ImageHistory

ImageHistory describes the returned structure from ImageHistory.
Expand Down
1 change: 1 addition & 0 deletions cmd/podman/cliconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ type ImagesValues struct {
NoTrunc bool
Quiet bool
Sort string
History bool
}

type EventValues struct {
Expand Down
10 changes: 10 additions & 0 deletions cmd/podman/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type imagesTemplateParams struct {
CreatedTime time.Time
Size string
ReadOnly bool
History string
}

type imagesJSONParams struct {
Expand All @@ -42,6 +43,7 @@ type imagesJSONParams struct {
Created time.Time `json:"created"`
Size *uint64 `json:"size"`
ReadOnly bool `json:"readonly"`
History []string `json:"history"`
}

type imagesOptions struct {
Expand All @@ -53,6 +55,7 @@ type imagesOptions struct {
outputformat string
sort string
all bool
history bool
}

// Type declaration and functions for sorting the images output
Expand Down Expand Up @@ -124,6 +127,7 @@ func imagesInit(command *cliconfig.ImagesValues) {
flags.BoolVar(&command.NoTrunc, "no-trunc", false, "Do not truncate output")
flags.BoolVarP(&command.Quiet, "quiet", "q", false, "Display only image IDs")
flags.StringVar(&command.Sort, "sort", "created", "Sort by created, id, repository, size, or tag")
flags.BoolVarP(&command.History, "history", "", false, "Display the image name history")

}

Expand Down Expand Up @@ -171,6 +175,7 @@ func imagesCmd(c *cliconfig.ImagesValues) error {
format: c.Format,
sort: c.Sort,
all: c.All,
history: c.History,
}

opts.outputformat = opts.setOutputFormat()
Expand Down Expand Up @@ -214,6 +219,9 @@ func (i imagesOptions) setOutputFormat() string {
format += "{{.Digest}}\t"
}
format += "{{.ID}}\t{{.Created}}\t{{.Size}}\t"
if i.history {
format += "{{if .History}}{{.History}}{{else}}<none>{{end}}\t"
}
return format
}

Expand Down Expand Up @@ -306,6 +314,7 @@ func getImagesTemplateOutput(ctx context.Context, images []*adapter.ContainerIma
Created: units.HumanDuration(time.Since(createdTime)) + " ago",
Size: sizeStr,
ReadOnly: img.IsReadOnly(),
History: strings.Join(img.NamesHistory(), ", "),
}
imagesOutput = append(imagesOutput, params)
if opts.quiet { // Show only one image ID when quiet
Expand Down Expand Up @@ -336,6 +345,7 @@ func getImagesJSONOutput(ctx context.Context, images []*adapter.ContainerImage)
Created: img.Created(),
Size: size,
ReadOnly: img.IsReadOnly(),
History: img.NamesHistory(),
}
imagesOutput = append(imagesOutput, params)
}
Expand Down
3 changes: 2 additions & 1 deletion cmd/podman/varlink/io.podman.varlink
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ type Image (
labels: [string]string,
isParent: bool,
topLayer: string,
readOnly: bool
readOnly: bool,
history: []string
)

# ImageHistory describes the returned structure from ImageHistory.
Expand Down
1 change: 1 addition & 0 deletions completions/bash/podman
Original file line number Diff line number Diff line change
Expand Up @@ -1563,6 +1563,7 @@ _podman_images() {
--filter
-h
--help
--history
--no-trunc
--notruncate
-n
Expand Down
4 changes: 4 additions & 0 deletions docs/source/markdown/podman-images.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ Filter output based on conditions provided
Change the default output format. This can be of a supported type like 'json'
or a Go template.

**--history**

Display the history of image names. If an image gets re-tagged or untagged, then the image name history gets prepended (latest image first). This is especially useful when undoing a tag operation or an image does not contain any name because it has been untagged.

**--noheading**, **-n**

Omit the table headings from the listing of images.
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ require (
github.com/containers/conmon v2.0.2+incompatible // indirect
github.com/containers/image/v5 v5.0.0
github.com/containers/psgo v1.3.2
github.com/containers/storage v1.14.0
github.com/containers/storage v1.15.0
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
github.com/cri-o/ocicni v0.1.1-0.20190920040751-deac903fd99b
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ github.com/containers/storage v1.13.5 h1:/SUzGeOP2HDijpF7Yur21Ch6WTZC1BNeZF917CW
github.com/containers/storage v1.13.5/go.mod h1:HELz8Sn+UVbPaUZMI8RvIG9doD4y4z6Gtg4k7xdd2ZY=
github.com/containers/storage v1.14.0 h1:LbX6WZaDmkXt4DT4xWIg3YXAWd6oA4K9Fi6/KG1xt84=
github.com/containers/storage v1.14.0/go.mod h1:qGPsti/qC1xxX+xcpHfiTMT+8ThVE2Jf83wFHHqkDAY=
github.com/containers/storage v1.15.0 h1:QNW7jJ94ccGcAbFIOSMHUAsUxvHceb71ecLye9EDrkk=
github.com/containers/storage v1.15.0/go.mod h1:qGPsti/qC1xxX+xcpHfiTMT+8ThVE2Jf83wFHHqkDAY=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-iptables v0.4.2 h1:KH0EwId05JwWIfb96gWvkiT2cbuOu8ygqUaB+yPAwIg=
Expand Down
15 changes: 15 additions & 0 deletions libpod/image/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,21 @@ func (i *Image) Names() []string {
return i.image.Names
}

// NamesHistory returns a string array of names previously associated with the
// image, which may be a mixture of tags and digests
func (i *Image) NamesHistory() []string {
if len(i.image.Names) > 0 && len(i.image.NamesHistory) > 0 &&
// We compare the latest (time-referenced) tags for equality and skip
// it in the history if they match to not display them twice. We have
// to compare like this, because `i.image.Names` (latest last) gets
// appended on retag, whereas `i.image.NamesHistory` gets prepended
// (latest first)
i.image.Names[len(i.image.Names)-1] == i.image.NamesHistory[0] {
return i.image.NamesHistory[1:]
}
return i.image.NamesHistory
}

// RepoTags returns a string array of repotags associated with the image
func (i *Image) RepoTags() ([]string, error) {
var repoTags []string
Expand Down
67 changes: 37 additions & 30 deletions pkg/adapter/runtime_remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,21 +136,22 @@ type ContainerImage struct {
}

type remoteImage struct {
ID string
Labels map[string]string
RepoTags []string
RepoDigests []string
Parent string
Size int64
Created time.Time
InputName string
Names []string
Digest digest.Digest
Digests []digest.Digest
isParent bool
Runtime *LocalRuntime
TopLayer string
ReadOnly bool
ID string
Labels map[string]string
RepoTags []string
RepoDigests []string
Parent string
Size int64
Created time.Time
InputName string
Names []string
Digest digest.Digest
Digests []digest.Digest
isParent bool
Runtime *LocalRuntime
TopLayer string
ReadOnly bool
NamesHistory []string
}

// Container ...
Expand Down Expand Up @@ -232,21 +233,22 @@ func imageInListToContainerImage(i iopodman.Image, name string, runtime *LocalRu
digests = append(digests, digest.Digest(d))
}
ri := remoteImage{
InputName: name,
ID: i.Id,
Digest: digest.Digest(i.Digest),
Digests: digests,
Labels: i.Labels,
RepoTags: i.RepoTags,
RepoDigests: i.RepoTags,
Parent: i.ParentId,
Size: i.Size,
Created: created,
Names: i.RepoTags,
isParent: i.IsParent,
Runtime: runtime,
TopLayer: i.TopLayer,
ReadOnly: i.ReadOnly,
InputName: name,
ID: i.Id,
Digest: digest.Digest(i.Digest),
Digests: digests,
Labels: i.Labels,
RepoTags: i.RepoTags,
RepoDigests: i.RepoTags,
Parent: i.ParentId,
Size: i.Size,
Created: created,
Names: i.RepoTags,
isParent: i.IsParent,
Runtime: runtime,
TopLayer: i.TopLayer,
ReadOnly: i.ReadOnly,
NamesHistory: i.History,
}
return &ContainerImage{ri}, nil
}
Expand Down Expand Up @@ -337,6 +339,11 @@ func (ci *ContainerImage) Names() []string {
return ci.remoteImage.Names
}

// NamesHistory returns a string array of names previously associated with the image
func (ci *ContainerImage) NamesHistory() []string {
return ci.remoteImage.NamesHistory
}

// Created returns the time the image was created
func (ci *ContainerImage) Created() time.Time {
return ci.remoteImage.Created
Expand Down
2 changes: 2 additions & 0 deletions pkg/varlinkapi/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ func (i *LibpodAPI) ListImages(call iopodman.VarlinkCall) error {
Labels: labels,
IsParent: isParent,
ReadOnly: image.IsReadOnly(),
History: image.NamesHistory(),
}
imageList = append(imageList, i)
}
Expand Down Expand Up @@ -111,6 +112,7 @@ func (i *LibpodAPI) GetImage(call iopodman.VarlinkCall, id string) error {
Labels: labels,
TopLayer: newImage.TopLayer(),
ReadOnly: newImage.IsReadOnly(),
History: newImage.NamesHistory(),
}
return call.ReplyGetImage(il)
}
Expand Down
15 changes: 15 additions & 0 deletions test/system/010-images.bats
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,19 @@ size | [0-9]\\\+

}

@test "podman images - history output" {
run_podman images --format json
actual=$(echo $output | jq -r '.[0].history | length')
is "$actual" "0"

run_podman tag $PODMAN_TEST_IMAGE_REGISTRY/$PODMAN_TEST_IMAGE_USER/$PODMAN_TEST_IMAGE_NAME:$PODMAN_TEST_IMAGE_TAG test-image
run_podman images --format json
actual=$(echo $output | jq -r '.[1].history | length')
is "$actual" "0"
actual=$(echo $output | jq -r '.[0].history | length')
is "$actual" "1"
actual=$(echo $output | jq -r '.[0].history[0]')
is "$actual" "$PODMAN_TEST_IMAGE_REGISTRY/$PODMAN_TEST_IMAGE_USER/$PODMAN_TEST_IMAGE_NAME:$PODMAN_TEST_IMAGE_TAG"
}

# vim: filetype=sh
2 changes: 1 addition & 1 deletion vendor/github.com/containers/storage/VERSION

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions vendor/github.com/containers/storage/images.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 2178875

Please sign in to comment.