Skip to content
Snippets Groups Projects
Commit 012be518 authored by Antoine Millet's avatar Antoine Millet
Browse files

Implemented static tags on VMs

parent fb6cc62b
No related branches found
No related tags found
No related merge requests found
......@@ -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)
......
......@@ -14,6 +14,7 @@
# along with CloudControl. If not, see <http://www.gnu.org/licenses/>.
import re
import errno
import logging
import socket
......@@ -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'))
......@@ -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
......@@ -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):
......@@ -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()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment