Bug 1567538 - Export to OVA fails because of exception in pack_ova.py on host
Summary: Export to OVA fails because of exception in pack_ova.py on host
Keywords:
Status: CLOSED CURRENTRELEASE
Alias: None
Product: ovirt-engine
Classification: oVirt
Component: Backup-Restore.VMs
Version: 4.2.2.6
Hardware: x86_64
OS: Linux
unspecified
high
Target Milestone: ovirt-4.2.3
: 4.2.3.2
Assignee: Arik
QA Contact: Nisim Simsolo
bugs@ovirt.org
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2018-04-14 20:04 UTC by Frederick Ding
Modified: 2018-05-10 06:27 UTC (History)
4 users (show)

Fixed In Version: ovirt-engine-4.2.3.2
Doc Type: Bug Fix
Doc Text:
Cause: The OVF configuration within OVA files exported from oVirt were UTF-8 encoded. Consequence: Virtual machines whose name, description, comment, or installed applications contain non-UTF-8 characters could not be exported to OVA. Fix: The OVF configuration within OVA files exported by oVirt is no longer UTF-8 encoded. Result: Virtual machines whose name, description, comment, or installed applications are localized can be exported to OVA.
Clone Of:
Environment:
Last Closed: 2018-05-10 06:27:02 UTC
oVirt Team: Virt
Embargoed:
rule-engine: ovirt-4.2+


Attachments (Terms of Use)
Ansible log from OVA export attempt noted in bug report (4.92 KB, text/plain)
2018-04-15 15:42 UTC, Frederick Ding
no flags Details
Relevant section of engine.log (77.38 KB, text/plain)
2018-04-15 15:51 UTC, Frederick Ding
no flags Details


Links
System ID Private Priority Status Summary Last Updated
oVirt gerrit 90290 0 master MERGED ansible: don't encode ovf in ova with utf-8 2020-11-12 11:44:18 UTC
oVirt gerrit 90368 0 ovirt-engine-4.2 MERGED ansible: don't encode ovf in ova with utf-8 2020-11-12 11:44:19 UTC

Description Frederick Ding 2018-04-14 20:04:57 UTC
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

Comment 1 Arik 2018-04-15 06:15:17 UTC
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).

Comment 2 Frederick Ding 2018-04-15 15:42:27 UTC
Created attachment 1422230 [details]
Ansible log from OVA export attempt noted in bug report

Hostname sanitized to ***.example.com

Comment 3 Frederick Ding 2018-04-15 15:51:04 UTC
Created attachment 1422231 [details]
Relevant section of engine.log

Comment 4 Frederick Ding 2018-04-15 15:59:17 UTC
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).

Comment 5 Arik 2018-04-15 16:04:34 UTC
(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';

Comment 6 Arik 2018-04-15 16:09:54 UTC
(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'...

Comment 7 Frederick Ding 2018-04-15 16:13:38 UTC
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?

Comment 8 Arik 2018-04-15 20:53:15 UTC
(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.

Comment 9 Nisim Simsolo 2018-04-26 13:32:41 UTC
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.

Comment 10 Sandro Bonazzola 2018-05-10 06:27:02 UTC
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.


Note You need to log in before you can comment on or make changes to this bug.