Merge "libvirt: read rotated "console.log" files"
This commit is contained in:
commit
8484c7d4d5
@ -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()
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user