Fixes HyperV VM Console Log

This patch intends to fix some small nits introduced along with
the Nova console log patch.

The size of the console log can get bigger than expected because
of a small nit when checking the existing log file size as well
as a wrong size constant.

The method which gets the serial port pipe at the moment returns
a list which contains at most one element being the actual pipe
path. In order to avoid confusion this should return the pipe path
or None instead of a list.

Change-Id: I5ce9d1bea572f9098971990d011fa97ebf09233e
Closes-Bug: #1363899
This commit is contained in:
Adelina Tuvenie 2014-09-01 11:44:14 +03:00
parent 5895d3e6f2
commit 1e54cae3d3
5 changed files with 25 additions and 17 deletions

View File

@ -15,6 +15,8 @@
import mock
import os
from nova import test
from nova.virt.hyperv import ioutils
@ -45,10 +47,11 @@ class IOThreadTestCase(test.NoDBTestCase):
mock_context_manager = mock.MagicMock()
fake_open.return_value = mock_context_manager
mock_context_manager.__enter__.side_effect = [fake_src, fake_dest]
self._iothread._stopped.isSet = mock.Mock(side_effect = [False, True])
self._iothread._stopped.isSet = mock.Mock(side_effect=[False, True])
self._iothread._copy(self._FAKE_SRC, self._FAKE_DEST)
fake_dest.seek.assert_called_once_with(0, os.SEEK_END)
fake_dest.write.assert_called_once_with(fake_data)
fake_dest.close.assert_called_once_with()
fake_rename.assert_called_once_with(

View File

@ -543,13 +543,12 @@ class VMUtilsTestCase(test.NoDBTestCase):
type(fake_vm).EnabledState = mock.PropertyMock(
side_effect=[constants.HYPERV_VM_STATE_ENABLED,
constants.HYPERV_VM_STATE_DISABLED])
self._vmutils._conn.Msvm_ComputerSystem.return_value = (
[fake_vm] * 2)
self._vmutils.list_instances = mock.MagicMock(
return_value=[mock.sentinel.fake_vm_name] * 2)
self._vmutils._lookup_vm = mock.MagicMock(side_effect=[fake_vm] * 2)
active_instances = self._vmutils.get_active_instances()
self.assertIn('active_vm', active_instances)
self.assertEqual(1, len(active_instances))
self.assertEqual(['active_vm'], active_instances)
def _test_get_vm_serial_port_connection(self, new_connection=None):
old_serial_connection = 'old_serial_connection'
@ -572,11 +571,11 @@ class VMUtilsTestCase(test.NoDBTestCase):
self._FAKE_VM_NAME, update_connection=new_connection)
if new_connection:
self.assertIn(new_connection, ret_val)
self.assertEqual(new_connection, ret_val)
fake_modify.assert_called_once_with(fake_serial_port,
mock_vm.path_())
else:
self.assertIn(old_serial_connection, ret_val)
self.assertEqual(old_serial_connection, ret_val)
def test_set_vm_serial_port_connection(self):
self._test_get_vm_serial_port_connection('new_serial_connection')

View File

@ -49,6 +49,7 @@ class IOThread(native_threading.Thread):
def _copy(self, src, dest):
with open(self._src, 'rb') as src:
with open(self._dest, 'ab', 0) as dest:
dest.seek(0, os.SEEK_END)
log_size = dest.tell()
while (not self._stopped.isSet()):
# Read one byte at a time to avoid blocking.

11
nova/virt/hyperv/vmops.py Executable file → Normal file
View File

@ -111,7 +111,9 @@ class VMOps(object):
'nova.virt.hyperv.vif.HyperVNovaNetworkVIFDriver',
}
_MAX_CONSOLE_BYTES = units.Mi
# The console log is stored in two files, each should have at most half of
# the maximum console log size.
_MAX_CONSOLE_LOG_FILE_SIZE = units.Mi / 2
def __init__(self):
self._vmutils = utilsfactory.get_vmutils()
@ -586,7 +588,7 @@ class VMOps(object):
pipe_path = r'\\.\pipe\%s' % instance_uuid
vm_log_writer = ioutils.IOThread(pipe_path, console_log_path,
self._MAX_CONSOLE_BYTES)
self._MAX_CONSOLE_LOG_FILE_SIZE)
self._vm_log_writers[instance_uuid] = vm_log_writer
vm_log_writer.start()
@ -597,7 +599,8 @@ class VMOps(object):
try:
instance_log = ''
for console_log_path in console_log_paths:
# Start with the oldest console log file.
for console_log_path in console_log_paths[::-1]:
if os.path.exists(console_log_path):
with open(console_log_path, 'rb') as fp:
instance_log += fp.read()
@ -648,5 +651,5 @@ class VMOps(object):
vm_serial_conn = self._vmutils.get_vm_serial_port_connection(
instance_name)
if vm_serial_conn:
instance_uuid = os.path.basename(vm_serial_conn[0])
instance_uuid = os.path.basename(vm_serial_conn)
self.log_vm_serial_output(instance_name, instance_uuid)

View File

@ -679,12 +679,14 @@ class VMUtils(object):
serial_port.Connection = [update_connection]
self._modify_virt_resource(serial_port, vm.path_())
return serial_port.Connection
if len(serial_port.Connection) > 0:
return serial_port.Connection[0]
def get_active_instances(self):
"""Return the names of all the active instances known to Hyper-V."""
vm_names = [v.ElementName for v in
self._conn.Msvm_ComputerSystem(Caption="Virtual Machine")
if v.EnabledState == constants.HYPERV_VM_STATE_ENABLED]
vm_names = self.list_instances()
vms = [self._lookup_vm(vm_name) for vm_name in vm_names]
active_vm_names = [v.ElementName for v in vms
if v.EnabledState == constants.HYPERV_VM_STATE_ENABLED]
return vm_names
return active_vm_names