119 Commits

Author SHA1 Message Date
fa18f8ac16 output: -o kubevirt: Fix firmware section to match specification
The previous firmware section in Kubevirt YAML didn't match the
current specification.  Unclear if it matched a previous spec or if we
just guessed at the format.

After this change, for BIOS:

..
spec:
  template:
    spec:
      domain:
        firmware:
          bootloader:
            bios: {}
..

For UEFI:

..
spec:
  template:
    spec:
      domain:
        firmware:
          bootloader:
            efi:
              persistent: true
..

Link: https://kubevirt.io/api-reference/v1.3.1/definitions.html#_v1_firmware
Reported-by: Martin Necas
Fixes: https://issues.redhat.com/browse/RHEL-58065
2024-09-10 10:25:18 +01:00
89ec5f9079 output/create_kubevirt_yaml.ml: Replace List [] with Assoc []
Previously several empty Kubevirt YAML nodes were represented as empty
lists (List []).  Our YAML generator incorrectly generated "{}" for
this, but this is the YAML for empty dictionary, not list.  However as
a consequence of two bugs cancelling out, this actually generated the
expected YAML.

Since we're going to fix the bug in our YAML generator, replace
List [] with Assoc [] so the output will remain the same.
2024-09-10 10:25:18 +01:00
321c980348 output: -o kubevirt: Update comments with reference to latest spec
I looked through the latest specification
(https://kubevirt.io/api-reference/v1.3.1/definitions.html#_v1_acpi)
and updated comments as appropriate.  No actual change to the output.
2024-09-09 16:04:13 +01:00
2e78fb4d10 output/create_libvirt_xml.ml: Hard-code libosinfo URL for W2K22
Also add a comment that we ought to get this from the libosinfo
information provided by libguestfs.  I'm not sure why we aren't doing
that already.
2024-08-29 15:09:10 +01:00
7a82e130c2 lib: Only get nbdkit config and version once
The configuration (--dump-config) and version of nbdkit won't change
while we are running, so we only need to get it once.  We also don't
need the config parameter to Nbdkit.version so drop that.
2024-07-30 15:57:57 +01:00
2b00025238 -o kubevirt: Create a VirtualMachine instead of a VirtualMachineInstance
VMs converted by virt-v2v are pets not cattle so we want to create
permanent non-running machines.  (They may later or even soon
afterwards be started up by some other tool, at which point they also
become Instances.)  Therefore use a different kind and slightly
restructure the yaml around this.

Thanks: Lee Yarwood
2024-07-11 12:14:21 +01:00
e0d79e9a2e -o kubevirt: Add metadata labels
Add various information which we have but cannot add to the Kubevirt
yaml in any other place.

Example output:

...
metadata:
  name: fedora-39
  labels:
    libguestfs.org/virt-v2v-version: "2.5.4"
    libguestfs.org/osinfo: fedora39
...

Thanks: Bella Khizgiyaev, Liran Rotenberg
Fixes: https://issues.redhat.com/browse/RHEL-45992
2024-07-11 12:14:21 +01:00
089d9a235e -o rhv-upload: Add O_TRUNC to truncate JSON file if it exists
Fixes: https://github.com/libguestfs/virt-v2v/issues/46
Thanks: Nir Soffer
2024-04-06 17:57:42 +01:00
5672d89531 -o rhv-upload: Don't share transfer.json (#49)
Use unique v2vtransferN.json for every transfer, like like
out.paramsN.json. If we keep the temporary files after the import, the
content of the file can help debugging.

Related to #46
2024-04-06 15:15:45 +01:00
ff341481eb -o rhv-upload: Improve host id logging
This log[1] is proved confusing for developers:

    cannot read /etc/vdsm/vdsm.id, using any host: [Errno 2] No such file or directory: '/etc/vdsm/vdsm.id'

This is actually a debug message, that can help RHV developers to
understand where virt-v2v was running. To make this more clear, in the
expected case when running on non-oVirt host, we log now:

    not an oVirt host, using non-oVirt host

For any other error, we can degrade to remote transfer, but we want to
warn the user about this, so we log:

    warning: cannot read host id, using non-oVirt host: [Errno 2] No such file or directory: '/etc/vdsm/vdsm.id'

[1] https://github.com/libguestfs/virt-v2v/issues/46#issuecomment-2039604719

RWMJ: Changed "any host" to "non-oVirt host" to make it clearer.
2024-04-06 07:38:25 +01:00
0ea92cc029 -o rhv-upload: Output outside of the with block
We write the json inside a with block, so what actually happen is:

1. Computing the values
2. Dumping the json to stdout
3. Closing the connection

If some code in sdk.Connection.close() write something to stdout, it
will corrupt our json output. Avoid this by moving the output out of the
with block.

This will not prevent bad code to write something before the json. We
need to log bad json in the Ocaml code to reveal such issue.
2024-04-06 07:34:31 +01:00
19ac262ceb -o rhv-upload: Dump the JSON before parsing
Related: https://github.com/libguestfs/virt-v2v/issues/46
2024-04-05 22:13:40 +01:00
d8f09872a6 -o rhv-upload: clarify debug message
Thanks: Nir Soffer
Related: https://github.com/libguestfs/virt-v2v/issues/46
2024-04-05 21:53:24 +01:00
cfeebf0f12 -o rhv-upload: Add context if parsing params fails (#47)
If parsing params fail we get unhelpful error:

    virt-v2v: error: internal error: invalid argument:
    /tmp/v2v.CtVpBL/v2vtransfer.json: JSON parse error: end of file expected
    near 'e'

Change the parsing code to read the entire json text and include it in
the error message. This will make it clear why the json could not be
parsed, and help to find the root cause for having invalid json.

Example error:

    $ cat out.params0.json
    This is not a json document

    $ python output/rhv-upload-transfer.py out.params0.json
    Traceback (most recent call last):
      File "/home/nsoffer/src/virt-v2v/output/rhv-upload-transfer.py", line 261, in <module>
        raise RuntimeError(f"Cannot parse params {data!r}: {e}").with_traceback(
      File "/home/nsoffer/src/virt-v2v/output/rhv-upload-transfer.py", line 259, in <module>
        params = json.loads(data)
                 ^^^^^^^^^^^^^^^^
      File "/usr/lib64/python3.12/json/__init__.py", line 346, in loads
        return _default_decoder.decode(s)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/lib64/python3.12/json/decoder.py", line 337, in decode
        obj, end = self.raw_decode(s, idx=_w(s, 0).end())
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/lib64/python3.12/json/decoder.py", line 355, in raw_decode
        raise JSONDecodeError("Expecting value", s, err.value) from None
    RuntimeError: Cannot parse params 'This is not a json document\n': Expecting value: line 1 column 1 (char 0)

Related to #46
2024-04-05 20:56:40 +01:00
86c43f70ac -o kubevirt: Update comment about displays
I believe we don't need to explicitly enable a display, as Kubevirt
will enable one by default.  Add these findings as a comment.

Thanks: Arik Hadas
2024-03-11 16:40:57 +00:00
54ca2da251 -o kubevirt: Add support for sound device
Thanks: Arik Hadas
2024-03-11 16:37:08 +00:00
53c9177a78 -o kubevirt: Use virtio-transitional for ancient guests 2024-03-11 16:04:29 +00:00
353a9348ea -o kubevirt: Add an RNG device if virtio-rng driver in the guest 2024-03-11 15:49:56 +00:00
eee069f8da -o kubevirt: Add network interfaces to output 2024-03-11 15:49:12 +00:00
81e0c33c84 -o kubevirt: Add CPU model & topology when available
See: https://kubevirt.io/user-guide/virtual_machines/templates/
See: https://kubevirt.io/api-reference/v1.2.0/definitions.html#_v1_cpu
2024-03-11 15:49:09 +00:00
43ca22168b -o qemu: Remove final use of error_unless_uefi_firmware
This function was used by -o libvirt / -o local to check that we have
UEFI firmware for the target architecture.  All it does is called
find_uefi_firmware early so that we fail early.

The same check was copied into -o qemu, probably wrongly as we call
find_uefi_firmware just below, so the early fail is not necessary.

This allows us to remove error_unless_uefi_firmware completely since
it is no longer used anywhere.
2024-03-11 12:05:46 +00:00
095bf10035 -o libvirt: Use <os firmware='efi'> finally
Libvirt has long supported <os firmware='efi'>, so use that in
preference to hard coding UEFI paths in the libvirt output.

See: https://libvirt.org/formatdomain.html#bios-bootloader
Fixes: https://github.com/libguestfs/virt-v2v/issues/45
2024-03-11 12:01:25 +00:00
4f16fec063 -o kubevirt: Add os firmware field in output
Fixes: https://github.com/libguestfs/virt-v2v/issues/45
Fixes: https://issues.redhat.com/browse/RHEL-28197
2024-03-11 11:32:11 +00:00
c5ec2b1ee4 -o rhv-upload: fix rhv-upload function to work with keycloak instead of basic auth only (#43)
Fixes: https://github.com/libguestfs/virt-v2v/issues/42
2024-02-26 12:18:56 +00:00
bfb8ca212e convert_linux: add CircleLinux to supported distros 2024-01-28 18:43:42 +08:00
482d75bbe5 -o qemu: Set -rtc base=localtime when guest expects RTC set to localtime
I didn't set the -rtc flag in the normal (UTC) case as that is the
default.

Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2023-09-25 17:21:00 +01:00
93b86b8634 -o libvirt: Add <clock offset="utc|localtime"/> to libvirt XML
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2023-09-25 17:21:00 +01:00
baaeead927 output/create_libvirt_xml.ml: Refactor os_section
Minor refactoring of how <os> section is generated in XML output.
There is no change in the output.

Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2023-09-25 17:21:00 +01:00
dfb44983a8 -o kubevirt: Add comment about future support for clock = localtime
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2023-09-25 17:21:00 +01:00
ebb0b7b239 Revert "Remove guestcaps_block_type Virtio_SCSI"
This code is needed to check whether virtio-scsi driver was installed.

This reverts commit f0afc43952.
Message-Id: <20230310175433.781335-2-andrey.drobyshev@virtuozzo.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
2023-03-14 13:02:04 +01:00
8ad152afc4 Rework Std_utils.Option so it works like the OCaml stdlib module
OCaml 4.08 introduces a stdlib Option module which looks a bit like
ours but has a number of differences.  In particular our functions
Option.may and Option.default have no corresponding functions in
stdlib, although there are close enough equivalents.

This change was automated using this command:

$ perl -pi.bak \
  -e 's/Option.may/Option.iter/g; s/Option.default /Option.value ~default:/g' \
  `git ls-files`

Update common module to include:

  commit cffa077323fafcdfcf78e230c022afa891a6b3ff
  Author: Richard W.M. Jones <rjones@redhat.com>
  Date:   Mon Feb 20 12:11:51 2023 +0000

    mlstdutils: Rework the Option module to be compatible with stdlib

  commit 007d0506c538db0a43fec7e9986a95ecdcd48b56
  Author: Richard W.M. Jones <rjones@redhat.com>
  Date:   Mon Feb 20 12:18:29 2023 +0000

    mltools: Replace Option.may with Option.iter
2023-02-20 12:21:47 +00:00
e4a7f08c40 -o qemu: Always use -cpu host unless overridden by source hypervisor
As with the prior commit, prefer -cpu host for all guests (except when
we have more information from the source hypervisor).  Although there
is the disadvantage that -cpu host is non-migratable, in practice it
would be very difficult to live migrate a host launched using direct
qemu commands.

Note that after this change, gcaps_arch_min_version is basically an
informational field.  No output uses it, but it will appear in debug
output and there's the possibility we might use it for a future output
mode.

Thanks: Laszlo Ersek
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2023-02-20 11:11:20 +00:00
83a6400aea -o libvirt: Always use host-model unless overridden by source hypervisor
In the case where the source hypervisor doesn't specify a CPU model,
previously we chose qemu64 (qemu's most basic model), except for a few
guests that we know won't work on qemu64, eg. RHEL 9 requires
x86_64-v2 where we use <cpu mode='host-model'/>

However we recently encountered an obscure KVM bug related to this
(https://bugzilla.redhat.com/show_bug.cgi?id=2168082).  Windows 11
thinks the qemu64 CPU model when booted on real AMD Milan is an AMD
Phenom and tried to apply an ancient erratum to it.  Since KVM didn't
emulate the correct MSRs for this it caused the guest to fail to boot.

After discussion upstream we can't see any reason not to give all
guests host-model.  This should fix the bug above and also generally
improve performance by allowing the guest to exploit all host
features.

Related: https://bugzilla.redhat.com/show_bug.cgi?id=2168082#c19
Related: https://listman.redhat.com/archives/libguestfs/2023-February/030624.html
Thanks: Laszlo Ersek, Dr. David Alan Gilbert, Daniel Berrangé
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2023-02-20 11:10:12 +00:00
2cf337c26e v2v: Rename gcaps_default_cpu to gcaps_arch_min_version
Some guests require not just a specific architecture, but cannot run
on qemu's default CPU model, eg. requiring x86_64-v2.  Since we
anticipate future guests requiring higher versions, let's encode the
minimum architecture version instead of a simple boolean.

This patch essentially just remaps:

  gcaps_default_cpu = true  => gcaps_arch_min_version = 0
  gcaps_default_cpu = false => gcaps_arch_min_version = 2

I removed a long comment about how this capability is used because we
intend to completely remove use of the capability in a coming commit.

Updates: commit a50b975024
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2023-02-20 11:08:39 +00:00
12473bfcb7 -o libvirt: Use cpu='host-model' for gcaps_default_cpu = false
For RHEL >= 9 / x86-64 guests we cannot use the default qemu CPU
(eg. "qemu64"), and so we have a mechanism for conversion to indicate
to the output modes that a more capable CPU is required.  We
previously picked cpu='host-passthrough' (ie. the equivalent of qemu's
-cpu host).  However this is not live migratable.  cpu='host-model' is
a better choice as it is more likely to be migratable.

See also discussion here:
https://listman.redhat.com/archives/libguestfs/2023-February/030625.html

and previous discussion here:
https://listman.redhat.com/archives/libguestfs/2022-April/thread.html#28711

Acked-by: Laszlo Ersek <lersek@redhat.com>
2023-02-07 12:35:00 +00:00
ebfdca56bc -o libvirt: Add correct xmlns:libosinfo for Rocky Linux
Also a small whitespace fix and improve the warning message.

Updates: commit db831c167b
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2166618
Reported-by: Ming Xie
2023-02-02 12:30:01 +00:00
050a0ba714 -o kubevirt: Replace PCRE ~anchored with ^...$
Because this regexp was not anchored at both ends it would still
report a match for incorrect names.

Update common submodule to get this commit:

    mlpcre: Remove ~anchored trap

    PCRE2_ANCHORED only anchors the regexp at the start (ie.  equivalent
    to adding ^ at the beginning).  It *does not* anchor it at the end as
    well (for which there is a separate PCRE2_ENDANCHORED which has
    various traps of its own).

    Everywhere I've tried to use ~anchored I've fallen into the trap of
    believing it anchors both ends, causing actual bugs.  So remove it
    completely from the bindings.

    Replace ~anchored:true with ^...$ around the regular expression.

Fixes: commit 8a9c914544
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2162332
Reported-by: Ming Xie
2023-01-30 09:27:07 +00:00
e09250fcf6 -o rhv-upload: Improve error message for invalid or missing -os parameter
For -o rhv-upload, the -os parameter specifies the storage domain.
Because the RHV API allows globs when searching for a domain, if you
used a parameter like -os 'data*' then this would confuse the Python
code, since it can glob to the name of a storage domain, but then
later fail when we try to exact match the storage domain we found.
The result of this was a confusing error in the precheck script:

  IndexError: list index out of range

This fix validates the output storage parameter before trying to use
it.  Since valid storage domain names cannot contain glob characters
or spaces, it avoids the problems above and improves the error message
that the user sees:

  $ virt-v2v [...] -o rhv-upload -os ''
  ...
  RuntimeError: The storage domain (-os) parameter ‘’ is not valid
  virt-v2v: error: failed server prechecks, see earlier errors

  $ virt-v2v [...] -o rhv-upload -os 'data*'
  ...
  RuntimeError: The storage domain (-os) parameter ‘data*’ is not valid
  virt-v2v: error: failed server prechecks, see earlier errors

Although the IndexError should no longer happen (except in extremely
rare cases like the storage domain being renamed), I also added a
try...catch around that code to improve the error.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1986386
Reported-by: Junqin Zhou
Reviewed-by: Nir Soffer <nsoffer@redhat.com>
2023-01-30 09:27:07 +00:00
ada1815054 -o kubevirt: Implement -oo compressed for qcow2 files
Reported-by: Xiaodai Wang
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2162444
Updates: commit 53690a0c60
2023-01-20 10:35:55 +00:00
d2b01e487f Split long lines in messages
This commit splits up any long lines found in errors, warnings or
other messages.  OCaml ignores whitespace following "\<CR>" within a
string, eg:

  "long string \
   more stuff"

is parsed as:

  "long string more stuff"

Thanks: Laszlo Ersek, for working out the OCaml syntax for this
2023-01-20 10:29:24 +00:00
8a9c914544 -o kubevirt: Error on invalid output guest names
Kubevirt supports something like RFC 1123 names (without the length
restriction).  Helpfully it prints the regexp that it uses the
validate the names, so just use the same regexp.

Note that virt-v2v never renames guests (since that would add
unpredictability for automation).  You must use the -on option to
rename the guest if the name is wrong.  Hence this is an error, not a
warning or an attempt to rename the guest.

Reported-by: Ming Xie
Fixes: commit bfa62b4683
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2162332
2023-01-20 09:54:46 +00:00
8db50a85f0 -o kubevirt: Move "cpu" element under "domain"
Apparently this element doesn't go in the obvious place (under
"resources", next to memory), but in a whole new section under "cpu",
which makes no logical sense but here we are.  Also verified this
against Kubevirt examples/vm-template-fedora.yaml

Reported-by: Ming Xie
Fixes: commit bfa62b4683
2023-01-20 09:39:17 +00:00
be322ed49b -o kubevirt: Fix mistake in error message
The error message was copied from output_local.ml:

virt-v2v: error: -o local: -op option cannot be used in this output mode

Reported-by: Xiaodai Wang
2023-01-19 08:52:19 +00:00
1ea99fb2a7 Remove support for RHEL 3
This was the only guest type which did not support ACPI.  It also only
supported direct to libvirt output.  It hasn't been tested for a long
time, and hasn't been supported by Red Hat for very much longer.
Removing this means we no longer have to think about non-ACPI guests.
2023-01-17 14:23:08 +00:00
bfa62b4683 output: Add new -o kubevirt mode
This commit adds a new -o kubevirt mode.  You can specify where to
place the disks and metadata (guest.yaml) file using -os.  Also
allocation mode (-oa) and disk format (-of) may be set.  For example:

  $ virt-v2v -i disk guest.img -o kubevirt -os /var/tmp

will generate /var/tmp/guest.yaml and /var/tmp/guest-sda

This is not finalized since undoubtedly the way the disks are handled
will have to be changed in future.
2023-01-06 09:58:57 +00:00
e5297c3180 output/create_libvirt_xml: relax VCPU feature checking for "qemu64"
When the source domain doesn't specify a VCPU model ("s_cpu_model" is
None), and the guest OS is assumed to work with the default VCPU model
("gcaps_default_cpu" is true), we don't output any <cpu> element. In that
case, libvirtd augments the domain config with:

  [1] <cpu mode='custom' match='exact' check='none'>
        <model fallback='forbid'>qemu64</model>
      </cpu>

where the @check='none' attribute ensures that the converted domain will
be launched, for example, on an Intel host, despite the "qemu64" VCPU
model containing AMD-only feature flags such as "svm".

However, if the source domain explicitly specifies the "qemu64" model
(mostly seen with "-i libvirt -ic qemu://..."), we presently output

  [2] <cpu match='minimum'>
        <model fallback='allow'>qemu64</model>
      </cpu>

which libvirtd completes as

  [3] <cpu mode='custom' match='minimum' check='partial'>
        <model fallback='allow'>qemu64</model>
      </cpu>

In [3], cpu/@match='minimum' and cpu/model/@fallback='allow' are both
laxer than @match='exact' and @fallback='forbid', respectively, in [1].

However, cpu/@check='partial' in [3] is stricter than @check='none' in
[1]; it causes libvirtd to catch the "svm" feature flag on an Intel host,
and prevents the converted domain from starting.

The "qemu64" VCPU model is supposed to run on every possible host
<https://gitlab.com/qemu-project/qemu/-/blob/master/docs/system/cpu-models-x86.rst.inc>,
therefore make an exception for the explicitly specified "qemu64" VCPU
model, and generate the @check='none' attribute.

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2107503
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20220722073627.6511-1-lersek@redhat.com>
Acked-by: Richard W.M. Jones <rjones@redhat.com>
2022-07-22 14:56:47 +02:00
2fbd578b4e -o rhv: Wait for the NBD server to exit to avoid a race with unmounting
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1953286#c26
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2022-07-15 15:15:08 +01:00
e2a1a7b4df output: Permit output modes to wait on the local NBD server
Output.output_to_local_file is used by several output modes that write
to local files or devices.  It launches an instance of qemu-nbd or
nbdkit connected to the local file.

Previously we unconditionally added an On_exit handler to kill the NBD
server.  This is usually safe because nbdcopy --flush has guaranteed
that the data was written through to permanent storage, and so killing
the NBD server is just there to prevent orphaned processes.

However for output to RHV (-o rhv) we actually need the NBD server to
be cleaned up before we exit.  See the analysis here:

https://bugzilla.redhat.com/show_bug.cgi?id=1953286#c26

Allow an alternate strategy of waiting for the NBD server to exit
during virt-v2v shutdown.

We only need this in virt-v2v so implement it here instead of pushing
it all the way into the On_exit module.

Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2022-07-15 15:14:28 +01:00
e96357fc3b -o rhv: Unmount the temporary NFS mountpoint as late as possible
To partially avoid a potential race against nbdkit or qemu-nbd
releasing files on the mountpoint before they exit, unmount as late as
we can.

See also https://bugzilla.redhat.com/show_bug.cgi?id=1953286#c26

Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2022-07-15 10:21:03 +01:00
2eb6441264 common: Adapt to renamed function On_exit.rmdir -> On_exit.rm_rf
This function was renamed to make it clearer what it does (and that
it's potentially dangerous).  The functionality is unchanged.

Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2022-07-15 08:57:52 +01:00