[Libguestfs] [PATCH v2v v3 REBASE] rhv-upload: Validate UUIDs passed to -oo rhv-disk-uuid (RHBZ#1789279)
Nir Soffer
nsoffer at redhat.com
Tue May 18 11:23:19 UTC 2021
On Tue, May 18, 2021 at 12:48 AM Martin Kletzander <mkletzan at redhat.com> wrote:
>
> The validation helps us fail early and with a sensible error message. The NIL
> UUID is not valid for oVirt, but other than that there is no other logic in
> there merely because the UUID types are a matter of the generator and they are
> just forwarded in this partucular case.
particular
>
> On top of that also check that the UUID is not already taken. This makes the
> code fail with a sensible error message instead of cryptic error from ovirtsdk.
Sounds good, ovirt sdk errors are not very helpful.
> Signed-off-by: Martin Kletzander <mkletzan at redhat.com>
> ---
>
> v4:
> - https://listman.redhat.com/archives/libguestfs/2021-May/msg00095.html
> - Merge the two patches together
> - Things mentioned in the review are already in, so there is no other change
> v3:
> - https://listman.redhat.com/archives/libguestfs/2020-March/msg00084.html
> - Do the check in precheck
> - Fix for Lazy evaluation of regexp UUID
> v2:
> - https://www.redhat.com/archives/libguestfs/2020-January/msg00221.html
> - Use EEXIST instead of EINVAL
> - Put the colliding UUID into the error
> - Do not evaluate the PCRE needlessly multiple times
> v1:
> - https://www.redhat.com/archives/libguestfs/2020-January/msg00184.html
>
> v2v/output_rhv_upload.ml | 18 ++++++++++++++++++
> v2v/rhv-upload-precheck.py | 10 ++++++++++
> 2 files changed, 28 insertions(+)
>
> diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml
> index dbef7011b04b..15ba1078019e 100644
> --- a/v2v/output_rhv_upload.ml
> +++ b/v2v/output_rhv_upload.ml
> @@ -49,6 +49,16 @@ after their uploads (if you do, you must supply one for each disk):
> -oo rhv-disk-uuid=UUID Disk UUID
> ")
>
> +let is_nonnil_uuid uuid =
> + let nil_uuid = "00000000-0000-0000-0000-000000000000" in
> + let rex_uuid = lazy (
> + let hex = "[a-fA-F0-9]" in
> + let str = sprintf "^%s{8}-%s{4}-%s{4}-%s{4}-%s{12}$" hex hex hex hex hex in
> + PCRE.compile str
> + ) in
> + if uuid = nil_uuid then false
> + else PCRE.matches (Lazy.force rex_uuid) uuid
> +
> let parse_output_options options =
> let rhv_cafile = ref None in
> let rhv_cluster = ref None in
> @@ -71,6 +81,8 @@ let parse_output_options options =
> | "rhv-verifypeer", "" -> rhv_verifypeer := true
> | "rhv-verifypeer", v -> rhv_verifypeer := bool_of_string v
> | "rhv-disk-uuid", v ->
> + if not (is_nonnil_uuid v) then
> + error (f_"-o rhv-upload: invalid UUID for -oo rhv-disk-uuid");
> rhv_disk_uuids := Some (v :: (Option.default [] !rhv_disk_uuids))
> | k, _ ->
> error (f_"-o rhv-upload: unknown output option ‘-oo %s’") k
> @@ -256,6 +268,12 @@ object
> error_unless_output_alloc_sparse output_alloc;
>
> (* Python code prechecks. *)
> + let json_params = match rhv_options.rhv_disk_uuids with
> + | None -> json_params
> + | Some uuids ->
> + let ids = List.map (fun uuid -> JSON.String uuid) uuids in
> + ("rhv_disk_uuids", JSON.List ids) :: json_params
> + in
> let precheck_fn = tmpdir // "v2vprecheck.json" in
> let fd = Unix.openfile precheck_fn [O_WRONLY; O_CREAT] 0o600 in
> if Python_script.run_command ~stdout_fd:fd
> diff --git a/v2v/rhv-upload-precheck.py b/v2v/rhv-upload-precheck.py
> index 2180ea1043ab..c3f74df35f65 100644
> --- a/v2v/rhv-upload-precheck.py
> +++ b/v2v/rhv-upload-precheck.py
> @@ -97,6 +97,16 @@ if cpu.architecture == types.Architecture.UNDEFINED:
> raise RuntimeError("The cluster ‘%s’ has an unknown architecture" %
> (params['rhv_cluster']))
>
> +# Find if any disk already exists with specified UUID.
> +disks_service = system_service.disks_service()
> +
> +for uuid in params.get('rhv_disk_uuids', []):
> + try:
> + disk_service = disks_service.disk_service(uuid).get()
get() returns a disk, not a disk_service. You are overriding the
disk_service instance
with the result.
> + raise RuntimeError("Disk with the UUID '%s' already exists" % uuid)
> + except sdk.NotFoundError:
> + pass
Also this can be more clear using try-except-else:
try:
disks_service.disk_service(uuid).get()
except sdk.NotFoundError:
return results here?
else:
raise ...
> +
> # Otherwise everything is OK, print a JSON with the results.
> results = {
> "rhv_storagedomain_uuid": storage_domain.id,
> --
> 2.31.1
>
> _______________________________________________
> Libguestfs mailing list
> Libguestfs at redhat.com
> https://listman.redhat.com/mailman/listinfo/libguestfs
More information about the Libguestfs
mailing list