Exemple #1
0
    def test_set_property_no_modification(self):
        """Test various operations that should do nothing."""
        ovf = OVF(self.input_ovf, self.temp_file)
        # InstanceID 4, IDE controller
        item = ovf.hardware.item_dict['4']

        # set global value to empty for a property with no value
        self.assertFalse(item.modified)
        item.set_property(ovf.RESOURCE_SUB_TYPE, '')
        self.assertFalse(item.modified)

        # set per-profile value to empty for a property with no value
        item.set_property(ovf.RESOURCE_SUB_TYPE, '', ['2CPU-2GB-1NIC'])
        self.assertFalse(item.modified)

        # set global value to the same as existing global value
        item.set_property(ovf.ELEMENT_NAME, "VirtualIDEController 1")
        self.assertFalse(item.modified)

        # set per-profile value to the same as existing global value
        item.set_property(ovf.ELEMENT_NAME, "VirtualIDEController 1",
                          ['2CPU-2GB-1NIC'])
        self.assertFalse(item.modified)

        ovf.write()
        ovf.destroy()
        self.check_diff("")
Exemple #2
0
    def test_input_output_bad_file(self):
        """Test reading/writing of an OVF with incorrect file references."""
        self.staging_dir = tempfile.mkdtemp(prefix="cot_ut_ovfio_stage")
        input_dir = os.path.dirname(self.input_ovf)
        shutil.copy(os.path.join(input_dir, 'input.ovf'), self.staging_dir)
        shutil.copy(os.path.join(input_dir, 'input.iso'), self.staging_dir)
        shutil.copy(self.sample_cfg, self.staging_dir)
        # Copy blank.vmdk to input.vmdk so as to have the wrong size/checksum
        shutil.copy(self.blank_vmdk,
                    os.path.join(self.staging_dir, 'input.vmdk'))
        with OVF(os.path.join(self.staging_dir, 'input.ovf'),
                 os.path.join(self.temp_dir, "temp.ova")):
            # Write out to OVA (which will correct the file size information)
            pass
        self.assertLogged(msg="The size of file '%s' is expected"
                          " to be.*but is actually.*")
        self.assertLogged(msg="Capacity of disk.*seems to have changed.*"
                          "The updated OVF will reflect this change.")

        # Now read in the OVA
        with OVF(os.path.join(self.temp_dir, "temp.ova"),
                 os.path.join(self.temp_dir, "temp.ovf")):
            # Replace the tar file fake .vmdk with the real .vmdk
            with tarfile.open(os.path.join(self.temp_dir, "temp.ova"),
                              'a') as tarf:
                tarf.add(self.input_vmdk, 'input.vmdk')

        self.assertLogged(msg="Size of file '%s' has changed")
        self.assertLogged(msg="checksum of file '%s' has changed")
Exemple #3
0
    def test_invalid_ova_file(self):
        """Check that various invalid input OVA files result in VMInitError."""
        fake_file = os.path.join(self.temp_dir, "foo.ova")
        # .ova that is an empty file
        with open(fake_file, 'w') as fileobj:
            fileobj.write("")
        self.assertRaises(VMInitError, OVF, fake_file, None)

        # .ova that is not a TAR file
        with open(fake_file, 'w') as fileobj:
            fileobj.write("< hello world!")
        self.assertRaises(VMInitError, OVF, fake_file, None)

        # .ova that is an empty TAR file
        tarf = tarfile.open(fake_file, 'w')
        tarf.close()
        with self.assertRaises(VMInitError) as catcher:
            OVF(fake_file, None)
        self.assertEqual(catcher.exception.errno, 1)
        self.assertEqual(catcher.exception.strerror, "No files to untar")
        self.assertEqual(catcher.exception.filename, fake_file)

        # .ova that is a TAR file but does not contain an OVF descriptor
        tarf = tarfile.open(fake_file, 'w')
        try:
            tarf.add(self.blank_vmdk, os.path.basename(self.blank_vmdk))
        finally:
            tarf.close()
        self.assertRaises(VMInitError, OVF, fake_file, None)

        # .ova that contains an OVF descriptor but in the wrong position
        tarf = tarfile.open(fake_file, 'a')
        try:
            tarf.add(self.minimal_ovf, os.path.basename(self.minimal_ovf))
        finally:
            tarf.close()
        # this results in a logged error but not rejection - Postel's Law
        with OVF(fake_file, None):
            self.assertLogged(levelname="ERROR",
                              msg="OVF file %s found, but .*not.*first")

        # .ova with unsafe absolute path references
        tarf = tarfile.open(fake_file, 'w')
        try:
            # tarfile.add() is sometimes smart enough to protect us against
            # such unsafe references, but we can overrule it by using
            # gettarinfo() and addfile() instead of just add().
            tari = tarf.gettarinfo(self.minimal_ovf)
            tari.name = os.path.abspath(
                os.path.join(os.path.dirname(self.minimal_ovf), "..", "..",
                             "..", os.path.basename(self.minimal_ovf)))
            with open(self.minimal_ovf, 'rb') as fileobj:
                tarf.addfile(tari, fileobj)
        finally:
            tarf.close()
        self.assertRaises(VMInitError, OVF, fake_file, None)
Exemple #4
0
    def test_input_output(self):
        """Read an OVF then write it again, verify no changes."""
        with OVF(self.input_ovf, self.temp_file) as vm:
            self.assertEqual(vm.ovf_version, 1.0)
        self.check_diff('')

        # Filename output too
        with OVF(self.input_ovf, self.temp_file + '.a.b.c'):
            self.assertLogged(
                levelname='WARNING',
                msg="found '%s' in mid-filename; treating as such",
                args=('out.ovf.a.b.c', '.ovf'))
        self.check_diff('', file2=(self.temp_file + ".a.b.c"))
Exemple #5
0
    def test_configuration_profiles(self):
        """Check profile id list APIs."""
        # No profiles defined
        with OVF(self.vmware_ovf, None) as ovf:
            self.assertEqual(ovf.config_profiles, [])
            self.assertEqual(ovf.default_config_profile, None)

        # Profile list exists
        with OVF(self.input_ovf, None) as ovf:
            # default profile is first in the list
            self.assertEqual(
                ovf.config_profiles,
                ["4CPU-4GB-3NIC", "1CPU-1GB-1NIC", "2CPU-2GB-1NIC"])
            self.assertEqual(ovf.default_config_profile, "4CPU-4GB-3NIC")
Exemple #6
0
    def test_input_output_vmware(self):
        """Test reading/writing of an OVF with custom extensions."""
        with OVF(self.vmware_ovf, self.temp_file):
            pass
        # VMware disagrees with COT on some fiddly details of XML formatting
        self.check_diff(
            """
-<?xml version="1.0" encoding="UTF-8"?>
-<ovf:Envelope vmw:buildId="build-880146" \
xmlns="http://schemas.dmtf.org/ovf/envelope/1" \
xmlns:cim="http://schemas.dmtf.org/wbem/wscim/1/common" \
xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" \
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/\
CIM_ResourceAllocationSettingData" \
xmlns:vmw="http://www.vmware.com/schema/ovf" \
xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/\
CIM_VirtualSystemSettingData" \
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+<?xml version='1.0' encoding='utf-8'?>
+<ovf:Envelope xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" \
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/\
CIM_ResourceAllocationSettingData" \
xmlns:vmw="http://www.vmware.com/schema/ovf" \
xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/\
CIM_VirtualSystemSettingData" vmw:buildId="build-880146">
   <ovf:References>
...
   </ovf:VirtualSystem>
-</ovf:Envelope>        
+</ovf:Envelope>""",
            file1=self.vmware_ovf)  # noqa - trailing whitespace above
Exemple #7
0
 def test_basic_sanity(self):
     """Make sure basic loading is successful and APIs work."""
     with OVF(self.input_ovf, None) as ovf:
         hardware = ovf.hardware
         self.assertEqual(ovf, hardware.ovf)
         self.assertEqual(13, len(hardware.item_dict))
         self.assertEqual('14', hardware.find_unused_instance_id())
         self.assertEqual(2, len(hardware.find_all_items('ide')))
         self.assertEqual(
             1,
             len(
                 hardware.find_all_items('ide',
                                         properties={ovf.ADDRESS: '1'})))
         self.assertEqual(
             0,
             len(
                 hardware.find_all_items('ide',
                                         properties={ovf.ADDRESS: '2'})))
         self.assertNotEqual(None, hardware.find_item('harddisk'))
         self.assertEqual(None, hardware.find_item('usb'))
         self.assertRaises(LookupError, hardware.find_item, 'ide')
         self.assertEqual(1, hardware.get_item_count('ethernet', None))
         self.assertEqual(
             3, hardware.get_item_count('ethernet', "4CPU-4GB-3NIC"))
         self.assertEqual(
             3,
             hardware.get_item_count_per_profile('ethernet',
                                                 None)["4CPU-4GB-3NIC"])
Exemple #8
0
    def test_invalid_ovf_file(self):
        """Check that various invalid input OVF files result in VMInitError."""
        fake_file = os.path.join(self.temp_dir, "foo.ovf")
        # .ovf that is an empty file
        with open(fake_file, 'w') as fileobj:
            fileobj.write("")
        self.assertRaises(VMInitError, OVF, fake_file, None)

        # .ovf that isn't actually XML at all
        with open(fake_file, 'w') as fileobj:
            fileobj.write("< hello world!")
        self.assertRaises(VMInitError, OVF, fake_file, None)

        # .ovf that is XML but not OVF XML
        with open(fake_file, 'w') as fileobj:
            fileobj.write("<?xml version='1.0' encoding='utf-8'?>")
        self.assertRaises(VMInitError, OVF, fake_file, None)
        with open(fake_file, 'w') as fileobj:
            fileobj.write("<?xml version='1.0' encoding='utf-8'?>")
            fileobj.write("<foo/>")
        self.assertRaises(VMInitError, OVF, fake_file, None)

        # .ovf claiming to be OVF version 3.0, which doesn't exist yet
        with self.assertRaises(VMInitError) as catcher:
            OVF(self.ersatz_v3_ovf, None)
        self.assertEqual(catcher.exception.errno, 2)
        self.assertEqual(
            catcher.exception.strerror,
            "File has an Envelope but it is in unknown namespace "
            "'http://schemas.dmtf.org/ovf/envelope/3'")
        self.assertEqual(catcher.exception.filename, self.ersatz_v3_ovf)
Exemple #9
0
 def test_find_item_multiple_matches(self):
     """Check find_item raises LookupError if multiple matches are found."""
     with OVF(self.input_ovf, None) as ovf:
         self.assertRaisesRegex(LookupError,
                                r"multiple matching 'ide' Items",
                                ovf.hardware.find_item,
                                resource_type='ide')
Exemple #10
0
    def test_input_output_v20_vbox(self):
        """Test reading/writing of a v2.0 OVF from VirtualBox."""
        with OVF(self.v20_vbox_ovf, self.temp_file) as vm:
            self.assertEqual(vm.ovf_version, 2.0)

        # TODO - vbox XML is not very clean so the diffs are large...
        # self.check_diff('', file1=self.v20_vbox_ovf)

        # ovftool does not consider vbox ovfs to be valid
        self.validate_output_with_ovftool = False
Exemple #11
0
    def test_unknown_extension(self, mock_type):
        # pylint: disable=missing-type-doc,missing-param-doc
        """Test handling of unexpected behavior in detect_type_from_name."""
        # unsupported input file type
        with self.assertRaises(VMInitError) as catcher:
            OVF(self.input_ovf, None)
        self.assertEqual(catcher.exception.errno, 2)
        self.assertEqual(catcher.exception.strerror,
                         "File does not appear to be an OVA or OVF")
        self.assertEqual(catcher.exception.filename, self.input_ovf)

        # unsupported output file type
        mock_type.return_value = ".ovf"
        with self.assertRaises(NotImplementedError) as catcher, \
                OVF(self.input_ovf, None) as vm:
            mock_type.return_value = ".qcow2"
            vm.output_file = os.path.join(self.temp_dir, "foo.qcow2")

        self.assertEqual(catcher.exception.args[0],
                         "Not sure how to write a '.qcow2' file")
Exemple #12
0
 def test_filename_validation(self):
     """Test class method(s) for filename validation."""
     self.assertEqual('.ovf', OVF.detect_type_from_name("/foo/bar/foo.ovf"))
     self.assertEqual('.ova', OVF.detect_type_from_name("/foo/bar/foo.ova"))
     # Lazy filenames should be OK too
     self.assertEqual('.ovf',
                      OVF.detect_type_from_name("/foo/bar/foo.ovf.5.2.2"))
     self.assertLogged(levelname='WARNING',
                       msg="found '%s' in mid-filename; treating as such",
                       args=('foo.ovf.5.2.2', '.ovf'))
     self.assertEqual('.ova',
                      OVF.detect_type_from_name("/foo/bar/foo.ova.15.4.T"))
     self.assertLogged(levelname='WARNING',
                       msg="found '%s' in mid-filename; treating as such",
                       args=('foo.ova.15.4.T', '.ova'))
     # Unsupported formats
     self.assertRaises(ValueUnsupportedError, OVF.detect_type_from_name,
                       "/foo/bar.ovf/baz")
     self.assertRaises(ValueUnsupportedError, OVF.detect_type_from_name,
                       "/foo/bar.zip")
Exemple #13
0
    def test_input_output(self):
        """Read an OVF then write it again, verify no changes."""
        with OVF(self.input_ovf, self.temp_file) as vm:
            self.assertEqual(vm.ovf_version, 1.0)
        self.check_diff('')
        self.check_diff(file1=self.input_manifest,
                        file2=os.path.join(self.temp_dir, "out.mf"),
                        expected="""
-SHA1(input.ovf)= c3bd2579c2edc76ea35b5bde7d4f4e41eab08963
+SHA1(out.ovf)= c3bd2579c2edc76ea35b5bde7d4f4e41eab08963
 SHA1(input.vmdk)= 264caaa216ad928f82f727bb06d8e6e6fbd94df0
 """)

        # Filename output too
        with OVF(self.input_ovf, self.temp_file + '.a.b.c'):
            self.assertLogged(
                levelname='WARNING',
                msg="found '%s' in mid-filename; treating as such",
                args=('out.ovf.a.b.c', '.ovf'))
        self.check_diff('', file2=(self.temp_file + ".a.b.c"))
Exemple #14
0
    def test_set_property_no_modification(self):
        """Test various operations that should do nothing."""
        ovf = OVF(self.input_ovf, self.temp_file)
        # InstanceID 4, IDE controller
        item = ovf.hardware.item_dict['4']

        # set global value to empty for a property with no value
        self.assertFalse(item.modified)
        item.set_property(ovf.RESOURCE_SUB_TYPE, '')
        self.assertFalse(item.modified)

        # set per-profile value to empty for a property with no value
        item.set_property(ovf.RESOURCE_SUB_TYPE, '', ['2CPU-2GB-1NIC'])
        self.assertFalse(item.modified)

        # set global value to the same as existing global value
        item.set_property(ovf.ELEMENT_NAME, "VirtualIDEController 1")
        self.assertFalse(item.modified)

        # set per-profile value to the same as existing global value
        item.set_property(ovf.ELEMENT_NAME, "VirtualIDEController 1",
                          ['2CPU-2GB-1NIC'])
        self.assertFalse(item.modified)

        ovf.write()
        ovf.destroy()
        self.check_diff("")
Exemple #15
0
    def test_tar_links(self):
        """Check that OVA dereferences symlinks and hard links."""
        self.staging_dir = tempfile.mkdtemp(prefix="cot_ut_ovfio_stage")
        shutil.copy(self.input_ovf, self.staging_dir)
        # Hardlink self.input_vmdk to the staging dir
        os.link(self.input_vmdk, os.path.join(self.staging_dir, 'input.vmdk'))
        # Symlink self.input_iso to the staging dir
        os.symlink(self.input_iso, os.path.join(self.staging_dir, 'input.iso'))
        shutil.copy(self.sample_cfg, self.staging_dir)
        ovf = OVF(os.path.join(self.staging_dir, 'input.ovf'),
                  os.path.join(self.temp_dir, 'input.ova'))
        ovf.write()
        ovf.destroy()

        with tarfile.open(os.path.join(self.temp_dir, 'input.ova'),
                          'r') as tarf:
            try:
                vmdk = tarf.getmember('input.vmdk')
                self.assertTrue(vmdk.isfile(),
                                "hardlink was not added as a regular file")
                self.assertFalse(vmdk.islnk())
                iso = tarf.getmember('input.iso')
                self.assertTrue(iso.isfile(),
                                "symlink was not added as a regular file")
                self.assertFalse(iso.issym())
            except KeyError as exc:
                self.fail("KeyError: {0}\n Tarfile members = {1}".format(
                    exc, tarf.getnames()))
Exemple #16
0
    def test_input_output_relative_paths(self):
        """Make sure relative and implicit paths are handled."""
        os.chdir(os.path.dirname(self.input_ovf))
        with OVF(os.path.basename(self.input_ovf), self.temp_file) as vm:
            self.assertEqual(vm.ovf_version, 1.0)
        self.check_diff('')
        os.remove(self.temp_file)

        with OVF(os.path.join(".", os.path.basename(self.input_ovf)),
                 self.temp_file) as vm:
            self.assertEqual(vm.ovf_version, 1.0)
        self.check_diff('')
        os.remove(self.temp_file)

        os.chdir(os.path.dirname(self.temp_file))
        with OVF(self.input_ovf, os.path.basename(self.temp_file)) as vm:
            self.assertEqual(vm.ovf_version, 1.0)
        self.check_diff('')
        os.remove(self.temp_file)

        with OVF(self.input_ovf,
                 os.path.join(".", os.path.basename(self.temp_file))) as vm:
            self.assertEqual(vm.ovf_version, 1.0)
        self.check_diff('')
Exemple #17
0
    def test_remove_profile(self):
        """Test case for remove_profile() method."""
        with OVF(self.input_ovf, self.temp_file) as ovf:
            # InstanceID 11, NIC 0 (default, under all profiles)
            item = ovf.hardware.item_dict['11']
            self.assertTrue(item.has_profile(None))
            self.assertTrue(item.has_profile("1CPU-1GB-1NIC"))
            self.assertTrue(item.has_profile("2CPU-2GB-1NIC"))
            self.assertTrue(item.has_profile("4CPU-4GB-3NIC"))
            # nonexistent profile
            self.assertFalse(item.has_profile("nonexistent"))

            # Remove one profile
            item.remove_profile("1CPU-1GB-1NIC")
            self.assertTrue(item.has_profile("4CPU-4GB-3NIC"))
            self.assertTrue(item.has_profile("2CPU-2GB-1NIC"))
            # no longer available
            self.assertFalse(item.has_profile(None))
            self.assertFalse(item.has_profile("1CPU-1GB-1NIC"))
            self.assertFalse(item.has_profile("nonexistent"))

            self.assertEqual(
                item.get_value(ovf.ADDRESS_ON_PARENT,
                               ["2CPU-2GB-1NIC", "4CPU-4GB-3NIC"]), "11")
            self.assertEqual(
                item.get_value(ovf.ADDRESS_ON_PARENT, ["1CPU-1GB-1NIC"]), None)
            self.assertEqual(item.get_value(ovf.ADDRESS_ON_PARENT, [None]),
                             None)
            self.assertEqual(
                item.get_value(
                    ovf.ADDRESS_ON_PARENT,
                    ["1CPU-1GB-1NIC", "2CPU-2GB-1NIC", "4CPU-4GB-3NIC"]), None)

        self.check_diff("""
       </ovf:Item>
-      <ovf:Item>
+      <ovf:Item ovf:configuration="2CPU-2GB-1NIC 4CPU-4GB-3NIC">
         <rasd:AddressOnParent>11</rasd:AddressOnParent>
""")
Exemple #18
0
 def test_predicted_output_size(self):
     """Check output size prediction against reality."""
     self.validate_output_with_ovftool = False
     for input_file in [
             self.input_ovf,
             self.minimal_ovf,
             self.iosv_ovf,
             self.v09_ovf,
             self.v20_vbox_ovf,
             self.vmware_ovf,
     ]:
         with OVF(input_file, self.temp_file) as ovf:
             predicted = ovf.predicted_output_size()
         actual = os.stat(self.temp_file).st_size
         # Up to 10% greater than reality is OK,
         # but aim for never less than.
         self.assertGreaterEqual(
             predicted, actual,
             "predicted output size of {0} was {1} but actual size is {2}".
             format(input_file, predicted, actual))
         self.assertLessEqual(
             predicted, int(actual * 1.1),
             "predicted output size of {0} was {1} but actual size is {2}".
             format(input_file, predicted, actual))
Exemple #19
0
    def test_set_property(self):
        """Test cases for set_property() and related methods."""
        ovf = OVF(self.input_ovf, self.temp_file)
        # InstanceID 1, 'CPU' - entries for 'default' plus two other profiles
        item = ovf.hardware.item_dict['1']

        self.assertTrue(item.has_profile(None))
        self.assertTrue(item.has_profile("2CPU-2GB-1NIC"))
        self.assertTrue(item.has_profile("4CPU-4GB-3NIC"))
        # implied by default profile
        self.assertTrue(item.has_profile("1CPU-1GB-1NIC"))
        # nonexistent profile
        self.assertFalse(item.has_profile("nonexistent"))

        self.assertEqual(
            item.get_value(ovf.VIRTUAL_QUANTITY, ['1CPU-1GB-1NIC']), '1')
        self.assertEqual(
            item.get_value(ovf.VIRTUAL_QUANTITY, ['2CPU-2GB-1NIC']), '2')
        # value differs between profiles, so get_value returns None
        self.assertEqual(
            item.get_value(ovf.VIRTUAL_QUANTITY,
                           ['1CPU-1GB-1NIC', '2CPU-2GB-1NIC']), None)
        self.assertFalse(item.modified)

        # Set profile 1 to same as default (this is a no-op)
        item.set_property(ovf.VIRTUAL_QUANTITY, '1', ["1CPU-1GB-1NIC"])
        self.assertFalse(item.modified)
        ovf.write()
        self.check_diff("")

        # Change profile 1 to same as profile 2
        item.set_property(ovf.VIRTUAL_QUANTITY, '2', ["1CPU-1GB-1NIC"])
        self.assertEqual(
            item.get_value(ovf.VIRTUAL_QUANTITY,
                           ['1CPU-1GB-1NIC', '2CPU-2GB-1NIC']), '2')
        self.assertTrue(item.modified)
        ovf.write()
        self.check_diff("""
       </ovf:Item>
-      <ovf:Item ovf:configuration="2CPU-2GB-1NIC">
+      <ovf:Item ovf:configuration="1CPU-1GB-1NIC 2CPU-2GB-1NIC">
         <rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>
""")

        # Change profile 1 back under default
        item.set_property(ovf.VIRTUAL_QUANTITY, '1', ["1CPU-1GB-1NIC"])
        self.assertTrue(item.modified)
        ovf.write()
        self.check_diff("")

        # Change profile 2 to fall under default
        item.set_property(ovf.VIRTUAL_QUANTITY, '1', ["2CPU-2GB-1NIC"])
        self.assertTrue(item.modified)
        self.assertTrue(item.has_profile(None))
        self.assertTrue(item.has_profile("4CPU-4GB-3NIC"))
        # implied by default profile
        self.assertTrue(item.has_profile("1CPU-1GB-1NIC"))
        self.assertTrue(item.has_profile("2CPU-2GB-1NIC"))
        # nonexistent profile
        self.assertFalse(item.has_profile("nonexistent"))

        self.assertEqual(
            item.get_value(ovf.VIRTUAL_QUANTITY,
                           ['1CPU-1GB-1NIC', '2CPU-2GB-1NIC']), '1')
        self.assertEqual(item.get_value(ovf.VIRTUAL_QUANTITY, [None]), '1')
        self.assertEqual(
            item.get_value(ovf.VIRTUAL_QUANTITY,
                           [None, '1CPU-1GB-1NIC', '2CPU-2GB-1NIC']), '1')
        # disjoint sets
        self.assertEqual(
            item.get_value(
                ovf.VIRTUAL_QUANTITY,
                [None, '1CPU-1GB-1NIC', '2CPU-2GB-1NIC', '4CPU-4GB-3NIC']),
            None)

        ovf.write()
        self.check_diff("""
       </ovf:Item>
-      <ovf:Item ovf:configuration="2CPU-2GB-1NIC">
-        <rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>
-        <rasd:Description>Number of Virtual CPUs</rasd:Description>
-        <rasd:ElementName>2 virtual CPU(s)</rasd:ElementName>
-        <rasd:InstanceID>1</rasd:InstanceID>
-        <rasd:ResourceType>3</rasd:ResourceType>
-        <rasd:VirtualQuantity>2</rasd:VirtualQuantity>
-        <vmw:CoresPerSocket ovf:required="false">1</vmw:CoresPerSocket>
-      </ovf:Item>
       <ovf:Item ovf:configuration="4CPU-4GB-3NIC">
""")
        ovf.destroy()
Exemple #20
0
 def test_find_empty_drive_unsupported(self):
     """Negative test for find_empty_drive()."""
     with OVF(self.input_ovf, None) as ovf:
         self.assertRaises(ValueUnsupportedError, ovf.find_empty_drive,
                           'floppy')
Exemple #21
0
 def test_input_output_v09(self):
     """Test reading/writing of a v0.9 OVF."""
     with OVF(self.v09_ovf, self.temp_file) as vm:
         self.assertEqual(vm.ovf_version, 0.9)
     self.check_diff('', file1=self.v09_ovf)
Exemple #22
0
 def test_find_item_no_matches(self):
     """Test that find_item returns None if no matches are found."""
     with OVF(self.input_ovf, None) as ovf:
         self.assertEqual(None, ovf.hardware.find_item(resource_type='usb'))
Exemple #23
0
    def test_input_output_missing_file(self):
        """Test reading/writing of an OVF with missing file references."""
        # Read OVF, write OVF - make sure invalid file reference is removed
        self.staging_dir = tempfile.mkdtemp(prefix="cot_ut_ovfio_stage")
        shutil.copy(self.input_ovf, self.staging_dir)
        shutil.copy(self.input_vmdk, self.staging_dir)
        shutil.copy(self.sample_cfg, self.staging_dir)
        # Don't copy input.iso to the staging directory.
        with OVF(os.path.join(self.staging_dir, 'input.ovf'), self.temp_file):
            self.assertLogged(**self.NONEXISTENT_FILE)
        self.assertLogged(**self.REMOVING_FILE)
        self.check_diff("""
     <ovf:File ovf:href="input.vmdk" ovf:id="file1" ovf:size="{vmdk_size}" />
-    <ovf:File ovf:href="input.iso" ovf:id="file2" ovf:size="{iso_size}" />
     <ovf:File ovf:href="sample_cfg.txt" ovf:id="textfile" \
ovf:size="{cfg_size}" />
""".format(vmdk_size=self.FILE_SIZE['input.vmdk'],
           iso_size=self.FILE_SIZE['input.iso'],
           cfg_size=self.FILE_SIZE['sample_cfg.txt']))

        # Read-only OVF
        with OVF(os.path.join(self.staging_dir, 'input.ovf'), None):
            self.assertLogged(**self.NONEXISTENT_FILE)

        # File exists at read time but has disappeared by write time
        shutil.copy(self.input_iso, self.staging_dir)
        with OVF(os.path.join(self.staging_dir, 'input.ovf'), self.temp_file):
            os.remove(os.path.join(self.staging_dir, 'input.iso'))
        self.assertLogged(**self.FILE_DISAPPEARED)
        self.assertLogged(**self.REMOVING_FILE)
        self.check_diff("""
     <ovf:File ovf:href="input.vmdk" ovf:id="file1" ovf:size="{vmdk_size}" />
-    <ovf:File ovf:href="input.iso" ovf:id="file2" ovf:size="{iso_size}" />
     <ovf:File ovf:href="sample_cfg.txt" ovf:id="textfile" \
ovf:size="{cfg_size}" />
""".format(vmdk_size=self.FILE_SIZE['input.vmdk'],
           iso_size=self.FILE_SIZE['input.iso'],
           cfg_size=self.FILE_SIZE['sample_cfg.txt']))

        # Read OVA, write OVF
        with tarfile.open(os.path.join(self.staging_dir, 'input.ova'),
                          'w') as tarf:
            tarf.add(os.path.join(self.staging_dir, 'input.ovf'), 'input.ovf')
            tarf.add(os.path.join(self.staging_dir, 'input.vmdk'),
                     'input.vmdk')
            tarf.add(self.sample_cfg, 'sample_cfg.txt')
        with OVF(os.path.join(self.staging_dir, 'input.ova'),
                 os.path.join(self.temp_dir, 'output.ovf')):
            self.assertLogged(**self.NONEXISTENT_FILE)
        self.assertLogged(**self.REMOVING_FILE)
        self.check_diff(file2=os.path.join(self.temp_dir, 'output.ovf'),
                        expected="""
     <ovf:File ovf:href="input.vmdk" ovf:id="file1" ovf:size="{vmdk_size}" />
-    <ovf:File ovf:href="input.iso" ovf:id="file2" ovf:size="{iso_size}" />
     <ovf:File ovf:href="sample_cfg.txt" ovf:id="textfile" \
ovf:size="{cfg_size}" />
""".format(vmdk_size=self.FILE_SIZE['input.vmdk'],
           iso_size=self.FILE_SIZE['input.iso'],
           cfg_size=self.FILE_SIZE['sample_cfg.txt']))

        # Also test read-only OVA logic:
        with OVF(os.path.join(self.staging_dir, "input.ova"), None):
            self.assertLogged(**self.NONEXISTENT_FILE)
Exemple #24
0
    def test_set_property(self):
        """Test cases for set_property() and related methods."""
        ovf = OVF(self.input_ovf, self.temp_file)
        # InstanceID 1, 'CPU' - entries for 'default' plus two other profiles
        item = ovf.hardware.item_dict['1']

        self.assertTrue(item.has_profile(None))
        self.assertTrue(item.has_profile("2CPU-2GB-1NIC"))
        self.assertTrue(item.has_profile("4CPU-4GB-3NIC"))
        # implied by default profile
        self.assertTrue(item.has_profile("1CPU-1GB-1NIC"))
        # nonexistent profile
        self.assertFalse(item.has_profile("nonexistent"))

        self.assertEqual(item.get_value(ovf.VIRTUAL_QUANTITY,
                                        ['1CPU-1GB-1NIC']),
                         '1')
        self.assertEqual(item.get_value(ovf.VIRTUAL_QUANTITY,
                                        ['2CPU-2GB-1NIC']),
                         '2')
        # value differs between profiles, so get_value returns None
        self.assertEqual(item.get_value(ovf.VIRTUAL_QUANTITY,
                                        ['1CPU-1GB-1NIC', '2CPU-2GB-1NIC']),
                         None)
        self.assertFalse(item.modified)

        # Set profile 1 to same as default (this is a no-op)
        item.set_property(ovf.VIRTUAL_QUANTITY, '1', ["1CPU-1GB-1NIC"])
        self.assertFalse(item.modified)
        ovf.write()
        self.check_diff("")

        # Change profile 1 to same as profile 2
        item.set_property(ovf.VIRTUAL_QUANTITY, '2', ["1CPU-1GB-1NIC"])
        self.assertEqual(item.get_value(ovf.VIRTUAL_QUANTITY,
                                        ['1CPU-1GB-1NIC', '2CPU-2GB-1NIC']),
                         '2')
        self.assertTrue(item.modified)
        ovf.write()
        self.check_diff("""
       </ovf:Item>
-      <ovf:Item ovf:configuration="2CPU-2GB-1NIC">
+      <ovf:Item ovf:configuration="1CPU-1GB-1NIC 2CPU-2GB-1NIC">
         <rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>
""")

        # Change profile 1 back under default
        item.set_property(ovf.VIRTUAL_QUANTITY, '1', ["1CPU-1GB-1NIC"])
        self.assertTrue(item.modified)
        ovf.write()
        self.check_diff("")

        # Change profile 2 to fall under default
        item.set_property(ovf.VIRTUAL_QUANTITY, '1', ["2CPU-2GB-1NIC"])
        self.assertTrue(item.modified)
        self.assertTrue(item.has_profile(None))
        self.assertTrue(item.has_profile("4CPU-4GB-3NIC"))
        # implied by default profile
        self.assertTrue(item.has_profile("1CPU-1GB-1NIC"))
        self.assertTrue(item.has_profile("2CPU-2GB-1NIC"))
        # nonexistent profile
        self.assertFalse(item.has_profile("nonexistent"))

        self.assertEqual(item.get_value(ovf.VIRTUAL_QUANTITY,
                                        ['1CPU-1GB-1NIC',
                                         '2CPU-2GB-1NIC']),
                         '1')
        self.assertEqual(item.get_value(ovf.VIRTUAL_QUANTITY, [None]),
                         '1')
        self.assertEqual(item.get_value(ovf.VIRTUAL_QUANTITY,
                                        [None, '1CPU-1GB-1NIC',
                                         '2CPU-2GB-1NIC']),
                         '1')
        # disjoint sets
        self.assertEqual(item.get_value(ovf.VIRTUAL_QUANTITY,
                                        [None, '1CPU-1GB-1NIC',
                                         '2CPU-2GB-1NIC', '4CPU-4GB-3NIC']),
                         None)

        ovf.write()
        self.check_diff("""
       </ovf:Item>
-      <ovf:Item ovf:configuration="2CPU-2GB-1NIC">
-        <rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>
-        <rasd:Description>Number of Virtual CPUs</rasd:Description>
-        <rasd:ElementName>2 virtual CPU(s)</rasd:ElementName>
-        <rasd:InstanceID>1</rasd:InstanceID>
-        <rasd:ResourceType>3</rasd:ResourceType>
-        <rasd:VirtualQuantity>2</rasd:VirtualQuantity>
-        <vmw:CoresPerSocket ovf:required="false">1</vmw:CoresPerSocket>
-      </ovf:Item>
       <ovf:Item ovf:configuration="4CPU-4GB-3NIC">
""")
        ovf.destroy()
Exemple #25
0
    def test_tar_untar(self):
        """Output OVF to OVA and vice versa."""
        # Read OVF and write to OVA
        ovf = OVF(self.input_ovf, os.path.join(self.temp_dir, "temp.ova"))
        ovf.write()
        ovf.destroy()

        # Read OVA and overwrite itself
        # Issue #66 resulted from the two strings not being identical
        # So mix relative and absolute paths:
        os.chdir(self.temp_dir)
        ova = OVF("temp.ova", os.path.join(self.temp_dir, "temp.ova"))
        ova.write()
        ova.destroy()

        # Another permutation of issue #66 - output file is a
        # symlink to input file
        os.symlink("temp.ova", "symlink.ova")
        ova = OVF("temp.ova", "symlink.ova")
        ova.write()
        ova.destroy()

        # A third permutation - output file is hardlink to input
        os.link("temp.ova", "hardlink.ova")
        ova = OVF("temp.ova", "hardlink.ova")
        ova.write()
        ova.destroy()

        # Read OVA and write to OVF
        ovf2 = OVF(os.path.join(self.temp_dir, "temp.ova"),
                   os.path.join(self.temp_dir, "input.ovf"))
        ovf2.write()
        ovf2.destroy()

        # Make sure everything propagated over successfully
        input_dir = os.path.dirname(self.input_ovf)
        for ext in ['.ovf', '.mf', '.iso', '.vmdk']:
            if ext == '.mf' or ext == '.ovf':
                self.check_diff("", os.path.join(input_dir, "input" + ext),
                                os.path.join(self.temp_dir, "input" + ext))
            else:
                self.assertTrue(
                    filecmp.cmp(os.path.join(input_dir, "input" + ext),
                                os.path.join(self.temp_dir, "input" + ext)),
                    "{0} file changed after OVF->OVA->OVF conversion".format(
                        ext))