Skip to content

Commit

Permalink
api/admin: remove admin.vm.Clone operation
Browse files Browse the repository at this point in the history
The same can be achieved with Create+volume.Clone

QubesOS/qubes-issues#2622
  • Loading branch information
marmarek committed Jun 26, 2017
1 parent fabd811 commit 3dcd29a
Show file tree
Hide file tree
Showing 3 changed files with 0 additions and 101 deletions.
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ ADMIN_API_METHODS_SIMPLE = \
admin.property.List \
admin.property.Reset \
admin.property.Set \
admin.vm.Clone \
admin.vm.Create.AppVM \
admin.vm.Create.DispVM \
admin.vm.Create.StandaloneVM \
Expand Down
34 changes: 0 additions & 34 deletions qubes/api/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -829,40 +829,6 @@ def vm_remove(self):

self.app.save()

@qubes.api.method('admin.vm.Clone')
@asyncio.coroutine
def vm_clone(self, untrusted_payload):
assert not self.arg

assert untrusted_payload.startswith(b'name=')
untrusted_name = untrusted_payload[5:].decode('ascii')
qubes.vm.validate_name(None, None, untrusted_name)
new_name = untrusted_name

del untrusted_payload

if new_name in self.app.domains:
raise qubes.exc.QubesValueError('Already exists')

self.fire_event_for_permission(new_name=new_name)

src_vm = self.dest

dst_vm = self.app.add_new_vm(src_vm.__class__, name=new_name)
try:
dst_vm.clone_properties(src_vm)
dst_vm.tags.update(src_vm.tags)
dst_vm.features.update(src_vm.features)
#dst_vm.firewall.clone(src_vm.firewall)
for devclass in src_vm.devices:
for device_assignment in src_vm.devices[devclass].assignments():
dst_vm.devices[devclass].attach(device_assignment.clone())
yield from dst_vm.clone_disk_files(src_vm)
except:
del self.app.domains[dst_vm]
raise
self.app.save()

@qubes.api.method('admin.vm.device.{endpoint}.Available', endpoints=(ep.name
for ep in pkg_resources.iter_entry_points('qubes.devices')),
no_payload=True)
Expand Down
66 changes: 0 additions & 66 deletions qubes/tests/api_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -1236,72 +1236,6 @@ def test_346_vm_create_in_pool_duplicate_pool(self, storage_mock):
self.assertNotIn('test-vm2', self.app.domains)
self.assertFalse(self.app.save.called)

@unittest.mock.patch('qubes.storage.Storage.clone')
@unittest.mock.patch('qubes.storage.Storage.verify')
def test_350_vm_clone(self, mock_verify, mock_clone):
mock_clone.side_effect = self.dummy_coro
mock_verify.side_effect = self.dummy_coro
self.call_mgmt_func(b'admin.vm.Clone',
b'test-vm1', b'', b'name=test-vm2')

self.assertIn('test-vm2', self.app.domains)
vm = self.app.domains['test-vm2']
self.assertEqual(vm.label, self.app.get_label('red'))
self.assertEqual(vm.template, self.app.domains['test-template'])
self.assertEqual(vm.tags, self.vm.tags)
self.assertEqual(vm.features, self.vm.features)
#self.assertEqual(vm.firewall, self.vm.firewall)
self.assertEqual(mock_clone.mock_calls,
[unittest.mock.call(self.app.domains['test-vm2']).clone(
self.app.domains['test-vm1'])])
self.assertTrue(os.path.exists(os.path.join(
self.test_base_dir, 'appvms', 'test-vm2')))

self.assertTrue(self.app.save.called)

@unittest.mock.patch('qubes.storage.Storage.clone')
@unittest.mock.patch('qubes.storage.Storage.verify')
def test_351_vm_clone_extra_params(self, mock_verify, mock_clone):
mock_clone.side_effect = self.dummy_coro
mock_verify.side_effect = self.dummy_coro
with self.assertRaises(qubes.exc.QubesException):
self.call_mgmt_func(b'admin.vm.Clone',
b'test-vm1', b'', b'name=test-vm2 label=red')

self.assertNotIn('test-vm2', self.app.domains)
self.assertEqual(mock_clone.mock_calls, [])
self.assertFalse(os.path.exists(os.path.join(
self.test_base_dir, 'appvms', 'test-vm2')))

self.assertFalse(self.app.save.called)

@unittest.mock.patch('qubes.storage.Storage.clone')
@unittest.mock.patch('qubes.storage.Storage.verify')
def test_352_vm_clone_duplicate_name(self, mock_verify, mock_clone):
mock_clone.side_effect = self.dummy_coro
mock_verify.side_effect = self.dummy_coro
with self.assertRaises(qubes.exc.QubesException):
self.call_mgmt_func(b'admin.vm.Clone',
b'test-vm1', b'', b'name=test-vm1')

self.assertFalse(self.app.save.called)

@unittest.mock.patch('qubes.storage.Storage.clone')
@unittest.mock.patch('qubes.storage.Storage.verify')
def test_353_vm_clone_invalid_name(self, mock_verify, mock_clone):
mock_clone.side_effect = self.dummy_coro
mock_verify.side_effect = self.dummy_coro
with self.assertRaises(qubes.exc.QubesException):
self.call_mgmt_func(b'admin.vm.Clone',
b'test-vm1', b'', b'name=test-vm2/..')

self.assertNotIn('test-vm2/..', self.app.domains)
self.assertEqual(mock_clone.mock_calls, [])
self.assertFalse(os.path.exists(os.path.join(
self.test_base_dir, 'appvms', 'test-vm2/..')))

self.assertFalse(self.app.save.called)


def test_400_property_list(self):
# actual function tested for admin.vm.property.* already
Expand Down

0 comments on commit 3dcd29a

Please sign in to comment.