diff options
| author | Vishvananda Ishaya <vishvananda@gmail.com> | 2012-01-28 01:17:00 -0800 |
|---|---|---|
| committer | Vishvananda Ishaya <vishvananda@gmail.com> | 2012-02-04 11:35:16 -0800 |
| commit | 94d8553201e50e3e9e25992bfe4735addae4ffda (patch) | |
| tree | 881809bbeeb441ad70fe6abc139712f9486458a5 /nova/virt | |
| parent | 65e233133e801439caaa8265b0de68c70a04ccd2 (diff) | |
Add initiator to initialize_connection
Some volumes need to know the name of the initiator that will be
connecting to the iscsi volume. This adds a call down to the hypervisor
driver to get the ip and the initiator name for the vm before calling
initialize connection. This connection is passed down to the volume
driver so that it can be used to authenticate when the hypervisor
tries to connect to the volume.
* Adds initiator initialize_connection
* Makes a call to driver to get initiator name and ip address
* Gets initiator from openiscsi for libvirt
* Gets initiator from config for xenapi
* Add tests for the driver calls
* Fixes bug 924461
Change-Id: I5b6a2dd84560c7f7b447571e0abf0993e5512ca0
Diffstat (limited to 'nova/virt')
| -rw-r--r-- | nova/virt/driver.py | 14 | ||||
| -rw-r--r-- | nova/virt/fake.py | 3 | ||||
| -rw-r--r-- | nova/virt/libvirt/connection.py | 16 | ||||
| -rw-r--r-- | nova/virt/libvirt/utils.py | 10 | ||||
| -rw-r--r-- | nova/virt/vmwareapi_conn.py | 9 | ||||
| -rw-r--r-- | nova/virt/xenapi_conn.py | 15 |
6 files changed, 65 insertions, 2 deletions
diff --git a/nova/virt/driver.py b/nova/virt/driver.py index e726f7933..d87a7286a 100644 --- a/nova/virt/driver.py +++ b/nova/virt/driver.py @@ -623,3 +623,17 @@ class ComputeDriver(object): the cache and remove images which are no longer of interest. """ raise NotImplementedError() + + def get_volume_connector(self, instance): + """ + Get connector information for the instance for attaching to volumes. + + Connector information is a dictionary representing the ip of the + machine that will be making the connection and and the name of the + iscsi initiator as follows: + { + 'ip': ip, + 'initiator': initiator, + } + """ + raise NotImplementedError() diff --git a/nova/virt/fake.py b/nova/virt/fake.py index 780d644eb..ff8da4724 100644 --- a/nova/virt/fake.py +++ b/nova/virt/fake.py @@ -301,3 +301,6 @@ class FakeConnection(driver.ComputeDriver): def get_disk_available_least(self): """ """ pass + + def get_volume_connector(self, instance): + return {'ip': '127.0.0.1', 'initiator': 'fake'} diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py index 45af96a0a..5b8508da6 100644 --- a/nova/virt/libvirt/connection.py +++ b/nova/virt/libvirt/connection.py @@ -187,6 +187,7 @@ class LibvirtConnection(driver.ComputeDriver): super(LibvirtConnection, self).__init__() self._host_state = None + self._initiator = None self._wrapped_conn = None self.container = None self.read_only = read_only @@ -423,6 +424,16 @@ class LibvirtConnection(driver.ComputeDriver): if os.path.exists(target): shutil.rmtree(target) + def get_volume_connector(self, _instance): + if not self._initiator: + self._initiator = libvirt_utils.get_iscsi_initiator() + if not self._initiator: + LOG.warn(_('Could not determine iscsi initiator name')) + return { + 'ip': FLAGS.my_ip, + 'initiator': self._initiator, + } + def volume_driver_method(self, method_name, connection_info, *args, **kwargs): driver_type = connection_info.get('driver_volume_type') @@ -723,7 +734,7 @@ class LibvirtConnection(driver.ComputeDriver): if virsh_output.startswith('/dev/'): LOG.info(_("cool, it's a device")) out, err = utils.execute('dd', - "if=%s" % virsh_output, + 'if=%s' % virsh_output, 'iflag=nonblock', run_as_root=True, check_exit_code=False) @@ -751,7 +762,8 @@ class LibvirtConnection(driver.ComputeDriver): if FLAGS.libvirt_type == 'xen': # Xen is special - virsh_output = utils.execute('virsh', 'ttyconsole', + virsh_output = utils.execute('virsh', + 'ttyconsole', instance['name']) data = self._flush_xen_console(virsh_output) fpath = self._append_to_file(data, console_log) diff --git a/nova/virt/libvirt/utils.py b/nova/virt/libvirt/utils.py index 4409e6aa6..f96128124 100644 --- a/nova/virt/libvirt/utils.py +++ b/nova/virt/libvirt/utils.py @@ -44,6 +44,16 @@ def execute(*args, **kwargs): return utils.execute(*args, **kwargs) +def get_iscsi_initiator(): + """Get iscsi initiator name for this machine""" + # NOTE(vish) openiscsi stores initiator name in a file that + # needs root permission to read. + contents = utils.read_file_as_root('/etc/iscsi/initiatorname.iscsi') + for l in contents.split('\n'): + if l.startswith('InitiatorName='): + return l[l.index('=') + 1:].strip() + + def create_image(disk_format, path, size): """Create a disk image diff --git a/nova/virt/vmwareapi_conn.py b/nova/virt/vmwareapi_conn.py index c63f1e9d5..909969fac 100644 --- a/nova/virt/vmwareapi_conn.py +++ b/nova/virt/vmwareapi_conn.py @@ -178,6 +178,15 @@ class VMWareESXConnection(driver.ComputeDriver): """Return link to instance's ajax console.""" return self._vmops.get_ajax_console(instance) + def get_volume_connector(self, _instance): + """Return volume connector information""" + # TODO(vish): When volume attaching is supported, return the + # proper initiator iqn. + return { + 'ip': FLAGS.vmwareapi_host_ip, + 'initiator': None + } + def attach_volume(self, connection_info, instance_name, mountpoint): """Attach volume storage to VM instance.""" pass diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py index 236bd4762..26e36b911 100644 --- a/nova/virt/xenapi_conn.py +++ b/nova/virt/xenapi_conn.py @@ -179,6 +179,7 @@ class XenAPIConnection(driver.ComputeDriver): self._host_state = None self._product_version = self._session.get_product_version() self._vmops = VMOps(self._session, self._product_version) + self._initiator = None @property def host_state(self): @@ -348,6 +349,20 @@ class XenAPIConnection(driver.ComputeDriver): """Return link to instance's ajax console""" return self._vmops.get_vnc_console(instance) + def get_volume_connector(self, _instance): + """Return volume connector information""" + if not self._initiator: + stats = self.get_host_stats(update=True) + try: + self._initiator = stats['host_other-config']['iscsi_iqn'] + except (TypeError, KeyError): + LOG.warn(_('Could not determine iscsi initiator name')) + self._initiator = None + return { + 'ip': self.get_host_ip_addr(), + 'initiator': self._initiator + } + @staticmethod def get_host_ip_addr(): xs_url = urlparse.urlparse(FLAGS.xenapi_connection_url) |
