Skip to content

Commit

Permalink
qvm-template-postprocess: fix installing templates with small rootfs
Browse files Browse the repository at this point in the history
There is already support for importing volume of a specific size, no
need for calling resize manually. This fixes template install on storage
pools that do not support resize (shrinking).

Fixes QubesOS/qubes-issues#7426
  • Loading branch information
marmarek committed Apr 13, 2022
1 parent 008bca5 commit 177f336
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 48 deletions.
40 changes: 6 additions & 34 deletions qubesadmin/tests/tools/qvm_template_postprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,24 +58,10 @@ def test_000_import_root_img_raw(self):
self.app.expected_calls[('test-vm', 'admin.vm.volume.List', None,
None)] = \
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',
str(len(volume_data)).encode())] = \
b'0\0'

self.app.expected_calls[('test-vm', 'admin.vm.volume.Import', 'root',
volume_data)] = b'0\0'
self.app.expected_calls[(
'test-vm', 'admin.vm.volume.ImportWithSize', 'root',
str(len(volume_data)).encode() + b'\n' + volume_data)] = b'0\0'
vm = self.app.domains['test-vm']
qubesadmin.tools.qvm_template_postprocess.import_root_img(
vm, self.source_dir.name)
Expand All @@ -95,27 +81,13 @@ def test_001_import_root_img_tar(self):

self.app.expected_calls[('dom0', 'admin.vm.List', None, None)] = \
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,
None)] = \
b'0\0root\nprivate\nvolatile\nkernel\n'
self.app.expected_calls[('test-vm', 'admin.vm.volume.Resize', 'root',
str(len(volume_data)).encode())] = \
b'0\0'

self.app.expected_calls[('test-vm', 'admin.vm.volume.Import', 'root',
volume_data)] = b'0\0'
self.app.expected_calls[(
'test-vm', 'admin.vm.volume.ImportWithSize', 'root',
str(len(volume_data)).encode() + b'\n' + volume_data)] = b'0\0'
vm = self.app.domains['test-vm']
qubesadmin.tools.qvm_template_postprocess.import_root_img(
vm, self.source_dir.name)
Expand Down
20 changes: 6 additions & 14 deletions qubesadmin/tools/qvm_template_postprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,6 @@ def import_root_img(vm, source_dir):
# volume needs to be extended, do it before import, if reduced - after.

root_size = get_root_img_size(source_dir)
if vm.volumes['root'].size < root_size:
vm.volumes['root'].resize(root_size)

root_path = os.path.join(source_dir, 'root.img')
if os.path.exists(root_path + '.part.00'):
Expand All @@ -106,7 +104,8 @@ def import_root_img(vm, source_dir):
stdin=cat.stdout,
stdout=subprocess.PIPE) as tar:
cat.stdout.close()
vm.volumes['root'].import_data(stream=tar.stdout)
vm.volumes['root'].import_data_with_size(
stream=tar.stdout, size=root_size)
if tar.returncode != 0:
raise qubesadmin.exc.QubesException(
'root.img extraction failed')
Expand All @@ -116,7 +115,8 @@ def import_root_img(vm, source_dir):
elif os.path.exists(root_path + '.tar'):
with subprocess.Popen(['tar', 'xSOf', root_path + '.tar'],
stdout=subprocess.PIPE) as tar:
vm.volumes['root'].import_data(stream=tar.stdout)
vm.volumes['root'].import_data_with_size(
stream=tar.stdout, size=root_size)
if tar.returncode != 0:
raise qubesadmin.exc.QubesException('root.img extraction failed')
elif os.path.exists(root_path):
Expand All @@ -131,16 +131,8 @@ def import_root_img(vm, source_dir):
vm.log.info('root.img already in place, do not re-import')
return
with open(root_path, 'rb') as 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)))
vm.volumes['root'].import_data_with_size(
stream=root_file, size=root_size)


def reset_private_img(vm):
Expand Down

0 comments on commit 177f336

Please sign in to comment.