Merge "libvirt: read rotated "console.log" files"

This commit is contained in:
Jenkins 2016-11-10 16:54:49 +00:00 committed by Gerrit Code Review
commit 8484c7d4d5
2 changed files with 78 additions and 8 deletions

View File

@ -10820,7 +10820,8 @@ class LibvirtConnTestCase(test.NoDBTestCase):
self.assertEqual('', output)
def test_get_console_output_pty(self):
@mock.patch('os.path.exists', return_value=True)
def test_get_console_output_pty(self, mocked_path_exists):
fake_libvirt_utils.files['pty'] = '01234567890'
with utils.tempdir() as tmpdir:
@ -10894,6 +10895,66 @@ class LibvirtConnTestCase(test.NoDBTestCase):
self.assertRaises(exception.ConsoleNotAvailable,
drvr.get_console_output, self.context, instance)
@mock.patch('nova.virt.libvirt.host.Host.get_domain')
@mock.patch.object(libvirt_guest.Guest, "get_xml_desc")
def test_get_console_output_logrotate(self, mock_get_xml, get_domain):
fake_libvirt_utils.files['console.log'] = 'uvwxyz'
fake_libvirt_utils.files['console.log.0'] = 'klmnopqrst'
fake_libvirt_utils.files['console.log.1'] = 'abcdefghij'
def mock_path_exists(path):
return os.path.basename(path) in fake_libvirt_utils.files
xml = """
<domain type='kvm'>
<devices>
<disk type='file'>
<source file='filename'/>
</disk>
<console type='file'>
<source path='console.log'/>
<target port='0'/>
</console>
</devices>
</domain>
"""
mock_get_xml.return_value = xml
get_domain.return_value = mock.MagicMock()
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
instance = objects.Instance(**self.test_instance)
def _get_logd_output(bytes_to_read):
with utils.tempdir() as tmp_dir:
self.flags(instances_path=tmp_dir)
log_data = ""
try:
prev_max = libvirt_driver.MAX_CONSOLE_BYTES
libvirt_driver.MAX_CONSOLE_BYTES = bytes_to_read
with mock.patch('os.path.exists',
side_effect=mock_path_exists):
log_data = drvr.get_console_output(self.context,
instance)
finally:
libvirt_driver.MAX_CONSOLE_BYTES = prev_max
return log_data
# span across only 1 file (with remaining bytes)
self.assertEqual('wxyz', _get_logd_output(4))
# span across only 1 file (exact bytes)
self.assertEqual('uvwxyz', _get_logd_output(6))
# span across 2 files (with remaining bytes)
self.assertEqual('opqrstuvwxyz', _get_logd_output(12))
# span across all files (exact bytes)
self.assertEqual('abcdefghijklmnopqrstuvwxyz', _get_logd_output(26))
# span across all files with more bytes than available
self.assertEqual('abcdefghijklmnopqrstuvwxyz', _get_logd_output(30))
# files are not available
fake_libvirt_utils.files = {}
self.assertEqual('', _get_logd_output(30))
# reset the file for other tests
fake_libvirt_utils.files['console.log'] = '01234567890'
def test_get_host_ip_addr(self):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
ip = drvr.get_host_ip_addr()

View File

@ -2661,17 +2661,26 @@ class LibvirtDriver(driver.ComputeDriver):
return fpath
def _get_console_output_file(self, instance, path):
libvirt_utils.chown(path, os.getuid())
with libvirt_utils.file_open(path, 'rb') as fp:
log_data, remaining = utils.last_bytes(fp,
MAX_CONSOLE_BYTES)
def _get_console_output_file(self, instance, console_log):
bytes_to_read = MAX_CONSOLE_BYTES
log_data = "" # The last N read bytes
i = 0 # in case there is a log rotation (like "virtlogd")
path = console_log
while bytes_to_read > 0 and os.path.exists(path):
libvirt_utils.chown(path, os.getuid())
with libvirt_utils.file_open(path, 'rb') as fp:
read_log_data, remaining = utils.last_bytes(fp, bytes_to_read)
# We need the log file content in chronological order,
# that's why we *prepend* the log data.
log_data = read_log_data + log_data
bytes_to_read -= len(read_log_data)
path = console_log + "." + str(i)
i += 1
if remaining > 0:
LOG.info(_LI('Truncated console log returned, '
'%d bytes ignored'), remaining,
instance=instance)
return log_data
return log_data
def get_console_output(self, context, instance):
guest = self._host.get_guest(instance)