Skip to content

Commit 9afa478

Browse files
author
Zhenchao Liu
committed
Add storage and image management support
Signed-off-by: Zhenchao Liu <zhencliu@redhat.com>
1 parent 6b65e9e commit 9afa478

52 files changed

Lines changed: 4283 additions & 38 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

avocado_vt/plugins/vt_cluster.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
from avocado.core.plugin_interfaces import JobPostTests as Post
77
from avocado.core.plugin_interfaces import JobPreTests as Pre
88
from avocado.utils.stacktrace import log_exc_info
9+
910
from virttest.vt_cluster import cluster, node_metadata
11+
from virttest.vt_imgr import imgr
12+
from virttest.vt_resmgr import resmgr
1013

1114

1215
class ClusterSetupError(Exception):
@@ -50,21 +53,17 @@ def _pre_node_setup():
5053
def _pre_mgr_setup():
5154
try:
5255
# Pre-setup the cluster manager
53-
# e.g:
54-
# startup_resmgr()
55-
# vt_imgr.startup()
56-
pass
56+
resmgr.startup()
57+
imgr.startup()
5758
except Exception as err:
5859
raise ClusterManagerSetupError(err)
5960

6061
@staticmethod
6162
def _post_mgr_cleanup():
6263
try:
6364
# Post-cleanup the cluster manager
64-
# e.g:
65-
# teardown_resmgr()
66-
# vt_imgr.teardown()
67-
pass
65+
imgr.teardown()
66+
resmgr.teardown()
6867
except Exception as err:
6968
raise ClusterManagerCleanupError(err)
7069

virttest/bootstrap.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from avocado.utils import process
1313

1414
from virttest.vt_cluster import cluster, node
15+
from virttest.vt_resmgr import resmgr
1516

1617
from . import arch, asset, cartesian_config, data_dir, defaults, utils_selinux
1718
from .compat import get_opt
@@ -895,6 +896,10 @@ def _register_hosts(hosts_configs):
895896
LOG.debug("Host %s registered", host)
896897

897898

899+
def _initialize_managers(pools_params):
900+
resmgr.setup(pools_params)
901+
902+
898903
def _config_master_server(master_config):
899904
"""Configure the master server."""
900905
if master_config:
@@ -1084,6 +1089,7 @@ def bootstrap(options, interactive=False):
10841089
cluster_config = _load_cluster_config(vt_cluster_config)
10851090
_register_hosts(cluster_config.get("hosts"))
10861091
_config_master_server(cluster_config.get("master"))
1092+
_initialize_managers(cluster_config.get("pools"))
10871093

10881094
LOG.info("")
10891095
LOG.info("VT-BOOTSTRAP FINISHED")

virttest/env_process.py

Lines changed: 110 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
from virttest.test_setup.storage import StorageConfig
6969
from virttest.test_setup.verify import VerifyHostDMesg
7070
from virttest.test_setup.vms import ProcessVMOff, UnrequestedVMHandler
71+
from virttest.vt_imgr import imgr
7172

7273
utils_libvirtd = lazy_import("virttest.utils_libvirtd")
7374
virsh = lazy_import("virttest.virsh")
@@ -112,42 +113,72 @@
112113
LOG = logging.getLogger("avocado." + __name__)
113114

114115

115-
def preprocess_image(test, params, image_name, vm_process_status=None):
116+
def preprocess_image(test, params, image_name, vm_process_status=None, vm_name=None):
116117
"""
117118
Preprocess a single QEMU image according to the instructions in params.
118119
119120
:param test: Autotest test object.
120121
:param params: A dict containing image preprocessing parameters.
121122
:param vm_process_status: This is needed in postprocess_image. Add it here
122123
only for keep it work with process_images()
124+
:param vm_name: vm tag defined in 'vms'
123125
:note: Currently this function just creates an image if requested.
124126
"""
127+
# FIXME:
128+
image_id = None
129+
if params.get_boolean("multihost"):
130+
params = params.copy()
131+
# 'images' is the vm's param, e.g. 'images_vm1', so when the 'vms' is
132+
# set, the images defined in 'images' should be used by the vm
133+
params[f"image_owner_{image_name}"] = vm_name
134+
image_config = imgr.define_logical_image_config(image_name, params)
135+
image_id = imgr.create_logical_image_object(image_config)
136+
137+
params = params.object_params(image_name)
125138
base_dir = params.get("images_base_dir", data_dir.get_data_dir())
126139

127140
if not storage.preprocess_image_backend(base_dir, params, image_name):
128141
LOG.error("Backend can't be prepared correctly.")
129142

130-
image_filename = storage.get_image_filename(params, base_dir)
143+
image_filename = None
144+
if not params.get_boolean("multihost"):
145+
image_filename = storage.get_image_filename(params, base_dir)
131146

132147
create_image = False
133148
if params.get("force_create_image") == "yes":
134149
create_image = True
135-
elif params.get("create_image") == "yes" and not storage.file_exists(
136-
params, image_filename
137-
):
138-
create_image = True
150+
elif params.get("create_image") == "yes":
151+
# FIXME: check all volumes allocated
152+
if params.get_boolean("multihost"):
153+
volume = imgr.get_logical_image_info(
154+
image_id, request=f"spec.images.{image_name}.spec.volume.meta"
155+
)
156+
create_image = True if not volume["meta"]["allocated"] else False
157+
else:
158+
create_image = (
159+
True if not storage.file_exists(params, image_filename) else False
160+
)
161+
else:
162+
# FIXME: sync all volumes configurations
163+
if params.get_boolean("multihost"):
164+
imgr.get_logical_image_info(image_id)
165+
# TODO: check if file allocated
139166

140167
if params.get("backup_image_before_testing", "no") == "yes":
168+
# FIXME: add backup_image
141169
image = qemu_storage.QemuImg(params, base_dir, image_name)
142170
image.backup_image(params, base_dir, "backup", True, True)
143171
if create_image:
144-
if storage.file_exists(params, image_filename):
145-
# As rbd image can not be covered, so need remove it if we need
146-
# force create a new image.
147-
storage.file_remove(params, image_filename)
148-
image = qemu_storage.QemuImg(params, base_dir, image_name)
149-
LOG.info("Create image on %s." % image.storage_type)
150-
image.create(params)
172+
if params.get_boolean("multihost"):
173+
imgr.update_logical_image(image_id, {"create": {}})
174+
else:
175+
if storage.file_exists(params, image_filename):
176+
# As rbd image can not be covered, so need remove it if we need
177+
# force create a new image.
178+
storage.file_remove(params, image_filename)
179+
image = qemu_storage.QemuImg(params, base_dir, image_name)
180+
LOG.info("Create image on %s." % image.storage_type)
181+
image.create(params)
151182

152183

153184
def preprocess_fs_source(test, params, fs_name, vm_process_status=None):
@@ -432,7 +463,7 @@ def preprocess_vm(test, params, env, name):
432463
)
433464

434465

435-
def check_image(test, params, image_name, vm_process_status=None):
466+
def check_image(test, params, image_name, vm_process_status=None, vm_name=None):
436467
"""
437468
Check a single QEMU image according to the instructions in params.
438469
@@ -441,6 +472,7 @@ def check_image(test, params, image_name, vm_process_status=None):
441472
:param vm_process_status: (optional) vm process status like running, dead
442473
or None for no vm exist.
443474
"""
475+
params = params.object_params(image_name)
444476
clone_master = params.get("clone_master", None)
445477
base_dir = data_dir.get_data_dir()
446478
check_image_flag = params.get("check_image") == "yes"
@@ -511,7 +543,7 @@ def check_image(test, params, image_name, vm_process_status=None):
511543
raise e
512544

513545

514-
def postprocess_image(test, params, image_name, vm_process_status=None):
546+
def postprocess_image(test, params, image_name, vm_process_status=None, vm_name=None):
515547
"""
516548
Postprocess a single QEMU image according to the instructions in params.
517549
@@ -528,6 +560,16 @@ def postprocess_image(test, params, image_name, vm_process_status=None):
528560
)
529561
return
530562

563+
# FIXME: multihost
564+
image_id = None
565+
if params.get_boolean("multihost"):
566+
image_id = imgr.query_logical_image(image_name, vm_name)
567+
if image_id is None:
568+
LOG.warning(f"Cannot find the image {image_name}")
569+
image_config = imgr.define_logical_image_config(image_name, params)
570+
image_id = imgr.create_logical_image_object(image_config)
571+
params = params.object_params(image_name)
572+
531573
restored, removed = (False, False)
532574
clone_master = params.get("clone_master", None)
533575
base_dir = params.get("images_base_dir", data_dir.get_data_dir())
@@ -585,10 +627,18 @@ def postprocess_image(test, params, image_name, vm_process_status=None):
585627
)
586628
LOG.info("Remove image on %s." % image.storage_type)
587629
if clone_master is None:
588-
image.remove()
630+
if params.get_boolean("multihost"):
631+
imgr.update_logical_image(image_id, {"destroy": {}})
632+
imgr.destroy_logical_image_object(image_id)
633+
else:
634+
image.remove()
589635
elif clone_master == "yes":
590636
if image_name in params.get("master_images_clone").split():
591-
image.remove()
637+
if params.get_boolean("multihost"):
638+
imgr.update_logical_image(image_id, {"destroy": {}})
639+
imgr.destroy_logical_image_object(image_id)
640+
else:
641+
image.remove()
592642

593643

594644
def postprocess_fs_source(test, params, fs_name, vm_process_status=None):
@@ -742,7 +792,16 @@ class _CreateImages(threading.Thread):
742792
in self.exc_info
743793
"""
744794

745-
def __init__(self, image_func, test, images, params, exit_event, vm_process_status):
795+
def __init__(
796+
self,
797+
image_func,
798+
test,
799+
images,
800+
params,
801+
exit_event,
802+
vm_process_status,
803+
vm_name=None,
804+
):
746805
threading.Thread.__init__(self)
747806
self.image_func = image_func
748807
self.test = test
@@ -751,6 +810,7 @@ def __init__(self, image_func, test, images, params, exit_event, vm_process_stat
751810
self.exit_event = exit_event
752811
self.exc_info = None
753812
self.vm_process_status = vm_process_status
813+
self.vm_name = vm_name
754814

755815
def run(self):
756816
try:
@@ -761,13 +821,14 @@ def run(self):
761821
self.params,
762822
self.exit_event,
763823
self.vm_process_status,
824+
self.vm_name,
764825
)
765826
except Exception:
766827
self.exc_info = sys.exc_info()
767828
self.exit_event.set()
768829

769830

770-
def process_images(image_func, test, params, vm_process_status=None):
831+
def process_images(image_func, test, params, vm_process_status=None, vm_name=None):
771832
"""
772833
Wrapper which chooses the best way to process images.
773834
@@ -780,11 +841,20 @@ def process_images(image_func, test, params, vm_process_status=None):
780841
images = params.objects("images")
781842
if len(images) > 20: # Lets do it in parallel
782843
_process_images_parallel(
783-
image_func, test, params, vm_process_status=vm_process_status
844+
image_func,
845+
test,
846+
params,
847+
vm_process_status=vm_process_status,
848+
vm_name=vm_name,
784849
)
785850
else:
786851
_process_images_serial(
787-
image_func, test, images, params, vm_process_status=vm_process_status
852+
image_func,
853+
test,
854+
images,
855+
params,
856+
vm_process_status=vm_process_status,
857+
vm_name=vm_name,
788858
)
789859

790860

@@ -804,7 +874,13 @@ def process_fs_sources(fs_source_func, test, params, vm_process_status=None):
804874

805875

806876
def _process_images_serial(
807-
image_func, test, images, params, exit_event=None, vm_process_status=None
877+
image_func,
878+
test,
879+
images,
880+
params,
881+
exit_event=None,
882+
vm_process_status=None,
883+
vm_name=None,
808884
):
809885
"""
810886
Original process_image function, which allows custom set of images
@@ -817,14 +893,17 @@ def _process_images_serial(
817893
or None for no vm exist.
818894
"""
819895
for image_name in images:
820-
image_params = params.object_params(image_name)
821-
image_func(test, image_params, image_name, vm_process_status)
896+
# image_params = params.object_params(image_name)
897+
# image_func(test, image_params, image_name, vm_process_status)
898+
image_func(test, params, image_name, vm_process_status, vm_name)
822899
if exit_event and exit_event.is_set():
823900
LOG.error("Received exit_event, stop processing of images.")
824901
break
825902

826903

827-
def _process_images_parallel(image_func, test, params, vm_process_status=None):
904+
def _process_images_parallel(
905+
image_func, test, params, vm_process_status=None, vm_name=None
906+
):
828907
"""
829908
The same as _process_images but in parallel.
830909
:param image_func: Process function
@@ -840,7 +919,9 @@ def _process_images_parallel(image_func, test, params, vm_process_status=None):
840919
for i in xrange(no_threads):
841920
imgs = images[i::no_threads]
842921
threads.append(
843-
_CreateImages(image_func, test, imgs, params, exit_event, vm_process_status)
922+
_CreateImages(
923+
image_func, test, imgs, params, exit_event, vm_process_status, vm_name
924+
)
844925
)
845926
threads[-1].start()
846927

@@ -895,7 +976,9 @@ def _call_image_func():
895976
unpause_vm = True
896977
vm_params["skip_cluster_leak_warn"] = "yes"
897978
try:
898-
process_images(image_func, test, vm_params, vm_process_status)
979+
process_images(
980+
image_func, test, vm_params, vm_process_status, vm_name
981+
)
899982
finally:
900983
if unpause_vm:
901984
vm.resume()

virttest/staging/service.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ def __init__(
604604
# :param runlevel: sys_v runlevel to set as default in inittab
605605
# :type runlevel: str
606606
# """
607-
# raise NotImplemented
607+
# raise NotImplementedError
608608

609609

610610
def convert_sysv_runlevel(level):

virttest/test_setup/storage.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ def setup(self):
2626
self.params["image_raw_device"] = "yes"
2727
self.env.register_lvmdev("lvm_%s" % self.params["main_vm"], lvmdev)
2828

29-
if self.params.get("storage_type") == "nfs":
29+
if self.params.get("storage_type") == "nfs" and self.params.get_boolean(
30+
"setup_local_nfs"
31+
):
3032
selinux_local = self.params.get("set_sebool_local", "yes") == "yes"
3133
selinux_remote = self.params.get("set_sebool_remote", "no") == "yes"
3234
image_nfs = Nfs(self.params)
@@ -89,7 +91,9 @@ def cleanup(self):
8991
finally:
9092
self.env.unregister_lvmdev("lvm_%s" % self.params["main_vm"])
9193

92-
if self.params.get("storage_type") == "nfs":
94+
if self.params.get("storage_type") == "nfs" and self.params.get_boolean(
95+
"setup_local_nfs"
96+
):
9397
migration_setup = self.params.get("migration_setup", "no") == "yes"
9498
image_nfs = Nfs(self.params)
9599
image_nfs.cleanup()
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
from .connect import ConnectManager
22
from .console import ConsoleManager
3+
from .image_manager import ImageHandlerManager
4+
from .resource_backing_manager import ResourceBackingManager
35

46
connect_mgr = ConnectManager()
57
console_mgr = ConsoleManager()
8+
resbacking_mgr = ResourceBackingManager()
9+
image_handler_mgr = ImageHandlerManager()

0 commit comments

Comments
 (0)