[Kimchi-devel] [PATCH 07/13] refactor model: Move StoragePooldef from model to libvirtstoragepools.py

Aline Manera alinefm at linux.vnet.ibm.com
Fri Jan 17 02:24:43 UTC 2014


From: Aline Manera <alinefm at br.ibm.com>

Separate StoragePoolDef from model as it handles the xml generation for
libvirt storage pools.

Signed-off-by: Aline Manera <alinefm at br.ibm.com>
---
 src/kimchi/model.py                     |  202 +--------------------------
 src/kimchi/model_/libvirtstoragepool.py |  225 +++++++++++++++++++++++++++++++
 2 files changed, 226 insertions(+), 201 deletions(-)
 create mode 100644 src/kimchi/model_/libvirtstoragepool.py

diff --git a/src/kimchi/model.py b/src/kimchi/model.py
index 0577088..027d6d5 100644
--- a/src/kimchi/model.py
+++ b/src/kimchi/model.py
@@ -65,9 +65,9 @@ from kimchi.distroloader import DistroLoader
 from kimchi.exception import InvalidOperation, InvalidParameter, IsoFormatError
 from kimchi.exception import MissingParameter, NotFoundError, OperationFailed
 from kimchi.featuretests import FeatureTests
-from kimchi.iscsi import TargetClient
 from kimchi.isoinfo import IsoImage
 from kimchi.model_.libvirtconnection import LibvirtConnection
+from kimchi.model_.libvirtstoragepool import StoragePoolDef
 from kimchi.objectstore import ObjectStore
 from kimchi.scan import Scanner
 from kimchi.screenshot import VMScreenshot
@@ -1510,206 +1510,6 @@ class LibvirtVMScreenshot(VMScreenshot):
         finally:
             os.close(fd)
 
-
-class StoragePoolDef(object):
-    @classmethod
-    def create(cls, poolArgs):
-        for klass in cls.__subclasses__():
-            if poolArgs['type'] == klass.poolType:
-                return klass(poolArgs)
-        raise OperationFailed('Unsupported pool type: %s' % poolArgs['type'])
-
-    def __init__(self, poolArgs):
-        self.poolArgs = poolArgs
-
-    def prepare(self, conn):
-        ''' Validate pool arguments and perform preparations. Operation which
-        would cause side effect should be put here. Subclasses can optionally
-        override this method, or it always succeeds by default. '''
-        pass
-
-    @property
-    def xml(self):
-        ''' Subclasses have to override this method to actually generate the
-        storage pool XML definition. Should cause no side effect and be
-        idempotent'''
-        # TODO: When add new pool type, should also add the related test in
-        # tests/test_storagepool.py
-        raise OperationFailed('self.xml is not implemented: %s' % self)
-
-
-class DirPoolDef(StoragePoolDef):
-    poolType = 'dir'
-
-    @property
-    def xml(self):
-        # Required parameters
-        # name:
-        # type:
-        # path:
-        xml = """
-        <pool type='dir'>
-          <name>{name}</name>
-          <target>
-            <path>{path}</path>
-          </target>
-        </pool>
-        """.format(**self.poolArgs)
-        return xml
-
-
-class NetfsPoolDef(StoragePoolDef):
-    poolType = 'netfs'
-
-    def __init__(self, poolArgs):
-        super(NetfsPoolDef, self).__init__(poolArgs)
-        self.path = '/var/lib/kimchi/nfs_mount/' + self.poolArgs['name']
-
-    def prepare(self, conn):
-        # TODO: Verify the NFS export can be actually mounted.
-        pass
-
-    @property
-    def xml(self):
-        # Required parameters
-        # name:
-        # type:
-        # source[host]:
-        # source[path]:
-        poolArgs = copy.deepcopy(self.poolArgs)
-        poolArgs['path'] = self.path
-        xml = """
-        <pool type='netfs'>
-          <name>{name}</name>
-          <source>
-            <host name='{source[host]}'/>
-            <dir path='{source[path]}'/>
-          </source>
-          <target>
-            <path>{path}</path>
-          </target>
-        </pool>
-        """.format(**poolArgs)
-        return xml
-
-
-class LogicalPoolDef(StoragePoolDef):
-    poolType = 'logical'
-
-    def __init__(self, poolArgs):
-        super(LogicalPoolDef, self).__init__(poolArgs)
-        self.path = '/var/lib/kimchi/logical_mount/' + self.poolArgs['name']
-
-    @property
-    def xml(self):
-        # Required parameters
-        # name:
-        # type:
-        # source[devices]:
-        poolArgs = copy.deepcopy(self.poolArgs)
-        devices = []
-        for device_path in poolArgs['source']['devices']:
-            devices.append('<device path="%s" />' % device_path)
-
-        poolArgs['source']['devices'] = ''.join(devices)
-        poolArgs['path'] = self.path
-
-        xml = """
-        <pool type='logical'>
-        <name>{name}</name>
-            <source>
-            {source[devices]}
-            </source>
-        <target>
-            <path>{path}</path>
-        </target>
-        </pool>
-        """.format(**poolArgs)
-        return xml
-
-
-class IscsiPoolDef(StoragePoolDef):
-    poolType = 'iscsi'
-
-    def prepare(self, conn):
-        source = self.poolArgs['source']
-        if not TargetClient(**source).validate():
-            raise OperationFailed("Can not login to iSCSI host %s target %s" %
-                                  (source['host'], source['target']))
-        self._prepare_auth(conn)
-
-    def _prepare_auth(self, conn):
-        try:
-            auth = self.poolArgs['source']['auth']
-        except KeyError:
-            return
-
-        try:
-            virSecret = conn.secretLookupByUsage(
-                libvirt.VIR_SECRET_USAGE_TYPE_ISCSI, self.poolArgs['name'])
-        except libvirt.libvirtError:
-            xml = '''
-            <secret ephemeral='no' private='yes'>
-              <description>Secret for iSCSI storage pool {name}</description>
-              <auth type='chap' username='{username}'/>
-              <usage type='iscsi'>
-                <target>{name}</target>
-              </usage>
-            </secret>'''.format(name=self.poolArgs['name'],
-                                username=auth['username'])
-            virSecret = conn.secretDefineXML(xml)
-
-        virSecret.setValue(auth['password'])
-
-    def _format_port(self, poolArgs):
-        try:
-            port = poolArgs['source']['port']
-        except KeyError:
-            return ""
-        return "port='%s'" % port
-
-    def _format_auth(self, poolArgs):
-        try:
-            auth = poolArgs['source']['auth']
-        except KeyError:
-            return ""
-
-        return '''
-        <auth type='chap' username='{username}'>
-          <secret type='iscsi' usage='{name}'/>
-        </auth>'''.format(name=poolArgs['name'], username=auth['username'])
-
-    @property
-    def xml(self):
-        # Required parameters
-        # name:
-        # type:
-        # source[host]:
-        # source[target]:
-        #
-        # Optional parameters
-        # source[port]:
-        poolArgs = copy.deepcopy(self.poolArgs)
-        poolArgs['source'].update({'port': self._format_port(poolArgs),
-                                   'auth': self._format_auth(poolArgs)})
-        poolArgs['path'] = '/dev/disk/by-id'
-
-        xml = """
-        <pool type='iscsi'>
-          <name>{name}</name>
-          <source>
-            <host name='{source[host]}' {source[port]}/>
-            <device path='{source[target]}'/>
-            {source[auth]}
-          </source>
-          <target>
-            <path>{path}</path>
-          </target>
-        </pool>
-        """.format(**poolArgs)
-        return xml
-
-
 def _get_volume_xml(**kwargs):
     # Required parameters
     # name:
diff --git a/src/kimchi/model_/libvirtstoragepool.py b/src/kimchi/model_/libvirtstoragepool.py
new file mode 100644
index 0000000..e9b9aa8
--- /dev/null
+++ b/src/kimchi/model_/libvirtstoragepool.py
@@ -0,0 +1,225 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013
+#
+# Authors:
+#  Aline Manera <alinefm at linux.vnet.ibm.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+import copy
+import libvirt
+
+from kimchi.exception import OperationFailed
+from kimchi.iscsi import TargetClient
+
+class StoragePoolDef(object):
+    @classmethod
+    def create(cls, poolArgs):
+        for klass in cls.__subclasses__():
+            if poolArgs['type'] == klass.poolType:
+                return klass(poolArgs)
+        raise OperationFailed('Unsupported pool type: %s' % poolArgs['type'])
+
+    def __init__(self, poolArgs):
+        self.poolArgs = poolArgs
+
+    def prepare(self, conn):
+        ''' Validate pool arguments and perform preparations. Operation which
+        would cause side effect should be put here. Subclasses can optionally
+        override this method, or it always succeeds by default. '''
+        pass
+
+    @property
+    def xml(self):
+        ''' Subclasses have to override this method to actually generate the
+        storage pool XML definition. Should cause no side effect and be
+        idempotent'''
+        # TODO: When add new pool type, should also add the related test in
+        # tests/test_storagepool.py
+        raise OperationFailed('self.xml is not implemented: %s' % self)
+
+
+class DirPoolDef(StoragePoolDef):
+    poolType = 'dir'
+
+    @property
+    def xml(self):
+        # Required parameters
+        # name:
+        # type:
+        # path:
+        xml = """
+        <pool type='dir'>
+          <name>{name}</name>
+          <target>
+            <path>{path}</path>
+          </target>
+        </pool>
+        """.format(**self.poolArgs)
+        return xml
+
+
+class NetfsPoolDef(StoragePoolDef):
+    poolType = 'netfs'
+
+    def __init__(self, poolArgs):
+        super(NetfsPoolDef, self).__init__(poolArgs)
+        self.path = '/var/lib/kimchi/nfs_mount/' + self.poolArgs['name']
+
+    def prepare(self, conn):
+        # TODO: Verify the NFS export can be actually mounted.
+        pass
+
+    @property
+    def xml(self):
+        # Required parameters
+        # name:
+        # type:
+        # source[host]:
+        # source[path]:
+        poolArgs = copy.deepcopy(self.poolArgs)
+        poolArgs['path'] = self.path
+        xml = """
+        <pool type='netfs'>
+          <name>{name}</name>
+          <source>
+            <host name='{source[host]}'/>
+            <dir path='{source[path]}'/>
+          </source>
+          <target>
+            <path>{path}</path>
+          </target>
+        </pool>
+        """.format(**poolArgs)
+        return xml
+
+
+class LogicalPoolDef(StoragePoolDef):
+    poolType = 'logical'
+
+    def __init__(self, poolArgs):
+        super(LogicalPoolDef, self).__init__(poolArgs)
+        self.path = '/var/lib/kimchi/logical_mount/' + self.poolArgs['name']
+
+    @property
+    def xml(self):
+        # Required parameters
+        # name:
+        # type:
+        # source[devices]:
+        poolArgs = copy.deepcopy(self.poolArgs)
+        devices = []
+        for device_path in poolArgs['source']['devices']:
+            devices.append('<device path="%s" />' % device_path)
+
+        poolArgs['source']['devices'] = ''.join(devices)
+        poolArgs['path'] = self.path
+
+        xml = """
+        <pool type='logical'>
+        <name>{name}</name>
+            <source>
+            {source[devices]}
+            </source>
+        <target>
+            <path>{path}</path>
+        </target>
+        </pool>
+        """.format(**poolArgs)
+        return xml
+
+
+class IscsiPoolDef(StoragePoolDef):
+    poolType = 'iscsi'
+
+    def prepare(self, conn):
+        source = self.poolArgs['source']
+        if not TargetClient(**source).validate():
+            raise OperationFailed("Can not login to iSCSI host %s target %s" %
+                                  (source['host'], source['target']))
+        self._prepare_auth(conn)
+
+    def _prepare_auth(self, conn):
+        try:
+            auth = self.poolArgs['source']['auth']
+        except KeyError:
+            return
+
+        try:
+            virSecret = conn.secretLookupByUsage(
+                libvirt.VIR_SECRET_USAGE_TYPE_ISCSI, self.poolArgs['name'])
+        except libvirt.libvirtError:
+            xml = '''
+            <secret ephemeral='no' private='yes'>
+              <description>Secret for iSCSI storage pool {name}</description>
+              <auth type='chap' username='{username}'/>
+              <usage type='iscsi'>
+                <target>{name}</target>
+              </usage>
+            </secret>'''.format(name=self.poolArgs['name'],
+                                username=auth['username'])
+            virSecret = conn.secretDefineXML(xml)
+
+        virSecret.setValue(auth['password'])
+
+    def _format_port(self, poolArgs):
+        try:
+            port = poolArgs['source']['port']
+        except KeyError:
+            return ""
+        return "port='%s'" % port
+
+    def _format_auth(self, poolArgs):
+        try:
+            auth = poolArgs['source']['auth']
+        except KeyError:
+            return ""
+
+        return '''
+        <auth type='chap' username='{username}'>
+          <secret type='iscsi' usage='{name}'/>
+        </auth>'''.format(name=poolArgs['name'], username=auth['username'])
+
+    @property
+    def xml(self):
+        # Required parameters
+        # name:
+        # type:
+        # source[host]:
+        # source[target]:
+        #
+        # Optional parameters
+        # source[port]:
+        poolArgs = copy.deepcopy(self.poolArgs)
+        poolArgs['source'].update({'port': self._format_port(poolArgs),
+                                   'auth': self._format_auth(poolArgs)})
+        poolArgs['path'] = '/dev/disk/by-id'
+
+        xml = """
+        <pool type='iscsi'>
+          <name>{name}</name>
+          <source>
+            <host name='{source[host]}' {source[port]}/>
+            <device path='{source[target]}'/>
+            {source[auth]}
+          </source>
+          <target>
+            <path>{path}</path>
+          </target>
+        </pool>
+        """.format(**poolArgs)
+        return xml
-- 
1.7.10.4




More information about the Kimchi-devel mailing list