summaryrefslogtreecommitdiffstats
path: root/nova/virt
diff options
context:
space:
mode:
authorKevin L. Mitchell <kevin.mitchell@rackspace.com>2012-07-25 15:31:11 -0500
committerKevin L. Mitchell <kevin.mitchell@rackspace.com>2012-07-25 15:31:34 -0500
commit82afe7ad5eac668aaefc79e16bbf2226eddde97d (patch)
tree2f6fbe30e9e5e1b1246c64027be1a4b0415cb6c7 /nova/virt
parent9a40e9e9a4538f6ba87451137bf0d6d2598f2319 (diff)
Inject instance metadata into xenstore
When using Xenserver, inject instance metadata into the xenstore, for the use of the instance. Implements blueprint xenstore-metadata. Change-Id: I88a59f1b783eaaaef6ba5efd8bd448aece2f869c
Diffstat (limited to 'nova/virt')
-rw-r--r--nova/virt/driver.py11
-rw-r--r--nova/virt/xenapi/driver.py4
-rw-r--r--nova/virt/xenapi/vmops.py49
3 files changed, 64 insertions, 0 deletions
diff --git a/nova/virt/driver.py b/nova/virt/driver.py
index 6c370ffbd..4e821eab2 100644
--- a/nova/virt/driver.py
+++ b/nova/virt/driver.py
@@ -528,6 +528,17 @@ class ComputeDriver(object):
# TODO(Vek): Need to pass context in for access to auth_token
raise NotImplementedError()
+ def change_instance_metadata(self, context, instance, diff):
+ """
+ Applies a diff to the instance metadata.
+
+ This is an optional driver method which is used to publish
+ changes to the instance's metadata to the hypervisor. If the
+ hypervisor has no means of publishing the instance metadata to
+ the instance, then this method should not be implemented.
+ """
+ pass
+
def agent_update(self, instance, url, md5hash):
"""
Update agent on the specified instance.
diff --git a/nova/virt/xenapi/driver.py b/nova/virt/xenapi/driver.py
index 2a86277e5..9a81311cb 100644
--- a/nova/virt/xenapi/driver.py
+++ b/nova/virt/xenapi/driver.py
@@ -214,6 +214,10 @@ class XenAPIDriver(driver.ComputeDriver):
"""
self._vmops.inject_file(instance, b64_path, b64_contents)
+ def change_instance_metadata(self, context, instance, diff):
+ """Apply a diff to the instance metadata."""
+ self._vmops.change_instance_metadata(instance, diff)
+
def destroy(self, instance, network_info, block_device_info=None):
"""Destroy VM instance"""
self._vmops.destroy(instance, network_info, block_device_info)
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index 83970e861..5dcc53b94 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -415,6 +415,8 @@ class VMOps(object):
hostname = self._generate_hostname(instance)
self.inject_hostname(instance, vm_ref, hostname)
+ self.inject_instance_metadata(instance, vm_ref)
+
return vm_ref
def _attach_disks(self, instance, disk_image_type, vm_ref, vdis):
@@ -841,6 +843,44 @@ class VMOps(object):
vm_ref = self._get_vm_opaque_ref(instance)
agent.inject_file(self._session, instance, vm_ref, path, contents)
+ def inject_instance_metadata(self, instance, vm_ref):
+ """Inject instance metadata into xenstore."""
+ def store_meta(topdir, data_list):
+ for item in data_list:
+ key = item.key
+ value = item.value or ''
+ self._add_to_param_xenstore(vm_ref, '%s/%s' % (topdir, key),
+ jsonutils.dumps(value))
+
+ # Store user metadata
+ store_meta('vm-data/user-metadata', instance['metadata'])
+
+ # Store system metadata
+ store_meta('vm-data/system-metadata', instance['system_metadata'])
+
+ def change_instance_metadata(self, instance, diff):
+ """Apply changes to instance metadata to xenstore."""
+ vm_ref = self._get_vm_opaque_ref(instance)
+ for key, change in diff.items():
+ location = 'vm-data/user-metadata/%s' % key
+ if change[0] == '-':
+ self._remove_from_param_xenstore(vm_ref, location)
+ try:
+ self._delete_from_xenstore(instance, location,
+ vm_ref=vm_ref)
+ except KeyError:
+ # catch KeyError for domid if instance isn't running
+ pass
+ elif change[0] == '+':
+ self._add_to_param_xenstore(vm_ref, location,
+ jsonutils.dumps(change[1]))
+ try:
+ self._write_to_xenstore(instance, location, change[1],
+ vm_ref=vm_ref)
+ except KeyError:
+ # catch KeyError for domid if instance isn't running
+ pass
+
def _find_root_vdi_ref(self, vm_ref):
"""Find and return the root vdi ref for a VM."""
if not vm_ref:
@@ -1328,6 +1368,15 @@ class VMOps(object):
vm_ref=vm_ref, path=path,
value=jsonutils.dumps(value))
+ def _delete_from_xenstore(self, instance, path, vm_ref=None):
+ """
+ Deletes the value from the xenstore record for the given VM at
+ the specified location. A XenAPIPlugin.PluginError will be
+ raised if any error is encountered in the delete process.
+ """
+ return self._make_plugin_call('xenstore.py', 'delete_record', instance,
+ vm_ref=vm_ref, path=path)
+
def _make_plugin_call(self, plugin, method, instance, vm_ref=None,
**addl_args):
"""