storage.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. # The Qubes OS Project, https://www.qubes-os.org/
  2. #
  3. # Copyright (C) 2015 Bahtiar `kalkin-` Gadimov <bahtiar@gadimov.de>
  4. #
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 2 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License along
  16. # with this program; if not, write to the Free Software Foundation, Inc.,
  17. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18. import os
  19. import shutil
  20. import qubes.storage
  21. from qubes.qubes import defaults
  22. from qubes.storage.xen import XenPool, XenStorage
  23. from qubes.tests import QubesTestCase, SystemTestsMixin
  24. class TC_00_Storage(SystemTestsMixin, QubesTestCase):
  25. """ This class tests the utility methods from :mod:``qubes.storage`` """
  26. def test_000_dump(self):
  27. """ Dumps storage instance to a storage string """
  28. vmname = self.make_vm_name('appvm')
  29. template = self.qc.get_default_template()
  30. vm = self.qc.add_new_vm('QubesAppVm', name=vmname,
  31. pool_name='default', template=template)
  32. storage = vm.storage
  33. result = qubes.storage.dump(storage)
  34. expected = 'qubes.storage.xen.XenStorage'
  35. self.assertEquals(result, expected)
  36. def test_001_load(self):
  37. """ Loads storage driver from a storage string """
  38. result = qubes.storage.load('qubes.storage.xen.XenStorage')
  39. self.assertTrue(result is XenStorage)
  40. def test_002_default_pool_drivers(self):
  41. """ The only predifined pool driver is xen """
  42. result = defaults['pool_drivers'].keys()
  43. expected = ["xen"]
  44. self.assertEquals(result, expected)
  45. def test_003_get_pool_klass(self):
  46. """ Expect the default pool to be `XenPool` """
  47. result = qubes.storage._get_pool_klass('default')
  48. self.assertTrue(result is XenPool)
  49. def test_004_pool_exists_default(self):
  50. """ Expect the default pool to exists """
  51. self.assertTrue(qubes.storage.pool_exists('default'))
  52. def test_005_pool_exists_random(self):
  53. """ Expect this pool to not a exist """
  54. self.assertFalse(
  55. qubes.storage.pool_exists('asdh312096r832598213iudhas'))
  56. def test_006_add_remove_pool(self):
  57. """ Tries to adding and removing a pool. """
  58. pool_name = 'asdjhrp89132'
  59. # make sure it's really does not exist
  60. qubes.storage.remove_pool(pool_name)
  61. qubes.storage.add_pool(pool_name, driver='xen')
  62. self.assertTrue(qubes.storage.pool_exists(pool_name))
  63. qubes.storage.remove_pool(pool_name)
  64. self.assertFalse(qubes.storage.pool_exists(pool_name))
  65. class TC_00_Pool(SystemTestsMixin, QubesTestCase):
  66. """ This class tests some properties of the 'default' pool. """
  67. def test000_default_pool_dir(self):
  68. """ The predefined dir for the default pool should be ``/var/lib/qubes``
  69. .. sealso::
  70. Data :data:``qubes.qubes.defaults['pool_config']``.
  71. """
  72. vm = self._init_app_vm()
  73. result = qubes.storage.get_pool("default", vm).dir_path
  74. expected = '/var/lib/qubes/'
  75. self.assertEquals(result, expected)
  76. def test001_default_storage_class(self):
  77. """ Check when using default pool the Storage is ``XenStorage``. """
  78. result = self._init_app_vm().storage
  79. self.assertIsInstance(result, XenStorage)
  80. def test_002_default_pool_name(self):
  81. """ Default pool_name is 'default'. """
  82. vm = self._init_app_vm()
  83. self.assertEquals(vm.pool_name, "default")
  84. def _init_app_vm(self):
  85. """ Return initalised, but not created, AppVm. """
  86. vmname = self.make_vm_name('appvm')
  87. template = self.qc.get_default_template()
  88. return self.qc.add_new_vm('QubesAppVm', name=vmname, template=template,
  89. pool_name='default')
  90. class TC_01_Pool(SystemTestsMixin, QubesTestCase):
  91. """ Test the paths for the default Xen file based storage (``XenStorage``).
  92. """
  93. POOL_DIR = '/var/lib/qubes/test-pool'
  94. APPVMS_DIR = '/var/lib/qubes/test-pool/appvms'
  95. TEMPLATES_DIR = '/var/lib/qubes/test-pool/vm-templates'
  96. SERVICE_DIR = '/var/lib/qubes/test-pool/servicevms'
  97. def setUp(self):
  98. """ Add a test file based storage pool """
  99. super(TC_01_Pool, self).setUp()
  100. qubes.storage.add_pool('test-pool', driver='xen',
  101. dir_path=self.POOL_DIR)
  102. def tearDown(self):
  103. """ Remove the file based storage pool after testing """
  104. super(TC_01_Pool, self).tearDown()
  105. qubes.storage.remove_pool("test-pool")
  106. shutil.rmtree(self.POOL_DIR, ignore_errors=True)
  107. def test_001_pool_exists(self):
  108. """ Check if the storage pool was added to the storage pool config """
  109. self.assertTrue(qubes.storage.pool_exists('test-pool'))
  110. def test_002_pool_dir_create(self):
  111. """ Check if the storage pool dir and subdirs were created """
  112. # The dir should not exists before
  113. self.assertFalse(os.path.exists(self.POOL_DIR))
  114. vmname = self.make_vm_name('appvm')
  115. template = self.qc.get_default_template()
  116. self.qc.add_new_vm('QubesAppVm', name=vmname, template=template,
  117. pool_name='test-pool')
  118. self.assertTrue(os.path.exists(self.POOL_DIR))
  119. self.assertTrue(os.path.exists(self.APPVMS_DIR))
  120. self.assertTrue(os.path.exists(self.SERVICE_DIR))
  121. self.assertTrue(os.path.exists(self.TEMPLATES_DIR))
  122. def test_003_pool_dir(self):
  123. """ Check if the vm storage pool_dir is the same as specified """
  124. vmname = self.make_vm_name('appvm')
  125. template = self.qc.get_default_template()
  126. vm = self.qc.add_new_vm('QubesAppVm', name=vmname, template=template,
  127. pool_name='test-pool')
  128. result = qubes.storage.get_pool('test-pool', vm).dir_path
  129. self.assertEquals(self.POOL_DIR, result)
  130. def test_004_app_vmdir(self):
  131. """ Check the vm storage dir for an AppVm"""
  132. vmname = self.make_vm_name('appvm')
  133. template = self.qc.get_default_template()
  134. vm = self.qc.add_new_vm('QubesAppVm', name=vmname, template=template,
  135. pool_name='test-pool')
  136. expected = os.path.join(self.APPVMS_DIR, vm.name)
  137. result = vm.storage.vmdir
  138. self.assertEquals(expected, result)
  139. def test_005_hvm_vmdir(self):
  140. """ Check the vm storage dir for a HVM"""
  141. vmname = self.make_vm_name('hvm')
  142. vm = self.qc.add_new_vm('QubesHVm', name=vmname,
  143. pool_name='test-pool')
  144. expected = os.path.join(self.APPVMS_DIR, vm.name)
  145. result = vm.storage.vmdir
  146. self.assertEquals(expected, result)
  147. def test_006_net_vmdir(self):
  148. """ Check the vm storage dir for a Netvm"""
  149. vmname = self.make_vm_name('hvm')
  150. vm = self.qc.add_new_vm('QubesNetVm', name=vmname,
  151. pool_name='test-pool')
  152. expected = os.path.join(self.SERVICE_DIR, vm.name)
  153. result = vm.storage.vmdir
  154. self.assertEquals(expected, result)
  155. def test_007_proxy_vmdir(self):
  156. """ Check the vm storage dir for a ProxyVm"""
  157. vmname = self.make_vm_name('proxyvm')
  158. vm = self.qc.add_new_vm('QubesProxyVm', name=vmname,
  159. pool_name='test-pool')
  160. expected = os.path.join(self.SERVICE_DIR, vm.name)
  161. result = vm.storage.vmdir
  162. self.assertEquals(expected, result)
  163. def test_008_admin_vmdir(self):
  164. """ Check the vm storage dir for a AdminVm"""
  165. # TODO How to test AdminVm?
  166. pass
  167. def test_009_template_vmdir(self):
  168. """ Check the vm storage dir for a TemplateVm"""
  169. vmname = self.make_vm_name('templatevm')
  170. vm = self.qc.add_new_vm('QubesTemplateVm', name=vmname,
  171. pool_name='test-pool')
  172. expected = os.path.join(self.TEMPLATES_DIR, vm.name)
  173. result = vm.storage.vmdir
  174. self.assertEquals(expected, result)
  175. def test_010_template_hvm_vmdir(self):
  176. """ Check the vm storage dir for a TemplateHVm"""
  177. vmname = self.make_vm_name('templatehvm')
  178. vm = self.qc.add_new_vm('QubesTemplateHVm', name=vmname,
  179. pool_name='test-pool')
  180. expected = os.path.join(self.TEMPLATES_DIR, vm.name)
  181. result = vm.storage.vmdir
  182. self.assertEquals(expected, result)
  183. def test_011_appvm_file_images(self):
  184. """ Check if all the needed image files are created for an AppVm"""
  185. vmname = self.make_vm_name('appvm')
  186. template = self.qc.get_default_template()
  187. vm = self.qc.add_new_vm('QubesAppVm', name=vmname, template=template,
  188. pool_name='test-pool')
  189. vm.create_on_disk(verbose=False)
  190. expected_vmdir = os.path.join(self.APPVMS_DIR, vm.name)
  191. self.assertEqualsAndExists(vm.storage.vmdir, expected_vmdir)
  192. expected_private_path = os.path.join(expected_vmdir, 'private.img')
  193. self.assertEqualsAndExists(vm.storage.private_img,
  194. expected_private_path)
  195. expected_volatile_path = os.path.join(expected_vmdir, 'volatile.img')
  196. self.assertEqualsAndExists(vm.storage.volatile_img,
  197. expected_volatile_path)
  198. def test_012_hvm_file_images(self):
  199. """ Check if all the needed image files are created for a HVm"""
  200. vmname = self.make_vm_name('hvm')
  201. vm = self.qc.add_new_vm('QubesHVm', name=vmname,
  202. pool_name='test-pool')
  203. vm.create_on_disk(verbose=False)
  204. expected_vmdir = os.path.join(self.APPVMS_DIR, vm.name)
  205. self.assertEqualsAndExists(vm.storage.vmdir, expected_vmdir)
  206. expected_private_path = os.path.join(expected_vmdir, 'private.img')
  207. self.assertEqualsAndExists(vm.storage.private_img,
  208. expected_private_path)
  209. expected_root_path = os.path.join(expected_vmdir, 'root.img')
  210. self.assertEqualsAndExists(vm.storage.root_img, expected_root_path)
  211. expected_volatile_path = os.path.join(expected_vmdir, 'volatile.img')
  212. self.assertEqualsAndExists(vm.storage.volatile_img,
  213. expected_volatile_path)
  214. def assertEqualsAndExists(self, result_path, expected_path):
  215. """ Check if the ``result_path``, matches ``expected_path`` and exists.
  216. See also: :meth:``assertExist``
  217. """
  218. self.assertEquals(result_path, expected_path)
  219. self.assertExist(result_path)
  220. def assertExist(self, path):
  221. """ Assert that the given path exists. """
  222. self.assertTrue(os.path.exists(path))