[lxc-devel] [lxd/master] Add --format and json output for image list command
ctrlrsf on Github
lxc-bot at linuxcontainers.org
Tue May 17 18:35:49 UTC 2016
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 5644 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20160517/efcec008/attachment.bin>
-------------- next part --------------
From 39751b85e083f3fa629e9be23f02d3e8b8097f1e Mon Sep 17 00:00:00 2001
From: Rene Fragoso <ctrlrsf at gmail.com>
Date: Tue, 17 May 2016 14:23:17 -0400
Subject: [PATCH] Add --format and json output for image list command
Adds the --format option to the `lxc image list` command. Possible options are
table and json.
Image list filters still work regardless of output format.
--format table example:
```
$ lxc image list images: 'description=.*yakkety.*s390x.*' --format table
+-------------------------------+--------------+--------+-----------------------------------------+-------+---------+------------------------------+
| ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCH | SIZE | UPLOAD DATE |
+-------------------------------+--------------+--------+-----------------------------------------+-------+---------+------------------------------+
| ubuntu/yakkety/s390x (1 more) | 03a93a03d6bb | yes | Ubuntu yakkety (s390x) (20160517_03:49) | s390x | 73.19MB | May 17, 2016 at 4:26am (UTC) |
+-------------------------------+--------------+--------+-----------------------------------------+-------+---------+------------------------------+
| | 42f6c2bb9348 | yes | Ubuntu yakkety (s390x) (20160515_03:49) | s390x | 73.09MB | May 15, 2016 at 5:20am (UTC) |
+-------------------------------+--------------+--------+-----------------------------------------+-------+---------+------------------------------+
| | a6539f9ece07 | yes | Ubuntu yakkety (s390x) (20160515_09:20) | s390x | 73.19MB | May 16, 2016 at 6:22pm (UTC) |
+-------------------------------+--------------+--------+-----------------------------------------+-------+---------+------------------------------+
```
--format json example:
```
$ lxc image list images: 'description=.*yakkety.*s390x.*' --format json
[{"aliases":[],"architecture":"s390x","cached":false,"filename":"ubuntu-yakkety-s390x-default-20160515_03:49.tar.xz","fingerprint":"42f6c2bb9348e27a8a048ce9657574cc524473bfa801902f4461da1ca1a456ba","properties":{"architecture":"s390x","build":"20160515_03:49","description":"Ubuntu
yakkety (s390x)
(20160515_03:49)","distribution":"ubuntu","release":"yakkety"},"public":true,"size":76642122,"auto_update":false,"created_at":"2016-05-15T05:20:21Z","expires_at":"1970-01-01T00:00:00Z","last_used_at":"0001-01-01T00:00:00Z","uploaded_at":"2016-05-15T05:20:21Z"},{},{}]
[{"aliases":[],"architecture":"s390x","cached":false,"filename":"ubuntu-yakkety-s390x-default-20160515_03:49.tar.xz","fingerprint":"42f6c2bb9348e27a8a048ce9657574cc524473bfa801902f4461da1ca1a456ba","properties":{"architecture":"s390x","build":"20160515_03:49","description":"Ubuntu
yakkety (s390x)
(20160515_03:49)","distribution":"ubuntu","release":"yakkety"},"public":true,"size":76642122,"auto_update":false,"created_at":"2016-05-15T05:20:21Z","expires_at":"1970-01-01T00:00:00Z","last_used_at":"0001-01-01T00:00:00Z","uploaded_at":"2016-05-15T05:20:21Z"},{"aliases":[],"architecture":"s390x","cached":false,"filename":"ubuntu-yakkety-s390x-default-20160515_09:20.tar.xz","fingerprint":"a6539f9ece0734574e6ffdaf81e421975fbeb32ac2637b16fe2cbc5648c909fd","properties":{"architecture":"s390x","build":"20160515_09:20","description":"Ubuntu
yakkety (s390x)
(20160515_09:20)","distribution":"ubuntu","release":"yakkety"},"public":true,"size":76743878,"auto_update":false,"created_at":"2016-05-16T18:22:41Z","expires_at":"1970-01-01T00:00:00Z","last_used_at":"0001-01-01T00:00:00Z","uploaded_at":"2016-05-16T18:22:41Z"},{}]
[{"aliases":[],"architecture":"s390x","cached":false,"filename":"ubuntu-yakkety-s390x-default-20160515_03:49.tar.xz","fingerprint":"42f6c2bb9348e27a8a048ce9657574cc524473bfa801902f4461da1ca1a456ba","properties":{"architecture":"s390x","build":"20160515_03:49","description":"Ubuntu
yakkety (s390x)
(20160515_03:49)","distribution":"ubuntu","release":"yakkety"},"public":true,"size":76642122,"auto_update":false,"created_at":"2016-05-15T05:20:21Z","expires_at":"1970-01-01T00:00:00Z","last_used_at":"0001-01-01T00:00:00Z","uploaded_at":"2016-05-15T05:20:21Z"},{"aliases":[],"architecture":"s390x","cached":false,"filename":"ubuntu-yakkety-s390x-default-20160515_09:20.tar.xz","fingerprint":"a6539f9ece0734574e6ffdaf81e421975fbeb32ac2637b16fe2cbc5648c909fd","properties":{"architecture":"s390x","build":"20160515_09:20","description":"Ubuntu
yakkety (s390x)
(20160515_09:20)","distribution":"ubuntu","release":"yakkety"},"public":true,"size":76743878,"auto_update":false,"created_at":"2016-05-16T18:22:41Z","expires_at":"1970-01-01T00:00:00Z","last_used_at":"0001-01-01T00:00:00Z","uploaded_at":"2016-05-16T18:22:41Z"},{"aliases":[{"name":"ubuntu/yakkety/s390x/default","description":"Ubuntu
yakkety (s390x)
(default)"},{"name":"ubuntu/yakkety/s390x","description":"Ubuntu yakkety
(s390x)"}],"architecture":"s390x","cached":false,"filename":"ubuntu-yakkety-s390x-default-20160517_03:49.tar.xz","fingerprint":"03a93a03d6bb370a129518c0fd53aa6b199342d8ef40c643c43710972334c4df","properties":{"architecture":"s390x","build":"20160517_03:49","description":"Ubuntu
yakkety (s390x)
(20160517_03:49)","distribution":"ubuntu","release":"yakkety"},"public":true,"size":76740678,"auto_update":false,"created_at":"2016-05-17T04:26:27Z","expires_at":"1970-01-01T00:00:00Z","last_used_at":"0001-01-01T00:00:00Z","uploaded_at":"2016-05-17T04:26:27Z"}]
```
Closes https://github.com/lxc/lxd/issues/1951
Signed-off-by: Rene Fragoso <ctrlrsf at gmail.com>
---
lxc/image.go | 100 ++++++++++++++++++++++++++++++++++++++---------------------
1 file changed, 64 insertions(+), 36 deletions(-)
diff --git a/lxc/image.go b/lxc/image.go
index 752b9c6..fad808e 100644
--- a/lxc/image.go
+++ b/lxc/image.go
@@ -1,6 +1,7 @@
package main
import (
+ "encoding/json"
"fmt"
"io/ioutil"
"os"
@@ -73,6 +74,7 @@ type imageCmd struct {
publicImage bool
copyAliases bool
autoUpdate bool
+ format string
}
func (c *imageCmd) showByDefault() bool {
@@ -126,7 +128,7 @@ lxc image export [remote:]<image>
lxc image info [remote:]<image>
Print everything LXD knows about a given image.
-lxc image list [remote:] [filter]
+lxc image list [remote:] [filter] [--format table|json]
List images in the LXD image store. Filters may be of the
<key>=<value> form for property based filtering, or part of the image
hash or part of the image alias name.
@@ -155,6 +157,7 @@ func (c *imageCmd) flags() {
gnuflag.BoolVar(&c.copyAliases, "copy-aliases", false, i18n.G("Copy aliases from source"))
gnuflag.BoolVar(&c.autoUpdate, "auto-update", false, i18n.G("Keep the image up to date after initial copy"))
gnuflag.Var(&c.addAliases, "alias", i18n.G("New alias to define at target"))
+ gnuflag.StringVar(&c.format, "format", "table", i18n.G("Format"))
}
func (c *imageCmd) doImageAlias(config *lxd.Config, args []string) error {
@@ -446,11 +449,20 @@ func (c *imageCmd) run(config *lxd.Config, args []string) error {
return err
}
- images, err := d.ListImages()
+ var images []shared.ImageInfo
+ allImages, err := d.ListImages()
if err != nil {
return err
}
+ for _, image := range allImages {
+ if !c.imageShouldShow(filters, &image) {
+ continue
+ }
+
+ images = append(images, image)
+ }
+
return c.showImages(images, filters)
case "edit":
@@ -572,46 +584,62 @@ func (c *imageCmd) findDescription(props map[string]string) string {
}
func (c *imageCmd) showImages(images []shared.ImageInfo, filters []string) error {
- data := [][]string{}
- for _, image := range images {
- if !c.imageShouldShow(filters, &image) {
- continue
- }
+ switch c.format {
+ case listFormatTable:
+ data := [][]string{}
+ for _, image := range images {
+ if !c.imageShouldShow(filters, &image) {
+ continue
+ }
- shortest := c.shortestAlias(image.Aliases)
- if len(image.Aliases) > 1 {
- shortest = fmt.Sprintf(i18n.G("%s (%d more)"), shortest, len(image.Aliases)-1)
- }
- fp := image.Fingerprint[0:12]
- public := i18n.G("no")
- description := c.findDescription(image.Properties)
+ shortest := c.shortestAlias(image.Aliases)
+ if len(image.Aliases) > 1 {
+ shortest = fmt.Sprintf(i18n.G("%s (%d more)"), shortest, len(image.Aliases)-1)
+ }
+ fp := image.Fingerprint[0:12]
+ public := i18n.G("no")
+ description := c.findDescription(image.Properties)
- if image.Public {
- public = i18n.G("yes")
+ if image.Public {
+ public = i18n.G("yes")
+ }
+
+ const layout = "Jan 2, 2006 at 3:04pm (MST)"
+ uploaded := image.UploadDate.UTC().Format(layout)
+ size := fmt.Sprintf("%.2fMB", float64(image.Size)/1024.0/1024.0)
+ data = append(data, []string{shortest, fp, public, description, image.Architecture, size, uploaded})
+ }
+
+ table := tablewriter.NewWriter(os.Stdout)
+ table.SetAutoWrapText(false)
+ table.SetAlignment(tablewriter.ALIGN_LEFT)
+ table.SetRowLine(true)
+ table.SetHeader([]string{
+ i18n.G("ALIAS"),
+ i18n.G("FINGERPRINT"),
+ i18n.G("PUBLIC"),
+ i18n.G("DESCRIPTION"),
+ i18n.G("ARCH"),
+ i18n.G("SIZE"),
+ i18n.G("UPLOAD DATE")})
+ sort.Sort(SortImage(data))
+ table.AppendBulk(data)
+ table.Render()
+ case listFormatJSON:
+ data := make([]*shared.ImageInfo, len(images))
+ for i := range images {
+ data[i] = &images[i]
+ enc := json.NewEncoder(os.Stdout)
+ err := enc.Encode(data)
+ if err != nil {
+ return err
+ }
}
- const layout = "Jan 2, 2006 at 3:04pm (MST)"
- uploaded := image.UploadDate.UTC().Format(layout)
- size := fmt.Sprintf("%.2fMB", float64(image.Size)/1024.0/1024.0)
- data = append(data, []string{shortest, fp, public, description, image.Architecture, size, uploaded})
+ default:
+ return fmt.Errorf("invalid format %q", c.format)
}
- table := tablewriter.NewWriter(os.Stdout)
- table.SetAutoWrapText(false)
- table.SetAlignment(tablewriter.ALIGN_LEFT)
- table.SetRowLine(true)
- table.SetHeader([]string{
- i18n.G("ALIAS"),
- i18n.G("FINGERPRINT"),
- i18n.G("PUBLIC"),
- i18n.G("DESCRIPTION"),
- i18n.G("ARCH"),
- i18n.G("SIZE"),
- i18n.G("UPLOAD DATE")})
- sort.Sort(SortImage(data))
- table.AppendBulk(data)
- table.Render()
-
return nil
}
More information about the lxc-devel
mailing list