def test_create_raw_with_contents(self): """Creation of raw disk image containing files.""" disk_path = os.path.join(self.temp_dir, "out.img") try: create_disk_image(disk_path, contents=[self.input_ovf]) except HelperNotFoundError as e: self.fail(e.strerror) (f, sf) = get_disk_format(disk_path) self.assertEqual(f, 'raw') try: capacity = get_disk_capacity(disk_path) self.assertEqual(capacity, "8388608") except HelperNotFoundError as e: self.fail(e.strerror) # TODO check raw file contents # Again, but now force the disk size try: create_disk_image(disk_path, contents=[self.input_ovf], capacity="64M") except HelperNotFoundError as e: self.fail(e.strerror) (f, sf) = get_disk_format(disk_path) self.assertEqual(f, 'raw') try: capacity = get_disk_capacity(disk_path) self.assertEqual(capacity, "67108864") except HelperNotFoundError as e: self.fail(e.strerror)
def test_get_disk_format(self): """Get format and subformat of various disk images.""" # First, tests that just use qemu-img try: temp_disk = os.path.join(self.temp_dir, 'foo.img') create_disk_image(temp_disk, capacity="16M") (f, sf) = get_disk_format(temp_disk) self.assertEqual(f, 'raw') self.assertEqual(sf, None) temp_disk = os.path.join(self.temp_dir, 'foo.qcow2') create_disk_image(temp_disk, capacity="1G") (f, sf) = get_disk_format(temp_disk) self.assertEqual(f, 'qcow2') self.assertEqual(sf, None) except HelperNotFoundError as e: self.fail(e.strerror) # Now a test that uses both qemu-img and file inspection try: (f, sf) = get_disk_format(self.blank_vmdk) self.assertEqual(f, 'vmdk') self.assertEqual(sf, 'streamOptimized') except HelperNotFoundError as e: self.fail(e.strerror)
def test_convert_to_vmdk_streamoptimized(self): """Convert a disk to vmdk streamOptimized sub-format.""" # Raw to stream-optimized vmdk temp_disk = os.path.join(self.temp_dir, "foo.img") try: create_disk_image(temp_disk, capacity="16M") except HelperNotFoundError as e: self.fail(e.strerror) try: new_disk_path = convert_disk_image(temp_disk, self.temp_dir, 'vmdk', 'streamOptimized') except HelperNotFoundError as e: self.fail(e.strerror) (f, sf) = get_disk_format(new_disk_path) self.assertEqual(f, 'vmdk') self.assertEqual(sf, 'streamOptimized') # Non-stream-optimized to stream-optimized temp_disk = os.path.join(self.temp_dir, "foo.vmdk") create_disk_image(temp_disk, capacity="16M") new_disk_path = convert_disk_image(temp_disk, self.temp_dir, 'vmdk', 'streamOptimized') (f, sf) = get_disk_format(new_disk_path) self.assertEqual(f, 'vmdk') self.assertEqual(sf, 'streamOptimized')
def test_create_iso_with_contents(self): """Creation of ISO image containing files.""" disk_path = os.path.join(self.temp_dir, "out.iso") try: create_disk_image(disk_path, contents=[self.input_ovf]) except HelperNotFoundError as e: self.fail(e.strerror)
def test_disk_conversion_and_replacement(self): """Convert a disk to implicitly replace an existing disk.""" # Create a qcow2 image and add it as replacement for the existing vmdk new_qcow2 = os.path.join(self.temp_dir, "input.qcow2") # Keep it small! create_disk_image(new_qcow2, capacity="16M") self.instance.package = self.input_ovf self.instance.disk_image = new_qcow2 self.instance.run() self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_HARDDISK) self.assertLogged(**self.OVERWRITING_FILE) self.assertLogged(**self.OVERWRITING_DISK) self.assertLogged(**self.OVERWRITING_DISK_ITEM) self.instance.finished() # Make sure the disk was converted and replaced the existing disk self.check_diff(""" <ovf:References> - <ovf:File ovf:href="input.vmdk" ovf:id="file1" ovf:size="{input_size}" /> + <ovf:File ovf:href="input.vmdk" ovf:id="file1" ovf:size="{new_size}" /> <ovf:File ovf:href="input.iso" ovf:id="file2" ovf:size="{iso_size}" /> ... <ovf:Info>Virtual disk information</ovf:Info> - <ovf:Disk ovf:capacity="1" ovf:capacityAllocationUnits="byte * 2^30" \ ovf:diskId="vmdisk1" ovf:fileRef="file1" ovf:format=\ "http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized" /> + <ovf:Disk ovf:capacity="16" ovf:capacityAllocationUnits="byte * 2^20" \ ovf:diskId="vmdisk1" ovf:fileRef="file1" ovf:format=\ "http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized" /> </ovf:DiskSection> """.format(input_size=self.FILE_SIZE['input.vmdk'], iso_size=self.FILE_SIZE['input.iso'], new_size=os.path.getsize(os.path.join(self.temp_dir, "input.vmdk"))))
def test_convert_to_vmdk_streamoptimized_new_qemu(self): """Code flow for new QEMU version.""" COT.helpers.api.QEMUIMG._version = StrictVersion("2.1.0") try: temp_disk = os.path.join(self.temp_dir, "foo.qcow2") create_disk_image(temp_disk, capacity="16M") new_disk_path = convert_disk_image(temp_disk, self.temp_dir, 'vmdk', 'streamOptimized') self.assertEqual(new_disk_path, os.path.join(self.temp_dir, 'foo.vmdk')) (f, sf) = get_disk_format(new_disk_path) self.assertEqual(f, 'vmdk') self.assertEqual(sf, 'streamOptimized') except HelperNotFoundError as e: self.fail(e.strerror) finally: COT.helpers.api.QEMUIMG._version = None
def test_disk_conversion(self): """Make sure hard disk is converted to stream-optimized VMDK format.""" # Create a qcow2 image and add it as a new disk new_qcow2 = os.path.join(self.temp_dir, "new.qcow2") # Make it a small file to keep the test fast create_disk_image(new_qcow2, capacity="16M") self.instance.package = self.input_ovf self.instance.disk_image = new_qcow2 self.instance.controller = 'scsi' self.instance.run() self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_HARDDISK) self.instance.finished() # Make sure the disk was converted and added to the OVF self.check_diff(""" <ovf:File ovf:href="input.iso" ovf:id="file2" ovf:size="{iso_size}" /> + <ovf:File ovf:href="new.vmdk" ovf:id="new.vmdk" ovf:size="{new_size}" /> </ovf:References> ... <ovf:Disk ovf:capacity="1" ovf:capacityAllocationUnits="byte * 2^30" \ ovf:diskId="vmdisk1" ovf:fileRef="file1" ovf:format=\ "http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized" /> + <ovf:Disk ovf:capacity="16" ovf:capacityAllocationUnits="byte * 2^20" \ ovf:diskId="new.vmdk" ovf:fileRef="new.vmdk" ovf:format=\ "http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized" /> </ovf:DiskSection> ... </ovf:Item> + <ovf:Item> + <rasd:AddressOnParent>1</rasd:AddressOnParent> + <rasd:ElementName>Hard Disk Drive</rasd:ElementName> + <rasd:HostResource>ovf:/disk/new.vmdk</rasd:HostResource> + <rasd:InstanceID>14</rasd:InstanceID> + <rasd:Parent>3</rasd:Parent> + <rasd:ResourceType>17</rasd:ResourceType> + </ovf:Item> </ovf:VirtualHardwareSection> """.format(iso_size=self.FILE_SIZE['input.iso'], new_size=os.path.getsize(os.path.join(self.temp_dir, "new.vmdk")))) # Make sure the disk was actually converted to the right format format, subformat = get_disk_format(os.path.join(self.temp_dir, "new.vmdk")) self.assertEqual(format, 'vmdk') self.assertEqual(subformat, "streamOptimized")
def test_add_disk_no_room(self): """Negative test - add a disk to an OVF whose controllers are full.""" # iosv.ovf already has two disks. Add a third disk... self.instance.package = self.iosv_ovf self.instance.disk_image = self.blank_vmdk self.instance.run() self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_HARDDISK) self.assertLogged(**self.CONTROLLER_NOT_SPECIFIED_GUESS_IDE) self.assertLogged(**self.ADDRESS_ON_PARENT_NOT_SPECIFIED) self.instance.finished() self.check_diff(file1=self.iosv_ovf, expected=""" <ovf:File ovf:href="input.vmdk" ovf:id="vios-adventerprisek9-m.vmdk" \ ovf:size="152576" /> + <ovf:File ovf:href="blank.vmdk" ovf:id="blank.vmdk" \ ovf:size="{blank_size}" /> </ovf:References> ... <ovf:Disk ovf:capacity="1073741824" ovf:capacityAllocationUnits="byte" \ ovf:diskId="vios-adventerprisek9-m.vmdk" \ ovf:fileRef="vios-adventerprisek9-m.vmdk" \ ovf:format="http://www.vmware.com/interfaces/specifications/\ vmdk.html#streamOptimized" /> + <ovf:Disk ovf:capacity="512" ovf:capacityAllocationUnits="byte * 2^20" \ ovf:diskId="blank.vmdk" ovf:fileRef="blank.vmdk" \ ovf:format="http://www.vmware.com/interfaces/specifications/\ vmdk.html#streamOptimized" /> </ovf:DiskSection> ... </ovf:Item> + <ovf:Item> + <rasd:Address>1</rasd:Address> + <rasd:Description>IDE Controller 1</rasd:Description> + <rasd:ElementName>IDE Controller</rasd:ElementName> + <rasd:InstanceID>6</rasd:InstanceID> + <rasd:ResourceSubType>virtio</rasd:ResourceSubType> + <rasd:ResourceType>5</rasd:ResourceType> + </ovf:Item> + <ovf:Item> + <rasd:AddressOnParent>0</rasd:AddressOnParent> + <rasd:ElementName>Hard Disk Drive</rasd:ElementName> + <rasd:HostResource>ovf:/disk/blank.vmdk</rasd:HostResource> + <rasd:InstanceID>7</rasd:InstanceID> + <rasd:Parent>6</rasd:Parent> + <rasd:ResourceType>17</rasd:ResourceType> + </ovf:Item> <ovf:Item ovf:required="false"> """.format(blank_size=self.FILE_SIZE['blank.vmdk'])) # Add a fourth disk... self.instance.package = self.temp_file self.instance.disk_image = resource_filename(__name__, 'input.iso') self.instance.run() self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_CDROM) self.assertLogged(**self.CONTROLLER_NOT_SPECIFIED_GUESS_IDE) self.instance.finished() self.check_diff(file1=self.iosv_ovf, expected=""" <ovf:File ovf:href="input.vmdk" ovf:id="vios-adventerprisek9-m.vmdk" \ ovf:size="152576" /> + <ovf:File ovf:href="blank.vmdk" ovf:id="blank.vmdk" \ ovf:size="{blank_size}" /> + <ovf:File ovf:href="input.iso" ovf:id="input.iso" ovf:size="{iso_size}" /> </ovf:References> ... <ovf:Disk ovf:capacity="1073741824" ovf:capacityAllocationUnits="byte" \ ovf:diskId="vios-adventerprisek9-m.vmdk" \ ovf:fileRef="vios-adventerprisek9-m.vmdk" ovf:format="http://www.vmware.com/\ interfaces/specifications/vmdk.html#streamOptimized" /> + <ovf:Disk ovf:capacity="512" ovf:capacityAllocationUnits="byte * 2^20" \ ovf:diskId="blank.vmdk" ovf:fileRef="blank.vmdk" \ ovf:format="http://www.vmware.com/interfaces/specifications/\ vmdk.html#streamOptimized" /> </ovf:DiskSection> ... </ovf:Item> + <ovf:Item> + <rasd:Address>1</rasd:Address> + <rasd:Description>IDE Controller 1</rasd:Description> + <rasd:ElementName>IDE Controller</rasd:ElementName> + <rasd:InstanceID>6</rasd:InstanceID> + <rasd:ResourceSubType>virtio</rasd:ResourceSubType> + <rasd:ResourceType>5</rasd:ResourceType> + </ovf:Item> + <ovf:Item> + <rasd:AddressOnParent>0</rasd:AddressOnParent> + <rasd:ElementName>Hard Disk Drive</rasd:ElementName> + <rasd:HostResource>ovf:/disk/blank.vmdk</rasd:HostResource> + <rasd:InstanceID>7</rasd:InstanceID> + <rasd:Parent>6</rasd:Parent> + <rasd:ResourceType>17</rasd:ResourceType> + </ovf:Item> + <ovf:Item> + <rasd:AddressOnParent>1</rasd:AddressOnParent> + <rasd:ElementName>CD-ROM Drive</rasd:ElementName> + <rasd:HostResource>ovf:/file/input.iso</rasd:HostResource> + <rasd:InstanceID>8</rasd:InstanceID> + <rasd:Parent>6</rasd:Parent> + <rasd:ResourceType>15</rasd:ResourceType> + </ovf:Item> <ovf:Item ovf:required="false"> """.format(blank_size=self.FILE_SIZE['blank.vmdk'], iso_size=self.FILE_SIZE['input.iso'])) # Create a qcow2 image new_qcow2 = os.path.join(self.temp_dir, "foozle.qcow2") # Keep it small! create_disk_image(new_qcow2, capacity="16M") # Try to add a fifth disk - IDE controllers are full! self.instance.package = self.temp_file self.instance.disk_image = new_qcow2 self.assertRaises(ValueTooHighError, self.instance.run) self.assertLogged(**self.TYPE_NOT_SPECIFIED_GUESS_HARDDISK) self.assertLogged(**self.CONTROLLER_NOT_SPECIFIED_GUESS_IDE)
def run(self): """Do the actual work of this submodule. :raises InvalidInputError: if :func:`ready_to_run` reports ``False`` """ super(COTInjectConfig, self).run() vm = self.vm platform = vm.platform # Find the disk drive where the config should be injected # First, look for any previously-injected config disk to overwrite: if platform.BOOTSTRAP_DISK_TYPE == 'cdrom': (f, d, ci, drive_device) = vm.search_from_filename('config.iso') elif platform.BOOTSTRAP_DISK_TYPE == 'harddisk': (f, d, ci, drive_device) = vm.search_from_filename('config.vmdk') else: raise ValueUnsupportedError("bootstrap disk type", platform.BOOTSTRAP_DISK_TYPE, "'cdrom' or 'harddisk'") if f is not None: file_id = vm.get_id_from_file(f) self.UI.confirm_or_die( "Existing configuration disk '{0}' found.\n" "Continue and overwrite it?".format(file_id)) logger.warning("Overwriting existing config disk '{0}'" .format(file_id)) else: file_id = None # Find the empty slot where we should inject the config drive_device = vm.find_empty_drive(platform.BOOTSTRAP_DISK_TYPE) if drive_device is None: raise LookupError("Could not find an empty {0} drive to " "inject the config into" .format(platform.BOOTSTRAP_DISK_TYPE)) (cont_type, drive_address) = vm.find_device_location(drive_device) # Copy config file(s) to per-platform name in working directory config_files = [] if self.config_file: dest = os.path.join(vm.working_dir, platform.CONFIG_TEXT_FILE) shutil.copy(self.config_file, dest) config_files.append(dest) if self.secondary_config_file: dest = os.path.join(vm.working_dir, platform.SECONDARY_CONFIG_TEXT_FILE) shutil.copy(self.secondary_config_file, dest) config_files.append(dest) # Package the config files into a disk image if platform.BOOTSTRAP_DISK_TYPE == 'cdrom': bootstrap_file = os.path.join(vm.working_dir, 'config.iso') create_disk_image(bootstrap_file, contents=config_files) elif platform.BOOTSTRAP_DISK_TYPE == 'harddisk': bootstrap_file = os.path.join(vm.working_dir, 'config.img') create_disk_image(bootstrap_file, file_format='raw', contents=config_files) else: raise ValueUnsupportedError("bootstrap disk type", platform.BOOTSTRAP_DISK_TYPE, "'cdrom' or 'harddisk'") # Inject the disk image into the OVA, using "add-disk" functionality add_disk_worker( UI=self.UI, vm=vm, DISK_IMAGE=bootstrap_file, type=platform.BOOTSTRAP_DISK_TYPE, file_id=file_id, controller=cont_type, address=drive_address, subtype=None, description='Configuration disk', diskname=None, )