backupdispvm.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. #
  2. # The Qubes OS Project, https://www.qubes-os.org/
  3. #
  4. # Copyright (C) 2019
  5. # Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
  6. #
  7. # This library is free software; you can redistribute it and/or
  8. # modify it under the terms of the GNU Lesser General Public
  9. # License as published by the Free Software Foundation; either
  10. # version 2.1 of the License, or (at your option) any later version.
  11. #
  12. # This library is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. # Lesser General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU Lesser General Public
  18. # License along with this library; if not, see <https://www.gnu.org/licenses/>.
  19. #
  20. import hashlib
  21. import logging
  22. import multiprocessing
  23. import os
  24. import shutil
  25. import sys
  26. import asyncio
  27. import tempfile
  28. import unittest.mock
  29. import qubes
  30. import qubes.backup
  31. import qubes.storage.lvm
  32. import qubes.tests
  33. import qubes.tests.integ.backup
  34. import qubes.tests.storage_lvm
  35. import qubes.vm
  36. import qubes.vm.appvm
  37. import qubes.vm.templatevm
  38. import qubes.vm.qubesvm
  39. try:
  40. import qubesadmin.exc
  41. from qubesadmin.backup.dispvm import RestoreInDisposableVM
  42. restore_available = True
  43. except ImportError:
  44. restore_available = False
  45. class TC_00_RestoreInDispVM(qubes.tests.integ.backup.BackupTestsMixin):
  46. def setUp(self):
  47. if not restore_available:
  48. self.skipTest('qubesadmin module not installed')
  49. super(TC_00_RestoreInDispVM, self).setUp()
  50. self.mgmt_vm = self.app.add_new_vm(
  51. qubes.vm.appvm.AppVM,
  52. label='red',
  53. name=self.make_vm_name('mgmtvm'),
  54. template=self.template
  55. )
  56. self.loop.run_until_complete(self.mgmt_vm.create_on_disk())
  57. self.mgmt_vm.template_for_dispvms = True
  58. self.app.management_dispvm = self.mgmt_vm
  59. self.backupvm = self.app.add_new_vm(
  60. qubes.vm.appvm.AppVM,
  61. label='red',
  62. name=self.make_vm_name('backupvm'),
  63. template=self.template
  64. )
  65. self.loop.run_until_complete(self.backupvm.create_on_disk())
  66. def restore_backup(self, source=None, appvm=None, options=None,
  67. expect_errors=None, manipulate_restore_info=None,
  68. passphrase='qubes'):
  69. args = unittest.mock.Mock(spec=['app', 'appvm', 'backup_location', 'vms'])
  70. args.app = qubesadmin.Qubes()
  71. args.appvm = appvm
  72. args.backup_location = source
  73. # XXX FIXME
  74. args.app.blind_mode = True
  75. args.vms = []
  76. args.auto_close = True
  77. with tempfile.NamedTemporaryFile() as pass_file:
  78. pass_file.file.write(passphrase.encode())
  79. pass_file.file.flush()
  80. args.pass_file = pass_file.name
  81. restore_in_dispvm = RestoreInDisposableVM(args.app, args)
  82. try:
  83. backup_log = self.loop.run_until_complete(
  84. self.loop.run_in_executor(None, restore_in_dispvm.run))
  85. except qubesadmin.exc.BackupRestoreError as e:
  86. self.fail(str(e) + ' backup log: ' + e.backup_log.decode())
  87. self.app.log.debug(backup_log.decode())
  88. def test_000_basic_backup(self):
  89. self.loop.run_until_complete(self.backupvm.start())
  90. self.loop.run_until_complete(self.backupvm.run_for_stdio(
  91. "mkdir '/var/tmp/backup directory'"))
  92. vms = self.create_backup_vms()
  93. try:
  94. orig_hashes = self.vm_checksum(vms)
  95. vms_info = self.get_vms_info(vms)
  96. self.make_backup(vms,
  97. target='/var/tmp/backup directory',
  98. target_vm=self.backupvm)
  99. self.remove_vms(reversed(vms))
  100. finally:
  101. del vms
  102. (backup_path, _) = self.loop.run_until_complete(
  103. self.backupvm.run_for_stdio("ls /var/tmp/backup*/qubes-backup*"))
  104. backup_path = backup_path.decode().strip()
  105. self.restore_backup(source=backup_path,
  106. appvm=self.backupvm.name)
  107. self.assertCorrectlyRestored(vms_info, orig_hashes)
  108. def create_testcases_for_templates():
  109. return qubes.tests.create_testcases_for_templates('TC_10_RestoreInDispVM',
  110. TC_00_RestoreInDispVM, qubes.tests.SystemTestCase,
  111. module=sys.modules[__name__])
  112. def load_tests(loader, tests, pattern):
  113. tests.addTests(loader.loadTestsFromNames(
  114. create_testcases_for_templates()))
  115. return tests
  116. qubes.tests.maybe_create_testcases_on_import(create_testcases_for_templates)