Description of problem: oVirt is unable to export OVAs. Any time this is attempted, the task will fail, no output is produced. While tracking down this problem (which another user reported at http://lists.ovirt.org/pipermail/users/2018-March/087423.html), I found that the host logged an unhandled Python exception thrown by the `pack_ova.py` script (which is in the ovirt-engine repository at `packaging/playbooks/roles/ovirt-ova-pack/files/pack_ova.py`). Version-Release number of selected component (if applicable): 4.2.2.6-1.el7.centos How reproducible: occurs on every attempt to export OVA, no matter which VM or destination directory, on this host Steps to Reproduce: 1. Log in to oVirt web admin. 2. Navigate to a VM that is currently powered off. 3. From the three-dot dropdown, select "Export as OVA." 4. Type a destination directory (I've tried with NFS-mounted directories, local filesystem directories, and /tmp). 5. Click OK. 6. Wait as the ansible playbook is executed. Actual results: Web admin shows the failed task "Exporting VM *** as an OVA to /tmp/***-20180414.ova on Host storm". No OVA file exists at the destination path. Expected results: The export should complete and an OVA file should exist at the destination path. Additional info: /var/log/messages on host shows that the ovirt engine began to execute the ansible playbook, but the Python script throws an exception without more detail: Apr 14 15:58:12 storm systemd: Starting Session 659 of user root. Apr 14 15:58:13 storm python: ansible-stat Invoked with checksum_algorithm=sha1 get_checksum=True follow=False path=/tmp get_md5=True get_mime=True get_attributes=True Apr 14 15:58:15 storm python: ansible-file Invoked with directory_mode=None force=False remote_src=None path=/tmp/***-20180414.ova.tmp owner=None follow=False group=None unsafe_writes=None state=absent content=NOT_LOGGING_PARAMETER serole=None diff_peek=None setype=None selevel=None original_basename=None regexp=None validate=None src=None seuser=None recurse=False delimiter=None mode=None attributes=None backup=None Apr 14 15:58:15 storm python: ansible-file Invoked with directory_mode=None force=False remote_src=None path=/tmp/***-20180414.ova.tmp owner=None follow=False group=None unsafe_writes=None state=touch content=NOT_LOGGING_PARAMETER serole=None diff_peek=None setype=None selevel=None original_basename=None regexp=None validate=None src=None seuser=None recurse=False delimiter=None mode=None attributes=None backup=None Apr 14 15:58:16 storm python: detected unhandled Python exception in '/root/.ansible/tmp/ansible-tmp-1523735896.19-40291427300158/pack_ova.py' Apr 14 15:58:17 storm abrt-server: Executable '/root/.ansible/tmp/ansible-tmp-1523735896.19-40291427300158/pack_ova.py' doesn't belong to any package and ProcessUnpackaged is set to 'no' Apr 14 15:58:17 storm abrt-server: 'post-create' on '/var/tmp/abrt/Python-2018-04-14-15:58:16-546' exited with 1 Apr 14 15:58:17 storm abrt-server: Deleting problem directory '/var/tmp/abrt/Python-2018-04-14-15:58:16-546' Apr 14 15:58:18 storm python: ansible-file Invoked with directory_mode=None force=False remote_src=None path=/tmp/dev-hlr-20180414.ova.tmp owner=None follow=False group=None unsafe_writes=None state=absent content=NOT_LOGGING_PARAMETER serole=None diff_peek=None setype=None selevel=None original_basename=None regexp=None validate=None src=None seuser=None recurse=False delimiter=None mode=None attributes=None backup=None
Please provide engine.log and the relevant ovirt-export-ova-ansible-*.log (in engine.log you can find the specific log file that was created as part of the failed operation).
Created attachment 1422230 [details] Ansible log from OVA export attempt noted in bug report Hostname sanitized to ***.example.com
Created attachment 1422231 [details] Relevant section of engine.log
Just based on what I saw in uploading these logs, it seems like the Python script bugged out on a non-ASCII character in the OVF XML: ``` Traceback (most recent call last): File "/root/.ansible/tmp/ansible-tmp-1523735896.19-40291427300158/pack_ova.py", line 94, in <module> write_ovf(ova_path, ovf) File "/root/.ansible/tmp/ansible-tmp-1523735896.19-40291427300158/pack_ova.py", line 33, in write_ovf ovf = ovf.encode('utf-8') UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 3092: ordinal not in range(128) ``` As for why there would be any non-ASCII characters, it seems like oVirt is including the list of applications (as reported by the QEMU or oVirt guest agents in Windows) in the XML, and somewhere in that mess there are glyphs with diacritical marks that require UTF-8 handling, e.g. ``` <ProductSection ovf:class="2016"><Info>Herramientas de corrección de Microsoft Office 2016: español</Info><Product>2016</Product><Version></Version></ProductSection> ``` Note that the guest OS is using English (United States); these parts of the OVF result from having Microsoft Office installed. The oVirt engine and virtualization host both have $LANG=en_US.UTF-8 as is default for a North American installation of CentOS, and Python is the system default (python-2.7.5-58.el7.x86_64).
(In reply to Frederick Ding from comment #4) Right, nice analysis. I wonder whether we should store the application list in OVFs that reside within OVAs. Anyway, for now, you can just clear the application list and then export the VM: > update vm_dynamic set app_list=NULL where vm_guid='eb6353ef-7ce4-42c9-91e2-eed53a3e211b';
(In reply to Arik from comment #5) > (In reply to Frederick Ding from comment #4) > Right, nice analysis. > I wonder whether we should store the application list in OVFs that reside > within OVAs. > > Anyway, for now, you can just clear the application list and then export the > VM: > > update vm_dynamic set app_list=NULL where vm_guid='eb6353ef-7ce4-42c9-91e2-eed53a3e211b'; So the OVF specification declares that some elements could be localized, so apparently, that's a mistake to try to encode it with 'utf-8'...
It's my understanding that Python 2 treats strings just as bytes -- and pack_ova.py ingests the OVF as `ovf = sys.argv[2]`. So there may be no need to use `ovf = ovf.encode('utf-8')` at all?
(In reply to Frederick Ding from comment #7) > It's my understanding that Python 2 treats strings just as bytes -- and > pack_ova.py ingests the OVF as `ovf = sys.argv[2]`. So there may be no need > to use `ovf = ovf.encode('utf-8')` at all? The posted fix removes the UTF-8 encoding.
Verification builds: rhvm-4.2.3.2-0.1.el7 vdsm-4.20.26-1.el7ev.x86_64 libvirt-client-3.9.0-14.el7_5.2.x86_64 sanlock-3.6.0-1.el7.x86_64 qemu-kvm-rhev-2.10.0-21.el7_5.2.x86_64 virt-v2v-1.36.10-6.6.rhvpreview.el7ev.x86_64 Verification scenario: 1. Export VM as OVA which its name,description and comment is encoded to UTF-8 (Rename VM name to Hebrew and add comment and description in Hebrew). 2. Remove VM and Import OVA. 3. Verify import succeeds. Run VM and verify Vm is running properly. 4. Repeat steps 1-3, this time export VM as OVA to NFS storage and import OVA as clone.
This bugzilla is included in oVirt 4.2.3 release, published on May 4th 2018. Since the problem described in this bug report should be resolved in oVirt 4.2.3 release, it has been closed with a resolution of CURRENT RELEASE. If the solution does not work for you, please open a new bug report.