Storage move rename() logic to XenPool

- Fix config renaming
This commit is contained in:
Bahtiar `kalkin-` Gadimov 2016-04-15 17:11:42 +02:00
parent e3ae6cdc1b
commit 49b4951389
3 changed files with 86 additions and 25 deletions

View File

@ -56,7 +56,11 @@ class Volume(object):
script = None script = None
usage = 0 usage = 0
def __init__(self, name=None, pool=None, volume_type=None, vid=None, def __init__(self,
name=None,
pool=None,
volume_type=None,
vid=None,
size=0): size=0):
assert name and pool and volume_type assert name and pool and volume_type
self.name = str(name) self.name = str(name)
@ -167,23 +171,12 @@ class Storage(object):
volume) volume)
self.vm.volumes[name] = volume self.vm.volumes[name] = volume
# TODO migrate this def rename(self, old_name, new_name):
@staticmethod ''' Notify the pools that the domain was renamed '''
def rename(newpath, oldpath): volumes = self.vm.volumes
'''Move storage directory, most likely during domain's rename. for name, volume in volumes.items():
pool = self.get_pool(volume)
.. note:: volumes[name] = pool.rename(volume, old_name, new_name)
The arguments are in different order than in :program:`cp` utility.
.. versionchange:: 4.0
This is now dummy method that just passes everything to
:py:func:`os.rename`.
:param str newpath: New path
:param str oldpath: Old path
'''
os.rename(oldpath, newpath)
def verify_files(self): def verify_files(self):
'''Verify that the storage is sane. '''Verify that the storage is sane.
@ -271,6 +264,11 @@ class Pool(object):
raise NotImplementedError("Pool %s has remove() not implemented" % raise NotImplementedError("Pool %s has remove() not implemented" %
self.name) self.name)
def rename(self, volume, old_name, new_name):
''' Called when the domain changes its name '''
raise NotImplementedError("Pool %s has rename() not implemented" %
self.name)
def start(self, volume): def start(self, volume):
''' Do what ever is needed on start ''' ''' Do what ever is needed on start '''
raise NotImplementedError("Pool %s has start() not implemented" % raise NotImplementedError("Pool %s has start() not implemented" %

View File

@ -114,6 +114,23 @@ class XenPool(Pool):
_remove_if_exists(volume.vid) _remove_if_exists(volume.vid)
_remove_if_exists(volume.path_cow) _remove_if_exists(volume.path_cow)
def rename(self, volume, old_name, new_name):
assert issubclass(volume.__class__, XenVolume)
old_dir = os.path.dirname(volume.path)
new_dir = os.path.join(os.path.dirname(old_dir), new_name)
if not os.path.exists(new_dir):
os.makedirs(new_dir)
if volume.volume_type == 'read-write':
volume.rename_target_dir(new_name, new_dir)
elif volume.volume_type == 'read-only':
volume.rename_target_dir(old_name, new_dir)
elif volume.volume_type in ['origin', 'volatile']:
volume.rename_target_dir(new_dir)
return volume
def _resize_loop_device(self, path): def _resize_loop_device(self, path):
# find loop device if any # find loop device if any
p = subprocess.Popen( p = subprocess.Popen(
@ -275,6 +292,17 @@ class ReadWriteFile(SizeMixIn):
self.path = os.path.join(self.target_dir, self.name + '.img') self.path = os.path.join(self.target_dir, self.name + '.img')
self.vid = self.path self.vid = self.path
def rename_target_dir(self, new_name, new_dir):
# :pylint: disable=unused-argument
old_path = self.path
file_name = os.path.basename(self.path)
new_path = os.path.join(new_dir, file_name)
os.rename(old_path, new_path)
self.target_dir = new_dir
self.path = new_path
self.vid = self.path
class ReadOnlyFile(XenVolume): class ReadOnlyFile(XenVolume):
# :pylint: disable=missing-docstring # :pylint: disable=missing-docstring
@ -285,6 +313,20 @@ class ReadOnlyFile(XenVolume):
super(ReadOnlyFile, self).__init__(size=int(size), **kwargs) super(ReadOnlyFile, self).__init__(size=int(size), **kwargs)
self.path = self.vid self.path = self.vid
def rename_target_dir(self, old_name, new_dir):
# only copy the read-only volume if it's "owned" by the current vm
# "owned" means that it's in a directory named the same as the vm
if os.path.basename(self.target_dir) == old_name:
file_name = os.path.basename(self.path)
new_path = os.path.join(new_dir, file_name)
old_path = self.path
os.rename(old_path, new_path)
self.target_dir = new_dir
self.path = new_path
self.vid = self.path
class OriginFile(SizeMixIn): class OriginFile(SizeMixIn):
# :pylint: disable=missing-docstring # :pylint: disable=missing-docstring
@ -300,6 +342,19 @@ class OriginFile(SizeMixIn):
def commit(self): def commit(self):
raise NotImplementedError raise NotImplementedError
def rename_target_dir(self, new_dir):
old_path_origin = self.path_origin
old_path_cow = self.path_cow
new_path_origin = os.path.join(new_dir, self.name + '.img')
new_path_cow = os.path.join(new_dir, self.name + '-cow.img')
os.rename(old_path_origin, new_path_origin)
os.rename(old_path_cow, new_path_cow)
self.target_dir = new_dir
self.path_origin = new_path_origin
self.path_cow = new_path_cow
self.path = '%s:%s' % (self.path_origin, self.path_cow)
self.vid = self.path_origin
@property @property
def usage(self): def usage(self):
result = 0 result = 0
@ -335,7 +390,15 @@ class VolatileFile(SizeMixIn):
def __init__(self, **kwargs): def __init__(self, **kwargs):
super(VolatileFile, self).__init__(**kwargs) super(VolatileFile, self).__init__(**kwargs)
self.path = os.path.join(self.target_dir, 'volatile.img') self.path = os.path.join(self.target_dir, self.name + '.img')
self.vid = self.path
def rename_target_dir(self, new_dir):
_remove_if_exists(self)
file_name = os.path.basename(self.path)
self.target_dir = new_dir
new_path = os.path.join(new_dir, file_name)
self.path = new_path
self.vid = self.path self.vid = self.path

View File

@ -566,18 +566,18 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
self._qdb_connection.close() self._qdb_connection.close()
self._qdb_connection = None self._qdb_connection = None
self.storage.rename( self.storage.rename(old_name, new_name)
os.path.join(qubes.config.system_path['qubes_base_dir'],
self.dir_path_prefix, new_name), prefix = os.path.join(qubes.config.system_path['qubes_base_dir'], self.dir_path_prefix)
os.path.join(qubes.config.system_path['qubes_base_dir'], old_config = os.path.join(prefix, old_name, old_name + '.conf')
self.dir_path_prefix, old_name)) new_config = os.path.join(prefix, new_name, new_name + '.conf')
os.rename(old_config, new_config)
self._update_libvirt_domain() self._update_libvirt_domain()
if self.autostart: if self.autostart:
self.autostart = self.autostart self.autostart = self.autostart
@qubes.events.handler('property-pre-set:autostart') @qubes.events.handler('property-pre-set:autostart')
def on_property_pre_set_autostart(self, event, prop, name, value, def on_property_pre_set_autostart(self, event, prop, name, value,
oldvalue=None): oldvalue=None):