diff options
| author | Salvatore Orlando <salvatore.orlando@eu.citrix.com> | 2010-12-27 14:06:50 +0000 |
|---|---|---|
| committer | Tarmac <> | 2010-12-27 14:06:50 +0000 |
| commit | 0ef58bac84f5a5824cf91cc3d583ded2ccb1fd9a (patch) | |
| tree | 2dd7fbc7970847d25c3baa77eeed0ae6ec336bcc /nova | |
| parent | bd6a3cb1acb68ac2252c1bafc531b3b12f9746d8 (diff) | |
| parent | c2e645416d88e4438b9359c5dccacf4690c4f54e (diff) | |
| download | nova-0ef58bac84f5a5824cf91cc3d583ded2ccb1fd9a.tar.gz nova-0ef58bac84f5a5824cf91cc3d583ded2ccb1fd9a.tar.xz nova-0ef58bac84f5a5824cf91cc3d583ded2ccb1fd9a.zip | |
Fixed after Jay's review.
Integrated code from Soren (we now use the same 'magic number' for images without kernel & ramdisk.
Diffstat (limited to 'nova')
| -rw-r--r-- | nova/compute/api.py | 11 | ||||
| -rw-r--r-- | nova/tests/test_virt.py | 1 | ||||
| -rw-r--r-- | nova/virt/libvirt_conn.py | 15 | ||||
| -rw-r--r-- | nova/virt/xenapi/fake.py | 1 | ||||
| -rw-r--r-- | nova/virt/xenapi/vm_utils.py | 82 | ||||
| -rw-r--r-- | nova/virt/xenapi/vmops.py | 31 | ||||
| -rw-r--r-- | nova/virt/xenapi/volume_utils.py | 6 |
7 files changed, 107 insertions, 40 deletions
diff --git a/nova/compute/api.py b/nova/compute/api.py index 4953fe559..a3245940e 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -91,15 +91,16 @@ class ComputeAPI(base.Base): is_vpn = image_id == FLAGS.vpn_image_id if not is_vpn: image = self.image_service.show(context, image_id) - - # If kernel_id/ramdisk_id isn't explicitly set in API call - # we take the defaults from the image's metadata if kernel_id is None: kernel_id = image.get('kernelId', None) if ramdisk_id is None: ramdisk_id = image.get('ramdiskId', None) - - # Make sure we have access to kernel and ramdisk + #No kernel and ramdisk for raw images + if kernel_id == str(FLAGS.null_kernel): + kernel_id = None + ramdisk_id = None + logging.debug("Creating a raw instance") + # Make sure we have access to kernel and ramdisk (if not raw) if kernel_id: self.image_service.show(context, kernel_id) if ramdisk_id: diff --git a/nova/tests/test_virt.py b/nova/tests/test_virt.py index 8dab8de2f..1c155abe4 100644 --- a/nova/tests/test_virt.py +++ b/nova/tests/test_virt.py @@ -157,7 +157,6 @@ class LibvirtConnTestCase(test.TestCase): (lambda t: t.find('./devices/serial/source').get( 'path').split('/')[1], 'console.log'), (lambda t: t.find('./memory').text, '2097152')] - if rescue: common_checks += [ (lambda t: t.findall('./devices/disk/source')[0].get( diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 651b2af93..67b9fc47e 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -512,9 +512,10 @@ class LibvirtConnection(object): if FLAGS.allow_project_net_traffic: net, mask = _get_net_and_mask(network['cidr']) - extra_params = ("<parameter name=\"PROJNET\" value=\"%s\" />\n" - "<parameter name=\"PROJMASK\" value=\"%s\" />\n" - ) % (net, mask) + extra_params = ("<parameter name=\"PROJNET\" " + "value=\"%s\" />\n" + "<parameter name=\"PROJMASK\" " + "value=\"%s\" />\n") % (net, mask) else: extra_params = "\n" @@ -800,8 +801,8 @@ class NWFilterFirewall(object): the base filter are all in place. """ - nwfilter_xml = ("<filter name='nova-instance-%s' chain='root'>\n" - ) % instance['name'] + nwfilter_xml = ("<filter name='nova-instance-%s' " + "chain='root'>\n") % instance['name'] if instance['image_id'] == FLAGS.vpn_image_id: nwfilter_xml += " <filterref filter='nova-vpn' />\n" @@ -814,8 +815,8 @@ class NWFilterFirewall(object): for security_group in instance.security_groups: self.ensure_security_group_filter(security_group['id']) - nwfilter_xml += (" <filterref filter='nova-secgroup-%d' />\n" - ) % security_group['id'] + nwfilter_xml += (" <filterref filter='nova-secgroup-%d' " + "/>\n") % security_group['id'] nwfilter_xml += "</filter>" self._define_filter(nwfilter_xml) diff --git a/nova/virt/xenapi/fake.py b/nova/virt/xenapi/fake.py index 7a6c9ee71..1eaf31c25 100644 --- a/nova/virt/xenapi/fake.py +++ b/nova/virt/xenapi/fake.py @@ -235,6 +235,7 @@ class SessionBase(object): elif '.' in name: impl = getattr(self, name.replace('.', '_')) if impl is not None: + def callit(*params): logging.warn('Calling %s %s', name, impl) self._check_session(params) diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index 89e02c917..2f02f4677 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -43,15 +43,31 @@ XENAPI_POWER_STATE = { 'Crashed': power_state.CRASHED} +class ImageType: + """ + Enumeration class for distinguishing different image types + 0 - kernel/ramdisk image (goes on dom0's filesystem) + 1 - disk image (local SR, partitioned by objectstore plugin) + 2 - raw disk image (local SR, NOT partitioned by plugin) + """ + + KERNEL_RAMDISK = 0 + DISK = 1 + DISK_RAW = 2 + + class VMHelper(HelperBase): """ The class that wraps the helper methods together. """ @classmethod - def create_vm(cls, session, instance, kernel, ramdisk): + def create_vm(cls, session, instance, kernel, ramdisk, pv_kernel=False): """Create a VM record. Returns a Deferred that gives the new - VM reference.""" + VM reference. + the pv_kernel flag indicates whether the guest is HVM or PV + """ + instance_type = instance_types.INSTANCE_TYPES[instance.instance_type] mem = str(long(instance_type['memory_mb']) * 1024 * 1024) vcpus = str(instance_type['vcpus']) @@ -70,9 +86,9 @@ class VMHelper(HelperBase): 'actions_after_reboot': 'restart', 'actions_after_crash': 'destroy', 'PV_bootloader': '', - 'PV_kernel': kernel, - 'PV_ramdisk': ramdisk, - 'PV_args': 'root=/dev/xvda1', + 'PV_kernel': '', + 'PV_ramdisk': '', + 'PV_args': '', 'PV_bootloader_args': '', 'PV_legacy_args': '', 'HVM_boot_policy': '', @@ -84,7 +100,25 @@ class VMHelper(HelperBase): 'user_version': '0', 'other_config': {}, } - logging.debug(_('Created VM %s...'), instance.name) + #Complete VM configuration record according to the image type + #non-raw/raw with PV kernel/raw in HVM mode + if instance.kernel_id: + rec['PV_bootloader'] = '' + rec['PV_kernel'] = kernel + rec['PV_ramdisk'] = ramdisk + rec['PV_args'] = 'root=/dev/xvda1' + rec['PV_bootloader_args'] = '' + rec['PV_legacy_args'] = '' + else: + if pv_kernel: + rec['PV_args'] = 'noninteractive' + rec['PV_bootloader'] = 'pygrub' + else: + rec['HVM_boot_policy'] = 'BIOS order' + rec['HVM_boot_params'] = {'order': 'dc'} + rec['platform'] = {'acpi': 'true', 'apic': 'true', + 'pae': 'true', 'viridian': 'true'} + logging.debug('Created VM %s...', instance.name) vm_ref = session.call_xenapi('VM.create', rec) logging.debug(_('Created VM %s as %s.'), instance.name, vm_ref) return vm_ref @@ -170,22 +204,24 @@ class VMHelper(HelperBase): return vif_ref @classmethod - def fetch_image(cls, session, image, user, project, use_sr): - """use_sr: True to put the image as a VDI in an SR, False to place - it on dom0's filesystem. The former is for VM disks, the latter for - its kernel and ramdisk (if external kernels are being used). - Returns a Deferred that gives the new VDI UUID.""" - + def fetch_image(cls, session, image, user, project, type): + """ + type is interpreted as an ImageType instance + """ url = images.image_url(image) access = AuthManager().get_access_key(user, project) - logging.debug(_("Asking xapi to fetch %s as %s"), url, access) - fn = use_sr and 'get_vdi' or 'get_kernel' + logging.debug("Asking xapi to fetch %s as %s", url, access) + fn = (type != ImageType.KERNEL_RAMDISK) and 'get_vdi' or 'get_kernel' args = {} args['src_url'] = url args['username'] = access args['password'] = user.secret - if use_sr: + args['add_partition'] = 'false' + args['raw'] = 'false' + if type != ImageType.KERNEL_RAMDISK: args['add_partition'] = 'true' + if type == ImageType.DISK_RAW: + args['raw'] = 'true' task = session.async_call_plugin('objectstore', fn, args) #FIXME(armando): find a solution to missing instance_id #with Josh Kearney @@ -193,6 +229,22 @@ class VMHelper(HelperBase): return uuid @classmethod + def lookup_image(cls, session, vdi_ref): + logging.debug("Looking up vdi %s for PV kernel", vdi_ref) + fn = "is_vdi_pv" + args = {} + args['vdi-ref'] = vdi_ref + #TODO: Call proper function in plugin + task = session.async_call_plugin('objectstore', fn, args) + pv_str = session.wait_for_task(task) + if pv_str.lower() == 'true': + pv = True + elif pv_str.lower() == 'false': + pv = False + logging.debug("PV Kernel in VDI:%d", pv) + return pv + + @classmethod def lookup(cls, session, i): """Look the instance i up, and returns it if available""" vms = session.get_xenapi().VM.get_by_name_label(i) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 39bb0f1e8..b1de73641 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -29,6 +29,7 @@ from nova.auth.manager import AuthManager from nova.compute import power_state from nova.virt.xenapi.network_utils import NetworkHelper from nova.virt.xenapi.vm_utils import VMHelper +from nova.virt.xenapi.vm_utils import ImageType class VMOps(object): @@ -64,16 +65,30 @@ class VMOps(object): user = AuthManager().get_user(instance.user_id) project = AuthManager().get_project(instance.project_id) - vdi_uuid = VMHelper.fetch_image( - self._session, instance.image_id, user, project, True) - kernel = VMHelper.fetch_image( - self._session, instance.kernel_id, user, project, False) - ramdisk = VMHelper.fetch_image( - self._session, instance.ramdisk_id, user, project, False) + #if kernel is not present we must download a raw disk + if instance.kernel_id: + disk_image_type = ImageType.DISK + else: + disk_image_type = ImageType.DISK_RAW + vdi_uuid = VMHelper.fetch_image(self._session, + instance.image_id, user, project, disk_image_type) vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', vdi_uuid) - vm_ref = VMHelper.create_vm( - self._session, instance, kernel, ramdisk) + #Have a look at the VDI and see if it has a PV kernel + pv_kernel = False + if not instance.kernel_id: + pv_kernel = VMHelper.lookup_image(self._session, vdi_ref) + kernel = None + if instance.kernel_id: + kernel = VMHelper.fetch_image(self._session, + instance.kernel_id, user, project, ImageType.KERNEL_RAMDISK) + ramdisk = None + if instance.ramdisk_id: + ramdisk = VMHelper.fetch_image(self._session, + instance.ramdisk_id, user, project, ImageType.KERNEL_RAMDISK) + vm_ref = VMHelper.create_vm(self._session, + instance, kernel, ramdisk, pv_kernel) VMHelper.create_vbd(self._session, vm_ref, vdi_ref, 0, True) + if network_ref: VMHelper.create_vif(self._session, vm_ref, network_ref, instance.mac_address) diff --git a/nova/virt/xenapi/volume_utils.py b/nova/virt/xenapi/volume_utils.py index a0c0a67d4..1ca813bcf 100644 --- a/nova/virt/xenapi/volume_utils.py +++ b/nova/virt/xenapi/volume_utils.py @@ -60,13 +60,11 @@ class VolumeHelper(HelperBase): 'port': info['targetPort'], 'targetIQN': info['targetIQN'], 'chapuser': info['chapuser'], - 'chappassword': info['chappassword'] - } + 'chappassword': info['chappassword']} else: record = {'target': info['targetHost'], 'port': info['targetPort'], - 'targetIQN': info['targetIQN'] - } + 'targetIQN': info['targetIQN']} try: sr_ref = session.get_xenapi().SR.create( session.get_xenapi_host(), |
