[lxc-devel] [lxd/master] Bugfix and minor improvements
stgraber on Github
lxc-bot at linuxcontainers.org
Mon Aug 15 21:34:35 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/20160815/b7d2945f/attachment.bin>
-------------- next part --------------
From 1342bd8261349626122da0f3cf9663edaf952064 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 15 Aug 2016 15:10:35 -0400
Subject: [PATCH 1/5] Report download progress on image import
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 | 39 ++++++++++++++++++++++++++++++++++++++-
lxc/image.go | 6 +++++-
po/lxd.pot | 37 +++++++++++++++++++++----------------
3 files changed, 64 insertions(+), 18 deletions(-)
diff --git a/client.go b/client.go
index 84f9558..17dc0a6 100644
--- a/client.go
+++ b/client.go
@@ -886,7 +886,7 @@ func (c *Client) ExportImage(image string, target string) (string, error) {
return destpath, nil
}
-func (c *Client) PostImageURL(imageFile string, public bool, aliases []string) (string, error) {
+func (c *Client) PostImageURL(imageFile string, public bool, aliases []string, progressHandler func(progress string)) (string, error) {
if c.Remote.Public {
return "", fmt.Errorf("This function isn't supported by public remotes.")
}
@@ -897,11 +897,48 @@ func (c *Client) PostImageURL(imageFile string, public bool, aliases []string) (
"url": imageFile}
body := shared.Jmap{"public": public, "source": source}
+ operation := ""
+ handler := func(msg interface{}) {
+ if msg == nil {
+ return
+ }
+
+ event := msg.(map[string]interface{})
+ if event["type"].(string) != "operation" {
+ return
+ }
+
+ if event["metadata"] == nil {
+ return
+ }
+
+ md := event["metadata"].(map[string]interface{})
+ if !strings.HasSuffix(operation, md["id"].(string)) {
+ return
+ }
+
+ if md["metadata"] == nil {
+ return
+ }
+
+ opMd := md["metadata"].(map[string]interface{})
+ _, ok := opMd["download_progress"]
+ if ok {
+ progressHandler(opMd["download_progress"].(string))
+ }
+ }
+
+ if progressHandler != nil {
+ go c.Monitor([]string{"operation"}, handler)
+ }
+
resp, err := c.post("images", body, Async)
if err != nil {
return "", err
}
+ operation = resp.Operation
+
op, err := c.WaitFor(resp.Operation)
if err != nil {
return "", err
diff --git a/lxc/image.go b/lxc/image.go
index d878f22..1016852 100644
--- a/lxc/image.go
+++ b/lxc/image.go
@@ -424,7 +424,11 @@ func (c *imageCmd) run(config *lxd.Config, args []string) error {
}
if strings.HasPrefix(imageFile, "https://") {
- fingerprint, err = d.PostImageURL(imageFile, c.publicImage, c.addAliases)
+ progressHandler := func(progress string) {
+ fmt.Printf(i18n.G("Importing the image: %s")+"\r", progress)
+ }
+
+ fingerprint, err = d.PostImageURL(imageFile, c.publicImage, c.addAliases, progressHandler)
} else if strings.HasPrefix(imageFile, "http://") {
return fmt.Errorf(i18n.G("Only https:// is supported for remote image import."))
} else {
diff --git a/po/lxd.pot b/po/lxd.pot
index b334194..dc1d89e 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-07-26 14:46+0200\n"
+ "POT-Creation-Date: 2016-08-15 15:10-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"
@@ -77,7 +77,7 @@ msgid "### This is a yaml representation of the profile.\n"
"### Note that the name is shown but cannot be changed"
msgstr ""
-#: lxc/image.go:612
+#: lxc/image.go:616
#, c-format
msgid "%s (%d more)"
msgstr ""
@@ -90,11 +90,11 @@ msgstr ""
msgid "(none)"
msgstr ""
-#: lxc/image.go:633 lxc/image.go:675
+#: lxc/image.go:637 lxc/image.go:679
msgid "ALIAS"
msgstr ""
-#: lxc/image.go:637
+#: lxc/image.go:641
msgid "ARCH"
msgstr ""
@@ -187,7 +187,7 @@ msgstr ""
msgid "Config key/value to apply to the new container"
msgstr ""
-#: lxc/config.go:531 lxc/config.go:596 lxc/image.go:729 lxc/profile.go:218
+#: lxc/config.go:531 lxc/config.go:596 lxc/image.go:733 lxc/profile.go:218
#, c-format
msgid "Config parsing error: %s"
msgstr ""
@@ -259,7 +259,7 @@ msgstr ""
msgid "Creating the container"
msgstr ""
-#: lxc/image.go:636 lxc/image.go:677
+#: lxc/image.go:640 lxc/image.go:681
msgid "DESCRIPTION"
msgstr ""
@@ -326,7 +326,7 @@ msgstr ""
msgid "Expires: never"
msgstr ""
-#: lxc/config.go:273 lxc/image.go:634 lxc/image.go:676
+#: lxc/config.go:273 lxc/image.go:638 lxc/image.go:680
msgid "FINGERPRINT"
msgstr ""
@@ -393,11 +393,16 @@ msgstr ""
msgid "Image copied successfully!"
msgstr ""
-#: lxc/image.go:437
+#: lxc/image.go:441
#, c-format
msgid "Image imported with fingerprint: %s"
msgstr ""
+#: lxc/image.go:428
+#, c-format
+msgid "Importing the image: %s"
+msgstr ""
+
#: lxc/init.go:73
msgid "Initialize a container from a particular image.\n"
"\n"
@@ -781,7 +786,7 @@ msgstr ""
msgid "Only https URLs are supported for simplestreams"
msgstr ""
-#: lxc/image.go:429
+#: lxc/image.go:433
msgid "Only https:// is supported for remote image import."
msgstr ""
@@ -789,7 +794,7 @@ msgstr ""
msgid "Options:"
msgstr ""
-#: lxc/image.go:533
+#: lxc/image.go:537
#, c-format
msgid "Output is in %s"
msgstr ""
@@ -814,7 +819,7 @@ msgstr ""
msgid "PROTOCOL"
msgstr ""
-#: lxc/image.go:635 lxc/remote.go:379
+#: lxc/image.go:639 lxc/remote.go:379
msgid "PUBLIC"
msgstr ""
@@ -853,7 +858,7 @@ msgstr ""
msgid "Press enter to open the editor again"
msgstr ""
-#: lxc/config.go:532 lxc/config.go:597 lxc/image.go:730
+#: lxc/config.go:532 lxc/config.go:597 lxc/image.go:734
msgid "Press enter to start the editor again"
msgstr ""
@@ -955,7 +960,7 @@ msgstr ""
msgid "Retrieving image: %s"
msgstr ""
-#: lxc/image.go:638
+#: lxc/image.go:642
msgid "SIZE"
msgstr ""
@@ -1122,7 +1127,7 @@ msgstr ""
msgid "Type: persistent"
msgstr ""
-#: lxc/image.go:639
+#: lxc/image.go:643
msgid "UPLOAD DATE"
msgstr ""
@@ -1218,7 +1223,7 @@ msgstr ""
msgid "got bad version"
msgstr ""
-#: lxc/image.go:336 lxc/image.go:615
+#: lxc/image.go:336 lxc/image.go:619
msgid "no"
msgstr ""
@@ -1276,7 +1281,7 @@ msgstr ""
msgid "wrong number of subcommand arguments"
msgstr ""
-#: lxc/delete.go:45 lxc/image.go:338 lxc/image.go:619
+#: lxc/delete.go:45 lxc/image.go:338 lxc/image.go:623
msgid "yes"
msgstr ""
From ff4b6590873744613a376c39fb2403d72f12edf0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 15 Aug 2016 15:20:24 -0400
Subject: [PATCH 2/5] Fix image import from URL
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Support URLs containing an equals signs
- Actually respect the provided properties
Closes #2272
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
client.go | 14 ++++++++++++--
lxc/image.go | 5 +++--
2 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/client.go b/client.go
index 17dc0a6..f7a6c53 100644
--- a/client.go
+++ b/client.go
@@ -886,16 +886,26 @@ func (c *Client) ExportImage(image string, target string) (string, error) {
return destpath, nil
}
-func (c *Client) PostImageURL(imageFile string, public bool, aliases []string, progressHandler func(progress string)) (string, error) {
+func (c *Client) PostImageURL(imageFile string, properties []string, public bool, aliases []string, progressHandler func(progress string)) (string, error) {
if c.Remote.Public {
return "", fmt.Errorf("This function isn't supported by public remotes.")
}
+ imgProperties := map[string]string{}
+ for _, entry := range properties {
+ fields := strings.SplitN(entry, "=", 2)
+ if len(fields) != 2 {
+ return "", fmt.Errorf("Invalid image property: %s", entry)
+ }
+
+ imgProperties[fields[0]] = fields[1]
+ }
+
source := shared.Jmap{
"type": "url",
"mode": "pull",
"url": imageFile}
- body := shared.Jmap{"public": public, "source": source}
+ body := shared.Jmap{"public": public, "properties": imgProperties, "source": source}
operation := ""
handler := func(msg interface{}) {
diff --git a/lxc/image.go b/lxc/image.go
index 1016852..488adab 100644
--- a/lxc/image.go
+++ b/lxc/image.go
@@ -408,7 +408,8 @@ func (c *imageCmd) run(config *lxd.Config, args []string) error {
}
if imageFile == "" {
- return errArgs
+ imageFile = args[1]
+ properties = properties[1:]
}
d, err := lxd.NewClient(config, remote)
@@ -428,7 +429,7 @@ func (c *imageCmd) run(config *lxd.Config, args []string) error {
fmt.Printf(i18n.G("Importing the image: %s")+"\r", progress)
}
- fingerprint, err = d.PostImageURL(imageFile, c.publicImage, c.addAliases, progressHandler)
+ fingerprint, err = d.PostImageURL(imageFile, properties, c.publicImage, c.addAliases, progressHandler)
} else if strings.HasPrefix(imageFile, "http://") {
return fmt.Errorf(i18n.G("Only https:// is supported for remote image import."))
} else {
From 8181bfca010ba05f7112f1bbc73842a40c05e0b2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 15 Aug 2016 15:52:11 -0400
Subject: [PATCH 3/5] Allow "lxc copy" to pick a random name
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Closes #2281
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxc/copy.go | 45 ++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 42 insertions(+), 3 deletions(-)
diff --git a/lxc/copy.go b/lxc/copy.go
index 74631c4..e920c76 100644
--- a/lxc/copy.go
+++ b/lxc/copy.go
@@ -38,7 +38,7 @@ func (c *copyCmd) copyContainer(config *lxd.Config, sourceResource string, destR
return fmt.Errorf(i18n.G("you must specify a source container name"))
}
- if destName == "" {
+ if destName == "" && destResource != "" {
destName = sourceName
}
@@ -104,7 +104,27 @@ func (c *copyCmd) copyContainer(config *lxd.Config, sourceResource string, destR
return err
}
- return source.WaitForSuccess(cp.Operation)
+ err = source.WaitForSuccess(cp.Operation)
+ if err != nil {
+ return err
+ }
+
+ if destResource == "" {
+ op, err := cp.MetadataAsOperation()
+ if err != nil {
+ return fmt.Errorf(i18n.G("didn't get any affected image, container or snapshot from server"))
+ }
+
+ containers, ok := op.Resources["containers"]
+ if !ok || len(containers) == 0 {
+ return fmt.Errorf(i18n.G("didn't get any affected image, container or snapshot from server"))
+ }
+
+ fields := strings.Split(containers[0], "/")
+ fmt.Printf(i18n.G("Container name is: %s")+"\n", fields[len(fields)-1])
+ }
+
+ return nil
}
dest, err := lxd.NewClient(config, destRemote)
@@ -177,6 +197,21 @@ func (c *copyCmd) copyContainer(config *lxd.Config, sourceResource string, destR
return err
}
+ if destResource == "" {
+ op, err := migration.MetadataAsOperation()
+ if err != nil {
+ return fmt.Errorf(i18n.G("didn't get any affected image, container or snapshot from server"))
+ }
+
+ containers, ok := op.Resources["containers"]
+ if !ok || len(containers) == 0 {
+ return fmt.Errorf(i18n.G("didn't get any affected image, container or snapshot from server"))
+ }
+
+ fields := strings.Split(containers[0], "/")
+ fmt.Printf(i18n.G("Container name is: %s")+"\n", fields[len(fields)-1])
+ }
+
return nil
}
@@ -184,7 +219,7 @@ func (c *copyCmd) copyContainer(config *lxd.Config, sourceResource string, destR
}
func (c *copyCmd) run(config *lxd.Config, args []string) error {
- if len(args) != 2 {
+ if len(args) < 1 {
return errArgs
}
@@ -193,5 +228,9 @@ func (c *copyCmd) run(config *lxd.Config, args []string) error {
ephem = 1
}
+ if len(args) < 2 {
+ return c.copyContainer(config, args[0], "", false, ephem)
+ }
+
return c.copyContainer(config, args[0], args[1], false, ephem)
}
From 71945c6192344fcf4b403a8af205b0eef2e1e06d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 15 Aug 2016 16:11:10 -0400
Subject: [PATCH 4/5] Allow additional profiles and config on copy
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Closes #2282
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxc/copy.go | 20 ++++++++++++++++++--
po/lxd.pot | 56 ++++++++++++++++++++++++++++----------------------------
2 files changed, 46 insertions(+), 30 deletions(-)
diff --git a/lxc/copy.go b/lxc/copy.go
index e920c76..8e07479 100644
--- a/lxc/copy.go
+++ b/lxc/copy.go
@@ -11,7 +11,9 @@ import (
)
type copyCmd struct {
- ephem bool
+ profArgs profileList
+ confArgs configList
+ ephem bool
}
func (c *copyCmd) showByDefault() bool {
@@ -22,10 +24,14 @@ func (c *copyCmd) usage() string {
return i18n.G(
`Copy containers within or in between lxd instances.
-lxc copy [remote:]<source container> [remote:]<destination container> [--ephemeral|e]`)
+lxc copy [remote:]<source container> [remote:]<destination container> [--ephemeral|e] [--profile|-p <profile>...] [--config|-c <key=value>...]`)
}
func (c *copyCmd) flags() {
+ gnuflag.Var(&c.confArgs, "config", i18n.G("Config key/value to apply to the new container"))
+ gnuflag.Var(&c.confArgs, "c", i18n.G("Config key/value to apply to the new container"))
+ gnuflag.Var(&c.profArgs, "profile", i18n.G("Profile to apply to the new container"))
+ gnuflag.Var(&c.profArgs, "p", i18n.G("Profile to apply to the new container"))
gnuflag.BoolVar(&c.ephem, "ephemeral", false, i18n.G("Ephemeral container"))
gnuflag.BoolVar(&c.ephem, "e", false, i18n.G("Ephemeral container"))
}
@@ -83,6 +89,16 @@ func (c *copyCmd) copyContainer(config *lxd.Config, sourceResource string, destR
status.Profiles = result.Profiles
}
+ if c.profArgs != nil {
+ status.Profiles = append(status.Profiles, c.profArgs...)
+ }
+
+ if configMap != nil {
+ for key, value := range configMap {
+ status.Config[key] = value
+ }
+ }
+
baseImage = status.Config["volatile.base_image"]
if !keepVolatile {
diff --git a/po/lxd.pot b/po/lxd.pot
index dc1d89e..1eadd99 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-08-15 15:10-0400\n"
+ "POT-Creation-Date: 2016-08-15 16:10-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"
@@ -77,7 +77,7 @@ msgid "### This is a yaml representation of the profile.\n"
"### Note that the name is shown but cannot be changed"
msgstr ""
-#: lxc/image.go:616
+#: lxc/image.go:617
#, c-format
msgid "%s (%d more)"
msgstr ""
@@ -90,11 +90,11 @@ msgstr ""
msgid "(none)"
msgstr ""
-#: lxc/image.go:637 lxc/image.go:679
+#: lxc/image.go:638 lxc/image.go:680
msgid "ALIAS"
msgstr ""
-#: lxc/image.go:641
+#: lxc/image.go:642
msgid "ARCH"
msgstr ""
@@ -183,11 +183,11 @@ msgstr ""
msgid "Columns"
msgstr ""
-#: lxc/init.go:134 lxc/init.go:135 lxc/launch.go:40 lxc/launch.go:41
+#: lxc/copy.go:31 lxc/copy.go:32 lxc/init.go:134 lxc/init.go:135 lxc/launch.go:40 lxc/launch.go:41
msgid "Config key/value to apply to the new container"
msgstr ""
-#: lxc/config.go:531 lxc/config.go:596 lxc/image.go:733 lxc/profile.go:218
+#: lxc/config.go:531 lxc/config.go:596 lxc/image.go:734 lxc/profile.go:218
#, c-format
msgid "Config parsing error: %s"
msgstr ""
@@ -200,7 +200,7 @@ msgstr ""
msgid "Container name is mandatory"
msgstr ""
-#: lxc/init.go:210
+#: lxc/copy.go:140 lxc/copy.go:228 lxc/init.go:210
#, c-format
msgid "Container name is: %s"
msgstr ""
@@ -214,10 +214,10 @@ msgstr ""
msgid "Copy aliases from source"
msgstr ""
-#: lxc/copy.go:22
+#: lxc/copy.go:24
msgid "Copy containers within or in between lxd instances.\n"
"\n"
- "lxc copy [remote:]<source container> [remote:]<destination container> [--ephemeral|e]"
+ "lxc copy [remote:]<source container> [remote:]<destination container> [--ephemeral|e] [--profile|-p <profile>...] [--config|-c <key=value>...]"
msgstr ""
#: lxc/image.go:280
@@ -259,7 +259,7 @@ msgstr ""
msgid "Creating the container"
msgstr ""
-#: lxc/image.go:640 lxc/image.go:681
+#: lxc/image.go:641 lxc/image.go:682
msgid "DESCRIPTION"
msgstr ""
@@ -301,7 +301,7 @@ msgstr ""
msgid "Environment:"
msgstr ""
-#: lxc/copy.go:29 lxc/copy.go:30 lxc/init.go:138 lxc/init.go:139 lxc/launch.go:44 lxc/launch.go:45
+#: lxc/copy.go:35 lxc/copy.go:36 lxc/init.go:138 lxc/init.go:139 lxc/launch.go:44 lxc/launch.go:45
msgid "Ephemeral container"
msgstr ""
@@ -326,7 +326,7 @@ msgstr ""
msgid "Expires: never"
msgstr ""
-#: lxc/config.go:273 lxc/image.go:638 lxc/image.go:680
+#: lxc/config.go:273 lxc/image.go:639 lxc/image.go:681
msgid "FINGERPRINT"
msgstr ""
@@ -393,12 +393,12 @@ msgstr ""
msgid "Image copied successfully!"
msgstr ""
-#: lxc/image.go:441
+#: lxc/image.go:442
#, c-format
msgid "Image imported with fingerprint: %s"
msgstr ""
-#: lxc/image.go:428
+#: lxc/image.go:429
#, c-format
msgid "Importing the image: %s"
msgstr ""
@@ -786,7 +786,7 @@ msgstr ""
msgid "Only https URLs are supported for simplestreams"
msgstr ""
-#: lxc/image.go:433
+#: lxc/image.go:434
msgid "Only https:// is supported for remote image import."
msgstr ""
@@ -794,7 +794,7 @@ msgstr ""
msgid "Options:"
msgstr ""
-#: lxc/image.go:537
+#: lxc/image.go:538
#, c-format
msgid "Output is in %s"
msgstr ""
@@ -819,7 +819,7 @@ msgstr ""
msgid "PROTOCOL"
msgstr ""
-#: lxc/image.go:639 lxc/remote.go:379
+#: lxc/image.go:640 lxc/remote.go:379
msgid "PUBLIC"
msgstr ""
@@ -858,7 +858,7 @@ msgstr ""
msgid "Press enter to open the editor again"
msgstr ""
-#: lxc/config.go:532 lxc/config.go:597 lxc/image.go:734
+#: lxc/config.go:532 lxc/config.go:597 lxc/image.go:735
msgid "Press enter to start the editor again"
msgstr ""
@@ -905,7 +905,7 @@ msgstr ""
msgid "Profile %s removed from %s"
msgstr ""
-#: lxc/init.go:136 lxc/init.go:137 lxc/launch.go:42 lxc/launch.go:43
+#: lxc/copy.go:33 lxc/copy.go:34 lxc/init.go:136 lxc/init.go:137 lxc/launch.go:42 lxc/launch.go:43
msgid "Profile to apply to the new container"
msgstr ""
@@ -960,7 +960,7 @@ msgstr ""
msgid "Retrieving image: %s"
msgstr ""
-#: lxc/image.go:642
+#: lxc/image.go:643
msgid "SIZE"
msgstr ""
@@ -1109,7 +1109,7 @@ msgstr ""
msgid "To start your first container, try: lxc launch ubuntu:16.04"
msgstr ""
-#: lxc/image.go:420
+#: lxc/image.go:421
#, c-format
msgid "Transferring image: %d%%"
msgstr ""
@@ -1127,7 +1127,7 @@ msgstr ""
msgid "Type: persistent"
msgstr ""
-#: lxc/image.go:643
+#: lxc/image.go:644
msgid "UPLOAD DATE"
msgstr ""
@@ -1185,7 +1185,7 @@ msgstr ""
msgid "bad result type from action"
msgstr ""
-#: lxc/copy.go:99
+#: lxc/copy.go:115
msgid "can't copy to the same container name"
msgstr ""
@@ -1197,7 +1197,7 @@ msgstr ""
msgid "default"
msgstr ""
-#: lxc/init.go:200 lxc/init.go:205 lxc/launch.go:95 lxc/launch.go:100
+#: lxc/copy.go:131 lxc/copy.go:136 lxc/copy.go:219 lxc/copy.go:224 lxc/init.go:200 lxc/init.go:205 lxc/launch.go:95 lxc/launch.go:100
msgid "didn't get any affected image, container or snapshot from server"
msgstr ""
@@ -1223,11 +1223,11 @@ msgstr ""
msgid "got bad version"
msgstr ""
-#: lxc/image.go:336 lxc/image.go:619
+#: lxc/image.go:336 lxc/image.go:620
msgid "no"
msgstr ""
-#: lxc/copy.go:122
+#: lxc/copy.go:158
msgid "not all the profiles from the source exist on the target"
msgstr ""
@@ -1281,11 +1281,11 @@ msgstr ""
msgid "wrong number of subcommand arguments"
msgstr ""
-#: lxc/delete.go:45 lxc/image.go:338 lxc/image.go:623
+#: lxc/delete.go:45 lxc/image.go:338 lxc/image.go:624
msgid "yes"
msgstr ""
-#: lxc/copy.go:38
+#: lxc/copy.go:44
msgid "you must specify a source container name"
msgstr ""
From 16bac94c72f1d4ac2af2d2aeb91d5c3688947369 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 15 Aug 2016 17:33:18 -0400
Subject: [PATCH 5/5] Fix unix-char/unix-block in nested containers
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This comes with a number of limitations due to us not being able to
mknod the device, but it's better than what we have currently.
Closes #2279
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxd/container_lxc.go | 98 ++++++++++++++++++++++++++++++++++++----------------
1 file changed, 68 insertions(+), 30 deletions(-)
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index cb2f2ca..8982e88 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -1096,15 +1096,17 @@ func (c *containerLXC) startCommon() (string, error) {
return "", err
}
- // Add the new device cgroup rule
- dType, dMajor, dMinor, err := deviceGetAttributes(devPath)
- if err != nil {
- return "", err
- }
+ if c.IsPrivileged() && !runningInUserns && cgDevicesController {
+ // Add the new device cgroup rule
+ dType, dMajor, dMinor, err := deviceGetAttributes(devPath)
+ if err != nil {
+ return "", err
+ }
- err = lxcSetConfigItem(c.c, "lxc.cgroup.devices.allow", fmt.Sprintf("%s %d:%d rwm", dType, dMajor, dMinor))
- if err != nil {
- return "", fmt.Errorf("Failed to add cgroup rule for device")
+ err = lxcSetConfigItem(c.c, "lxc.cgroup.devices.allow", fmt.Sprintf("%s %d:%d rwm", dType, dMajor, dMinor))
+ if err != nil {
+ return "", fmt.Errorf("Failed to add cgroup rule for device")
+ }
}
} else if m["type"] == "usb" {
if usbs == nil {
@@ -1121,9 +1123,11 @@ func (c *containerLXC) startCommon() (string, error) {
continue
}
- err = lxcSetConfigItem(c.c, "lxc.cgroup.devices.allow", fmt.Sprintf("c %d:%d rwm", usb.major, usb.minor))
- if err != nil {
- return "", err
+ if c.IsPrivileged() && !runningInUserns && cgDevicesController {
+ err = lxcSetConfigItem(c.c, "lxc.cgroup.devices.allow", fmt.Sprintf("c %d:%d rwm", usb.major, usb.minor))
+ if err != nil {
+ return "", err
+ }
}
m["major"] = fmt.Sprintf("%d", usb.major)
@@ -3657,6 +3661,15 @@ func (c *containerLXC) createUnixDevice(m shared.Device) (string, error) {
devName := fmt.Sprintf("unix.%s", strings.Replace(tgtPath, "/", "-", -1))
devPath := filepath.Join(c.DevicesPath(), devName)
+ // Extra checks for nesting
+ if runningInUserns {
+ for key, value := range m {
+ if shared.StringInSlice(key, []string{"major", "minor", "mode", "uid", "gid"}) && value != "" {
+ return "", fmt.Errorf("The \"%s\" property may not be set when adding a device to a nested container", key)
+ }
+ }
+ }
+
// Get the major/minor of the device we want to create
if m["major"] == "" && m["minor"] == "" {
// If no major and minor are set, use those from the device on the host
@@ -3722,6 +3735,10 @@ func (c *containerLXC) createUnixDevice(m shared.Device) (string, error) {
// Clean any existing entry
if shared.PathExists(devPath) {
+ if runningInUserns {
+ syscall.Unmount(devPath, syscall.MNT_DETACH)
+ }
+
err = os.Remove(devPath)
if err != nil {
return "", fmt.Errorf("Failed to remove existing entry: %s", err)
@@ -3729,23 +3746,36 @@ func (c *containerLXC) createUnixDevice(m shared.Device) (string, error) {
}
// Create the new entry
- if err := syscall.Mknod(devPath, uint32(mode), minor|(major<<8)); err != nil {
- return "", fmt.Errorf("Failed to create device %s for %s: %s", devPath, m["path"], err)
- }
+ if !runningInUserns {
+ if err := syscall.Mknod(devPath, uint32(mode), minor|(major<<8)); err != nil {
+ return "", fmt.Errorf("Failed to create device %s for %s: %s", devPath, m["path"], err)
+ }
- if err := os.Chown(devPath, uid, gid); err != nil {
- return "", fmt.Errorf("Failed to chown device %s: %s", devPath, err)
- }
+ if err := os.Chown(devPath, uid, gid); err != nil {
+ return "", fmt.Errorf("Failed to chown device %s: %s", devPath, err)
+ }
- // Needed as mknod respects the umask
- if err := os.Chmod(devPath, mode); err != nil {
- return "", fmt.Errorf("Failed to chmod device %s: %s", devPath, err)
- }
+ // Needed as mknod respects the umask
+ if err := os.Chmod(devPath, mode); err != nil {
+ return "", fmt.Errorf("Failed to chmod device %s: %s", devPath, err)
+ }
- if c.idmapset != nil {
- if err := c.idmapset.ShiftFile(devPath); err != nil {
- // uidshift failing is weird, but not a big problem. Log and proceed
- shared.Debugf("Failed to uidshift device %s: %s\n", m["path"], err)
+ if c.idmapset != nil {
+ if err := c.idmapset.ShiftFile(devPath); err != nil {
+ // uidshift failing is weird, but not a big problem. Log and proceed
+ shared.Debugf("Failed to uidshift device %s: %s\n", m["path"], err)
+ }
+ }
+ } else {
+ f, err := os.Create(devPath)
+ if err != nil {
+ return "", err
+ }
+ f.Close()
+
+ err = deviceMountDisk(srcPath, devPath, false, false)
+ if err != nil {
+ return "", err
}
}
@@ -3777,8 +3807,10 @@ func (c *containerLXC) insertUnixDevice(name string, m shared.Device) error {
return fmt.Errorf("Failed to get device attributes: %s", err)
}
- if err := c.CGroupSet("devices.allow", fmt.Sprintf("%s %d:%d rwm", dType, dMajor, dMinor)); err != nil {
- return fmt.Errorf("Failed to add cgroup rule for device")
+ if c.IsPrivileged() && !runningInUserns && cgDevicesController {
+ if err := c.CGroupSet("devices.allow", fmt.Sprintf("%s %d:%d rwm", dType, dMajor, dMinor)); err != nil {
+ return fmt.Errorf("Failed to add cgroup rule for device")
+ }
}
return nil
@@ -3803,9 +3835,11 @@ func (c *containerLXC) removeUnixDevice(m shared.Device) error {
return err
}
- err = c.CGroupSet("devices.deny", fmt.Sprintf("%s %d:%d rwm", dType, dMajor, dMinor))
- if err != nil {
- return err
+ if c.IsPrivileged() && !runningInUserns && cgDevicesController {
+ err = c.CGroupSet("devices.deny", fmt.Sprintf("%s %d:%d rwm", dType, dMajor, dMinor))
+ if err != nil {
+ return err
+ }
}
// Remove the bind-mount from the container
@@ -3824,6 +3858,10 @@ func (c *containerLXC) removeUnixDevice(m shared.Device) error {
}
// Remove the host side
+ if runningInUserns {
+ syscall.Unmount(devPath, syscall.MNT_DETACH)
+ }
+
err = os.Remove(devPath)
if err != nil {
return err
More information about the lxc-devel
mailing list