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:
Alessandro Pilotti
2012-11-09 17:17:35 +02:00
parent b0a65c2f1b
commit 8110c1b0c8
229 changed files with 136 additions and 29 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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]

View File

@@ -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)

Some files were not shown because too many files have changed in this diff Show More