[lxc-devel] [lxd/master] Make "lxc profile list" look like the other lists

stgraber on Github lxc-bot at linuxcontainers.org
Sat Oct 1 02:25:41 UTC 2016


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20161001/e30c9bcd/attachment.bin>
-------------- next part --------------
From ae5c07f56d8baace9056b09135ba1e8eb6578015 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Fri, 30 Sep 2016 22:10:09 -0400
Subject: [PATCH 1/3] Add a new used_by property to profiles
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 doc/api-extensions.md |  3 +++
 doc/rest-api.md       |  5 ++++-
 lxd/api_1.0.go        |  1 +
 lxd/profiles.go       | 17 ++++++++++++++++-
 shared/container.go   |  1 +
 5 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/doc/api-extensions.md b/doc/api-extensions.md
index 83818a9..546def9 100644
--- a/doc/api-extensions.md
+++ b/doc/api-extensions.md
@@ -115,3 +115,6 @@ This includes:
  * ipv4.address property on "nic" type devices (when nictype is "bridged")
  * ipv6.address property on "nic" type devices (when nictype is "bridged")
  * security.mac\_filtering property on "nic" type devices (when nictype is "bridged")
+
+## profile\_usedby
+Adds a new used\_by field to profile entries listing the containers that are using it.
diff --git a/doc/rest-api.md b/doc/rest-api.md
index 61ad513..ecd2648 100644
--- a/doc/rest-api.md
+++ b/doc/rest-api.md
@@ -1686,7 +1686,10 @@ Output:
                 "path": "/dev/kvm",
                 "type": "unix-char"
             }
-        }
+        },
+        "used_by": [
+            "/1.0/containers/blah"
+        ]
     }
 
 ### PUT (ETag supported)
diff --git a/lxd/api_1.0.go b/lxd/api_1.0.go
index d229f5f..b2f4ad9 100644
--- a/lxd/api_1.0.go
+++ b/lxd/api_1.0.go
@@ -70,6 +70,7 @@ func api10Get(d *Daemon, r *http.Request) Response {
 			"storage_zfs_use_refquota",
 			"storage_lvm_mount_options",
 			"network",
+			"profile_usedby",
 		},
 
 		"api_status":  "stable",
diff --git a/lxd/profiles.go b/lxd/profiles.go
index a76e612..30a9d45 100644
--- a/lxd/profiles.go
+++ b/lxd/profiles.go
@@ -109,7 +109,22 @@ var profilesCmd = Command{
 
 func doProfileGet(d *Daemon, name string) (*shared.ProfileConfig, error) {
 	_, profile, err := dbProfileGet(d.db, name)
-	return profile, err
+	if err != nil {
+		return nil, err
+	}
+
+	cts, err := dbProfileContainersGet(d.db, name)
+	if err != nil {
+		return nil, err
+	}
+
+	usedBy := []string{}
+	for _, ct := range cts {
+		usedBy = append(usedBy, fmt.Sprintf("/%s/containers/%s", shared.APIVersion, ct))
+	}
+	profile.UsedBy = usedBy
+
+	return profile, nil
 }
 
 func profileGet(d *Daemon, r *http.Request) Response {
diff --git a/shared/container.go b/shared/container.go
index a1d0b7c..cf558db 100644
--- a/shared/container.go
+++ b/shared/container.go
@@ -148,6 +148,7 @@ type ProfileConfig struct {
 	Config      map[string]string `json:"config"`
 	Description string            `json:"description"`
 	Devices     Devices           `json:"devices"`
+	UsedBy      []string          `json:"used_by"`
 }
 
 type NetworkConfig struct {

From 48adcf2aa7308bd222d42863abd1205473916b46 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Fri, 30 Sep 2016 22:18:57 -0400
Subject: [PATCH 2/3] Update "lxc profile list" to show a table
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 client.go      | 33 +++++----------------------------
 lxc/copy.go    |  8 +++++++-
 lxc/profile.go | 22 ++++++++++++++++++++--
 po/lxd.pot     | 34 +++++++++++++++++-----------------
 test/main.sh   |  2 +-
 5 files changed, 50 insertions(+), 49 deletions(-)

diff --git a/client.go b/client.go
index 58586a3..46609df 100644
--- a/client.go
+++ b/client.go
@@ -2329,45 +2329,22 @@ func (c *Client) PutProfile(name string, profile shared.ProfileConfig) error {
 	return err
 }
 
-func (c *Client) ListProfiles() ([]string, error) {
+func (c *Client) ListProfiles() ([]shared.ProfileConfig, error) {
 	if c.Remote.Public {
 		return nil, fmt.Errorf("This function isn't supported by public remotes.")
 	}
 
-	resp, err := c.get("profiles")
+	resp, err := c.get("profiles?recursion=1")
 	if err != nil {
 		return nil, err
 	}
 
-	var result []string
-
-	if err := json.Unmarshal(resp.Metadata, &result); err != nil {
+	profiles := []shared.ProfileConfig{}
+	if err := json.Unmarshal(resp.Metadata, &profiles); err != nil {
 		return nil, err
 	}
 
-	names := []string{}
-
-	for _, url := range result {
-		toScan := strings.Replace(url, "/", " ", -1)
-		version := ""
-		name := ""
-		count, err := fmt.Sscanf(toScan, " %s profiles %s", &version, &name)
-		if err != nil {
-			return nil, err
-		}
-
-		if count != 2 {
-			return nil, fmt.Errorf("bad profile url %s", url)
-		}
-
-		if version != shared.APIVersion {
-			return nil, fmt.Errorf("bad version in profile url")
-		}
-
-		names = append(names, name)
-	}
-
-	return names, nil
+	return profiles, nil
 }
 
 func (c *Client) AssignProfile(container, profile string) (*Response, error) {
diff --git a/lxc/copy.go b/lxc/copy.go
index cac2d50..9a696a8 100644
--- a/lxc/copy.go
+++ b/lxc/copy.go
@@ -149,11 +149,17 @@ func (c *copyCmd) copyContainer(config *lxd.Config, sourceResource string, destR
 	}
 
 	sourceProfs := shared.NewStringSet(status.Profiles)
-	destProfs, err := dest.ListProfiles()
+	destProfs := []string{}
+
+	profiles, err := dest.ListProfiles()
 	if err != nil {
 		return err
 	}
 
+	for _, profile := range profiles {
+		destProfs = append(destProfs, profile.Name)
+	}
+
 	if !sourceProfs.IsSubset(shared.NewStringSet(destProfs)) {
 		return fmt.Errorf(i18n.G("not all the profiles from the source exist on the target"))
 	}
diff --git a/lxc/profile.go b/lxc/profile.go
index 7d672d5..2d03eaa 100644
--- a/lxc/profile.go
+++ b/lxc/profile.go
@@ -4,9 +4,10 @@ import (
 	"fmt"
 	"io/ioutil"
 	"os"
-	"strings"
+	"sort"
 	"syscall"
 
+	"github.com/olekukonko/tablewriter"
 	"gopkg.in/yaml.v2"
 
 	"github.com/lxc/lxd"
@@ -431,6 +432,23 @@ func (c *profileCmd) doProfileList(config *lxd.Config, args []string) error {
 	if err != nil {
 		return err
 	}
-	fmt.Printf("%s\n", strings.Join(profiles, "\n"))
+
+	data := [][]string{}
+	for _, profile := range profiles {
+		strUsedBy := fmt.Sprintf("%d", len(profile.UsedBy))
+		data = append(data, []string{profile.Name, strUsedBy})
+	}
+
+	table := tablewriter.NewWriter(os.Stdout)
+	table.SetAutoWrapText(false)
+	table.SetAlignment(tablewriter.ALIGN_LEFT)
+	table.SetRowLine(true)
+	table.SetHeader([]string{
+		i18n.G("NAME"),
+		i18n.G("USED BY")})
+	sort.Sort(byName(data))
+	table.AppendBulk(data)
+	table.Render()
+
 	return nil
 }
diff --git a/po/lxd.pot b/po/lxd.pot
index 1d96f37..03aeb73 100644
--- a/po/lxd.pot
+++ b/po/lxd.pot
@@ -7,7 +7,7 @@
 msgid   ""
 msgstr  "Project-Id-Version: lxd\n"
         "Report-Msgid-Bugs-To: lxc-devel at lists.linuxcontainers.org\n"
-        "POT-Creation-Date: 2016-09-22 02:02-0400\n"
+        "POT-Creation-Date: 2016-09-30 22:18-0400\n"
         "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
         "Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
         "Language-Team: LANGUAGE <LL at li.org>\n"
@@ -80,7 +80,7 @@ msgid   "### This is a yaml representation of the network.\n"
         "### Note that only the configuration can be changed."
 msgstr  ""
 
-#: lxc/profile.go:26
+#: lxc/profile.go:27
 msgid   "### This is a yaml representation of the profile.\n"
         "### Any line starting with a '# will be ignored.\n"
         "###\n"
@@ -109,7 +109,7 @@ msgstr  ""
 msgid   "'/' not allowed in snapshot name"
 msgstr  ""
 
-#: lxc/profile.go:253
+#: lxc/profile.go:254
 msgid   "(none)"
 msgstr  ""
 
@@ -186,7 +186,7 @@ msgstr  ""
 msgid   "Can't unset key '%s', it's not currently set."
 msgstr  ""
 
-#: lxc/network.go:386 lxc/profile.go:419
+#: lxc/network.go:386 lxc/profile.go:420
 msgid   "Cannot provide container name to list"
 msgstr  ""
 
@@ -214,7 +214,7 @@ msgstr  ""
 msgid   "Config key/value to apply to the new container"
 msgstr  ""
 
-#: lxc/config.go:530 lxc/config.go:595 lxc/image.go:734 lxc/network.go:342 lxc/profile.go:217
+#: lxc/config.go:530 lxc/config.go:595 lxc/image.go:734 lxc/network.go:342 lxc/profile.go:218
 #, c-format
 msgid   "Config parsing error: %s"
 msgstr  ""
@@ -227,7 +227,7 @@ msgstr  ""
 msgid   "Container name is mandatory"
 msgstr  ""
 
-#: lxc/copy.go:140 lxc/copy.go:228 lxc/init.go:227
+#: lxc/copy.go:140 lxc/copy.go:234 lxc/init.go:227
 #, c-format
 msgid   "Container name is: %s"
 msgstr  ""
@@ -582,7 +582,7 @@ msgstr  ""
 msgid   "Make the image public"
 msgstr  ""
 
-#: lxc/profile.go:47
+#: lxc/profile.go:48
 msgid   "Manage configuration profiles.\n"
         "\n"
         "lxc profile list [filters]                     List available profiles.\n"
@@ -830,7 +830,7 @@ msgstr  ""
 msgid   "Must supply container name for: "
 msgstr  ""
 
-#: lxc/list.go:428 lxc/network.go:422 lxc/remote.go:375
+#: lxc/list.go:428 lxc/network.go:422 lxc/profile.go:447 lxc/remote.go:375
 msgid   "NAME"
 msgstr  ""
 
@@ -945,7 +945,7 @@ msgid   "Presents details on how to use LXD.\n"
         "lxd help [--all]"
 msgstr  ""
 
-#: lxc/network.go:343 lxc/profile.go:218
+#: lxc/network.go:343 lxc/profile.go:219
 msgid   "Press enter to open the editor again"
 msgstr  ""
 
@@ -980,22 +980,22 @@ msgstr  ""
 msgid   "Processes: %d"
 msgstr  ""
 
-#: lxc/profile.go:274
+#: lxc/profile.go:275
 #, c-format
 msgid   "Profile %s added to %s"
 msgstr  ""
 
-#: lxc/profile.go:169
+#: lxc/profile.go:170
 #, c-format
 msgid   "Profile %s created"
 msgstr  ""
 
-#: lxc/profile.go:239
+#: lxc/profile.go:240
 #, c-format
 msgid   "Profile %s deleted"
 msgstr  ""
 
-#: lxc/profile.go:305
+#: lxc/profile.go:306
 #, c-format
 msgid   "Profile %s removed from %s"
 msgstr  ""
@@ -1004,7 +1004,7 @@ msgstr  ""
 msgid   "Profile to apply to the new container"
 msgstr  ""
 
-#: lxc/profile.go:255
+#: lxc/profile.go:256
 #, c-format
 msgid   "Profiles %s applied to %s"
 msgstr  ""
@@ -1259,7 +1259,7 @@ msgstr  ""
 msgid   "URL"
 msgstr  ""
 
-#: lxc/network.go:425
+#: lxc/network.go:425 lxc/profile.go:448
 msgid   "USED BY"
 msgstr  ""
 
@@ -1333,7 +1333,7 @@ msgstr  ""
 msgid   "default"
 msgstr  ""
 
-#: lxc/copy.go:131 lxc/copy.go:136 lxc/copy.go:219 lxc/copy.go:224 lxc/init.go:217 lxc/init.go:222 lxc/launch.go:111 lxc/launch.go:116
+#: lxc/copy.go:131 lxc/copy.go:136 lxc/copy.go:225 lxc/copy.go:230 lxc/init.go:217 lxc/init.go:222 lxc/launch.go:111 lxc/launch.go:116
 msgid   "didn't get any affected image, container or snapshot from server"
 msgstr  ""
 
@@ -1363,7 +1363,7 @@ msgstr  ""
 msgid   "no"
 msgstr  ""
 
-#: lxc/copy.go:158
+#: lxc/copy.go:164
 msgid   "not all the profiles from the source exist on the target"
 msgstr  ""
 
diff --git a/test/main.sh b/test/main.sh
index 5afa7f9..77c0acd 100755
--- a/test/main.sh
+++ b/test/main.sh
@@ -226,7 +226,7 @@ kill_lxd() {
 
     # Delete all profiles
     echo "==> Deleting all profiles"
-    for profile in $(lxc profile list --force-local); do
+    for profile in $(lxc profile list --force-local | tail -n+3 | grep "^| " | cut -d' ' -f2); do
       lxc profile delete "${profile}" --force-local || true
     done
 

From 4224417cda6ea4678a578c93b5e249b83eda9620 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Fri, 30 Sep 2016 22:20:55 -0400
Subject: [PATCH 3/3] test: Make container cleanup more reliable
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

With --fast, a container with multiple IPs won't result in an empty
string being considered as a container name.

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 test/main.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/main.sh b/test/main.sh
index 77c0acd..f684ddf 100755
--- a/test/main.sh
+++ b/test/main.sh
@@ -214,7 +214,7 @@ kill_lxd() {
   if [ -e "${daemon_dir}/unix.socket" ]; then
     # Delete all containers
     echo "==> Deleting all containers"
-    for container in $(lxc list --force-local | tail -n+3 | grep "^| " | cut -d' ' -f2); do
+    for container in $(lxc list --fast --force-local | tail -n+3 | grep "^| " | cut -d' ' -f2); do
       lxc delete "${container}" --force-local -f || true
     done
 


More information about the lxc-devel mailing list