The user id is used by ceph to determine the keyring to use for
authentication. By default the admin keyring is used, which may
not be desirable.

Signed-off-by: David Mohr <da...@mcbf.net>
---
 lib/storage/bdev.py     |   45 ++++++++++++++++++++++++++++-----------------
 src/Ganeti/Constants.hs |   18 +++++++++++++++++-
 2 files changed, 45 insertions(+), 18 deletions(-)

diff --git a/lib/storage/bdev.py b/lib/storage/bdev.py
index e3a48de..4892ec2 100644
--- a/lib/storage/bdev.py
+++ b/lib/storage/bdev.py
@@ -886,6 +886,13 @@ class RADOSBlockDevice(base.BlockDev):
     self.Attach()
 
   @classmethod
+  def MakeRbdCmd(cls, params, cmd):
+    if constants.RBD_USER_ID in params and params[constants.RBD_USER_ID]:
+      cmd.append("--id")
+      cmd.append("%s" % params[constants.RBD_USER_ID])
+    return [constants.RBD_CMD] + cmd
+
+  @classmethod
   def Create(cls, unique_id, children, size, spindles, params, excl_stor,
              dyn_params, *args):
     """Create a new rbd device.
@@ -903,8 +910,8 @@ class RADOSBlockDevice(base.BlockDev):
     rbd_name = unique_id[1]
 
     # Provision a new rbd volume (Image) inside the RADOS cluster.
-    cmd = [constants.RBD_CMD, "create", "-p", rbd_pool,
-           rbd_name, "--size", "%s" % size]
+    cmd = cls.MakeRbdCmd(params, ["create", "-p", rbd_pool, rbd_name,
+                                  "--size", "%s" % size])
     result = utils.RunCmd(cmd)
     if result.failed:
       base.ThrowError("rbd creation failed (%s): %s",
@@ -928,7 +935,7 @@ class RADOSBlockDevice(base.BlockDev):
     self.Shutdown()
 
     # Remove the actual Volume (Image) from the RADOS cluster.
-    cmd = [constants.RBD_CMD, "rm", "-p", rbd_pool, rbd_name]
+    cmd = self.__class__.MakeRbdCmd(self.params, ["rm", "-p", rbd_pool, 
rbd_name])
     result = utils.RunCmd(cmd)
     if result.failed:
       base.ThrowError("Can't remove Volume from cluster with rbd rm: %s - %s",
@@ -987,7 +994,7 @@ class RADOSBlockDevice(base.BlockDev):
       return rbd_dev
 
     # The mapping doesn't exist. Create it.
-    map_cmd = [constants.RBD_CMD, "map", "-p", pool, name]
+    map_cmd = self.__class__.MakeRbdCmd(self.params, ["map", "-p", pool, name])
     result = utils.RunCmd(map_cmd)
     if result.failed:
       base.ThrowError("rbd map failed (%s): %s",
@@ -1017,14 +1024,13 @@ class RADOSBlockDevice(base.BlockDev):
     try:
       # Newer versions of the rbd tool support json output formatting. Use it
       # if available.
-      showmap_cmd = [
-        constants.RBD_CMD,
+      showmap_cmd = cls.MakeRbdCmd({}, [
         "showmapped",
         "-p",
         pool,
         "--format",
         "json"
-        ]
+        ])
       result = utils.RunCmd(showmap_cmd)
       if result.failed:
         logging.error("rbd JSON output formatting returned error (%s): %s,"
@@ -1036,7 +1042,7 @@ class RADOSBlockDevice(base.BlockDev):
     except RbdShowmappedJsonError:
       # For older versions of rbd, we have to parse the plain / text output
       # manually.
-      showmap_cmd = [constants.RBD_CMD, "showmapped", "-p", pool]
+      showmap_cmd = cls.MakeRbdCmd({}, ["showmapped", "-p", pool])
       result = utils.RunCmd(showmap_cmd)
       if result.failed:
         base.ThrowError("rbd showmapped failed (%s): %s",
@@ -1168,7 +1174,7 @@ class RADOSBlockDevice(base.BlockDev):
 
     if rbd_dev:
       # The mapping exists. Unmap the rbd device.
-      unmap_cmd = [constants.RBD_CMD, "unmap", "%s" % rbd_dev]
+      unmap_cmd = self.__class__.MakeRbdCmd(self.params, ["unmap", "%s" % 
rbd_dev])
       result = utils.RunCmd(unmap_cmd)
       if result.failed:
         base.ThrowError("rbd unmap failed (%s): %s",
@@ -1212,8 +1218,8 @@ class RADOSBlockDevice(base.BlockDev):
     new_size = self.size + amount
 
     # Resize the rbd volume (Image) inside the RADOS cluster.
-    cmd = [constants.RBD_CMD, "resize", "-p", rbd_pool,
-           rbd_name, "--size", "%s" % new_size]
+    cmd = self.__class__.MakeRbdCmd(self.params, ["resize", "-p", rbd_pool,
+           rbd_name, "--size", "%s" % new_size])
     result = utils.RunCmd(cmd)
     if result.failed:
       base.ThrowError("rbd resize failed (%s): %s",
@@ -1248,16 +1254,17 @@ class RADOSBlockDevice(base.BlockDev):
     self._UnmapVolumeFromBlockdev(self.unique_id)
 
     # Remove the actual Volume (Image) from the RADOS cluster.
-    cmd = [constants.RBD_CMD, "rm", "-p", rbd_pool, rbd_name]
+    cmd = self.__class__.MakeRbdCmd(self.params, ["rm", "-p", rbd_pool, 
rbd_name])
     result = utils.RunCmd(cmd)
     if result.failed:
       base.ThrowError("Can't remove Volume from cluster with rbd rm: %s - %s",
                       result.fail_reason, result.output)
 
     # We use "-" for importing from stdin
-    return [constants.RBD_CMD, "import",
+    return self.__class__.MakeRbdCmd(self.params, [
+            "import",
             "-p", rbd_pool,
-            "-", rbd_name]
+            "-", rbd_name])
 
   def Export(self):
     """Builds the shell command for exporting data from device.
@@ -1273,9 +1280,10 @@ class RADOSBlockDevice(base.BlockDev):
     rbd_name = self.unique_id[1]
 
     # We use "-" for exporting to stdout.
-    return [constants.RBD_CMD, "export",
+    return self.__class__.MakeRbdCmd(self.params, [
+            "export",
             "-p", rbd_pool,
-            rbd_name, "-"]
+            rbd_name, "-"])
 
   def GetUserspaceAccessUri(self, hypervisor):
     """Generate KVM userspace URIs to be used as `-drive file` settings.
@@ -1284,7 +1292,10 @@ class RADOSBlockDevice(base.BlockDev):
 
     """
     if hypervisor == constants.HT_KVM:
-      return "rbd:" + self.rbd_pool + "/" + self.rbd_name
+      uri = "rbd:" + self.rbd_pool + "/" + self.rbd_name
+      if constants.RBD_USER_ID in self.params and 
self.params[constants.RBD_USER_ID]:
+        uri += ":id=%s" % self.params[constants.RBD_USER_ID]
+      return uri
     else:
       base.ThrowError("Hypervisor %s doesn't support RBD userspace access" %
                       hypervisor)
diff --git a/src/Ganeti/Constants.hs b/src/Ganeti/Constants.hs
index 09ca78d..c186877 100644
--- a/src/Ganeti/Constants.hs
+++ b/src/Ganeti/Constants.hs
@@ -2330,6 +2330,9 @@ ldpPlanAhead = "c-plan-ahead"
 ldpPool :: String
 ldpPool = "pool"
 
+ldpUserId :: String
+ldpUserId = "user-id"
+
 ldpProtocol :: String
 ldpProtocol = "protocol"
 
@@ -2357,7 +2360,8 @@ diskLdTypes =
    (ldpDelayTarget, VTypeInt),
    (ldpMaxRate, VTypeInt),
    (ldpMinRate, VTypeInt),
-   (ldpPool, VTypeString)]
+   (ldpPool, VTypeString),
+   (ldpUserId, VTypeString)]
 
 diskLdParameters :: FrozenSet String
 diskLdParameters = ConstantUtils.mkSet (Map.keys diskLdTypes)
@@ -2418,6 +2422,9 @@ lvStripes = "stripes"
 rbdAccess :: String
 rbdAccess = "access"
 
+rbdUserId :: String
+rbdUserId = "user-id"
+
 rbdPool :: String
 rbdPool = "pool"
 
@@ -2440,6 +2447,7 @@ diskDtTypes =
                 (drbdMinRate, VTypeInt),
                 (lvStripes, VTypeInt),
                 (rbdAccess, VTypeString),
+                (rbdUserId, VTypeString),
                 (rbdPool, VTypeString),
                 (glusterHost, VTypeString),
                 (glusterVolume, VTypeString),
@@ -4240,6 +4248,9 @@ defaultPlanAhead = 20
 defaultRbdPool :: String
 defaultRbdPool = "rbd"
 
+defaultRbdUserId :: String
+defaultRbdUserId = ""
+
 diskLdDefaults :: Map DiskTemplate (Map String PyValueEx)
 diskLdDefaults =
   Map.fromList
@@ -4266,11 +4277,13 @@ diskLdDefaults =
   , (DTPlain, Map.fromList [(ldpStripes, PyValueEx lvmStripecount)])
   , (DTRbd, Map.fromList
             [ (ldpPool, PyValueEx defaultRbdPool)
+            , (ldpUserId, PyValueEx defaultRbdUserId)
             , (ldpAccess, PyValueEx diskKernelspace)
             ])
   , (DTSharedFile, Map.empty)
   , (DTGluster, Map.fromList
                 [ (rbdAccess, PyValueEx diskKernelspace)
+                , (rbdUserId, PyValueEx defaultRbdUserId)
                 , (glusterHost, PyValueEx glusterHostDefault)
                 , (glusterVolume, PyValueEx glusterVolumeDefault)
                 , (glusterPort, PyValueEx glusterPortDefault)
@@ -4301,16 +4314,19 @@ diskDtDefaults =
                    ])
   , (DTExt,        Map.fromList
                    [ (rbdAccess, PyValueEx diskKernelspace)
+                   , (rbdUserId, PyValueEx defaultRbdUserId)
                    ])
   , (DTFile,       Map.empty)
   , (DTPlain,      Map.fromList [(lvStripes, PyValueEx lvmStripecount)])
   , (DTRbd,        Map.fromList
                    [ (rbdPool, PyValueEx defaultRbdPool)
                    , (rbdAccess, PyValueEx diskKernelspace)
+                   , (rbdUserId, PyValueEx defaultRbdUserId)
                    ])
   , (DTSharedFile, Map.empty)
   , (DTGluster, Map.fromList
                 [ (rbdAccess, PyValueEx diskKernelspace)
+                , (rbdUserId, PyValueEx defaultRbdUserId)
                 , (glusterHost, PyValueEx glusterHostDefault)
                 , (glusterVolume, PyValueEx glusterVolumeDefault)
                 , (glusterPort, PyValueEx glusterPortDefault)
-- 
1.7.9.5

Reply via email to