VMware: serial console log (completed)

Commit ace11d3 adds a serial port device to instances, so the serial
console output can be sent to a virtual serial port concentrator (VSPC).
This patch finishes the implementation by returning the output saved by
VSPC to the end user. The config option 'serial_log_dir' should have the
same value as in the VSPC configuration (i.e. it must point to the same
directory).

The VSPC implementation is available at
https://github.com/openstack/vmware-vspc

blueprint vmware-console-log-complete

Change-Id: I7e40dc41b0354d414bc8eae331f8257959e1d123
This commit is contained in:
Radoslav Gerganov 2017-03-28 11:26:10 +03:00
parent b2f06b84d5
commit d9c03b1ecb
5 changed files with 53 additions and 5 deletions

View File

@ -955,7 +955,7 @@ driver-impl-libvirt-kvm-s390x=complete
driver-impl-libvirt-qemu-x86=complete
driver-impl-libvirt-lxc=missing
driver-impl-libvirt-xen=complete
driver-impl-vmware=missing
driver-impl-vmware=complete
driver-impl-hyperv=complete
driver-impl-ironic=missing
driver-impl-libvirt-vz-vm=missing

View File

@ -91,6 +91,13 @@ Possible values:
Related options:
This option is ignored if serial_port_service_uri is not specified.
* serial_port_service_uri
"""),
cfg.StrOpt('serial_log_dir',
default='/opt/vmware/vspc',
help="""
Specifies the directory where the Virtual Serial Port Concentrator is
storing console log files. It should match the 'serial_log_dir' config
value of VSPC.
"""),
]

View File

@ -1671,10 +1671,6 @@ class VMwareAPIVMTestCase(test.NoDBTestCase,
actual = self.conn.get_instance_diagnostics(instance)
self.assertDiagnosticsEqual(expected, actual)
def test_get_console_output(self):
self.assertRaises(NotImplementedError, self.conn.get_console_output,
None, None)
def test_get_vnc_console_non_existent(self):
self._create_instance()
self.assertRaises(exception.InstanceNotFound,
@ -1702,6 +1698,24 @@ class VMwareAPIVMTestCase(test.NoDBTestCase,
self.context,
self.instance)
def test_get_console_output(self):
self.flags(serial_log_dir='/opt/vspc', group='vmware')
self._create_instance()
with test.nested(
mock.patch('os.path.exists', return_value=True),
mock.patch('{}.open'.format(driver.__name__), create=True),
mock.patch('nova.privsep.path.last_bytes')
) as (fake_exists, fake_open, fake_last_bytes):
fake_open.return_value = mock.MagicMock()
fake_fd = fake_open.return_value.__enter__.return_value
fake_last_bytes.return_value = b'fira', 0
output = self.conn.get_console_output(self.context, self.instance)
fname = self.instance.uuid.replace('-', '')
fake_exists.assert_called_once_with('/opt/vspc/{}'.format(fname))
fake_last_bytes.assert_called_once_with(fake_fd,
driver.MAX_CONSOLE_BYTES)
self.assertEqual(b'fira', output)
def test_get_volume_connector(self):
self._create_vm()
connector_dict = self.conn.get_volume_connector(self.instance)

View File

@ -19,10 +19,12 @@
A connection to the VMware vCenter platform.
"""
import os
import re
from oslo_log import log as logging
from oslo_utils import excutils
from oslo_utils import units
from oslo_utils import versionutils as v_utils
from oslo_vmware import api
from oslo_vmware import exceptions as vexc
@ -35,6 +37,7 @@ from nova.compute import task_states
import nova.conf
from nova import exception
from nova.i18n import _
import nova.privsep.path
from nova.virt import driver
from nova.virt.vmwareapi import constants
from nova.virt.vmwareapi import error_util
@ -49,6 +52,7 @@ LOG = logging.getLogger(__name__)
CONF = nova.conf.CONF
TIME_BETWEEN_API_CALL_RETRIES = 1.0
MAX_CONSOLE_BYTES = 100 * units.Ki
class VMwareVCDriver(driver.ComputeDriver):
@ -259,6 +263,21 @@ class VMwareVCDriver(driver.ComputeDriver):
def get_mks_console(self, context, instance):
return self._vmops.get_mks_console(instance)
def get_console_output(self, context, instance):
if not CONF.vmware.serial_log_dir:
LOG.error("The 'serial_log_dir' config option is not set!")
return
fname = instance.uuid.replace('-', '')
path = os.path.join(CONF.vmware.serial_log_dir, fname)
if not os.path.exists(path):
LOG.warning('The console log is missing. Check your VSPC '
'configuration', instance=instance)
return b""
with open(path, 'rb') as fp:
read_log_data, remaining = nova.privsep.path.last_bytes(
fp, MAX_CONSOLE_BYTES)
return read_log_data
def _get_vcenter_uuid(self):
"""Retrieves the vCenter UUID."""

View File

@ -0,0 +1,8 @@
---
features:
- |
VMware serial console log is completed. `VSPC`_ must be deployed along
with nova-compute and configured properly. The ``[vmware]/serial_log_dir``
config option must have the same value in both nova.conf and vspc.conf.
.. _VSPC: https://github.com/openstack/vmware-vspc