
From: Aline Manera <alinefm@br.ibm.com> To avoid duplicating code in model and mockmodel, the code related to template resource was added to model_/templates.py and the specific code for each backend (libvirt or mock) was added to model_/libvirtbackend.py and model_/mockbackend.py Signed-off-by: Aline Manera <alinefm@br.ibm.com> --- src/kimchi/model_/libvirtbackend.py | 18 +++++++ src/kimchi/model_/mockbackend.py | 16 +++++++ src/kimchi/model_/templates.py | 89 +++++++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 src/kimchi/model_/templates.py diff --git a/src/kimchi/model_/libvirtbackend.py b/src/kimchi/model_/libvirtbackend.py index 630204b..41f1b06 100644 --- a/src/kimchi/model_/libvirtbackend.py +++ b/src/kimchi/model_/libvirtbackend.py @@ -67,6 +67,8 @@ class LibvirtBackend(object): 2: 'directory', 3: 'network'} + TEMPLATE_SCAN = True + def __init__(self, libvirt_uri=None, objstore_loc=None): self.libvirt_uri = libvirt_uri or 'qemu:///system' self.conn = LibvirtConnection(self.libvirt_uri) @@ -630,3 +632,19 @@ class LibvirtBackend(object): if iface.isActive(): iface.destroy() iface.undefine() + + def create_template(self, name, tmpl): + with self.objstore as session: + session.store('template', name, tmpl.info) + + def get_templates(self): + with self.objstore as session: + return session.get_list('template') + + def get_template_by_name(self, name): + with self.objstore as session: + return session.get('template', name) + + def delete_template(self, name): + with self.objstore as session: + session.delete('template', name) diff --git a/src/kimchi/model_/mockbackend.py b/src/kimchi/model_/mockbackend.py index 4c0fdf8..a598582 100644 --- a/src/kimchi/model_/mockbackend.py +++ b/src/kimchi/model_/mockbackend.py @@ -34,12 +34,15 @@ class MockBackend(object): 'interface': '', 'subnet': '', 'dhcp': {'start': '', 'stop': ''}} + TEMPLATE_SCAN = False + def __init__(self, objstore_loc=None): self.objstore = ObjectStore(objstore_loc) self.next_taskid = 1 self.host_stats = self._get_host_stats() self._storagepools = {} self._networks = {} + self._templates = {} def _get_host_stats(self): memory_stats = {'total': 3934908416L, @@ -181,6 +184,18 @@ class MockBackend(object): def delete_network(self, name): del self._networks[name] + def create_template(self, name, tmpl): + self._templates[name] = tmpl.info + + def get_templates(self): + return self._templates.keys() + + def get_template_by_name(self, name): + return self._templates[name] + + def delete_template(self, name): + del self._templates[name] + class MockStoragePool(object): def __init__(self, name): self.name = name @@ -209,3 +224,4 @@ class MockStorageVolume(object): self.info['os_version'] = '19' self.info['os_distro'] = 'fedora' self.info['bootable'] = True + diff --git a/src/kimchi/model_/templates.py b/src/kimchi/model_/templates.py new file mode 100644 index 0000000..86cd54f --- /dev/null +++ b/src/kimchi/model_/templates.py @@ -0,0 +1,89 @@ +# +# Project Kimchi +# +# Copyright IBM, Corp. 2013 +# +# Authors: +# Adam Litke <agl@linux.vnet.ibm.com> +# Aline Manera <alinefm@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 + +from kimchi.vmtemplate import VMTemplate +from kimchi.exception import InvalidOperation, InvalidParameter, NotFoundError +from kimchi.exception import OperationFailed + +class Templates(object): + def __init__(self, backend): + self.backend = backend + + def create(self, params): + name = params['name'] + if name in self.get_list: + raise InvalidOperation("Template '%s' already exists." % name) + + for net_name in params.get(u'networks', []): + if net_name not in self.backend.get_networks(): + raise InvalidParameter("Network '%s' not found," % net_name) + + try: + tmpl = VMTemplate(params, self.backend.TEMPLATE_SCAN) + self.backend.create_template(name, tmpl) + except Exception, e: + raise OperationFailed("Unable to create template '%s': %s" % + (name, e.message)) + + return name + + def get_list(self): + return sorted(self.backend.get_templates()) + +class Template(Templates): + def lookup(self, name): + if name not in self.get_list(): + raise NotFoundError("Template '%s' not found." % name) + + params = self.backend.get_template_by_name(name) + tmpl = VMTemplate(params, False) + return tmpl.info + + def delete(self, name): + if name not in self.get_list(): + raise NotFoundError("Template '%s' not found." % name) + + self.backend.delete_template(name) + + def update(self, name, params): + old_t = self.lookup(name) + new_t = copy.copy(old_t) + + new_t.update(params) + ident = name + + new_storagepool = new_t.get(u'storagepool', '') + if new_storagepool not in self.backend.get_storagepools(): + raise InvalidParameter("Storage pool '%s' not found." % name) + + for net_name in params.get(u'networks', []): + if net_name not in self.backend.get_networks(): + raise InvalidParameter("Network '%s' not found." % net_name) + + self.delete(name) + try: + ident = self.create(new_t) + except: + ident = self.create(old_t) + + return ident -- 1.7.10.4