tools/qvm-create: resize root volume if needed before imporing data
If file to be imported is larger than the default root volume, resize the volume first. It might be also a good idea to shrink it when needed, but currently the backend refuse it. Fixes QubesOS/qubes-issues#3422
This commit is contained in:
		
							parent
							
								
									835336d640
								
							
						
					
					
						commit
						045bad13e7
					
				@ -106,6 +106,12 @@ class TC_00_qvm_create(qubesadmin.tests.QubesTestCase):
 | 
				
			|||||||
            self.app.expected_calls[
 | 
					            self.app.expected_calls[
 | 
				
			||||||
                ('new-vm', 'admin.vm.volume.List', None, None)] = \
 | 
					                ('new-vm', 'admin.vm.volume.List', None, None)] = \
 | 
				
			||||||
                b'0\x00root\nprivate\nvolatile\nkernel\n'
 | 
					                b'0\x00root\nprivate\nvolatile\nkernel\n'
 | 
				
			||||||
 | 
					            self.app.expected_calls[
 | 
				
			||||||
 | 
					                ('new-vm', 'admin.vm.volume.Info', 'root', None)] = \
 | 
				
			||||||
 | 
					                b'0\x00' \
 | 
				
			||||||
 | 
					                b'pool=other-pool\n' \
 | 
				
			||||||
 | 
					                b'vid=new-vm-root\n' \
 | 
				
			||||||
 | 
					                b'size=10000000\n'
 | 
				
			||||||
            self.app.expected_calls[
 | 
					            self.app.expected_calls[
 | 
				
			||||||
                ('new-vm', 'admin.vm.volume.Import', 'root', b'root data')] = \
 | 
					                ('new-vm', 'admin.vm.volume.Import', 'root', b'root data')] = \
 | 
				
			||||||
                b'0\0'
 | 
					                b'0\0'
 | 
				
			||||||
@ -128,6 +134,12 @@ class TC_00_qvm_create(qubesadmin.tests.QubesTestCase):
 | 
				
			|||||||
            self.app.expected_calls[
 | 
					            self.app.expected_calls[
 | 
				
			||||||
                ('new-vm', 'admin.vm.volume.List', None, None)] = \
 | 
					                ('new-vm', 'admin.vm.volume.List', None, None)] = \
 | 
				
			||||||
                b'0\x00root\nprivate\nvolatile\nkernel\n'
 | 
					                b'0\x00root\nprivate\nvolatile\nkernel\n'
 | 
				
			||||||
 | 
					            self.app.expected_calls[
 | 
				
			||||||
 | 
					                ('new-vm', 'admin.vm.volume.Info', 'root', None)] = \
 | 
				
			||||||
 | 
					                b'0\x00' \
 | 
				
			||||||
 | 
					                b'pool=other-pool\n' \
 | 
				
			||||||
 | 
					                b'vid=new-vm-root\n' \
 | 
				
			||||||
 | 
					                b'size=20000000\n'
 | 
				
			||||||
            self.app.expected_calls[
 | 
					            self.app.expected_calls[
 | 
				
			||||||
                ('new-vm', 'admin.vm.volume.Import', 'root', b'root data')] = \
 | 
					                ('new-vm', 'admin.vm.volume.Import', 'root', b'root data')] = \
 | 
				
			||||||
                b'0\0'
 | 
					                b'0\0'
 | 
				
			||||||
@ -166,3 +178,35 @@ class TC_00_qvm_create(qubesadmin.tests.QubesTestCase):
 | 
				
			|||||||
            self.assertEqual(stdout.getvalue(),
 | 
					            self.assertEqual(stdout.getvalue(),
 | 
				
			||||||
                'AppVM\nDispVM\nStandaloneVM\nTemplateVM\n')
 | 
					                'AppVM\nDispVM\nStandaloneVM\nTemplateVM\n')
 | 
				
			||||||
        self.assertAllCalled()
 | 
					        self.assertAllCalled()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_010_root_copy_from_with_resize(self):
 | 
				
			||||||
 | 
					        with tempfile.NamedTemporaryFile() as root_file:
 | 
				
			||||||
 | 
					            root_file.file.write(b'root data')
 | 
				
			||||||
 | 
					            root_file.file.flush()
 | 
				
			||||||
 | 
					            self.app.expected_calls[('dom0', 'admin.vm.Create.AppVM',
 | 
				
			||||||
 | 
					                None, b'name=new-vm label=red')] = b'0\x00'
 | 
				
			||||||
 | 
					            self.app.expected_calls[('dom0', 'admin.label.List', None, None)] = \
 | 
				
			||||||
 | 
					                b'0\x00red\nblue\n'
 | 
				
			||||||
 | 
					            self.app.expected_calls[('dom0', 'admin.vm.List', None, None)] = \
 | 
				
			||||||
 | 
					                b'0\x00new-vm class=AppVM state=Halted\n'
 | 
				
			||||||
 | 
					            self.app.expected_calls[
 | 
				
			||||||
 | 
					                ('new-vm', 'admin.vm.volume.List', None, None)] = \
 | 
				
			||||||
 | 
					                b'0\x00root\nprivate\nvolatile\nkernel\n'
 | 
				
			||||||
 | 
					            self.app.expected_calls[
 | 
				
			||||||
 | 
					                ('new-vm', 'admin.vm.volume.Info', 'root', None)] = \
 | 
				
			||||||
 | 
					                b'0\x00' \
 | 
				
			||||||
 | 
					                b'pool=other-pool\n' \
 | 
				
			||||||
 | 
					                b'vid=new-vm-root\n' \
 | 
				
			||||||
 | 
					                b'size=2\n'
 | 
				
			||||||
 | 
					            self.app.expected_calls[
 | 
				
			||||||
 | 
					                ('new-vm', 'admin.vm.volume.Resize', 'root', b'9')] = \
 | 
				
			||||||
 | 
					                b'0\0'
 | 
				
			||||||
 | 
					            self.app.expected_calls[
 | 
				
			||||||
 | 
					                ('new-vm', 'admin.vm.volume.Import', 'root', b'root data')] = \
 | 
				
			||||||
 | 
					                b'0\0'
 | 
				
			||||||
 | 
					            qubesadmin.tools.qvm_create.main(['-l', 'red',
 | 
				
			||||||
 | 
					                '--root-copy-from=' + root_file.name, 'new-vm'],
 | 
				
			||||||
 | 
					                app=self.app)
 | 
				
			||||||
 | 
					            self.assertAllCalled()
 | 
				
			||||||
 | 
					            self.assertTrue(os.path.exists(root_file.name))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -159,6 +159,9 @@ def main(args=None, app=None):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if root_source_path:
 | 
					    if root_source_path:
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
 | 
					            root_size = os.path.getsize(root_source_path)
 | 
				
			||||||
 | 
					            if root_size > vm.volumes['root'].size:
 | 
				
			||||||
 | 
					                vm.volumes['root'].resize(root_size)
 | 
				
			||||||
            with open(root_source_path, 'rb') as root_file:
 | 
					            with open(root_source_path, 'rb') as root_file:
 | 
				
			||||||
                vm.volumes['root'].import_data(root_file)
 | 
					                vm.volumes['root'].import_data(root_file)
 | 
				
			||||||
            if args.root_move_from:
 | 
					            if args.root_move_from:
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user