Adds support for ConfigDriveV2 in Hyper-V
Supports iso9660 ConfigDriveV2 drives, which can be attached to the instance on boot as VHD or ISO. Admin password injection can be selectively enabled for security concerns. Updates also the hyperv tests. Change-Id: I22d1ab57bd2f75ddf8758b2ea1a958d7bbe35731
This commit is contained in:
@@ -21,6 +21,7 @@ TestCase for MockProxy based tests and related classes.
|
||||
import gzip
|
||||
import os
|
||||
import pickle
|
||||
import sys
|
||||
|
||||
from nova import test
|
||||
from nova.tests.hyperv import mockproxy
|
||||
@@ -77,7 +78,8 @@ class BaseTestCase(test.TestCase):
|
||||
not in ['true', 'yes', '1']:
|
||||
m = self._load_mock(module_name)
|
||||
else:
|
||||
module = __import__(module_name)
|
||||
__import__(module_name)
|
||||
module = sys.modules[module_name]
|
||||
m = mockproxy.MockProxy(module)
|
||||
self._mps[module_name] = m
|
||||
return m
|
||||
|
@@ -30,14 +30,20 @@ from nova import utils
|
||||
def get_fake_instance_data(name, project_id, user_id):
|
||||
return {'name': name,
|
||||
'id': 1,
|
||||
'uuid': uuid.uuid4(),
|
||||
'uuid': str(uuid.uuid4()),
|
||||
'project_id': project_id,
|
||||
'user_id': user_id,
|
||||
'image_ref': "1",
|
||||
'kernel_id': "1",
|
||||
'ramdisk_id': "1",
|
||||
'mac_address': "de:ad:be:ef:be:ef",
|
||||
'instance_type': 'm1.tiny',
|
||||
'instance_type':
|
||||
{'name': 'm1.tiny',
|
||||
'memory_mb': 512,
|
||||
'vcpus': 1,
|
||||
'root_gb': 0,
|
||||
'flavorid': 1,
|
||||
'rxtx_factor': 1}
|
||||
}
|
||||
|
||||
|
||||
@@ -105,14 +111,20 @@ def stub_out_db_instance_api(stubs):
|
||||
def __init__(self, values):
|
||||
self.values = values
|
||||
|
||||
def get(self, key, default=None):
|
||||
if key in self.values:
|
||||
return self.values[key]
|
||||
else:
|
||||
return default
|
||||
|
||||
def __getattr__(self, name):
|
||||
return self.values[name]
|
||||
|
||||
def __getitem__(self, key):
|
||||
if key in self.values:
|
||||
return self.values[key]
|
||||
else:
|
||||
raise NotImplementedError()
|
||||
return self.get(key)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.values)
|
||||
|
||||
def fake_instance_create(context, values):
|
||||
"""Stubs out the db.instance_create method."""
|
||||
@@ -120,12 +132,12 @@ def stub_out_db_instance_api(stubs):
|
||||
if 'instance_type' not in values:
|
||||
return
|
||||
|
||||
type_data = INSTANCE_TYPES[values['instance_type']]
|
||||
instance_type = values['instance_type']
|
||||
|
||||
base_options = {
|
||||
'name': values['name'],
|
||||
'id': values['id'],
|
||||
'uuid': uuid.uuid4(),
|
||||
'uuid': str(uuid.uuid4()),
|
||||
'reservation_id': utils.generate_uid('r'),
|
||||
'image_ref': values['image_ref'],
|
||||
'kernel_id': values['kernel_id'],
|
||||
@@ -135,11 +147,11 @@ def stub_out_db_instance_api(stubs):
|
||||
'user_id': values['user_id'],
|
||||
'project_id': values['project_id'],
|
||||
'launch_time': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()),
|
||||
'instance_type': values['instance_type'],
|
||||
'memory_mb': type_data['memory_mb'],
|
||||
'vcpus': type_data['vcpus'],
|
||||
'instance_type': instance_type,
|
||||
'memory_mb': instance_type['memory_mb'],
|
||||
'vcpus': instance_type['vcpus'],
|
||||
'mac_addresses': [{'address': values['mac_address']}],
|
||||
'root_gb': type_data['root_gb'],
|
||||
'root_gb': instance_type['root_gb'],
|
||||
}
|
||||
return FakeModel(base_options)
|
||||
|
||||
@@ -161,7 +173,12 @@ def stub_out_db_instance_api(stubs):
|
||||
def fake_instance_type_get_by_name(context, name):
|
||||
return INSTANCE_TYPES[name]
|
||||
|
||||
def fake_block_device_mapping_get_all_by_instance(context, instance_uuid):
|
||||
return {}
|
||||
|
||||
stubs.Set(db, 'instance_create', fake_instance_create)
|
||||
stubs.Set(db, 'network_get_by_instance', fake_network_get_by_instance)
|
||||
stubs.Set(db, 'instance_type_get_all', fake_instance_type_get_all)
|
||||
stubs.Set(db, 'instance_type_get_by_name', fake_instance_type_get_by_name)
|
||||
stubs.Set(db, 'block_device_mapping_get_all_by_instance',
|
||||
fake_block_device_mapping_get_all_by_instance)
|
||||
|
@@ -165,7 +165,13 @@ class HyperVUtils(object):
|
||||
drive_path = hostResources[0]
|
||||
volume_drives.append(drive_path)
|
||||
|
||||
return (disk_files, volume_drives)
|
||||
dvds = [r for r in rasds
|
||||
if r.ResourceSubType == 'Microsoft Virtual CD/DVD Disk']
|
||||
dvd_files = []
|
||||
for dvd in dvds:
|
||||
dvd_files.extend([c for c in dvd.Connection])
|
||||
|
||||
return (disk_files, volume_drives, dvd_files)
|
||||
|
||||
def remove_remote_vm(self, server, vm_name):
|
||||
conn = wmi.WMI(moniker='//' + server + '/root/virtualization')
|
||||
@@ -181,7 +187,8 @@ class HyperVUtils(object):
|
||||
#Stop the VM first.
|
||||
self._set_vm_state(conn, vm_name, 3)
|
||||
|
||||
(disk_files, volume_drives) = self._get_vm_disks(conn, vm_name)
|
||||
(disk_files, volume_drives, dvd_files) = self._get_vm_disks(conn,
|
||||
vm_name)
|
||||
|
||||
(job, ret_val) = vs_man_svc.DestroyVirtualSystem(vm.path_())
|
||||
if ret_val == constants.WMI_JOB_STATUS_STARTED:
|
||||
@@ -192,7 +199,7 @@ class HyperVUtils(object):
|
||||
raise Exception(_('Failed to destroy vm %s') % vm_name)
|
||||
|
||||
#Delete associated vhd disk files.
|
||||
for disk in disk_files:
|
||||
for disk in disk_files + dvd_files:
|
||||
vhd_file = conn_cimv2.query(
|
||||
"Select * from CIM_DataFile where Name = '" +
|
||||
disk.replace("'", "''") + "'")[0]
|
||||
|
@@ -18,6 +18,7 @@ Classes for dynamic generation of mock objects.
|
||||
"""
|
||||
|
||||
import inspect
|
||||
import pickle
|
||||
|
||||
|
||||
def serialize_obj(obj):
|
||||
@@ -39,7 +40,12 @@ def serialize_obj(obj):
|
||||
l1 = l1 + (serialize_obj(i1),)
|
||||
val = str(l1)
|
||||
else:
|
||||
val = str(obj)
|
||||
if isinstance(obj, str) or isinstance(obj, unicode):
|
||||
val = obj
|
||||
elif hasattr(obj, '__str__') and inspect.ismethod(obj.__str__):
|
||||
val = str(obj)
|
||||
else:
|
||||
val = str(type(obj))
|
||||
return val
|
||||
|
||||
|
||||
@@ -48,6 +54,11 @@ def serialize_args(*args, **kwargs):
|
||||
return serialize_obj((args, kwargs))
|
||||
|
||||
|
||||
class MockException(Exception):
|
||||
def __init__(self, message):
|
||||
super(MockException, self).__init__(message)
|
||||
|
||||
|
||||
class Mock(object):
|
||||
def _get_next_value(self, name):
|
||||
c = self._access_count.get(name)
|
||||
@@ -56,7 +67,13 @@ class Mock(object):
|
||||
else:
|
||||
c = c + 1
|
||||
self._access_count[name] = c
|
||||
return self._values[name][c]
|
||||
|
||||
try:
|
||||
value = self._values[name][c]
|
||||
except IndexError as ex:
|
||||
raise MockException(_('Couldn\'t find invocation num. %(c)d '
|
||||
'of attribute "%(name)s"') % locals())
|
||||
return value
|
||||
|
||||
def _get_next_ret_value(self, name, params):
|
||||
d = self._access_count.get(name)
|
||||
@@ -69,7 +86,23 @@ class Mock(object):
|
||||
else:
|
||||
c = c + 1
|
||||
d[params] = c
|
||||
return self._values[name][params][c]
|
||||
|
||||
try:
|
||||
m = self._values[name]
|
||||
except KeyError as ex:
|
||||
raise MockException(_('Couldn\'t find attribute "%s"') % (name))
|
||||
|
||||
try:
|
||||
value = m[params][c]
|
||||
except KeyError as ex:
|
||||
raise MockException(_('Couldn\'t find attribute "%(name)s" '
|
||||
'with arguments "%(params)s"') % locals())
|
||||
except IndexError as ex:
|
||||
raise MockException(_('Couldn\'t find invocation num. %(c)d '
|
||||
'of attribute "%(name)s" with arguments "%(params)s"')
|
||||
% locals())
|
||||
|
||||
return value
|
||||
|
||||
def __init__(self, values):
|
||||
self._values = values
|
||||
@@ -82,7 +115,13 @@ class Mock(object):
|
||||
if name.startswith('__') and name.endswith('__'):
|
||||
return object.__getattribute__(self, name)
|
||||
else:
|
||||
if isinstance(self._values[name], dict):
|
||||
try:
|
||||
isdict = isinstance(self._values[name], dict)
|
||||
except KeyError as ex:
|
||||
raise MockException(_('Couldn\'t find attribute "%s"')
|
||||
% (name))
|
||||
|
||||
if isdict:
|
||||
def newfunc(*args, **kwargs):
|
||||
params = serialize_args(args, kwargs)
|
||||
return self._get_next_ret_value(name, params)
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user