Previously this output method was almost completely untested. This commit adds a fake ovirtsdk4 module so we can test the -o rhv-upload method fairly completely without needing an actual oVirt instance around. --- v2v/Makefile.am | 2 + v2v/rhv-upload-plugin.py | 16 +- .../ovirtsdk4/__init__.py | 146 ++++++++++++++++++ .../ovirtsdk4/types.py | 125 +++++++++++++++ v2v/test-v2v-o-rhv-upload.sh | 51 ++++++ 5 files changed, 333 insertions(+), 7 deletions(-)
diff --git a/v2v/Makefile.am b/v2v/Makefile.am index 14183572b..9a2b4391d 100644 --- a/v2v/Makefile.am +++ b/v2v/Makefile.am @@ -382,6 +382,7 @@ TESTS += \ test-v2v-o-openstack.sh \ test-v2v-o-qemu.sh \ test-v2v-o-rhv.sh \ + test-v2v-o-rhv-upload.sh \ test-v2v-o-vdsm-options.sh \ test-v2v-oa-option.sh \ test-v2v-of-option.sh \ @@ -539,6 +540,7 @@ EXTRA_DIST += \ test-v2v-o-qemu.sh \ test-v2v-o-rhv.ovf.expected \ test-v2v-o-rhv.sh \ + test-v2v-o-rhv-upload.sh \ test-v2v-o-rhv-upload-oo-query.sh \ test-v2v-o-vdsm-oo-query.sh \ test-v2v-o-vdsm-options.ovf.expected \ diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py index 6e35b5057..b27349103 100644 --- a/v2v/rhv-upload-plugin.py +++ b/v2v/rhv-upload-plugin.py @@ -210,14 +210,16 @@ def open(readonly): if destination_url.scheme == "https": context = ssl.create_default_context() context.load_verify_locations(cafile = params['rhv_cafile']) + http = HTTPSConnection( + destination_url.hostname, + destination_url.port, + context = context + ) else: - context = None - - http = HTTPSConnection( - destination_url.hostname, - destination_url.port, - context = context - ) + http = HTTPConnection( + destination_url.hostname, + destination_url.port, + ) # The first request is to fetch the features of the server. diff --git a/v2v/test-v2v-o-rhv-upload-module/ovirtsdk4/__init__.py b/v2v/test-v2v-o-rhv-upload-module/ovirtsdk4/__init__.py new file mode 100644 index 000000000..2ddb950ea --- /dev/null +++ b/v2v/test-v2v-o-rhv-upload-module/ovirtsdk4/__init__.py @@ -0,0 +1,146 @@ +# -*- python -*- +# Copyright (C) 2018 Red Hat Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Fake ovirtsdk4 module used as a test harness. +# See v2v/test-v2v-o-rhv-upload.sh + +class Error(Exception): + pass +class NotFoundError(Error): + pass + +class Connection(object): + def __init__( + self, + url = None, + username = None, + password = None, + ca_file = None, + log = None, + insecure = False, + ): + pass + + def system_service(self): + return SystemService() + +class SystemService(object): + def data_centers_service(self): + return DataCentersService() + + def disks_service(self): + return DisksService() + + def image_transfers_service(self): + return ImageTransfersService() + + def storage_domains_service(self): + return StorageDomainsService() + + def vms_service(self): + return VmsService() + +class DataCentersService(object): + def list(self, search=None, case_sensitive=False): + return [] + +class DiskService(object): + def __init__(self, disk_id): + self._disk_id = disk_id + + def get(self): + return types.Disk() + + def remove(self): + pass + +class DisksService(object): + def add(self, disk=None): + return disk + + def disk_service(self, disk_id): + return DiskService(disk_id) + +class ImageTransferService(object): + def __init__(self): + self._finalized = False + + def get(self): + if self._finalized: + raise NotFoundError + else: + return types.ImageTransfer() + + def finalize(self): + self._finalized = True + +class ImageTransfersService(object): + def add(self, transfer): + return transfer + + def image_transfer_service(self, id): + return ImageTransferService() + +class StorageDomain(object): + id = "ba87af68-b630-4211-a73a-694c1a689405" + +class StorageDomainsService(object): + def list(self, search=None): + return [ StorageDomain() ] + +class VmsService(object): + def add(self, vm): + return vm + + def list(self, search=None): + return [] + +# Create a background thread running a web server which is +# simulating the imageio server. + +from http.server import HTTPServer, BaseHTTPRequestHandler +import random +import threading + +# Choose a random port number in range [50000,59999] +imageio_port = random.randint(50000,60000) + +class RequestHandler(BaseHTTPRequestHandler): + def do_OPTIONS(self): + self.send_response(200) + self.send_header("Content-type", "application/json; charset=UTF-8") + self.end_headers() + # Advertize only zero support. + self.wfile.write(b'''{ "features": [ "zero" ] }''') + + # eg. zero request. Just ignore it. + def do_PATCH(self): + self.send_response(200) + self.end_headers() + + # Flush request. Ignore it. + def do_PUT(self): + self.send_response(200) + self.end_headers() + +def server(): + server_address = ("", imageio_port) + httpd = HTTPServer(server_address, RequestHandler) + httpd.serve_forever() + +thread = threading.Thread(target = server, args = [], daemon = True) +thread.start() diff --git a/v2v/test-v2v-o-rhv-upload-module/ovirtsdk4/types.py b/v2v/test-v2v-o-rhv-upload-module/ovirtsdk4/types.py new file mode 100644 index 000000000..9b3f557ee --- /dev/null +++ b/v2v/test-v2v-o-rhv-upload-module/ovirtsdk4/types.py @@ -0,0 +1,125 @@ +# -*- python -*- +# Copyright (C) 2018 Red Hat Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Fake ovirtsdk4 module used as a test harness. +# See v2v/test-v2v-o-rhv-upload.sh + +from enum import Enum +from ovirtsdk4 import imageio_port + +class Cluster(object): + def __init__(self, name): + pass + +class Configuration(object): + def __init__(self, type=None, data=None): + pass +class ConfigurationType(Enum): + OVA = 'ova' + OVF = 'ovf' + + def __init__(self, image): + self._image = image + + def __str__(self): + return self._image + +class DiskFormat(Enum): + COW = "cow" + RAW = "raw" + + def __init__(self, image): + self._image = image + + def __str__(self): + return self._image + +class DiskStatus(Enum): + ILLEGAL = "illegal" + LOCKED = "locked" + OK = "ok" + + def __init__(self, image): + self._image = image + + def __str__(self): + return self._image + +class Disk(object): + def __init__( + self, + id = None, + name = None, + description = None, + format = None, + initial_size = None, + provisioned_size = None, + sparse = False, + storage_domains = None + ): + pass + + id = 123 + status = DiskStatus.OK + +class ImageTransferPhase(Enum): + CANCELLED = 'cancelled' + FINALIZING_FAILURE = 'finalizing_failure' + FINALIZING_SUCCESS = 'finalizing_success' + FINISHED_FAILURE = 'finished_failure' + FINISHED_SUCCESS = 'finished_success' + INITIALIZING = 'initializing' + PAUSED_SYSTEM = 'paused_system' + PAUSED_USER = 'paused_user' + RESUMING = 'resuming' + TRANSFERRING = 'transferring' + UNKNOWN = 'unknown' + + def __init__(self, image): + self._image = image + + def __str__(self): + return self._image + +class ImageTransfer(object): + def __init__( + self, + disk = None, + host = None, + inactivity_timeout = None, + ): + pass + + id = 456 + phase = ImageTransferPhase.TRANSFERRING + transfer_url = "http://localhost:" + str(imageio_port) + "/" + +class Initialization(object): + def __init__(self, configuration): + pass + +class StorageDomain(object): + def __init__(self, name = None): + pass + +class Vm(object): + def __init__( + self, + cluster = None, + initialization = None + ): + pass diff --git a/v2v/test-v2v-o-rhv-upload.sh b/v2v/test-v2v-o-rhv-upload.sh new file mode 100755 index 000000000..8bda7cc0b --- /dev/null +++ b/v2v/test-v2v-o-rhv-upload.sh @@ -0,0 +1,51 @@ +#!/bin/bash - +# libguestfs virt-v2v test script +# Copyright (C) 2018 Red Hat Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Test -o rhv-upload. +# +# These uses a test harness (see +# v2v/test-v2v-o-rhv-upload-module/ovirtsdk4) to fake responses from +# oVirt. + +set -e +set -x + +$TEST_FUNCTIONS +skip_if_skipped +skip_if_backend uml +skip_unless_phony_guest windows.img + +libvirt_uri="test://$abs_top_builddir/test-data/phony-guests/guests.xml" +f=$top_builddir/test-data/phony-guests/windows.img + +export VIRT_TOOLS_DATA_DIR="$top_srcdir/test-data/fake-virt-tools" +export VIRTIO_WIN="$top_srcdir/test-data/fake-virtio-win" +export PYTHONPATH=$srcdir/test-v2v-o-rhv-upload-module:$PYTHONPATH + +# Run virt-v2v -o rhv-upload. +# +# The fake ovirtsdk4 module doesn't care about most of the options +# like -oc, -oo rhv-cafile, -op etc. Any values may be used. +$VG virt-v2v --debug-gc -v -x \ + -i libvirt -ic "$libvirt_uri" windows \ + -o rhv-upload \ + -oc https://example.com/ovirt-engine/api \ + -oo rhv-cafile=/dev/null \ + -oo rhv-direct \ + -op /dev/null \ + -os . -- 2.19.0.rc0 _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs