Skip to content
Snippets Groups Projects
Commit b5af93d2 authored by Anael Beutot's avatar Anael Beutot
Browse files

Create volume and delete volume handlers.

parent c76efb7e
No related branches found
No related tags found
No related merge requests found
......@@ -11,3 +11,7 @@ class PluginError(CCNodeError):
class UndefinedDomain(CCNodeError):
pass
class PoolStorageError(CCNodeError):
pass
......@@ -12,7 +12,7 @@ from ccnode.hypervisor.lib import (
EventLoop as VirEventLoop,
)
from ccnode.hypervisor.domains import VirtualMachine
from ccnode.exc import UndefinedDomain
from ccnode.exc import UndefinedDomain, PoolStorageError
logger = logging.getLogger(__name__)
......@@ -247,6 +247,22 @@ class Handler(HostHandler):
logger.error(msg)
raise UndefinedDomain(msg)
def vol_create(self, pool, name, size):
logger.debug('Volume create %s, pool %s, size %s', name, pool, size)
try:
self.hypervisor.storage.create_volume(pool, name, size)
except Exception:
logger.exception('Error while creating volume')
raise
def vol_delete(self, pool, name):
logger.debug('Volume delete %s, pool %s', name, pool)
try:
self.hypervisor.storage.delete_volume(pool, name)
except Exception:
logger.exception('Error while deleting volume')
raise
class Hypervisor(object):
"""Container for all hypervisor related state."""
......@@ -415,8 +431,8 @@ class StorageIndex(object):
)
self.paths = dict(
(v.path, v) for v in chain.from_iterable(map(
lambda s: s.volumes,
(v.path, v) for v in chain.from_iterable(imap(
lambda s: s.volumes.itervalues(),
self.storages.itervalues(),
)),
)
......@@ -427,6 +443,62 @@ class StorageIndex(object):
def get_storage(self, name):
return self.storages.get(name)
def create_volume(self, pool_name, volume_name, capacity):
"""Create a new volume in the storage pool.
:param str name: name for the volume
:param int capacity: size for the volume
"""
# get volume
logger.debug('asked pool %s', pool_name)
logger.debug('Pool state %s', self.storages)
try:
pool = self.storages[pool_name]
except KeyError:
raise PoolStorageError('Invalid pool name')
if pool is None:
raise Exception('Storage pool not found')
try:
new_volume = pool.lv_storage.createXML("""<volume>
<name>%s</name>
<capacity>%d</capacity>
</volume>""" % (volume_name, capacity), 0)
except libvirt.libvirtError:
logger.exception('Error while creating volume')
raise
new_volume = Volume(new_volume)
# if success add the volume to the index
self.paths[new_volume.path] = new_volume
# and also to its storage pool
self.storages[new_volume.storage].volumes[new_volume.name] = new_volume
def delete_volume(self, pool_name, volume_name):
"""Delete a volume in the givent storage pool.
:param str pool_name: name for the storage pool
:param str volume_name: name for the volume
"""
# get volume
try:
pool = self.storages[pool_name]
except KeyError:
raise PoolStorageError('Invalid pool name')
try:
volume = pool.volumes[volume_name]
except KeyError:
raise PoolStorageError('Invalid volume name')
# delete from index
del self.paths[volume.path]
del self.storages[pool_name].volumes[volume_name]
# delete volume
try:
volume.lv_volume.delete(0)
except libvirt.libvirtError:
logger.exception('Error while deleting volume')
raise
class Storage(object):
"""Storage abstraction."""
......@@ -436,15 +508,16 @@ class Storage(object):
"""
self.uuid = lv_storage.UUID()
self.name = lv_storage.name()
self.lv_storage = lv_storage
self.state, self.capacity, self.allocation, self.available = lv_storage.info()
self.state = STORAGE_STATES[self.state]
self.volumes = map(
self.volumes = dict((v.name, v) for v in imap(
Volume,
(lv_storage.storageVolLookupByName(n) for n in
lv_storage.listVolumes()),
)
lv_storage.listVolumes()),
))
class Volume(object):
......@@ -457,3 +530,4 @@ class Volume(object):
self.path = lv_volume.path()
self.name = lv_volume.name()
self.capacity, self.allocation = lv_volume.info()[1:]
self.lv_volume = lv_volume
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment