forked from avocado-framework/avocado-vt
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Xu Tian <[email protected]>
- Loading branch information
Xu Tian
committed
Oct 23, 2019
1 parent
a21d905
commit 31aae63
Showing
19 changed files
with
1,503 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
class UnsupportedStoragePoolException(Exception): | ||
|
||
def __init__(self, sp_manager, sp_type): | ||
self.sp_manager = sp_manager | ||
self.sp_type = sp_type | ||
self.message = "Unsupported StoragePool type '%s', supported type are: %s" % ( | ||
self.sp_type, sp_manager.supported_storage_backend.keys()) | ||
|
||
def __str__(self): | ||
return "UnsupportedStoragePoolException:%s" % self.message | ||
|
||
|
||
class UnsupportedVolumeFormatException(Exception): | ||
"""""" | ||
|
||
def __init__(self, sp_manager, fmt): | ||
self.sp_manager = sp_manager | ||
self.fmt = fmt | ||
self.message = "Unsupported volume format '%s', supported format are: %s" % ( | ||
self.fmt, sp_manager.SUPPORTED_VOLUME_FORMAT.keys()) | ||
|
||
def __str__(self): | ||
return "UnsupportedVolumeFormatException:%s" % self.message | ||
|
||
|
||
class UnsupportedVolumeProtocolException(Exception): | ||
"""""" | ||
|
||
def __init__(self, sp_manager, protocol): | ||
self.sp_manager = sp_manager | ||
self.protocol = protocol | ||
self.message = "Unsupported volume protocol '%s', supported protocol are: %s" % ( | ||
self.protocol, sp_manager.SUPPORTED_VOLUME_PROTOCOL.keys()) | ||
|
||
def __str__(self): | ||
return "UnsupportedVolumeProtocolException:%s" % self.message |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
import logging | ||
|
||
from virttest.virt_storage import exception | ||
from virttest.virt_storage import storage_pool | ||
from virttest.virt_storage import storage_volume | ||
from virttest.virt_storage.utils import state | ||
|
||
|
||
class StoragePoolAdmin(object): | ||
supported_storage_backend = { | ||
"directory": storage_pool.VirtDirectoryPool, | ||
"nfs": storage_pool.NfsPool, | ||
"gluster": storage_pool.GlusterPool, | ||
"iscsi-direct": storage_pool.IscsiDriectPool, | ||
"rbd": storage_pool.RbdPool | ||
} | ||
|
||
pools = {} | ||
|
||
@classmethod | ||
def _find_storage_driver(cls, backend_type): | ||
try: | ||
return cls.supported_storage_backend[backend_type] | ||
except KeyError: | ||
raise exception.UnsupportedStoragePoolException(cls, backend_type) | ||
|
||
@classmethod | ||
def pool_define_by_params(cls, name, params): | ||
""" | ||
Define logical storage pool object by test params, | ||
initial status of the pool is dead. | ||
:param params: pool params object | ||
:param name: storage pool name | ||
:return StoragePool object | ||
""" | ||
driver = cls._find_storage_driver(params["storage_type"]) | ||
pool = driver.pool_define_by_params(name, params) | ||
state.register_pool_state_machine(pool) | ||
pool.name = name | ||
cls.pools[name] = pool | ||
return pool | ||
|
||
@classmethod | ||
def pools_define_by_params(cls, params): | ||
pools = list() | ||
for name in params.objects("storage_pools"): | ||
_params = params.object_params(name) | ||
pool = cls.pool_define_by_params(name, _params) | ||
pools.append(pool) | ||
return pools | ||
|
||
@classmethod | ||
def list_volumes(cls): | ||
"""List all volumes in host""" | ||
volumes = list() | ||
for pool in cls.pools.values(): | ||
volumes += pool.volumes.values() | ||
return volumes | ||
|
||
@classmethod | ||
def list_pools(cls): | ||
return cls.pools.values() | ||
|
||
@classmethod | ||
def find_pool_by_name(cls, name, driver=None): | ||
try: | ||
pool = cls.pools[name] | ||
if not driver: | ||
return pool | ||
if driver and pool.TYPE == driver: | ||
return pool | ||
except KeyError: | ||
logging.warn("no storage pool with matching name '%s'" % name) | ||
return None | ||
|
||
@classmethod | ||
def find_pool_by_uuid(cls, uuid): | ||
try: | ||
return filter(lambda x: x.uuid == uuid, cls.list_pools())[0] | ||
except IndexError: | ||
logging.warn("no storage pool with matching uuid '%s'" % uuid) | ||
return None | ||
|
||
@staticmethod | ||
def find_pool_by_volume(volume): | ||
return volume.pool | ||
|
||
@classmethod | ||
def find_pool_by_path(cls, path): | ||
try: | ||
return filter(lambda x: x.target.path == path, cls.list_pools())[0] | ||
except IndexError: | ||
logging.warn("no storage pool with matching path '%s'" % path) | ||
return None | ||
|
||
@classmethod | ||
def _get_next_pool(cls): | ||
return next([_ for _ in cls.list_pools() if not _.isDead()]) | ||
|
||
@classmethod | ||
def undefine_pool(cls, pool): | ||
"""Remove a pool if the pool is not in running state""" | ||
if not pool.isRunning(): | ||
try: | ||
del cls.pools[pool.name] | ||
except KeyError: | ||
logging.warn("Pool '%s' not found" % pool.name) | ||
else: | ||
logging.warn("Pool '%s' is running, skip it" % pool.name) | ||
|
||
@staticmethod | ||
def start_pool(pool): | ||
return pool.start_pool() | ||
|
||
@staticmethod | ||
def stop_pool(pool): | ||
return pool.stop_pool() | ||
|
||
@staticmethod | ||
def destroy_pool(pool): | ||
return pool.destroy_pool() | ||
|
||
@classmethod | ||
def undefine_all_pools(cls): | ||
"""Undefine pool, remove pool object from pools""" | ||
return list(map(cls.undefine_pool, cls.list_pools())) | ||
|
||
@staticmethod | ||
def refresh_pool(pool): | ||
return pool.refresh() | ||
|
||
@staticmethod | ||
def acquire_pool(pool): | ||
""" Create storage pool""" | ||
pool.create_pool() | ||
logging.info("build pool '%s', it's %s " % (pool.name, pool.state)) | ||
return pool | ||
|
||
@staticmethod | ||
def acqurie_volume(volume): | ||
"""Acqurie a volume""" | ||
return volume.pool.acqurie_volume(volume) | ||
|
||
@staticmethod | ||
def release_volume(volume): | ||
del volume.pool.volumes[str(volume.uuid)] | ||
|
||
@staticmethod | ||
def find_sources(pool, params): | ||
return pool.find_sources(params) | ||
|
||
@classmethod | ||
def volumes_define_by_params(cls, params): | ||
volumes = list() | ||
for name in params.objects("images"): | ||
vol_params = params.object_params(name) | ||
volume = cls.volume_define_by_params(name, vol_params) | ||
volumes.append(volume) | ||
|
||
for volume in volumes: | ||
vol_params = params.object_params(volume.name) | ||
backing_store_name = vol_params.get("backing") | ||
if not backing_store_name: | ||
continue | ||
backing_store = filter(lambda x: x.name == name, volumes)[0] | ||
volume.backing_store = backing_store | ||
return volumes | ||
|
||
@classmethod | ||
def volume_define_by_params(cls, name, params): | ||
pool_name = params.get("storage_pool") | ||
pool_params = params.object_params(pool_name) | ||
storage_type = pool_params.get("storage_type") | ||
pool = cls.find_pool_by_name(pool_name, storage_type) | ||
if not pool: | ||
pool = cls.pool_define_by_params(pool_name, pool_params) | ||
volume = storage_volume.StorageVolume(pool) | ||
volume.name = name | ||
volume.format = params.get("image_format") | ||
return volume | ||
|
||
@classmethod | ||
def acquire_volume(cls, volume): | ||
def get_volume_chain(top): | ||
chain = [top] | ||
backing_store = top.backing_store | ||
while backing_store: | ||
chain.insert(0, backing_store) | ||
backing_store = backing_store.backing_store | ||
return chain | ||
|
||
assert volume, "volume should not None" | ||
for vol in get_volume_chain(volume): | ||
pool = cls.find_pool_by_volume(vol) | ||
key = str(vol.uuid) | ||
_vol = pool.get_volume_by_uuid(key) | ||
if _vol != vol: | ||
pool.acquire_volume(vol) | ||
|
||
@classmethod | ||
def find_volume_by_name(cls, name): | ||
volumes = cls.list_volumes() | ||
for volume in volumes: | ||
if volume.name == name: | ||
return volume | ||
return None | ||
|
||
|
||
sp_admin = StoragePoolAdmin() |
Oops, something went wrong.