Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package open-vmdk for openSUSE:Factory 
checked in at 2023-12-18 22:57:19
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/open-vmdk (Old)
 and      /work/SRC/openSUSE:Factory/.open-vmdk.new.9037 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "open-vmdk"

Mon Dec 18 22:57:19 2023 rev:2 rq:1133892 version:0.3.6.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/open-vmdk/open-vmdk.changes      2023-09-04 
22:55:01.026810765 +0200
+++ /work/SRC/openSUSE:Factory/.open-vmdk.new.9037/open-vmdk.changes    
2023-12-18 22:57:28.394974055 +0100
@@ -1,0 +2,27 @@
+Tue Nov 21 19:41:56 UTC 2023 - [email protected]
+
+- Update to version 0.3.6.0:
+  * -add a test for the manifest file
+  * add option to support sha256 checksum type
+  * add github workflow for pytest
+  * add basic tests with pytest
+  * do not fail if 'transports' or 'categories' are missing
+  * Update README.md for categories and extra_configs
+  * don't fail if no network is configured
+  * add 'no_default_configs' option to 'system'
+  * add categories, fixes issue #35
+  * add extra_configs
+  * Add doc for OVF properties to README.md
+  * fix for split failure when there is more than one equals sign in 'param'
+  * fix error when product section doesn't exist
+  * Add OVF template for hardware version 21
+  * Fix typo, from PR #29
+  * fix vmdisk ids
+  * add OVF properties
+
+-------------------------------------------------------------------
+Thu Nov 16 20:42:19 UTC 2023 - Guilherme Moro <[email protected]>
+
+- Patch: shebang.patch fix bash/sh shebang issue
+
+-------------------------------------------------------------------

Old:
----
  open-vmdk-0.3.1.0.obscpio

New:
----
  open-vmdk-0.3.6.0.obscpio
  open-vmdk-0.3.6.0.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ open-vmdk.spec ++++++
--- /var/tmp/diff_new_pack.OUKgGK/_old  2023-12-18 22:57:29.431011997 +0100
+++ /var/tmp/diff_new_pack.OUKgGK/_new  2023-12-18 22:57:29.435012144 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           open-vmdk
-Version:        0.3.1.0
+Version:        0.3.6.0
 Release:        0
 Summary:        Tools to create OVA files from raw disk images
 License:        Apache-2.0

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.OUKgGK/_old  2023-12-18 22:57:29.483013902 +0100
+++ /var/tmp/diff_new_pack.OUKgGK/_new  2023-12-18 22:57:29.487014048 +0100
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param name="url">https://github.com/vmware/open-vmdk</param>
-              <param 
name="changesrevision">5afbfb5270099586b93e28ae7585f3c661f379b5</param></service></servicedata>
+              <param 
name="changesrevision">ba658b05c4bf95631e9b7ae55ce5bc248192b798</param></service></servicedata>
 (No newline at EOF)
 

++++++ open-vmdk-0.3.1.0.obscpio -> open-vmdk-0.3.6.0.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/open-vmdk-0.3.1.0/.github/workflows/pytest.yaml 
new/open-vmdk-0.3.6.0/.github/workflows/pytest.yaml
--- old/open-vmdk-0.3.1.0/.github/workflows/pytest.yaml 1970-01-01 
01:00:00.000000000 +0100
+++ new/open-vmdk-0.3.6.0/.github/workflows/pytest.yaml 2023-11-14 
19:12:25.000000000 +0100
@@ -0,0 +1,32 @@
+name: open-vmdk pytests
+
+on: [pull_request, push, workflow_dispatch]
+
+jobs:
+    pytests:
+        runs-on: ubuntu-latest
+        steps:
+            - uses: actions/checkout@v4
+
+            - name: install build deps
+              run: sudo apt-get -y install zlib1g-dev
+
+            - name: build
+              working-directory: ${{ github.workspace }}
+              run: make
+
+            - name: install
+              working-directory: ${{ github.workspace }}
+              run: sudo make install
+
+            - name: set up python 3
+              uses: actions/setup-python@v4
+              with:
+                python-version: '3.x'
+
+            - name: install pytest
+              run: pip install pytest PyYAML lxml xmltodict
+
+            - name: run tests
+              working-directory: ${{ github.workspace }}
+              run: pytest pytest/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/open-vmdk-0.3.1.0/.gitignore 
new/open-vmdk-0.3.6.0/.gitignore
--- old/open-vmdk-0.3.1.0/.gitignore    2023-07-25 23:40:09.000000000 +0200
+++ new/open-vmdk-0.3.6.0/.gitignore    2023-11-14 19:12:25.000000000 +0100
@@ -1,2 +1,4 @@
 /build/
 ._*
+__pycache__/
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/open-vmdk-0.3.1.0/README.md 
new/open-vmdk-0.3.6.0/README.md
--- old/open-vmdk-0.3.1.0/README.md     2023-07-25 23:40:09.000000000 +0200
+++ new/open-vmdk-0.3.6.0/README.md     2023-11-14 19:12:25.000000000 +0100
@@ -12,7 +12,7 @@
 
 The OVF file that will be embedded can be generated using `ova-compose` from a 
simple yaml config file.
 
-`ova-compose` will can then create the final OVA from the OVF file, the vmdk 
images and a manifest (a file that contains checksums of the other files).
+`ova-compose` will then create the final OVA from the OVF file, the vmdk 
images and a manifest (a file that contains checksums of the other files).
 
 
 There is also the legacy tool `mkova.sh` that generates OVF files from 
templates.
@@ -160,6 +160,28 @@
         label: Venti
         description: too much
 
+environment:
+    transports:
+        - com.vmware.guestInfo
+        - iso
+    categories:
+        email: Email Settings
+    properties:
+        guestinfo.admin.email:
+            value: [email protected]
+            user_configurable: true
+            type: string
+            description: "The Admin's email address"
+            label: "Email Address"
+            category: email
+
+extra_configs:
+    feature.enabled:
+        required: false
+        value: true
+    log.rotateSize:
+        value: 2048000
+
 product:
     product: An Example VM
     vendor: A Company Inc.
@@ -205,6 +227,8 @@
         description: just right
 ```
 The default can also be set with `default_configuration` in the `system` 
section.
+* `environment` is for setting OVF properties. Variables are added under the 
new `environment` section as a `properties` map. The key is the name of the 
variable. Each variable has a mandatory `type`. `value`, `user_configurable` 
(default: `false`), `qualifiers`, `password` (default `false`),`label`, 
`description` are optional. Additionally, `transports` can be set in a list. 
Valid values are `iso` and `com.vmware.guestInfo`. Note that at least one of 
them must be set to make the properties visible inside the guest. Optionally, 
categories are set with `categories` to a map with an id as key and a 
description as value. Each property can have a `category` set to a category id.
+* `extra_configs` is a map of settings with the fields `value` and optionally 
the boolean `required`.
 * `annotation` has the fields `info`, `text` and `file`. `text` and `file` are 
mutually exclusive - `text` is text inline, `file` can be set to a text file 
that will be filled in. The annotation text will appear for example as a 
comment in VMware Fusion.
 * `eula` also has the fields `info`, `text` and `file`. It contains the EULA 
agreement the user has to agree to when deploying the VM.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/open-vmdk-0.3.1.0/ova-compose/ova-compose.py 
new/open-vmdk-0.3.6.0/ova-compose/ova-compose.py
--- old/open-vmdk-0.3.1.0/ova-compose/ova-compose.py    2023-07-25 
23:40:09.000000000 +0200
+++ new/open-vmdk-0.3.6.0/ova-compose/ova-compose.py    2023-11-14 
19:12:25.000000000 +0100
@@ -532,7 +532,7 @@
 
 
     def __init__(self, path):
-        self.id = f"vmdisk{OVFFile.next_id}"
+        self.id = f"vmdisk{OVFDisk.next_id}"
         OVFDisk.next_id += 1
         self.file = OVFFile(path)
 
@@ -558,7 +558,7 @@
 
 class OVFEmptyDisk(OVFDisk):
     def __init__(self, capacity, units="MB"):
-        self.id = f"vmdisk{OVFFile.next_id}"
+        self.id = f"vmdisk{OVFDisk.next_id}"
         OVFDisk.next_id += 1
         self.capacity = capacity
         if units == "KB":
@@ -585,6 +585,51 @@
     return ''.join(x.title() for x in snake_str.split('_'))
 
 
+class OVFProperty(object):
+
+    def __init__(self, key, type,
+                 password = False,
+                 value=None,
+                 user_configurable=False, qualifiers=None,
+                 label=None, description=None, category=None):
+        self.key = key
+        self.type = type
+        self.password = False
+        self.value = value
+        self.user_configurable = user_configurable
+        self.qualifiers = qualifiers
+        self.label = label
+        self.description = description
+        self.category = category
+
+
+    @classmethod
+    def from_dict(cls, key, type, d):
+        item = cls(key, type, **d)
+        return item
+
+
+    def xml_item(self):
+        xml_attrs = {
+            '{%s}key' % NS_OVF: self.key,
+            '{%s}type' % NS_OVF: self.type
+        }
+        if self.value is not None:
+            xml_attrs['{%s}value' % NS_OVF] = str(self.value)
+        if self.qualifiers is not None:
+            xml_attrs['{%s}qualifiers' % NS_OVF] = self.qualifiers
+        if self.user_configurable:
+            xml_attrs['{%s}userConfigurable' % NS_OVF] = "true"
+        if self.password:
+            xml_attrs['{%s}password' % NS_OVF] = "true"
+        xml_property = ET.Element('{%s}Property' % NS_OVF, xml_attrs)
+        if self.label is not None:
+            xml_property.append(xml_text_element('{%s}Label' % NS_OVF, 
self.label))
+        if self.description is not None:
+            xml_property.append(xml_text_element('{%s}Description' % NS_OVF, 
self.description))
+        return xml_property
+
+
 class OVFProduct(object):
     # snake case will be converted to camel case in XML
     keys = ['info', 'product', 'vendor', 'version', 'full_version']
@@ -593,6 +638,20 @@
         self.info = "Information about the installed software"
         self.__dict__.update((k, v) for k, v in kwargs.items() if k in 
self.keys)
 
+        self.properties = []
+        if 'properties' in kwargs:
+            props = kwargs['properties']
+            for k, v in props.items():
+                self.properties.append(OVFProperty(k, **v))
+
+        self.transports = kwargs.get('transports', [])
+        self.categories = kwargs.get('categories', {})
+
+        # if a property references a non-existing category it will be dropped
+        for prop in self.properties:
+            assert prop.category is None or prop.category in self.categories,\
+                f"property '{prop.key}' references unknown category 
'{prop.category}'"
+
 
     @classmethod
     def from_dict(cls, d):
@@ -607,6 +666,18 @@
             if hasattr(self, k) and getattr(self, k) is not None:
                 xml_name = to_camel_case(k)
                 xml_product.append(xml_text_element('{%s}%s' % (NS_OVF, 
xml_name), getattr(self, k)))
+
+        # append category-less properties first
+        for prop in self.properties:
+            if prop.category is None:
+                xml_product.append(prop.xml_item())
+        # then go through all categories, and append matching props
+        for cat_id, cat_name in self.categories.items():
+            xml_product.append(xml_text_element('{%s}Category' % NS_OVF, 
cat_name))
+            for prop in self.properties:
+                if prop.category == cat_id:
+                    xml_product.append(prop.xml_item())
+
         return xml_product
 
 
@@ -679,7 +750,7 @@
 
 
     @classmethod
-    def from_dict(cls, config):
+    def from_dict(cls, d):
         item = cls(**d)
         return item
 
@@ -694,6 +765,34 @@
         return elem
 
 
+class VmwExtraConfigItem(object):
+
+    def __init__(self, key, value, required=None):
+        self.key = key
+        self.value = value
+        self.required = required
+
+
+    @classmethod
+    def from_dict(cls, d):
+        item = cls(**d)
+        return item
+
+
+    def xml_item(self):
+        value = self.value
+        if type(value) is bool:
+            value = "true" if value else "false"
+        elif type(value) is not str:
+            value = str(value)
+
+        attrs = {'{%s}key' % NS_VMW: self.key, '{%s}value' % NS_VMW: value}
+        if self.required is not None:
+            attrs['{%s}required' % NS_VMW] = "true" if self.required else 
"false"
+        elem = ET.Element('{%s}ExtraConfig' % NS_VMW, attrs)
+        return elem
+
+
 class OVF(object):
 
     CONFIG_DEFAULTS = {
@@ -722,10 +821,13 @@
 
     def __init__(self,
                  system, files, disks,
-                 networks, vssd_system, rasd_items,
+                 networks,
+                 vssd_system, rasd_items, extra_configs,
                  product, annotation, eula,
                  configurations):
-        self.hardware_config = OVF.CONFIG_DEFAULTS.copy()
+        self.hardware_config = {}
+        if not system.get('no_default_configs', False):
+            self.hardware_config.update(OVF.CONFIG_DEFAULTS)
         self.name = system['name']
         self.os_cim = system.get('os_cim', 100)
         self.os_vmw = system.get('os_vmw', "other4xLinux64Guest")
@@ -742,6 +844,7 @@
         self.networks = networks
         self.vssd_system = vssd_system
         self.rasd_items = rasd_items
+        self.extra_configs = extra_configs
         self.product = product
         self.annotation = annotation
         self.eula = eula
@@ -764,6 +867,8 @@
         annotation = None
         eula = None
 
+        assert 'hardware' in config, "config needs a 'hardware' section"
+
         hardware = config['hardware']
         for hw_id, hw in hardware.items():
             if isinstance(hw, dict):
@@ -782,25 +887,41 @@
                     hw['disk'] = disk
 
         networks = {}
-        for nw_id, nw in config['networks'].items():
-            network = OVFNetwork.from_dict(nw)
-            networks[nw_id] = network
+        if 'networks' in config:
+            for nw_id, nw in config['networks'].items():
+                network = OVFNetwork.from_dict(nw)
+                networks[nw_id] = network
 
         vssd_system = VssdSystem.from_dict(config)
         rasd_items = cls.rasd_items_from_dict(config)
+        extra_configs = cls.vmw_extra_config_items_from_dict(config)
+
+        # we want properties in their own section ('environment')
+        # but in OVF they are part of the ProductSection, so copy it
+        if 'environment' in config:
+            env = config['environment']
+            if 'product' not in config:
+                config['product'] = {}
+            for cfg in ['transports', 'properties', 'categories']:
+                if cfg in env:
+                    config['product'][cfg] = env[cfg]
+
         if 'product' in config:
             product = OVFProduct.from_dict(config['product'])
+
         if 'annotation' in config:
             annotation = OVFAnnotation.from_dict(config['annotation'])
+
         if 'eula' in config:
             eula = OVFEula.from_dict(config['eula'])
+
         configurations = {}
         if 'configurations' in config:
             for k, v in config['configurations'].items():
                 configurations[k] = OVFConfiguration(k, **v)
 
         ovf = cls(config['system'], files, disks,
-                  networks, vssd_system, rasd_items,
+                  networks, vssd_system, rasd_items, extra_configs,
                   product, annotation, eula,
                   configurations)
 
@@ -830,6 +951,19 @@
         return rasd_items
 
 
+    @classmethod
+    def vmw_extra_config_items_from_dict(cls, config):
+        xtra_cfgs = []
+        xconfigs = config.get('extra_configs', None)
+        if xconfigs is None:
+            return []
+        for key, cfg in xconfigs.items():
+            cfg['key'] = key
+            xtra_cfg_item = VmwExtraConfigItem.from_dict(cfg)
+            xtra_cfgs.append(xtra_cfg_item)
+        return xtra_cfgs
+
+
     def connect(self):
         for hw_id, rasd_item in self.rasd_items.items():
             rasd_item.connect(self)
@@ -882,7 +1016,13 @@
         oss.append(xml_text_element('{%s}Info' % NS_OVF, "Operating System"))
         virtual_system.append(oss)
 
-        hw = ET.Element('{%s}VirtualHardwareSection' % NS_OVF)
+        if self.product and self.product.transports:
+            transports = " ".join(self.product.transports)
+            hw_attrs = {'{%s}transport' % NS_OVF: transports}
+        else:
+            hw_attrs = None
+        hw = ET.Element('{%s}VirtualHardwareSection' % NS_OVF, hw_attrs)
+
         hw.append(xml_text_element('{%s}Info' % NS_OVF, "Virtual Hardware"))
         virtual_system.append(hw)
 
@@ -893,6 +1033,9 @@
             xml_item[:] = sorted(xml_item, key=lambda child: child.tag)
             hw.append(xml_item)
 
+        for xcfg in self.extra_configs:
+            hw.append(xcfg.xml_item())
+
         for key, val in sorted(self.hardware_config.items()):
             hw.append(xml_config(key, val))
 
@@ -933,13 +1076,14 @@
 
 
     @staticmethod
-    def _get_sha512(filename):
+    def _get_hash(filename, hash_type):
+        hash = hashlib.new(hash_type)
         with open(filename, "rb") as f:
-            hash = hashlib.sha512(f.read()).hexdigest();
-        return hash
+            hash.update(f.read())
+        return hash.hexdigest()
 
 
-    def write_manifest(self, ovf_file=None, mf_file=None):
+    def write_manifest(self, ovf_file=None, mf_file=None, hash_type="sha512"):
         if ovf_file == None:
             ovf_file = f"{self.name}.ovf"
         if mf_file == None:
@@ -950,9 +1094,9 @@
             filenames.append(file.path)
         with open(mf_file, "wt") as f:
             for fname in filenames:
-                hash = OVF._get_sha512(fname)
+                hash = OVF._get_hash(fname, hash_type)
                 fname = os.path.basename(fname)
-                f.write(f"SHA512({fname})= {hash}\n")
+                f.write(f"{hash_type.upper()}({fname})= {hash}\n")
 
 
 def usage():
@@ -963,6 +1107,7 @@
     print("  -o, --output-file <file>    output file or directory name")
     print("  -f, --format ova|ovf|dir    output format")
     print("  -m, --manifest              create manifest file along with ovf 
(default true for output formats ova and dir)")
+    print("  --checksum-type sha256|sha512  set the checksum type for the 
manifest. Must be sha256 or sha512.")
     print("  -q                          quiet mode")
     print("  -h                          print help")
     print("")
@@ -985,7 +1130,7 @@
     assert type(key) is str, f"param name must be a string"
 
     if '=' in key:
-        key, default = [t.strip() for t in key.split('=')]
+        key, default = [t.strip() for t in key.split('=', maxsplit=1)]
         default = yaml.safe_load(default)
     value = params.get(key, default)
 
@@ -1002,9 +1147,10 @@
     do_quiet = False
     do_manifest = False
     params = {}
+    checksum_type = "sha512"
 
     try:
-        opts, args = getopt.getopt(sys.argv[1:], 'f:hi:mo:q', 
longopts=['format=', 'input-file=', 'manifest', 'output-file=', 'param='])
+        opts, args = getopt.getopt(sys.argv[1:], 'f:hi:mo:q', 
longopts=['format=', 'input-file=', 'manifest', 'output-file=', 'param=', 
'checksum-type='])
     except:
         print ("invalid option")
         sys.exit(2)
@@ -1018,8 +1164,10 @@
             output_format = a
         elif o in ['-m', '--manifest']:
             do_manifest = True
+        elif o in ['--checksum-type']:
+            checksum_type = a
         elif o in ['--param']:
-            k,v = a.split('=')
+            k,v = a.split('=', maxsplit=1)
             params[k] = yaml.safe_load(v)
         elif o in ['-q']:
             do_quiet = True
@@ -1032,6 +1180,8 @@
     assert config_file != None, "no input file specified"
     assert output_file != None, "no output file/directory specified"
 
+    assert checksum_type in ["sha512", "sha256"], f"checksum-type 
'{checksum_type}' is invalid"
+
     if config_file != None:
         f = open(config_file, 'r')
 
@@ -1069,7 +1219,7 @@
         ovf_file = output_file
         ovf.write_xml(ovf_file=ovf_file)
         if do_manifest:
-            ovf.write_manifest(ovf_file=ovf_file, mf_file=mf_file)
+            ovf.write_manifest(ovf_file=ovf_file, mf_file=mf_file, 
hash_type=checksum_type)
     elif output_format == "ova" or output_format == "dir":
         pwd = os.getcwd()
         tmpdir = tempfile.mkdtemp(prefix=f"{basename}-", dir=pwd)
@@ -1084,7 +1234,7 @@
                 os.symlink(os.path.join(pwd, file.path), dst)
                 all_files.append(dst)
 
-            ovf.write_manifest(ovf_file=ovf_file, mf_file=mf_file)
+            ovf.write_manifest(ovf_file=ovf_file, mf_file=mf_file, 
hash_type=checksum_type)
 
             if output_format == "ova":
                 ret = subprocess.check_call(["tar", "--format=ustar", "-h",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/open-vmdk-0.3.1.0/pytest/configs/basic.yaml 
new/open-vmdk-0.3.6.0/pytest/configs/basic.yaml
--- old/open-vmdk-0.3.1.0/pytest/configs/basic.yaml     1970-01-01 
01:00:00.000000000 +0100
+++ new/open-vmdk-0.3.6.0/pytest/configs/basic.yaml     2023-11-14 
19:12:25.000000000 +0100
@@ -0,0 +1,34 @@
+system:
+    name: minimal
+    type: vmx-14 vmx-20
+    os_vmw: vmw.vmwarePhoton64Guest
+
+networks:
+    vm_network:
+        name: "None"
+        description: "The None network"
+
+hardware:
+    cpus: 2
+    memory:
+        type: memory
+        size: 4096
+    sata1:
+        type: sata_controller
+    cdrom1:
+        type: cd_drive
+        parent: sata1
+    rootdisk:
+        type: hard_disk
+        parent: sata1
+        disk_image: dummy.vmdk
+    usb1:
+        type: usb_controller
+    ethernet1:
+        type: ethernet
+        subtype: VmxNet3
+        network: vm_network
+    videocard1:
+        type: video_card
+    vmci1:
+        type: vmci
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/open-vmdk-0.3.1.0/pytest/configs/basic_no_network.yaml 
new/open-vmdk-0.3.6.0/pytest/configs/basic_no_network.yaml
--- old/open-vmdk-0.3.1.0/pytest/configs/basic_no_network.yaml  1970-01-01 
01:00:00.000000000 +0100
+++ new/open-vmdk-0.3.6.0/pytest/configs/basic_no_network.yaml  2023-11-14 
19:12:25.000000000 +0100
@@ -0,0 +1,25 @@
+system:
+    name: minimal
+    type: vmx-14 vmx-20
+    os_vmw: vmwarePhoton64Guest
+
+hardware:
+    cpus: 2
+    memory:
+        type: memory
+        size: 4096
+    sata1:
+        type: sata_controller
+    cdrom1:
+        type: cd_drive
+        parent: sata1
+    rootdisk:
+        type: hard_disk
+        parent: sata1
+        disk_image: dummy.vmdk
+    usb1:
+        type: usb_controller
+    videocard1:
+        type: video_card
+    vmci1:
+        type: vmci
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/open-vmdk-0.3.1.0/pytest/configs/configuration.yaml 
new/open-vmdk-0.3.6.0/pytest/configs/configuration.yaml
--- old/open-vmdk-0.3.1.0/pytest/configs/configuration.yaml     1970-01-01 
01:00:00.000000000 +0100
+++ new/open-vmdk-0.3.6.0/pytest/configs/configuration.yaml     2023-11-14 
19:12:25.000000000 +0100
@@ -0,0 +1,70 @@
+system:
+    name: minimal
+    type: vmx-14 vmx-20
+    os_vmw: vmwarePhoton64Guest
+    default_configuration: grande
+
+networks:
+    vm_network:
+        name: "None"
+        description: "The None network"
+
+hardware:
+    cpus: 2
+    memory_tall:
+        type: memory
+        size: 2048
+        configuration: tall
+    memory_grande:
+        type: memory
+        size: 4096
+        configuration: grande
+    memory_venti:
+        type: memory
+        size: 8192
+        configuration: venti
+    sata1:
+        type: sata_controller
+    cdrom1:
+        type: cd_drive
+        parent: sata1
+    rootdisk:
+        type: hard_disk
+        parent: sata1
+        disk_image: dummy.vmdk
+    homedisk_tall:
+        type: hard_disk
+        parent: sata1
+        disk_capacity: 10000
+        configuration: tall
+    homedisk_grande:
+        type: hard_disk
+        parent: sata1
+        disk_capacity: 20000
+        configuration: grande
+    homedisk_venti:
+        type: hard_disk
+        parent: sata1
+        disk_capacity: 40000
+        configuration: venti
+    usb1:
+        type: usb_controller
+    ethernet1:
+        type: ethernet
+        subtype: VmxNet3
+        network: vm_network
+    videocard1:
+        type: video_card
+    vmci1:
+        type: vmci
+
+configurations:
+    tall:
+        label: Tall
+        description: too little for the money
+    grande:
+        label: Grande
+        description: just right
+    venti:
+        label: Venti
+        description: too much
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/open-vmdk-0.3.1.0/pytest/configs/environment.yaml 
new/open-vmdk-0.3.6.0/pytest/configs/environment.yaml
--- old/open-vmdk-0.3.1.0/pytest/configs/environment.yaml       1970-01-01 
01:00:00.000000000 +0100
+++ new/open-vmdk-0.3.6.0/pytest/configs/environment.yaml       2023-11-14 
19:12:25.000000000 +0100
@@ -0,0 +1,56 @@
+system:
+    name: minimal
+    type: vmx-14 vmx-20
+    os_vmw: vmwarePhoton64Guest
+
+networks:
+    vm_network:
+        name: "None"
+        description: "The None network"
+
+hardware:
+    cpus: 2
+    memory:
+        type: memory
+        size: 4096
+    sata1:
+        type: sata_controller
+    cdrom1:
+        type: cd_drive
+        parent: sata1
+    rootdisk:
+        type: hard_disk
+        parent: sata1
+        disk_image: dummy.vmdk
+    usb1:
+        type: usb_controller
+    ethernet1:
+        type: ethernet
+        subtype: VmxNet3
+        network: vm_network
+    videocard1:
+        type: video_card
+    vmci1:
+        type: vmci
+
+environment:
+    transports:
+        - iso
+        - com.vmware.guestInfo
+    categories:
+        some: Some Properties
+    properties:
+        prop.int:
+            user_configurable: true
+            type: uint16
+            value: '50000'
+            description: "an unsigned integer"
+            label: "integer"
+            category: some
+        prop.string:
+            user_configurable: true
+            type: string
+            value: 'a string'
+            description: "a string, yo"
+            label: "string"
+            category: some
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/open-vmdk-0.3.1.0/pytest/configs/extra_configs.yaml 
new/open-vmdk-0.3.6.0/pytest/configs/extra_configs.yaml
--- old/open-vmdk-0.3.1.0/pytest/configs/extra_configs.yaml     1970-01-01 
01:00:00.000000000 +0100
+++ new/open-vmdk-0.3.6.0/pytest/configs/extra_configs.yaml     2023-11-14 
19:12:25.000000000 +0100
@@ -0,0 +1,51 @@
+system:
+    name: minimal
+    type: vmx-14 vmx-20
+    os_vmw: vmwarePhoton64Guest
+
+networks:
+    vm_network:
+        name: "None"
+        description: "The None network"
+
+hardware:
+    cpus: 2
+    memory:
+        type: memory
+        size: 4096
+    sata1:
+        type: sata_controller
+    cdrom1:
+        type: cd_drive
+        parent: sata1
+    rootdisk:
+        type: hard_disk
+        parent: sata1
+        disk_image: dummy.vmdk
+    usb1:
+        type: usb_controller
+    ethernet1:
+        type: ethernet
+        subtype: VmxNet3
+        network: vm_network
+    videocard1:
+        type: video_card
+    vmci1:
+        type: vmci
+
+extra_configs:
+    type.boolean:
+        required: false
+        value: true
+    type.int:
+        value: 2048000
+    type.string:
+        value: "foo bar"
+    is_required:
+        value: 1
+        required: true
+    not_required:
+        value: 2
+        required: false
+    no_required:
+        value: 3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/open-vmdk-0.3.1.0/pytest/configs/product.yaml 
new/open-vmdk-0.3.6.0/pytest/configs/product.yaml
--- old/open-vmdk-0.3.1.0/pytest/configs/product.yaml   1970-01-01 
01:00:00.000000000 +0100
+++ new/open-vmdk-0.3.6.0/pytest/configs/product.yaml   2023-11-14 
19:12:25.000000000 +0100
@@ -0,0 +1,38 @@
+system:
+    name: minimal
+    type: vmx-14 vmx-20
+    os_vmw: vmwarePhoton64Guest
+
+networks:
+    vm_network:
+        name: "None"
+        description: "The None network"
+
+hardware:
+    cpus: 2
+    memory:
+        type: memory
+        size: 4096
+    sata1:
+        type: sata_controller
+    cdrom1:
+        type: cd_drive
+        parent: sata1
+    rootdisk:
+        type: hard_disk
+        parent: sata1
+        disk_image: dummy.vmdk
+    usb1:
+        type: usb_controller
+    ethernet1:
+        type: ethernet
+        subtype: VmxNet3
+        network: vm_network
+    videocard1:
+        type: video_card
+    vmci1:
+        type: vmci
+
+product:
+    product: An Example VM
+    vendor: A Company Inc.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/open-vmdk-0.3.1.0/pytest/test_configs.py 
new/open-vmdk-0.3.6.0/pytest/test_configs.py
--- old/open-vmdk-0.3.1.0/pytest/test_configs.py        1970-01-01 
01:00:00.000000000 +0100
+++ new/open-vmdk-0.3.6.0/pytest/test_configs.py        2023-11-14 
19:12:25.000000000 +0100
@@ -0,0 +1,76 @@
+# Copyright (c) 2023 VMware, Inc.  All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the “License”); you may 
not
+# use this file except in compliance with the License.  You may obtain a copy 
of
+# the License at:
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software 
distributed
+# under the License is distributed on an “AS IS” BASIS, without warranties 
or
+# conditions of any kind, EITHER EXPRESS OR IMPLIED.  See the License for the
+# specific language governing permissions and limitations under the License.
+
+import glob
+import os
+import pytest
+import shutil
+import subprocess
+import yaml
+import xmltodict
+
+
+THIS_DIR = os.path.dirname(os.path.abspath(__file__))
+OVA_COMPOSE = os.path.join(THIS_DIR, "..", "ova-compose", "ova-compose.py")
+
+VMDK_CONVERT=os.path.join(THIS_DIR, "..", "build", "vmdk", "vmdk-convert")
+
+CONFIG_DIR=os.path.join(THIS_DIR, "configs")
+
+WORK_DIR=os.path.join(os.getcwd(), "pytest-tmp")
+
+
[email protected](scope='module', autouse=True)
+def setup_test():
+    os.makedirs(WORK_DIR, exist_ok=True)
+
+    process = subprocess.run(["dd", "if=/dev/zero", "of=dummy.img", "bs=1024", 
"count=1024"], cwd=WORK_DIR)
+    assert process.returncode == 0
+
+    process = subprocess.run([VMDK_CONVERT, "dummy.img", "dummy.vmdk"], 
cwd=WORK_DIR)
+    assert process.returncode == 0
+
+    yield
+    shutil.rmtree(WORK_DIR)
+    
+
[email protected]("in_yaml", glob.glob(os.path.join(CONFIG_DIR, 
"*.yaml")))
+def test_configs(in_yaml):
+    basename = os.path.basename(in_yaml.rsplit(".", 1)[0])
+    out_ovf = os.path.join(WORK_DIR, f"{basename}.ovf")
+
+    process = subprocess.run([OVA_COMPOSE, "-i", in_yaml, "-o", out_ovf], 
cwd=WORK_DIR)
+    assert process.returncode == 0
+
+    with open(in_yaml) as f:
+        yaml_loader = yaml.SafeLoader
+        config = yaml.load(f, Loader=yaml_loader)
+
+    with open(out_ovf) as f:
+        ovf = xmltodict.parse(f.read())
+
+    cfg_system = config['system']
+    assert cfg_system['name'] == 
ovf['ovf:Envelope']['ovf:VirtualSystem']['ovf:Name']
+    assert cfg_system['os_vmw'] == 
ovf['ovf:Envelope']['ovf:VirtualSystem']['ovf:OperatingSystemSection']['@vmw:osType']
+    assert cfg_system['type'] == 
ovf['ovf:Envelope']['ovf:VirtualSystem']['ovf:VirtualHardwareSection']['ovf:System']['vssd:VirtualSystemType']
+
+    vmw_configs = 
ovf['ovf:Envelope']['ovf:VirtualSystem']['ovf:VirtualHardwareSection']['vmw:Config']
+
+    # TODO: check if default is set to bios unless no_default_configs is set
+    if 'firmware' in cfg_system:
+        firmware = None
+        if type(vmw_configs) == list:
+            for vmw_config in vmw_configs:
+                if vmw_config['@vmw:key'] == "firmware":
+                    firmware = vmw_config['@vmw:value']
+        assert cfg_system['firmware'] == firmware
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/open-vmdk-0.3.1.0/pytest/test_manifest.py 
new/open-vmdk-0.3.6.0/pytest/test_manifest.py
--- old/open-vmdk-0.3.1.0/pytest/test_manifest.py       1970-01-01 
01:00:00.000000000 +0100
+++ new/open-vmdk-0.3.6.0/pytest/test_manifest.py       2023-11-14 
19:12:25.000000000 +0100
@@ -0,0 +1,115 @@
+# Copyright (c) 2023 VMware, Inc.  All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the “License”); you may 
not
+# use this file except in compliance with the License.  You may obtain a copy 
of
+# the License at:
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software 
distributed
+# under the License is distributed on an “AS IS” BASIS, without warranties 
or
+# conditions of any kind, EITHER EXPRESS OR IMPLIED.  See the License for the
+# specific language governing permissions and limitations under the License.
+
+import glob
+import hashlib
+import os
+import pytest
+import shutil
+import subprocess
+import yaml
+import xmltodict
+
+
+THIS_DIR = os.path.dirname(os.path.abspath(__file__))
+OVA_COMPOSE = os.path.join(THIS_DIR, "..", "ova-compose", "ova-compose.py")
+
+VMDK_CONVERT=os.path.join(THIS_DIR, "..", "build", "vmdk", "vmdk-convert")
+
+CONFIG_DIR=os.path.join(THIS_DIR, "configs")
+
+WORK_DIR=os.path.join(os.getcwd(), "pytest-tmp")
+
+
[email protected](scope='module', autouse=True)
+def setup_test():
+    os.makedirs(WORK_DIR, exist_ok=True)
+
+    process = subprocess.run(["dd", "if=/dev/zero", "of=dummy.img", "bs=1024", 
"count=1024"], cwd=WORK_DIR)
+    assert process.returncode == 0
+
+    process = subprocess.run([VMDK_CONVERT, "dummy.img", "dummy.vmdk"], 
cwd=WORK_DIR)
+    assert process.returncode == 0
+
+    yield
+    shutil.rmtree(WORK_DIR)
+
+
+def check_mf(mf_path, hash_type, work_dir=WORK_DIR):
+    with open(mf_path, "rt") as f:
+        for line in f:
+            left, hash_mf = line.split("=")
+            hash_mf = hash_mf.strip()
+
+            assert left.startswith(hash_type.upper())
+
+            filename = left[len(hash_type):].strip("()")
+            hash = hashlib.new(hash_type)
+            with open(os.path.join(work_dir, filename), "rb") as f:
+                hash.update(f.read())
+
+            assert hash.hexdigest() == hash_mf
+
+
[email protected]("hash_type", [None, "sha256", "sha512"])
+def test_ovf_manifest(hash_type):
+    in_yaml = os.path.join(CONFIG_DIR, "basic.yaml")
+    basename = os.path.basename(in_yaml.rsplit(".", 1)[0])
+    out_ovf = os.path.join(WORK_DIR, f"{basename}.ovf")
+    out_mf = os.path.join(WORK_DIR, f"{basename}.mf")
+
+    args = [OVA_COMPOSE, "-i", in_yaml, "-o", out_ovf, "-m"]
+    if hash_type is not None:
+        args += ["--checksum-type", hash_type]
+    else:
+        hash_type = "sha512"
+
+    process = subprocess.run(args, cwd=WORK_DIR)
+    assert process.returncode == 0
+
+    assert os.path.isfile(out_mf)
+
+    check_mf(out_mf, hash_type)
+
+
[email protected]("hash_type", [None, "sha256", "sha512"])
+def test_ova_manifest(hash_type):
+    in_yaml = os.path.join(CONFIG_DIR, "basic.yaml")
+    basename = os.path.basename(in_yaml.rsplit(".", 1)[0])
+    out_ova = os.path.join(WORK_DIR, f"{basename}.ova")
+    out_mf = os.path.join(WORK_DIR, f"{basename}.mf")
+
+    args = [OVA_COMPOSE, "-i", in_yaml, "-o", out_ova]
+    if hash_type is not None:
+        args += ["--checksum-type", hash_type]
+    else:
+        hash_type = "sha512"
+
+    process = subprocess.run(args, cwd=WORK_DIR)
+    assert process.returncode == 0
+
+    subprocess.run(["tar", "xf", out_ova], cwd=WORK_DIR)
+
+    check_mf(out_mf, hash_type)
+
+
+def test_manifest_invalid_checksum_type():
+    in_yaml = os.path.join(CONFIG_DIR, "basic.yaml")
+    basename = os.path.basename(in_yaml.rsplit(".", 1)[0])
+    out_ovf = os.path.join(WORK_DIR, f"{basename}.ovf")
+    out_mf = os.path.join(WORK_DIR, f"{basename}.mf")
+
+    args = [OVA_COMPOSE, "-i", in_yaml, "-o", out_ovf, "-m", 
"--checksum-type", "foobar"]
+    process = subprocess.run(args, cwd=WORK_DIR)
+    assert process.returncode != 0
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/open-vmdk-0.3.1.0/templates/template-hw21.ovf 
new/open-vmdk-0.3.6.0/templates/template-hw21.ovf
--- old/open-vmdk-0.3.1.0/templates/template-hw21.ovf   1970-01-01 
01:00:00.000000000 +0100
+++ new/open-vmdk-0.3.6.0/templates/template-hw21.ovf   2023-11-14 
19:12:25.000000000 +0100
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   Copyright (c) 2023 VMware, Inc.  All Rights Reserved.
+
+   Licensed under the Apache License, Version 2.0 (the “License”); you may 
not
+   use this file except in compliance with the License.  You may obtain a copy 
of
+   the License at:
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software 
distributed
+   under the License is distributed on an “AS IS” BASIS, without 
warranties or
+   conditions of any kind, EITHER EXPRESS OR IMPLIED.  See the License for the
+   specific language governing permissions and limitations under the License.
+-->
+<Envelope 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";>
+  <References>
+    <File ovf:href="@@NAME@@-disk1.vmdk" ovf:id="file1" 
ovf:size="@@VMDK_FILE_SIZE@@"/>
+  </References>
+  <DiskSection>
+    <Info>Virtual disk information</Info>
+    <Disk ovf:capacity="@@VMDK_CAPACITY@@" ovf:capacityAllocationUnits="byte" 
ovf:diskId="vmdisk1" ovf:fileRef="file1" 
ovf:format="http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized"/>
+  </DiskSection>
+  <NetworkSection>
+    <Info>The list of logical networks</Info>
+    <Network ovf:name="VM Network">
+      <Description>The VM Network network</Description>
+    </Network>
+  </NetworkSection>
+  <VirtualSystem ovf:id="@@NAME@@">
+    <Info>A virtual machine</Info>
+    <Name>@@NAME@@</Name>
+    <OperatingSystemSection ovf:id="1" vmw:osType="other4xLinux64Guest">
+      <Info>The kind of installed guest operating system</Info>
+    </OperatingSystemSection>
+    <VirtualHardwareSection>
+      <Info>Virtual hardware requirements</Info>
+      <System>
+        <vssd:ElementName>Virtual Hardware Family</vssd:ElementName>
+        <vssd:InstanceID>0</vssd:InstanceID>
+        <vssd:VirtualSystemIdentifier>@@NAME@@</vssd:VirtualSystemIdentifier>
+        <vssd:VirtualSystemType>vmx-21</vssd:VirtualSystemType>
+      </System>
+      <Item>
+        <rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>
+        <rasd:Description>Number of Virtual CPUs</rasd:Description>
+        <rasd:ElementName>@@NUM_CPUS@@ virtual CPU(s)</rasd:ElementName>
+        <rasd:InstanceID>1</rasd:InstanceID>
+        <rasd:ResourceType>3</rasd:ResourceType>
+        <rasd:VirtualQuantity>@@NUM_CPUS@@</rasd:VirtualQuantity>
+      </Item>
+      <Item>
+        <rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits>
+        <rasd:Description>Memory Size</rasd:Description>
+        <rasd:ElementName>@@MEM_SIZE@@MB of memory</rasd:ElementName>
+        <rasd:InstanceID>2</rasd:InstanceID>
+        <rasd:ResourceType>4</rasd:ResourceType>
+        <rasd:VirtualQuantity>@@MEM_SIZE@@</rasd:VirtualQuantity>
+      </Item>
+      <Item>
+        <rasd:Address>0</rasd:Address>
+        <rasd:Description>SCSI Controller</rasd:Description>
+        <rasd:ElementName>SCSI controller 0</rasd:ElementName>
+        <rasd:InstanceID>3</rasd:InstanceID>
+        <rasd:ResourceSubType>VirtualSCSI</rasd:ResourceSubType>
+        <rasd:ResourceType>6</rasd:ResourceType>
+      </Item>
+      <Item>
+        <rasd:Address>1</rasd:Address>
+        <rasd:Description>IDE Controller</rasd:Description>
+        <rasd:ElementName>IDE 1</rasd:ElementName>
+        <rasd:InstanceID>4</rasd:InstanceID>
+        <rasd:ResourceType>5</rasd:ResourceType>
+      </Item>
+      <Item>
+        <rasd:Address>0</rasd:Address>
+        <rasd:Description>IDE Controller</rasd:Description>
+        <rasd:ElementName>IDE 0</rasd:ElementName>
+        <rasd:InstanceID>5</rasd:InstanceID>
+        <rasd:ResourceType>5</rasd:ResourceType>
+      </Item>
+      <Item ovf:required="false">
+        <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
+        <rasd:ElementName>Video card</rasd:ElementName>
+        <rasd:InstanceID>6</rasd:InstanceID>
+        <rasd:ResourceType>24</rasd:ResourceType>
+        <vmw:Config ovf:required="false" vmw:key="useAutoDetect" 
vmw:value="false"/>
+        <vmw:Config ovf:required="false" vmw:key="videoRamSizeInKB" 
vmw:value="4096"/>
+        <vmw:Config ovf:required="false" vmw:key="enable3DSupport" 
vmw:value="false"/>
+        <vmw:Config ovf:required="false" vmw:key="use3dRenderer" 
vmw:value="automatic"/>
+        <vmw:Config ovf:required="false" vmw:key="graphicsMemorySizeInKB" 
vmw:value="262144"/>
+      </Item>
+      <Item ovf:required="false">
+        <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
+        <rasd:ElementName>VMCI device</rasd:ElementName>
+        <rasd:InstanceID>7</rasd:InstanceID>
+        <rasd:ResourceSubType>vmware.vmci</rasd:ResourceSubType>
+        <rasd:ResourceType>1</rasd:ResourceType>
+        <vmw:Config ovf:required="false" 
vmw:key="allowUnrestrictedCommunication" vmw:value="false"/>
+      </Item>
+      <Item ovf:required="false">
+        <rasd:AddressOnParent>0</rasd:AddressOnParent>
+        <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
+        <rasd:ElementName>CD/DVD drive 1</rasd:ElementName>
+        <rasd:InstanceID>8</rasd:InstanceID>
+        <rasd:Parent>5</rasd:Parent>
+        
<rasd:ResourceSubType>vmware.cdrom.remotepassthrough</rasd:ResourceSubType>
+        <rasd:ResourceType>15</rasd:ResourceType>
+        <vmw:Config ovf:required="false" vmw:key="backing.exclusive" 
vmw:value="false"/>
+        <vmw:Config ovf:required="false" 
vmw:key="connectable.allowGuestControl" vmw:value="true"/>
+      </Item>
+      <Item>
+        <rasd:AddressOnParent>0</rasd:AddressOnParent>
+        <rasd:ElementName>Hard disk 1</rasd:ElementName>
+        <rasd:HostResource>ovf:/disk/vmdisk1</rasd:HostResource>
+        <rasd:InstanceID>9</rasd:InstanceID>
+        <rasd:Parent>3</rasd:Parent>
+        <rasd:ResourceType>17</rasd:ResourceType>
+        <vmw:Config ovf:required="false" vmw:key="backing.writeThrough" 
vmw:value="false"/>
+      </Item>
+      <Item>
+        <rasd:AddressOnParent>7</rasd:AddressOnParent>
+        <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>
+        <rasd:Connection>VM Network</rasd:Connection>
+        <rasd:Description>VmxNet3 ethernet adapter on "VM 
Network"</rasd:Description>
+        <rasd:ElementName>Network adapter 1</rasd:ElementName>
+        <rasd:InstanceID>10</rasd:InstanceID>
+        <rasd:ResourceSubType>VmxNet3</rasd:ResourceSubType>
+        <rasd:ResourceType>10</rasd:ResourceType>
+        <vmw:Config ovf:required="false" vmw:key="wakeOnLanEnabled" 
vmw:value="true"/>
+        <vmw:Config ovf:required="false" 
vmw:key="connectable.allowGuestControl" vmw:value="true"/>
+      </Item>
+      <vmw:Config ovf:required="false" vmw:key="cpuHotAddEnabled" 
vmw:value="false"/>
+      <vmw:Config ovf:required="false" vmw:key="cpuHotRemoveEnabled" 
vmw:value="false"/>
+      <vmw:Config ovf:required="false" vmw:key="memoryHotAddEnabled" 
vmw:value="false"/>
+      <vmw:Config ovf:required="false" vmw:key="firmware" 
vmw:value="@@FIRMWARE@@"/>
+      <vmw:Config ovf:required="false" vmw:key="tools.syncTimeWithHost" 
vmw:value="false"/>
+      <vmw:Config ovf:required="false" vmw:key="tools.afterPowerOn" 
vmw:value="true"/>
+      <vmw:Config ovf:required="false" vmw:key="tools.afterResume" 
vmw:value="true"/>
+      <vmw:Config ovf:required="false" vmw:key="tools.beforeGuestShutdown" 
vmw:value="true"/>
+      <vmw:Config ovf:required="false" vmw:key="tools.beforeGuestStandby" 
vmw:value="true"/>
+      <vmw:Config ovf:required="false" vmw:key="tools.toolsUpgradePolicy" 
vmw:value="manual"/>
+      <vmw:Config ovf:required="false" vmw:key="powerOpInfo.powerOffType" 
vmw:value="soft"/>
+      <vmw:Config ovf:required="false" vmw:key="powerOpInfo.resetType" 
vmw:value="soft"/>
+      <vmw:Config ovf:required="false" vmw:key="powerOpInfo.suspendType" 
vmw:value="hard"/>
+      <vmw:Config ovf:required="false" vmw:key="nestedHVEnabled" 
vmw:value="false"/>
+      <vmw:Config ovf:required="false" vmw:key="vPMCEnabled" 
vmw:value="false"/>
+      <vmw:Config ovf:required="false" vmw:key="virtualICH7MPresent" 
vmw:value="false"/>
+      <vmw:Config ovf:required="false" vmw:key="virtualSMCPresent" 
vmw:value="false"/>
+      <vmw:Config ovf:required="false" vmw:key="flags.vvtdEnabled" 
vmw:value="false"/>
+      <vmw:Config ovf:required="false" vmw:key="flags.vbsEnabled" 
vmw:value="false"/>
+      <vmw:Config ovf:required="false" 
vmw:key="bootOptions.efiSecureBootEnabled" vmw:value="false"/>
+      <vmw:Config ovf:required="false" vmw:key="powerOpInfo.standbyAction" 
vmw:value="checkpoint"/>
+    </VirtualHardwareSection>
+  </VirtualSystem>
+</Envelope>

++++++ open-vmdk.obsinfo ++++++
--- /var/tmp/diff_new_pack.OUKgGK/_old  2023-12-18 22:57:29.603018296 +0100
+++ /var/tmp/diff_new_pack.OUKgGK/_new  2023-12-18 22:57:29.603018296 +0100
@@ -1,5 +1,5 @@
 name: open-vmdk
-version: 0.3.1.0
-mtime: 1690321209
-commit: 5afbfb5270099586b93e28ae7585f3c661f379b5
+version: 0.3.6.0
+mtime: 1699985545
+commit: ba658b05c4bf95631e9b7ae55ce5bc248192b798
 

Reply via email to