summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Grover <agrover@redhat.com>2015-02-03 16:55:20 -0800
committerAndy Grover <agrover@redhat.com>2015-02-03 16:55:20 -0800
commit0c3685df8d5dfb8b5cca3b5b47d2c7a722010688 (patch)
tree199b5414fc36e07568ade55d0c898dc53cf35aec
parenteb801f5b5db0b10990094dfd179a8e2bd1c14ca4 (diff)
downloadtargetcli-user-backstore-poc.tar.gz
proof-of-concept of dynamically loading a backstore instanceuser-backstore-poc
-rw-r--r--targetcli/dynbs_gluster.py62
-rw-r--r--targetcli/ui_backstore.py30
2 files changed, 91 insertions, 1 deletions
diff --git a/targetcli/dynbs_gluster.py b/targetcli/dynbs_gluster.py
new file mode 100644
index 0000000..44ad3b5
--- /dev/null
+++ b/targetcli/dynbs_gluster.py
@@ -0,0 +1,62 @@
+'''
+Implements the targetcli backstores related UI.
+
+Copyright (c) 2015 by Red Hat, Inc
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may
+not use this file except in compliance with the License. You may obtain
+a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations
+under the License.
+'''
+
+from rtslib_fb import UserBackedStorageObject
+
+# Note: Since this is exec'd at the end of ui_backstore.py, both
+# UIUserBackstore and UIUserBackedStorageObject are already in scope.
+
+class UIGlusterBackstore(UIUserBackstore):
+
+ def __init__(self, parent):
+ self.so_cls = UIUserBackedStorageObject
+ super(self.__class__, self).__init__("gluster", parent)
+
+ def ui_command_create(self, name, size, server, volume, path):
+ '''
+ Creates a Gluster-backed storage object.
+
+ SIZE SYNTAX
+ ===========
+ - If size is an int, it represents a number of bytes.
+ - If size is a string, the following units can be used:
+ - B{B} or no unit present for bytes
+ - B{k}, B{K}, B{kB}, B{KB} for kB (kilobytes)
+ - B{m}, B{M}, B{mB}, B{MB} for MB (megabytes)
+ - B{g}, B{G}, B{gB}, B{GB} for GB (gigabytes)
+ - B{t}, B{T}, B{tB}, B{TB} for TB (terabytes)
+
+ 'server' is the name of the Gluster server.
+ 'volume' is the name of the Gluster volume.
+ 'path' is the name of the path in the volume.
+
+ I{server}, I{volume}, and I{path} are also all required.
+ '''
+ self.assert_root()
+
+ size = human_to_bytes(size)
+ config = "gluster/%s@%s/%s" % (server, volume, path)
+ so = UserBackedStorageObject(name, size=size, config=config, level=1)
+ ui_so = UIUserBackedStorageObject(so, self)
+ self.setup_model_alias(so)
+ self.shell.log.info("Created Gluster storage object %s"
+ % (name,))
+ return self.new_node(ui_so)
+
+
+new_backstore(UIGlusterBackstore)
diff --git a/targetcli/ui_backstore.py b/targetcli/ui_backstore.py
index 90708d9..a8b8b12 100644
--- a/targetcli/ui_backstore.py
+++ b/targetcli/ui_backstore.py
@@ -29,6 +29,8 @@ import os
import stat
import re
+dynload_backstore_path = "/home/agrover/git/targetcli-fb/targetcli/dynbs_*"
+
def human_to_bytes(hsize, kilo=1024):
'''
This function converts human-readable amounts of bytes to bytes.
@@ -93,6 +95,7 @@ def complete_path(path, stat_fn):
return sorted(filtered,
key=lambda s: '~'+s if s.endswith('/') else s)
+
class UIBackstores(UINode):
'''
The backstores container UI.
@@ -107,7 +110,9 @@ class UIBackstores(UINode):
UIRDMCPBackstore(self)
UIFileIOBackstore(self)
UIBlockBackstore(self)
- UIUserBackedBackstore(self)
+
+ for entry in dyn_bs_list:
+ entry(self)
class UIBackstore(UINode):
@@ -182,6 +187,21 @@ class UIBackstore(UINode):
" emulate_model_alias\n not supported by kernel.")
+class UIUserBackstore(UIBackstore):
+ '''
+ Common code for user-backed backstores
+ Abstract Base Class, do not instantiate.
+ '''
+ def summary(self):
+ return ("User-backed Storage Objects: %d" % len(self._children), None)
+
+ def refresh(self):
+ self._children = set([])
+ for so in RTSRoot().storage_objects:
+ if so.plugin == 'user' and so.config.startswith(self.name + '/'):
+ ui_so = self.so_cls(so, self)
+
+
class UIPSCSIBackstore(UIBackstore):
'''
PSCSI backstore UI.
@@ -552,3 +572,11 @@ class UIUserBackedStorageObject(UIStorageObject):
config_str = so.config
return ("%s (%s) %s" % (config_str, bytes_to_human(so.size), so.status), True)
+
+
+dyn_bs_list = []
+def new_backstore(bs_cls):
+ dyn_bs_list.append(bs_cls)
+
+for file in glob.iglob(dynload_backstore_path):
+ execfile(file)