diff options
| author | Kevin L. Mitchell <kevin.mitchell@rackspace.com> | 2012-07-25 15:31:11 -0500 |
|---|---|---|
| committer | Kevin L. Mitchell <kevin.mitchell@rackspace.com> | 2012-07-25 15:31:34 -0500 |
| commit | 82afe7ad5eac668aaefc79e16bbf2226eddde97d (patch) | |
| tree | 2f6fbe30e9e5e1b1246c64027be1a4b0415cb6c7 /nova/virt | |
| parent | 9a40e9e9a4538f6ba87451137bf0d6d2598f2319 (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.py | 11 | ||||
| -rw-r--r-- | nova/virt/xenapi/driver.py | 4 | ||||
| -rw-r--r-- | nova/virt/xenapi/vmops.py | 49 |
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): """ |
