[lxc-devel] [PATCH] python: Update to the device related functions

Stéphane Graber stgraber at ubuntu.com
Tue Dec 4 22:30:13 UTC 2012


This commit does the following changes to the python API:
 - Rename the add_device API call to add_device_node
 - Adds an extra check that the container is running to add_device_node
 - Introduces a new add_device_net function

And the following changes to the lxc-device tool:
 - Change parser setup to better cope with variable number of arguments
 - Add support for network devices (currently auto-detected)
 - Support for different names on the host and in the container

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 src/lxc/lxc-device             | 48 ++++++++++++++++++++++++++++++++++--------
 src/python-lxc/lxc/__init__.py | 26 +++++++++++++++++++++--
 2 files changed, 63 insertions(+), 11 deletions(-)

diff --git a/src/lxc/lxc-device b/src/lxc/lxc-device
index 467df17..db9399d 100644
--- a/src/lxc/lxc-device
+++ b/src/lxc/lxc-device
@@ -42,24 +42,54 @@ gettext.textdomain("lxc-device")
 parser = argparse.ArgumentParser(description=_("LXC: Manage devices"),
                                  formatter_class=argparse.RawTextHelpFormatter)
 
+# Global arguments
 parser.add_argument("-n", dest="container", metavar="CONTAINER",
-                    help=_("Container to add the device to"), required=True)
+                    help=_("Name of the container to add the device to"),
+                    required=True)
 
-parser.add_argument("--add", action="append", default=[], metavar="DEVICE",
-                    help=_("Add a device"), required=True)
+# Commands
+subparsers = parser.add_subparsers()
+subparser_add = subparsers.add_parser('add', help=_('Add a device'))
+subparser_add.set_defaults(action="add")
+
+subparser_add.add_argument(dest="device", metavar="DEVICE",
+                           help=_("Add a device "
+                                  "(path to a node or interface name)"))
+
+subparser_add.add_argument(dest="name", metavar="NAME", nargs="?",
+                           help=_("Use an alternative path or name "
+                                  "in the container"))
 
 args = parser.parse_args()
 
-# The user needs to be uid 0
+# Some basic checks
+if not hasattr(args, "action"):
+    parser.error(_("You must specify an action."))
+
+## The user needs to be uid 0
 if not os.geteuid() == 0:
     parser.error(_("You must be root to run this script. Try running: sudo %s"
                    % (sys.argv[0])))
 
+## Don't rename if no alternative name
+if not args.name:
+    args.name = args.device
+
+## Check that the container is ready
 container = lxc.Container(args.container)
 if not container.running:
-    print("The container must be running.")
-    sys.exit(1)
+    parser.error("The container must be running.")
+
+# Do the work
+if args.action == "add":
+    if os.path.exists("/sys/class/net/%s/" % args.device):
+        ret = container.add_device_net(args.device, args.name)
+    else:
+        ret = container.add_device_node(args.device, args.name)
 
-for device in args.add:
-    container.add_device(device)
-    print("Added '%s' to '%s'." % (device, container.name))
+    if ret:
+        print("Added '%s' to '%s' as '%s'." %
+              (args.device, container.name, args.name))
+    else:
+        print("Failed to add '%s' to '%s' as '%s'." %
+              (args.device, container.name, args.name))
diff --git a/src/python-lxc/lxc/__init__.py b/src/python-lxc/lxc/__init__.py
index 78852ec..cde4fd1 100644
--- a/src/python-lxc/lxc/__init__.py
+++ b/src/python-lxc/lxc/__init__.py
@@ -154,11 +154,14 @@ class Container(_lxc.Container):
         _lxc.Container.__init__(self, name)
         self.network = ContainerNetworkList(self)
 
-    def add_device(self, path, destpath=None):
+    def add_device_node(self, path, destpath=None):
         """
-            Add device to running container.
+            Add block/char device to running container.
         """
 
+        if not self.running:
+            return False
+
         if not destpath:
             destpath = path
 
@@ -214,6 +217,25 @@ class Container(_lxc.Container):
 
         return True
 
+    def add_device_net(self, name, destname=None):
+        """
+            Add network device to running container.
+        """
+
+        if not self.running:
+            return False
+
+        if not destname:
+            destname = name
+
+        if not os.path.exists("/sys/class/net/%s/" % name):
+            return False
+
+        return subprocess.call(['ip', 'link', 'set',
+                                'dev', name,
+                                'netns', str(self.init_pid),
+                                'name', destname]) == 0
+
     def append_config_item(self, key, value):
         """
             Append 'value' to 'key', assuming 'key' is a list.
-- 
1.8.0





More information about the lxc-devel mailing list