Merge branch 'template-postprocess-fail'
* template-postprocess-fail: qvm-template-postprocess: do not remove VM on failed reinstall qvm-template-postprocess: resize volume only when needed
This commit is contained in:
commit
efae2dfd38
@ -57,6 +57,18 @@ class TC_00_qvm_template_postprocess(qubesadmin.tests.QubesTestCase):
|
|||||||
self.app.expected_calls[('test-vm', 'admin.vm.volume.List', None,
|
self.app.expected_calls[('test-vm', 'admin.vm.volume.List', None,
|
||||||
None)] = \
|
None)] = \
|
||||||
b'0\0root\nprivate\nvolatile\nkernel\n'
|
b'0\0root\nprivate\nvolatile\nkernel\n'
|
||||||
|
self.app.expected_calls[
|
||||||
|
('test-vm', 'admin.vm.volume.Info', 'root', None)] = \
|
||||||
|
b'0\x00pool=lvm\n' \
|
||||||
|
b'vid=qubes_dom0/vm-test-vm-root\n' \
|
||||||
|
b'size=10737418240\n' \
|
||||||
|
b'usage=0\n' \
|
||||||
|
b'rw=True\n' \
|
||||||
|
b'source=\n' \
|
||||||
|
b'save_on_stop=True\n' \
|
||||||
|
b'snap_on_start=False\n' \
|
||||||
|
b'revisions_to_keep=3\n' \
|
||||||
|
b'is_outdated=False\n'
|
||||||
self.app.expected_calls[('test-vm', 'admin.vm.volume.Resize', 'root',
|
self.app.expected_calls[('test-vm', 'admin.vm.volume.Resize', 'root',
|
||||||
str(len(volume_data)).encode())] = \
|
str(len(volume_data)).encode())] = \
|
||||||
b'0\0'
|
b'0\0'
|
||||||
@ -82,6 +94,18 @@ class TC_00_qvm_template_postprocess(qubesadmin.tests.QubesTestCase):
|
|||||||
|
|
||||||
self.app.expected_calls[('dom0', 'admin.vm.List', None, None)] = \
|
self.app.expected_calls[('dom0', 'admin.vm.List', None, None)] = \
|
||||||
b'0\0test-vm class=TemplateVM state=Halted\n'
|
b'0\0test-vm class=TemplateVM state=Halted\n'
|
||||||
|
self.app.expected_calls[
|
||||||
|
('test-vm', 'admin.vm.volume.Info', 'root', None)] = \
|
||||||
|
b'0\x00pool=lvm\n' \
|
||||||
|
b'vid=qubes_dom0/vm-test-vm-root\n' \
|
||||||
|
b'size=10737418240\n' \
|
||||||
|
b'usage=0\n' \
|
||||||
|
b'rw=True\n' \
|
||||||
|
b'source=\n' \
|
||||||
|
b'save_on_stop=True\n' \
|
||||||
|
b'snap_on_start=False\n' \
|
||||||
|
b'revisions_to_keep=3\n' \
|
||||||
|
b'is_outdated=False\n'
|
||||||
self.app.expected_calls[('test-vm', 'admin.vm.volume.List', None,
|
self.app.expected_calls[('test-vm', 'admin.vm.volume.List', None,
|
||||||
None)] = \
|
None)] = \
|
||||||
b'0\0root\nprivate\nvolatile\nkernel\n'
|
b'0\0root\nprivate\nvolatile\nkernel\n'
|
||||||
@ -114,17 +138,22 @@ class TC_00_qvm_template_postprocess(qubesadmin.tests.QubesTestCase):
|
|||||||
b'0\0root\nprivate\nvolatile\nkernel\n'
|
b'0\0root\nprivate\nvolatile\nkernel\n'
|
||||||
self.app.expected_calls[
|
self.app.expected_calls[
|
||||||
('test-vm', 'admin.vm.volume.Info', 'root', None)] = \
|
('test-vm', 'admin.vm.volume.Info', 'root', None)] = \
|
||||||
b'0\0pool=default\nvid=vm-templates/test-vm/root\n'
|
b'0\x00pool=default\n' \
|
||||||
|
b'vid=vm-templates/test-vm/root\n' \
|
||||||
|
b'size=10737418240\n' \
|
||||||
|
b'usage=0\n' \
|
||||||
|
b'rw=True\n' \
|
||||||
|
b'source=\n' \
|
||||||
|
b'save_on_stop=True\n' \
|
||||||
|
b'snap_on_start=False\n' \
|
||||||
|
b'revisions_to_keep=3\n' \
|
||||||
|
b'is_outdated=False\n'
|
||||||
self.app.expected_calls[
|
self.app.expected_calls[
|
||||||
('dom0', 'admin.pool.List', None, None)] = \
|
('dom0', 'admin.pool.List', None, None)] = \
|
||||||
b'0\0default\n'
|
b'0\0default\n'
|
||||||
self.app.expected_calls[
|
self.app.expected_calls[
|
||||||
('dom0', 'admin.pool.Info', 'default', None)] = \
|
('dom0', 'admin.pool.Info', 'default', None)] = \
|
||||||
b'0\0driver=file\ndir_path=' + self.source_dir.name.encode() + b'\n'
|
b'0\0driver=file\ndir_path=' + self.source_dir.name.encode() + b'\n'
|
||||||
self.app.expected_calls[
|
|
||||||
('test-vm', 'admin.vm.volume.Resize', 'root',
|
|
||||||
str(len(volume_data)).encode())] = \
|
|
||||||
b'0\0'
|
|
||||||
|
|
||||||
vm = self.app.domains['test-vm']
|
vm = self.app.domains['test-vm']
|
||||||
qubesadmin.tools.qvm_template_postprocess.import_root_img(
|
qubesadmin.tools.qvm_template_postprocess.import_root_img(
|
||||||
|
@ -77,8 +77,12 @@ def get_root_img_size(source_dir):
|
|||||||
def import_root_img(vm, source_dir):
|
def import_root_img(vm, source_dir):
|
||||||
'''Import root.img into VM object'''
|
'''Import root.img into VM object'''
|
||||||
|
|
||||||
|
# Try not break existing data in the volume in case of import failure. If
|
||||||
|
# volume needs to be extended, do it before import, if reduced - after.
|
||||||
|
|
||||||
root_size = get_root_img_size(source_dir)
|
root_size = get_root_img_size(source_dir)
|
||||||
vm.volumes['root'].resize(root_size)
|
if vm.volumes['root'].size < root_size:
|
||||||
|
vm.volumes['root'].resize(root_size)
|
||||||
|
|
||||||
root_path = os.path.join(source_dir, 'root.img')
|
root_path = os.path.join(source_dir, 'root.img')
|
||||||
if os.path.exists(root_path + '.part.00'):
|
if os.path.exists(root_path + '.part.00'):
|
||||||
@ -108,6 +112,15 @@ def import_root_img(vm, source_dir):
|
|||||||
with open(root_path, 'rb') as root_file:
|
with open(root_path, 'rb') as root_file:
|
||||||
vm.volumes['root'].import_data(stream=root_file)
|
vm.volumes['root'].import_data(stream=root_file)
|
||||||
|
|
||||||
|
if vm.volumes['root'].size > root_size:
|
||||||
|
try:
|
||||||
|
vm.volumes['root'].resize(root_size)
|
||||||
|
except qubesadmin.exc.QubesException as err:
|
||||||
|
vm.log.warning(
|
||||||
|
'Failed to resize root volume of {} from {} to {} after '
|
||||||
|
'import: {}'.format(vm.name, vm.volumes['root'].size,
|
||||||
|
root_size, str(err)))
|
||||||
|
|
||||||
|
|
||||||
def import_appmenus(vm, source_dir):
|
def import_appmenus(vm, source_dir):
|
||||||
'''Import appmenus settings into VM object (later: GUI VM)'''
|
'''Import appmenus settings into VM object (later: GUI VM)'''
|
||||||
@ -182,6 +195,7 @@ def post_install(args):
|
|||||||
'''Handle post-installation tasks'''
|
'''Handle post-installation tasks'''
|
||||||
|
|
||||||
app = args.app
|
app = args.app
|
||||||
|
vm_created = False
|
||||||
try:
|
try:
|
||||||
# reinstall
|
# reinstall
|
||||||
vm = app.domains[args.name]
|
vm = app.domains[args.name]
|
||||||
@ -198,13 +212,15 @@ def post_install(args):
|
|||||||
vm = app.add_new_vm('TemplateVM',
|
vm = app.add_new_vm('TemplateVM',
|
||||||
name=args.name,
|
name=args.name,
|
||||||
label=qubesadmin.config.defaults['template_label'])
|
label=qubesadmin.config.defaults['template_label'])
|
||||||
|
vm_created = True
|
||||||
|
|
||||||
vm.log.info('Importing data')
|
vm.log.info('Importing data')
|
||||||
try:
|
try:
|
||||||
import_root_img(vm, args.dir)
|
import_root_img(vm, args.dir)
|
||||||
except:
|
except:
|
||||||
# if data import fails, remove half-created VM
|
# if data import fails, remove half-created VM
|
||||||
del app.domains[vm.name]
|
if vm_created:
|
||||||
|
del app.domains[vm.name]
|
||||||
raise
|
raise
|
||||||
vm.installed_by_rpm = True
|
vm.installed_by_rpm = True
|
||||||
import_appmenus(vm, args.dir)
|
import_appmenus(vm, args.dir)
|
||||||
|
Loading…
Reference in New Issue
Block a user