Skip to content

Commit

Permalink
V2.3
Browse files Browse the repository at this point in the history
Signed-off-by: Xu Tian <[email protected]>
  • Loading branch information
Xu Tian committed Oct 23, 2019
1 parent a21d905 commit 31aae63
Show file tree
Hide file tree
Showing 19 changed files with 1,503 additions and 0 deletions.
Empty file.
36 changes: 36 additions & 0 deletions virttest/virt_storage/exception.py
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
211 changes: 211 additions & 0 deletions virttest/virt_storage/storage_admin.py
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()
Loading

0 comments on commit 31aae63

Please sign in to comment.