[PATCH V2 0/2] bug fix: from persistent xml get user and group

From: ShaoHe Feng <shaohef@linux.vnet.ibm.com> V1 -> V2: libvirt also support virDomain.metadata and virDomain.setMetadata two api. use virDomain.metadata to get the user and group. use virDomain.setMetadata to set the user and group. ShaoHe Feng (2): bug fix: get user and group metadata by libvirt virDomain.metadata API use libvirt api to set user and group metadata by virDomain.setMetadata API src/kimchi/i18n.py | 1 + src/kimchi/model/vms.py | 52 ++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 42 insertions(+), 11 deletions(-) -- 1.9.0

From: ShaoHe Feng <shaohef@linux.vnet.ibm.com> define domain just edit the persistent xml. So we should get user and group from persistent xml instead of live xml when domain is living. Now use livirt API to get metadata. Info: http://libvirt.org/formatdomain.html#elementsMetadata Signed-off-by: ShaoHe Feng <shaohef@linux.vnet.ibm.com> Signed-off-by: Royce Lv <lvroyce@linux.vnet.ibm.com> --- src/kimchi/i18n.py | 1 + src/kimchi/model/vms.py | 24 +++++++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py index 3fc3013..28b1c4d 100644 --- a/src/kimchi/i18n.py +++ b/src/kimchi/i18n.py @@ -86,6 +86,7 @@ messages = { "KCHVM0026E": _("Group name must be a string"), "KCHVM0027E": _("User %(user)s does not exist"), "KCHVM0028E": _("Group %(group)s does not exist"), + "KCHVM0029E": _("Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"), "KCHVMIF0001E": _("Interface %(iface)s does not exist in virtual machine %(name)s"), "KCHVMIF0002E": _("Network %(network)s specified for virtual machine %(name)s does not exist"), diff --git a/src/kimchi/model/vms.py b/src/kimchi/model/vms.py index 90e9537..4997478 100644 --- a/src/kimchi/model/vms.py +++ b/src/kimchi/model/vms.py @@ -56,6 +56,8 @@ VM_LIVE_UPDATE_PARAMS = {} stats = {} +KIMCHI_META_URL = "https://github.com/kimchi-project/kimchi/metadata/" + class VMsModel(object): def __init__(self, **kargs): @@ -253,6 +255,21 @@ class VMModel(object): return E.metadata(E.kimchi(access)) + def _get_metadata_element(self, dom, element, mode="persistent"): + flag = {"live": libvirt.VIR_DOMAIN_AFFECT_LIVE, + "persistent": libvirt.VIR_DOMAIN_AFFECT_CONFIG, + "current": libvirt.VIR_DOMAIN_AFFECT_CURRENT} + try: + return dom.metadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT, + KIMCHI_META_URL + element, flags=flag[mode]) + except libvirt.libvirtError as e: + if e.get_error_code() == libvirt.VIR_DOMAIN_METADATA_ELEMENT: + kimchi_log.error('Error to get access metadata: %s', e.message) + return "" + else: + raise OperationFailed("KCHVM0029E", {'name': dom.name(), + 'err': e.message}) + def _static_vm_update(self, dom, params): state = DOM_STATE_MAP[dom.info()[0]] @@ -346,9 +363,10 @@ class VMModel(object): res['io_throughput'] = vm_stats.get('disk_io', 0) res['io_throughput_peak'] = vm_stats.get('max_disk_io', 100) - xml = dom.XMLDesc(0) - users = xpath_get_text(xml, "/domain/metadata/kimchi/access/user") - groups = xpath_get_text(xml, "/domain/metadata/kimchi/access/group") + access_xml = (self._get_metadata_element(dom, "access") or + """<access></access>""") + users = xpath_get_text(access_xml, "/access/user") + groups = xpath_get_text(access_xml, "/access/group") return {'state': state, 'stats': res, -- 1.9.0

On 04/21/2014 05:15 PM, shaohef@linux.vnet.ibm.com wrote:
From: ShaoHe Feng <shaohef@linux.vnet.ibm.com>
define domain just edit the persistent xml. So we should get user and group from persistent xml instead of live xml when domain is living.
Now use livirt API to get metadata. Info: http://libvirt.org/formatdomain.html#elementsMetadata
Signed-off-by: ShaoHe Feng <shaohef@linux.vnet.ibm.com> Signed-off-by: Royce Lv <lvroyce@linux.vnet.ibm.com> --- src/kimchi/i18n.py | 1 + src/kimchi/model/vms.py | 24 +++++++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py index 3fc3013..28b1c4d 100644 --- a/src/kimchi/i18n.py +++ b/src/kimchi/i18n.py @@ -86,6 +86,7 @@ messages = { "KCHVM0026E": _("Group name must be a string"), "KCHVM0027E": _("User %(user)s does not exist"), "KCHVM0028E": _("Group %(group)s does not exist"), + "KCHVM0029E": _("Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"),
"KCHVMIF0001E": _("Interface %(iface)s does not exist in virtual machine %(name)s"), "KCHVMIF0002E": _("Network %(network)s specified for virtual machine %(name)s does not exist"), diff --git a/src/kimchi/model/vms.py b/src/kimchi/model/vms.py index 90e9537..4997478 100644 --- a/src/kimchi/model/vms.py +++ b/src/kimchi/model/vms.py @@ -56,6 +56,8 @@ VM_LIVE_UPDATE_PARAMS = {}
stats = {}
+KIMCHI_META_URL = "https://github.com/kimchi-project/kimchi/metadata/" +
class VMsModel(object): def __init__(self, **kargs): @@ -253,6 +255,21 @@ class VMModel(object):
return E.metadata(E.kimchi(access))
+ def _get_metadata_element(self, dom, element, mode="persistent"): + flag = {"live": libvirt.VIR_DOMAIN_AFFECT_LIVE, + "persistent": libvirt.VIR_DOMAIN_AFFECT_CONFIG, + "current": libvirt.VIR_DOMAIN_AFFECT_CURRENT} + try: + return dom.metadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT, + KIMCHI_META_URL + element, flags=flag[mode]) + except libvirt.libvirtError as e: + if e.get_error_code() == libvirt.VIR_DOMAIN_METADATA_ELEMENT: + kimchi_log.error('Error to get access metadata: %s', e.message) + return "" + else: + raise OperationFailed("KCHVM0029E", {'name': dom.name(), + 'err': e.message}) + discuss with Royce, need to move this get_metadata_element to utils.
For other models, like vm_storage or vm_iface need this function.
def _static_vm_update(self, dom, params): state = DOM_STATE_MAP[dom.info()[0]]
@@ -346,9 +363,10 @@ class VMModel(object): res['io_throughput'] = vm_stats.get('disk_io', 0) res['io_throughput_peak'] = vm_stats.get('max_disk_io', 100)
- xml = dom.XMLDesc(0) - users = xpath_get_text(xml, "/domain/metadata/kimchi/access/user") - groups = xpath_get_text(xml, "/domain/metadata/kimchi/access/group") + access_xml = (self._get_metadata_element(dom, "access") or + """<access></access>""") + users = xpath_get_text(access_xml, "/access/user") + groups = xpath_get_text(access_xml, "/access/group")
return {'state': state, 'stats': res,
-- Thanks and best regards! Sheldon Feng(冯少合)<shaohef@linux.vnet.ibm.com> IBM Linux Technology Center

From: ShaoHe Feng <shaohef@linux.vnet.ibm.com> add a method to wrap virDomain.setMetadata. Use this method to set user and group metadata Signed-off-by: ShaoHe Feng <shaohef@linux.vnet.ibm.com> Signed-off-by: Royce Lv <lvroyce@linux.vnet.ibm.com> --- src/kimchi/model/vms.py | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/kimchi/model/vms.py b/src/kimchi/model/vms.py index 4997478..f0b36ed 100644 --- a/src/kimchi/model/vms.py +++ b/src/kimchi/model/vms.py @@ -253,7 +253,18 @@ class VMModel(object): for group in groups: access.append(E.group(group)) - return E.metadata(E.kimchi(access)) + return access + + def _update_metadata(self, dom, meta_xml, element, mode="persistent"): + flag = {"live": libvirt.VIR_DOMAIN_AFFECT_LIVE, + "persistent": libvirt.VIR_DOMAIN_AFFECT_CONFIG, + "current": libvirt.VIR_DOMAIN_AFFECT_CURRENT, + "all": libvirt.VIR_DOMAIN_AFFECT_CURRENT + + libvirt.VIR_DOMAIN_AFFECT_CONFIG if dom.isPersistent() else + libvirt.VIR_DOMAIN_AFFECT_CURRENT} + dom.setMetadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT, meta_xml, + "kimchi", KIMCHI_META_URL + element, + flags=flag[mode]) def _get_metadata_element(self, dom, element, mode="persistent"): flag = {"live": libvirt.VIR_DOMAIN_AFFECT_LIVE, @@ -275,9 +286,10 @@ class VMModel(object): old_xml = new_xml = dom.XMLDesc(0) - metadata_xpath = "/domain/metadata/kimchi/access/%s" - users = xpath_get_text(old_xml, metadata_xpath % "user") - groups = xpath_get_text(old_xml, metadata_xpath % "group") + access_xml = (self._get_metadata_element(dom, "access") or + """<access></access>""") + users = xpath_get_text(access_xml, "/access/user") + groups = xpath_get_text(access_xml, "/access/group") for key, val in params.items(): if key == 'users': @@ -311,12 +323,12 @@ class VMModel(object): root = ET.fromstring(new_xml) current_metadata = root.find('metadata') new_metadata = self._get_metadata_node(users, groups) - if current_metadata is not None: - root.replace(current_metadata, new_metadata) - else: - root.append(new_metadata) dom = conn.defineXML(ET.tostring(root)) + meta = (new_metadata if current_metadata is not None + else current_metadata) + self._update_metadata(dom, ET.tostring(meta), 'access') + except libvirt.libvirtError as e: dom = conn.defineXML(old_xml) raise OperationFailed("KCHVM0008E", {'name': dom.name(), -- 1.9.0

On 04/21/2014 06:15 AM, shaohef@linux.vnet.ibm.com wrote:
From: ShaoHe Feng <shaohef@linux.vnet.ibm.com>
V1 -> V2: libvirt also support virDomain.metadata and virDomain.setMetadata two api. use virDomain.metadata to get the user and group. use virDomain.setMetadata to set the user and group.
ShaoHe Feng (2): bug fix: get user and group metadata by libvirt virDomain.metadata API use libvirt api to set user and group metadata by virDomain.setMetadata API
src/kimchi/i18n.py | 1 + src/kimchi/model/vms.py | 52 ++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 42 insertions(+), 11 deletions(-)
During the first development, I noticed the virDomain.metadata and virDomain.setMetadata does not work well in all libvirt versions. While using those functions, some libvirt versions will report: libvir: QEMU Driver error : argument unsupported: QEMU driver does not support<metadata> element But if you manually get and set metadata element, libvirt works fine.
participants (3)
-
Aline Manera
-
shaohef@linux.vnet.ibm.com
-
Sheldon