Adds docs for clone ignore_errors, feeds linter

Addresses review comments, specifically:

  * updates qvm-clone tests to handle ignore_errors option
  * adds manpage reference to new --ignore-errors option
  * trims line length in qvm-clone changes

All tests should now be passing, including the new qvm-clone
functionality.
This commit is contained in:
Conor Schaefer 2019-04-16 09:25:36 -07:00
parent 55a22e7955
commit 40eeddbfc8
No known key found for this signature in database
GPG Key ID: 6FB4762D12E4CDFB
3 changed files with 27 additions and 6 deletions

View File

@ -38,6 +38,11 @@ Options
Specify the pool to use for the specific volume Specify the pool to use for the specific volume
.. option:: --ignore-errors
Log errors encountered when creating metadata, but continue with clone
operation. Useful if qvm-appmenus call fails from an AdminVM during clone.
.. option:: --quiet, -q .. option:: --quiet, -q
Be quiet Be quiet

View File

@ -31,7 +31,7 @@ class TC_00_qvm_clone(qubesadmin.tests.QubesTestCase):
b'test-vm class=AppVM state=Halted\n' b'test-vm class=AppVM state=Halted\n'
qubesadmin.tools.qvm_clone.main(['test-vm', 'new-vm'], app=self.app) qubesadmin.tools.qvm_clone.main(['test-vm', 'new-vm'], app=self.app)
self.app.clone_vm.assert_called_with(self.app.domains['test-vm'], self.app.clone_vm.assert_called_with(self.app.domains['test-vm'],
'new-vm', new_cls=None, pool=None, pools={}) 'new-vm', new_cls=None, pool=None, pools={}, ignore_errors=False)
self.assertAllCalled() self.assertAllCalled()
def test_001_missing_vm(self): def test_001_missing_vm(self):
@ -43,6 +43,19 @@ class TC_00_qvm_clone(qubesadmin.tests.QubesTestCase):
self.assertFalse(self.app.clone_vm.called) self.assertFalse(self.app.clone_vm.called)
self.assertAllCalled() self.assertAllCalled()
def test_002_ignore_errors(self):
self.app.clone_vm = mock.Mock()
self.app.expected_calls[('dom0', 'admin.vm.List', None, None)] = \
b'0\x00new-vm class=AppVM state=Halted\n' \
b'test-vm class=AppVM state=Halted\n'
test_args = ['test-vm', 'new-vm', '--ignore-errors']
qubesadmin.tools.qvm_clone.main(test_args, app=self.app)
self.app.clone_vm.assert_called_with(self.app.domains['test-vm'],
'new-vm', new_cls=None, pool=None, pools={},
ignore_errors=True)
self.assertAllCalled()
def test_004_pool(self): def test_004_pool(self):
self.app.clone_vm = mock.Mock() self.app.clone_vm = mock.Mock()
self.app.expected_calls[('dom0', 'admin.vm.List', None, None)] = \ self.app.expected_calls[('dom0', 'admin.vm.List', None, None)] = \
@ -51,7 +64,7 @@ class TC_00_qvm_clone(qubesadmin.tests.QubesTestCase):
qubesadmin.tools.qvm_clone.main(['-P', 'some-pool', 'test-vm', 'new-vm'], qubesadmin.tools.qvm_clone.main(['-P', 'some-pool', 'test-vm', 'new-vm'],
app=self.app) app=self.app)
self.app.clone_vm.assert_called_with(self.app.domains['test-vm'], self.app.clone_vm.assert_called_with(self.app.domains['test-vm'],
'new-vm', new_cls=None, pool='some-pool', pools={}) 'new-vm', new_cls=None, pool='some-pool', pools={}, ignore_errors=False)
self.assertAllCalled() self.assertAllCalled()
def test_005_pools(self): def test_005_pools(self):
@ -64,7 +77,7 @@ class TC_00_qvm_clone(qubesadmin.tests.QubesTestCase):
app=self.app) app=self.app)
self.app.clone_vm.assert_called_with(self.app.domains['test-vm'], self.app.clone_vm.assert_called_with(self.app.domains['test-vm'],
'new-vm', new_cls=None, pool=None, pools={'private': 'some-pool', 'new-vm', new_cls=None, pool=None, pools={'private': 'some-pool',
'volatile': 'other-pool'}) 'volatile': 'other-pool'}, ignore_errors=False)
self.assertAllCalled() self.assertAllCalled()
def test_006_new_cls(self): def test_006_new_cls(self):
@ -76,5 +89,6 @@ class TC_00_qvm_clone(qubesadmin.tests.QubesTestCase):
'test-vm', 'new-vm'], 'test-vm', 'new-vm'],
app=self.app) app=self.app)
self.app.clone_vm.assert_called_with(self.app.domains['test-vm'], self.app.clone_vm.assert_called_with(self.app.domains['test-vm'],
'new-vm', new_cls='StandaloneVM', pool=None, pools={}) 'new-vm', new_cls='StandaloneVM', pool=None, pools={},
ignore_errors=False)
self.assertAllCalled() self.assertAllCalled()

View File

@ -39,7 +39,8 @@ parser.add_argument('--class', '-C', dest='cls',
parser.add_argument('--ignore-errors', action='store_true', parser.add_argument('--ignore-errors', action='store_true',
default=False, default=False,
help='log errors encountered during setting metadata, but continue clone operation') help='log errors encountered during setting metadata'
'but continue clone operation')
group = parser.add_mutually_exclusive_group() group = parser.add_mutually_exclusive_group()
group.add_argument('-P', group.add_argument('-P',
@ -76,7 +77,8 @@ def main(args=None, app=None):
'Pool argument must be of form: -P volume_name=pool_name') 'Pool argument must be of form: -P volume_name=pool_name')
try: try:
app.clone_vm(src_vm, new_name, new_cls=args.cls, pool=pool, pools=pools, ignore_errors=args.ignore_errors) app.clone_vm(src_vm, new_name, new_cls=args.cls, pool=pool, pools=pools,
ignore_errors=args.ignore_errors)
except qubesadmin.exc.QubesException as e: except qubesadmin.exc.QubesException as e:
parser.error_runtime(e) parser.error_runtime(e)