Merge branch 'devel-storage-fixes'
* devel-storage-fixes: storage/file: use proper exception instead of assert storage/file: import data into temporary volume storage/lvm: check for LVM LV existence and type when creating ThinPool storage/lvm: fix size reporting just after creating LV
This commit is contained in:
commit
6469705196
@ -267,17 +267,29 @@ class FileVolume(qubes.storage.Volume):
|
|||||||
return self.path
|
return self.path
|
||||||
|
|
||||||
def import_volume(self, src_volume):
|
def import_volume(self, src_volume):
|
||||||
msg = "Can not import snapshot volume {!s} in to pool {!s} "
|
if src_volume.snap_on_start:
|
||||||
msg = msg.format(src_volume, self)
|
raise qubes.storage.StoragePoolException(
|
||||||
assert not src_volume.snap_on_start, msg
|
"Can not import snapshot volume {!s} in to pool {!s} ".format(
|
||||||
|
src_volume, self))
|
||||||
if self.save_on_stop:
|
if self.save_on_stop:
|
||||||
_remove_if_exists(self.path)
|
_remove_if_exists(self.path)
|
||||||
copy_file(src_volume.export(), self.path)
|
copy_file(src_volume.export(), self.path)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
def import_data(self):
|
def import_data(self):
|
||||||
return self.path
|
if not self.save_on_stop:
|
||||||
|
raise qubes.storage.StoragePoolException(
|
||||||
|
"Can not import into save_on_stop=False volume {!s}".format(
|
||||||
|
self))
|
||||||
|
create_sparse_file(self.path_import, self.size)
|
||||||
|
return self.path_import
|
||||||
|
|
||||||
|
def import_data_end(self, success):
|
||||||
|
if success:
|
||||||
|
os.rename(self.path_import, self.path)
|
||||||
|
else:
|
||||||
|
os.unlink(self.path_import)
|
||||||
|
return self
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
''' Remove and recreate a volatile volume '''
|
''' Remove and recreate a volatile volume '''
|
||||||
@ -327,6 +339,11 @@ class FileVolume(qubes.storage.Volume):
|
|||||||
img_name = self.vid + '-cow.img'
|
img_name = self.vid + '-cow.img'
|
||||||
return os.path.join(self.dir_path, img_name)
|
return os.path.join(self.dir_path, img_name)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def path_import(self):
|
||||||
|
img_name = self.vid + '-import.img'
|
||||||
|
return os.path.join(self.dir_path, img_name)
|
||||||
|
|
||||||
def verify(self):
|
def verify(self):
|
||||||
''' Verifies the volume. '''
|
''' Verifies the volume. '''
|
||||||
if not os.path.exists(self.path) and \
|
if not os.path.exists(self.path) and \
|
||||||
|
@ -99,7 +99,15 @@ class ThinPool(qubes.storage.Pool):
|
|||||||
return volume
|
return volume
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
pass # TODO Should we create a non existing pool?
|
reset_cache()
|
||||||
|
cache_key = self.volume_group + '/' + self.thin_pool
|
||||||
|
if cache_key not in size_cache:
|
||||||
|
raise qubes.storage.StoragePoolException(
|
||||||
|
'Thin pool {} does not exist'.format(cache_key))
|
||||||
|
if size_cache[cache_key]['attr'][0] != 't':
|
||||||
|
raise qubes.storage.StoragePoolException(
|
||||||
|
'Volume {} is not a thin pool'.format(cache_key))
|
||||||
|
# TODO Should we create a non existing pool?
|
||||||
|
|
||||||
def get_volume(self, vid):
|
def get_volume(self, vid):
|
||||||
''' Return a volume with given vid'''
|
''' Return a volume with given vid'''
|
||||||
|
@ -1645,7 +1645,7 @@ class TC_00_VMs(AdminAPITestCase):
|
|||||||
value = self.call_mgmt_func(b'admin.vm.volume.Import', b'test-vm1',
|
value = self.call_mgmt_func(b'admin.vm.volume.Import', b'test-vm1',
|
||||||
b'private')
|
b'private')
|
||||||
self.assertEqual(value, '{} {}'.format(
|
self.assertEqual(value, '{} {}'.format(
|
||||||
2*2**30, '/tmp/qubes-test-dir/appvms/test-vm1/private.img'))
|
2*2**30, '/tmp/qubes-test-dir/appvms/test-vm1/private-import.img'))
|
||||||
self.assertFalse(self.app.save.called)
|
self.assertFalse(self.app.save.called)
|
||||||
|
|
||||||
def test_511_vm_volume_import_running(self):
|
def test_511_vm_volume_import_running(self):
|
||||||
|
@ -312,6 +312,48 @@ class TC_01_FileVolumes(qubes.tests.QubesTestCase):
|
|||||||
volume.revisions_to_keep = 2
|
volume.revisions_to_keep = 2
|
||||||
self.assertEqual(volume.revisions_to_keep, 1)
|
self.assertEqual(volume.revisions_to_keep, 1)
|
||||||
|
|
||||||
|
def test_020_import_data(self):
|
||||||
|
config = {
|
||||||
|
'name': 'root',
|
||||||
|
'pool': self.POOL_NAME,
|
||||||
|
'save_on_stop': True,
|
||||||
|
'rw': True,
|
||||||
|
'size': 1024 * 1024,
|
||||||
|
}
|
||||||
|
vm = qubes.tests.storage.TestVM(self)
|
||||||
|
volume = self.app.get_pool(self.POOL_NAME).init_volume(vm, config)
|
||||||
|
volume.create()
|
||||||
|
import_path = volume.import_data()
|
||||||
|
self.assertNotEqual(volume.path, import_path)
|
||||||
|
with open(import_path, 'w+') as import_file:
|
||||||
|
import_file.write('test')
|
||||||
|
volume.import_data_end(True)
|
||||||
|
self.assertFalse(os.path.exists(import_path), import_path)
|
||||||
|
with open(volume.path) as volume_file:
|
||||||
|
volume_data = volume_file.read().strip('\0')
|
||||||
|
self.assertEqual(volume_data, 'test')
|
||||||
|
|
||||||
|
def test_021_import_data_fail(self):
|
||||||
|
config = {
|
||||||
|
'name': 'root',
|
||||||
|
'pool': self.POOL_NAME,
|
||||||
|
'save_on_stop': True,
|
||||||
|
'rw': True,
|
||||||
|
'size': 1024 * 1024,
|
||||||
|
}
|
||||||
|
vm = qubes.tests.storage.TestVM(self)
|
||||||
|
volume = self.app.get_pool(self.POOL_NAME).init_volume(vm, config)
|
||||||
|
volume.create()
|
||||||
|
import_path = volume.import_data()
|
||||||
|
self.assertNotEqual(volume.path, import_path)
|
||||||
|
with open(import_path, 'w+') as import_file:
|
||||||
|
import_file.write('test')
|
||||||
|
volume.import_data_end(False)
|
||||||
|
self.assertFalse(os.path.exists(import_path), import_path)
|
||||||
|
with open(volume.path) as volume_file:
|
||||||
|
volume_data = volume_file.read().strip('\0')
|
||||||
|
self.assertNotEqual(volume_data, 'test')
|
||||||
|
|
||||||
def assertVolumePath(self, vm, dev_name, expected, rw=True):
|
def assertVolumePath(self, vm, dev_name, expected, rw=True):
|
||||||
# :pylint: disable=invalid-name
|
# :pylint: disable=invalid-name
|
||||||
volumes = vm.volumes
|
volumes = vm.volumes
|
||||||
|
Loading…
Reference in New Issue
Block a user