Loading cloudcontrol/node/hypervisor/__init__.py +35 −0 Original line number Diff line number Diff line Loading @@ -418,6 +418,41 @@ class Handler(HostHandler): # update autostart value now instead of 10 seconds lag vm.tag_db['__main__']['autostart'].update_value() @libvirt_handler def tag_add(self, name, tag, value): """Add a static tag on specified VM. :param name: VM name :param tag: tag name :param value: tag value """ vm = self.hypervisor.domains[name] vm.set_tag(tag, value) @libvirt_handler def tag_delete(self, name, tag): """Delete a static tag on specified VM. :param name: VM name :param tag: tag name """ vm = self.hypervisor.domains[name] vm.delete_tag(tag) @libvirt_handler def tag_show(self, name): """Show static tags of the specified VM. :param name: VM name """ vm = self.hypervisor.domains[name] return vm.tags @libvirt_handler def vol_create(self, pool, name, size): logger.debug('Volume create %s, pool %s, size %s', name, pool, size) Loading cloudcontrol/node/hypervisor/domains/__init__.py +85 −0 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ # along with CloudControl. If not, see <http://www.gnu.org/licenses/>. import re import errno import logging import socket Loading @@ -36,6 +37,10 @@ from cloudcontrol.node.exc import ConsoleAlreadyOpened, ConsoleError logger = logging.getLogger(__name__) REGEX_TAG_NAME = '[a-zA-Z0-9_-]+' REGEX_TAG_VALUE = '.+' REGEX_TAG_IN_DESCRIPTION = '^@(' + REGEX_TAG_NAME + ')[ ]*?=[ ]*?(' + REGEX_TAG_VALUE + ')$' REGEX_TAG_REPLACE = '^@%s[ ]*?=[ ]*?(' + REGEX_TAG_VALUE + ')$' NetworkInterface = namedtuple('NetworkInterface', ('source', 'mac', 'model')) Loading Loading @@ -97,6 +102,9 @@ class VirtualMachine(object): self.redefine_on_stop = False # for XML update (see KVM class) self._description_tags_db = TagDB(parent_db=self.tag_db) self.sync_description_tags() @property def state(self): return self._state Loading @@ -106,6 +114,67 @@ class VirtualMachine(object): self._state = value self.tag_db['__main__']['status'].update_value() self.tag_db['__main__']['vncport'].update_value() self.sync_description_tags() @property def description(self): descriptions = et.ElementTree().parse(StringIO(self.lv_dom.XMLDesc(0))).findall('description') if descriptions: return descriptions[0].text else: return '' @description.setter def description(self, value): try: xml = self.lv_dom.XMLDesc(0) except libvirt.libvirtError: logger.exception('Error while getting domain XML from libvirt, %s', self.name) raise xml_tree = et.ElementTree() xml_tree.parse(StringIO(xml)) desc = xml_tree.find('description') desc.text = value # write back the XML tree out = StringIO() xml_tree.write(out) try: self.hypervisor.vir_con.defineXML(out.getvalue()) except libvirt.libvirtError: logger.exception('Cannot update XML file for domain %s', self.name) raise @property def tags(self): return dict(re.findall(REGEX_TAG_IN_DESCRIPTION, self.description, re.MULTILINE)) def set_tag(self, tag, value): if not re.match(REGEX_TAG_NAME + '$', tag): raise RuntimeError('Bad tag name') elif not re.match(REGEX_TAG_VALUE + '$', value): raise RuntimeError('Bad tag value') tags = self.tags if tag in tags: self.description = re.sub(REGEX_TAG_REPLACE % re.escape(tag), '@%s=%s' % (tag, value), self.description, flags=re.MULTILINE) else: self.description += '\n@%s=%s' % (tag, value) def delete_tag(self, tag): tags = self.tags if tag in tags: self.description = re.sub(REGEX_TAG_REPLACE % tag, '', self.description, flags=re.MULTILINE) @property def lv_dom(self): Loading @@ -119,6 +188,22 @@ class VirtualMachine(object): self.lv_dom.createWithFlags(flags) def sync_description_tags(self): tags = dict(re.findall(REGEX_TAG_IN_DESCRIPTION, self.description, re.MULTILINE)) # Add/update static tags: for k, v in tags.iteritems(): tag = self._description_tags_db['__main__'].get(k) if tag is None: self._description_tags_db.add_tag(Tag(k, v, -1)) else: tag.value = v # Purge not more defined static tags: for k in self._description_tags_db['__main__']: if k not in tags: self._description_tags_db.remove_tag(k) def stop(self): self.lv_dom.shutdown() Loading Loading
cloudcontrol/node/hypervisor/__init__.py +35 −0 Original line number Diff line number Diff line Loading @@ -418,6 +418,41 @@ class Handler(HostHandler): # update autostart value now instead of 10 seconds lag vm.tag_db['__main__']['autostart'].update_value() @libvirt_handler def tag_add(self, name, tag, value): """Add a static tag on specified VM. :param name: VM name :param tag: tag name :param value: tag value """ vm = self.hypervisor.domains[name] vm.set_tag(tag, value) @libvirt_handler def tag_delete(self, name, tag): """Delete a static tag on specified VM. :param name: VM name :param tag: tag name """ vm = self.hypervisor.domains[name] vm.delete_tag(tag) @libvirt_handler def tag_show(self, name): """Show static tags of the specified VM. :param name: VM name """ vm = self.hypervisor.domains[name] return vm.tags @libvirt_handler def vol_create(self, pool, name, size): logger.debug('Volume create %s, pool %s, size %s', name, pool, size) Loading
cloudcontrol/node/hypervisor/domains/__init__.py +85 −0 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ # along with CloudControl. If not, see <http://www.gnu.org/licenses/>. import re import errno import logging import socket Loading @@ -36,6 +37,10 @@ from cloudcontrol.node.exc import ConsoleAlreadyOpened, ConsoleError logger = logging.getLogger(__name__) REGEX_TAG_NAME = '[a-zA-Z0-9_-]+' REGEX_TAG_VALUE = '.+' REGEX_TAG_IN_DESCRIPTION = '^@(' + REGEX_TAG_NAME + ')[ ]*?=[ ]*?(' + REGEX_TAG_VALUE + ')$' REGEX_TAG_REPLACE = '^@%s[ ]*?=[ ]*?(' + REGEX_TAG_VALUE + ')$' NetworkInterface = namedtuple('NetworkInterface', ('source', 'mac', 'model')) Loading Loading @@ -97,6 +102,9 @@ class VirtualMachine(object): self.redefine_on_stop = False # for XML update (see KVM class) self._description_tags_db = TagDB(parent_db=self.tag_db) self.sync_description_tags() @property def state(self): return self._state Loading @@ -106,6 +114,67 @@ class VirtualMachine(object): self._state = value self.tag_db['__main__']['status'].update_value() self.tag_db['__main__']['vncport'].update_value() self.sync_description_tags() @property def description(self): descriptions = et.ElementTree().parse(StringIO(self.lv_dom.XMLDesc(0))).findall('description') if descriptions: return descriptions[0].text else: return '' @description.setter def description(self, value): try: xml = self.lv_dom.XMLDesc(0) except libvirt.libvirtError: logger.exception('Error while getting domain XML from libvirt, %s', self.name) raise xml_tree = et.ElementTree() xml_tree.parse(StringIO(xml)) desc = xml_tree.find('description') desc.text = value # write back the XML tree out = StringIO() xml_tree.write(out) try: self.hypervisor.vir_con.defineXML(out.getvalue()) except libvirt.libvirtError: logger.exception('Cannot update XML file for domain %s', self.name) raise @property def tags(self): return dict(re.findall(REGEX_TAG_IN_DESCRIPTION, self.description, re.MULTILINE)) def set_tag(self, tag, value): if not re.match(REGEX_TAG_NAME + '$', tag): raise RuntimeError('Bad tag name') elif not re.match(REGEX_TAG_VALUE + '$', value): raise RuntimeError('Bad tag value') tags = self.tags if tag in tags: self.description = re.sub(REGEX_TAG_REPLACE % re.escape(tag), '@%s=%s' % (tag, value), self.description, flags=re.MULTILINE) else: self.description += '\n@%s=%s' % (tag, value) def delete_tag(self, tag): tags = self.tags if tag in tags: self.description = re.sub(REGEX_TAG_REPLACE % tag, '', self.description, flags=re.MULTILINE) @property def lv_dom(self): Loading @@ -119,6 +188,22 @@ class VirtualMachine(object): self.lv_dom.createWithFlags(flags) def sync_description_tags(self): tags = dict(re.findall(REGEX_TAG_IN_DESCRIPTION, self.description, re.MULTILINE)) # Add/update static tags: for k, v in tags.iteritems(): tag = self._description_tags_db['__main__'].get(k) if tag is None: self._description_tags_db.add_tag(Tag(k, v, -1)) else: tag.value = v # Purge not more defined static tags: for k in self._description_tags_db['__main__']: if k not in tags: self._description_tags_db.remove_tag(k) def stop(self): self.lv_dom.shutdown() Loading