backupcompatibility.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. #
  4. # The Qubes OS Project, http://www.qubes-os.org
  5. #
  6. # Copyright (C) 2014 Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
  7. #
  8. # This program is free software; you can redistribute it and/or
  9. # modify it under the terms of the GNU General Public License
  10. # as published by the Free Software Foundation; either version 2
  11. # of the License, or (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU General Public License
  19. # along with this program; if not, write to the Free Software
  20. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  21. #
  22. #
  23. from multiprocessing import Queue
  24. import os
  25. import shutil
  26. import subprocess
  27. import unittest
  28. import sys
  29. from qubes.qubes import QubesVmCollection, QubesException
  30. from qubes import backup
  31. import qubes.tests
  32. QUBESXML_R2B2 = '''
  33. <QubesVmCollection
  34. updatevm="3" default_kernel="3.7.6-2" default_netvm="3"
  35. default_fw_netvm="2" default_template="1" clockvm="2">
  36. <QubesTemplateVm
  37. installed_by_rpm="True" kernel="3.7.6-2" uses_default_kernelopts="True"
  38. qid="1" include_in_backups="True" uses_default_kernel="True"
  39. qrexec_timeout="60" internal="False" conf_file="fedora-18-x64.conf"
  40. label="black" template_qid="none" kernelopts="" memory="400"
  41. default_user="user" netvm_qid="3" uses_default_netvm="True"
  42. volatile_img="volatile.img" services="{'meminfo-writer': True}"
  43. maxmem="1535" pcidevs="[]" name="fedora-18-x64"
  44. private_img="private.img" vcpus="2" root_img="root.img" debug="False"
  45. dir_path="/var/lib/qubes/vm-templates/fedora-18-x64"/>
  46. <QubesNetVm
  47. installed_by_rpm="False" kernel="3.7.6-2"
  48. uses_default_kernelopts="True" qid="2" include_in_backups="True"
  49. uses_default_kernel="True" qrexec_timeout="60" internal="False"
  50. conf_file="netvm.conf" label="red" template_qid="1"
  51. kernelopts="iommu=soft swiotlb=4096" memory="200" default_user="user"
  52. volatile_img="volatile.img" services="{'ntpd': False, 'meminfo-writer':
  53. False}" maxmem="1535" pcidevs="['02:00.0', '03:00.0']" name="netvm"
  54. netid="1" private_img="private.img" vcpus="2" root_img="root.img"
  55. debug="False" dir_path="/var/lib/qubes/servicevms/netvm"/>
  56. <QubesProxyVm
  57. installed_by_rpm="False" kernel="3.7.6-2"
  58. uses_default_kernelopts="True" qid="3" include_in_backups="True"
  59. uses_default_kernel="True" qrexec_timeout="60" internal="False"
  60. conf_file="firewallvm.conf" label="green" template_qid="1"
  61. kernelopts="" memory="200" default_user="user" netvm_qid="2"
  62. volatile_img="volatile.img" services="{'meminfo-writer': True}"
  63. maxmem="1535" pcidevs="[]" name="firewallvm" netid="2"
  64. private_img="private.img" vcpus="2" root_img="root.img" debug="False"
  65. dir_path="/var/lib/qubes/servicevms/firewallvm"/>
  66. <QubesAppVm installed_by_rpm="False"
  67. kernel="3.7.6-2" uses_default_kernelopts="True" qid="4"
  68. include_in_backups="True" uses_default_kernel="True"
  69. qrexec_timeout="60" internal="True" conf_file="fedora-18-x64-dvm.conf"
  70. label="gray" template_qid="1" kernelopts="" memory="400"
  71. default_user="user" netvm_qid="3" uses_default_netvm="True"
  72. volatile_img="volatile.img" services="{'meminfo-writer': True}"
  73. maxmem="1535" pcidevs="[]" name="fedora-18-x64-dvm"
  74. private_img="private.img" vcpus="1" root_img="root.img" debug="False"
  75. dir_path="/var/lib/qubes/appvms/fedora-18-x64-dvm"/>
  76. <QubesAppVm installed_by_rpm="False"
  77. kernel="3.7.6-2" uses_default_kernelopts="True" qid="5"
  78. include_in_backups="True" uses_default_kernel="True"
  79. qrexec_timeout="60" internal="False" conf_file="test-work.conf"
  80. label="green" template_qid="1" kernelopts="" memory="400"
  81. default_user="user" netvm_qid="3" uses_default_netvm="True"
  82. volatile_img="volatile.img" services="{'meminfo-writer': True}"
  83. maxmem="1535" pcidevs="[]" name="test-work" private_img="private.img"
  84. vcpus="2" root_img="root.img" debug="False"
  85. dir_path="/var/lib/qubes/appvms/test-work"/>
  86. <QubesAppVm installed_by_rpm="False"
  87. kernel="3.7.6-2" uses_default_kernelopts="True" qid="6"
  88. include_in_backups="True" uses_default_kernel="True"
  89. qrexec_timeout="60" internal="False" conf_file="banking.conf"
  90. label="green" template_qid="1" kernelopts="" memory="400"
  91. default_user="user" netvm_qid="3" uses_default_netvm="True"
  92. volatile_img="volatile.img" services="{'meminfo-writer': True}"
  93. maxmem="1535" pcidevs="[]" name="banking" private_img="private.img"
  94. vcpus="2" root_img="root.img" debug="False"
  95. dir_path="/var/lib/qubes/appvms/banking"/>
  96. <QubesAppVm installed_by_rpm="False"
  97. kernel="3.7.6-2" uses_default_kernelopts="True" qid="7"
  98. include_in_backups="True" uses_default_kernel="True"
  99. qrexec_timeout="60" internal="False" conf_file="personal.conf"
  100. label="yellow" template_qid="1" kernelopts="" memory="400"
  101. default_user="user" netvm_qid="3" uses_default_netvm="True"
  102. volatile_img="volatile.img" services="{'meminfo-writer': True}"
  103. maxmem="1535" pcidevs="[]" name="personal" private_img="private.img"
  104. vcpus="2" root_img="root.img" debug="False"
  105. dir_path="/var/lib/qubes/appvms/personal"/>
  106. <QubesAppVm installed_by_rpm="False"
  107. kernel="3.7.6-2" uses_default_kernelopts="True" qid="8"
  108. include_in_backups="True" uses_default_kernel="True"
  109. qrexec_timeout="60" internal="False" conf_file="untrusted.conf"
  110. label="red" template_qid="1" kernelopts="" memory="400"
  111. default_user="user" netvm_qid="12" uses_default_netvm="False"
  112. volatile_img="volatile.img" services="{'meminfo-writer': True}"
  113. maxmem="1535" pcidevs="[]" name="untrusted" private_img="private.img"
  114. vcpus="2" root_img="root.img" debug="False"
  115. dir_path="/var/lib/qubes/appvms/untrusted"/>
  116. <QubesTemplateVm installed_by_rpm="False"
  117. kernel="3.7.6-2" uses_default_kernelopts="True" qid="9"
  118. include_in_backups="True" uses_default_kernel="True"
  119. qrexec_timeout="60" internal="False"
  120. conf_file="test-template-clone.conf" label="green" template_qid="none"
  121. kernelopts="" memory="400" default_user="user" netvm_qid="3"
  122. uses_default_netvm="True" volatile_img="volatile.img"
  123. services="{'meminfo-writer': True}" maxmem="1535" pcidevs="[]"
  124. name="test-template-clone" private_img="private.img" vcpus="2"
  125. root_img="root.img" debug="False"
  126. dir_path="/var/lib/qubes/vm-templates/test-template-clone"/>
  127. <QubesAppVm installed_by_rpm="False"
  128. kernel="3.7.6-2" uses_default_kernelopts="True" qid="10"
  129. include_in_backups="True" uses_default_kernel="True"
  130. qrexec_timeout="60" internal="False"
  131. conf_file="test-custom-template-appvm.conf" label="yellow"
  132. template_qid="9" kernelopts="" memory="400" default_user="user"
  133. netvm_qid="3" uses_default_netvm="True" volatile_img="volatile.img"
  134. services="{'meminfo-writer': True}" maxmem="1535" pcidevs="[]"
  135. name="test-custom-template-appvm" private_img="private.img" vcpus="2"
  136. root_img="root.img" debug="False"
  137. dir_path="/var/lib/qubes/appvms/test-custom-template-appvm"/>
  138. <QubesAppVm installed_by_rpm="False"
  139. kernel="3.7.6-2" uses_default_kernelopts="True" qid="11"
  140. include_in_backups="True" uses_default_kernel="True"
  141. qrexec_timeout="60" internal="False" conf_file="test-standalonevm.conf"
  142. label="blue" template_qid="none" kernelopts="" memory="400"
  143. default_user="user" netvm_qid="3" uses_default_netvm="True"
  144. volatile_img="volatile.img" services="{'meminfo-writer': True}"
  145. maxmem="1535" pcidevs="[]" name="test-standalonevm"
  146. private_img="private.img" vcpus="2" root_img="root.img" debug="False"
  147. dir_path="/var/lib/qubes/appvms/test-standalonevm"/>
  148. <QubesProxyVm installed_by_rpm="False"
  149. kernel="3.7.6-2" uses_default_kernelopts="True" qid="12"
  150. include_in_backups="True" uses_default_kernel="True"
  151. qrexec_timeout="60" internal="False" conf_file="test-testproxy.conf"
  152. label="red" template_qid="1" kernelopts="" memory="200"
  153. default_user="user" netvm_qid="3" volatile_img="volatile.img"
  154. services="{'meminfo-writer': True}" maxmem="1535" pcidevs="[]"
  155. name="test-testproxy" netid="3" private_img="private.img" vcpus="2"
  156. root_img="root.img" debug="False"
  157. dir_path="/var/lib/qubes/servicevms/test-testproxy"/>
  158. <QubesProxyVm installed_by_rpm="False"
  159. kernel="3.7.6-2" uses_default_kernelopts="True" qid="13"
  160. include_in_backups="True" uses_default_kernel="True"
  161. qrexec_timeout="60" internal="False" conf_file="testproxy2.conf"
  162. label="red" template_qid="9" kernelopts="" memory="200"
  163. default_user="user" netvm_qid="2" volatile_img="volatile.img"
  164. services="{'meminfo-writer': True}" maxmem="1535" pcidevs="[]"
  165. name="testproxy2" netid="4" private_img="private.img" vcpus="2"
  166. root_img="root.img" debug="False"
  167. dir_path="/var/lib/qubes/servicevms/testproxy2"/>
  168. <QubesHVm installed_by_rpm="False"
  169. netvm_qid="none" qid="14" include_in_backups="True"
  170. timezone="localtime" qrexec_timeout="60" conf_file="test-testhvm.conf"
  171. label="purple" template_qid="none" internal="False" memory="512"
  172. uses_default_netvm="True" services="{'meminfo-writer': False}"
  173. default_user="user" pcidevs="[]" name="test-testhvm"
  174. qrexec_installed="False" private_img="private.img" drive="None"
  175. vcpus="2" root_img="root.img" guiagent_installed="False" debug="False"
  176. dir_path="/var/lib/qubes/appvms/test-testhvm"/>
  177. </QubesVmCollection>
  178. '''
  179. APPTEMPLATE_R2B2 = '''
  180. [Desktop Entry]
  181. Name=%VMNAME%: {name}
  182. GenericName=%VMNAME%: {name}
  183. GenericName[ca]=%VMNAME%: Navegador web
  184. GenericName[cs]=%VMNAME%: Webový prohlížeč
  185. GenericName[es]=%VMNAME%: Navegador web
  186. GenericName[fa]=%VMNAME%: مرورر اینترنتی
  187. GenericName[fi]=%VMNAME%: WWW-selain
  188. GenericName[fr]=%VMNAME%: Navigateur Web
  189. GenericName[hu]=%VMNAME%: Webböngésző
  190. GenericName[it]=%VMNAME%: Browser Web
  191. GenericName[ja]=%VMNAME%: ウェブ・ブラウザ
  192. GenericName[ko]=%VMNAME%: 웹 브라우저
  193. GenericName[nb]=%VMNAME%: Nettleser
  194. GenericName[nl]=%VMNAME%: Webbrowser
  195. GenericName[nn]=%VMNAME%: Nettlesar
  196. GenericName[no]=%VMNAME%: Nettleser
  197. GenericName[pl]=%VMNAME%: Przeglądarka WWW
  198. GenericName[pt]=%VMNAME%: Navegador Web
  199. GenericName[pt_BR]=%VMNAME%: Navegador Web
  200. GenericName[sk]=%VMNAME%: Internetový prehliadač
  201. GenericName[sv]=%VMNAME%: Webbläsare
  202. Comment={comment}
  203. Comment[ca]=Navegueu per el web
  204. Comment[cs]=Prohlížení stránek World Wide Webu
  205. Comment[de]=Im Internet surfen
  206. Comment[es]=Navegue por la web
  207. Comment[fa]=صفحات شبه جهانی اینترنت را مرور نمایید
  208. Comment[fi]=Selaa Internetin WWW-sivuja
  209. Comment[fr]=Navigue sur Internet
  210. Comment[hu]=A világháló böngészése
  211. Comment[it]=Esplora il web
  212. Comment[ja]=ウェブを閲覧します
  213. Comment[ko]=웹을 돌아 다닙니다
  214. Comment[nb]=Surf på nettet
  215. Comment[nl]=Verken het internet
  216. Comment[nn]=Surf på nettet
  217. Comment[no]=Surf på nettet
  218. Comment[pl]=Przeglądanie stron WWW
  219. Comment[pt]=Navegue na Internet
  220. Comment[pt_BR]=Navegue na Internet
  221. Comment[sk]=Prehliadanie internetu
  222. Comment[sv]=Surfa på webben
  223. Exec=qvm-run -q --tray -a %VMNAME% '{command} %u'
  224. Categories=Network;WebBrowser;
  225. X-Qubes-VmName=%VMNAME%
  226. Icon=%VMDIR%/icon.png
  227. '''
  228. QUBESXML_R1 = '''<?xml version='1.0' encoding='UTF-8'?>
  229. <QubesVmCollection
  230. clockvm="2" default_fw_netvm="2" default_kernel="3.2.7-10"
  231. default_netvm="3" default_template="1" updatevm="3"><QubesTemplateVm
  232. conf_file="fedora-17-x64.conf" debug="False" default_user="user"
  233. dir_path="/var/lib/qubes/vm-templates/fedora-17-x64"
  234. include_in_backups="True" installed_by_rpm="True" internal="False"
  235. kernel="3.2.7-10" kernelopts="" label="gray" maxmem="4063" memory="400"
  236. name="fedora-17-x64" netvm_qid="3" pcidevs="[]"
  237. private_img="private.img" qid="1" root_img="root.img"
  238. services="{&apos;meminfo-writer&apos;: True}" template_qid="none"
  239. uses_default_kernel="True" uses_default_kernelopts="True"
  240. uses_default_netvm="True" vcpus="2" volatile_img="volatile.img"/>
  241. <QubesNetVm
  242. conf_file="netvm.conf" debug="False" default_user="user"
  243. dir_path="/var/lib/qubes/servicevms/netvm" include_in_backups="True"
  244. installed_by_rpm="False" internal="False" kernel="3.2.7-10"
  245. kernelopts="iommu=soft swiotlb=2048" label="red" maxmem="4063"
  246. memory="200" name="netvm" netid="1" pcidevs="[&apos;00:19.0&apos;,
  247. &apos;03:00.0&apos;]" private_img="private.img" qid="2"
  248. root_img="root.img" services="{&apos;ntpd&apos;: False,
  249. &apos;meminfo-writer&apos;: False}" template_qid="1"
  250. uses_default_kernel="True" uses_default_kernelopts="True" vcpus="2"
  251. volatile_img="volatile.img"/>
  252. <QubesProxyVm
  253. conf_file="firewallvm.conf" debug="False" default_user="user"
  254. dir_path="/var/lib/qubes/servicevms/firewallvm"
  255. include_in_backups="True" installed_by_rpm="False" internal="False"
  256. kernel="3.2.7-10" kernelopts="" label="green" maxmem="4063"
  257. memory="200" name="firewallvm" netid="2" netvm_qid="2" pcidevs="[]"
  258. private_img="private.img" qid="3" root_img="root.img"
  259. services="{&apos;meminfo-writer&apos;: True}" template_qid="1"
  260. uses_default_kernel="True" uses_default_kernelopts="True" vcpus="2"
  261. volatile_img="volatile.img"/>
  262. <QubesAppVm
  263. conf_file="fedora-17-x64-dvm.conf" debug="False" default_user="user"
  264. dir_path="/var/lib/qubes/appvms/fedora-17-x64-dvm"
  265. include_in_backups="True" installed_by_rpm="False" internal="True"
  266. kernel="3.2.7-10" kernelopts="" label="gray" maxmem="4063" memory="400"
  267. name="fedora-17-x64-dvm" netvm_qid="3" pcidevs="[]"
  268. private_img="private.img" qid="4" root_img="root.img"
  269. services="{&apos;meminfo-writer&apos;: True}" template_qid="1"
  270. uses_default_kernel="True" uses_default_kernelopts="True"
  271. uses_default_netvm="True" vcpus="1" volatile_img="volatile.img"/>
  272. <QubesAppVm
  273. conf_file="test-work.conf" debug="False" default_user="user"
  274. dir_path="/var/lib/qubes/appvms/test-work" include_in_backups="True"
  275. installed_by_rpm="False" internal="False" kernel="3.2.7-10"
  276. kernelopts="" label="green" maxmem="4063" memory="400" name="test-work"
  277. netvm_qid="3" pcidevs="[]" private_img="private.img" qid="5"
  278. root_img="root.img" services="{&apos;meminfo-writer&apos;: True}"
  279. template_qid="1" uses_default_kernel="True"
  280. uses_default_kernelopts="True" uses_default_netvm="True" vcpus="2"
  281. volatile_img="volatile.img"/>
  282. <QubesAppVm
  283. conf_file="personal.conf" debug="False" default_user="user"
  284. dir_path="/var/lib/qubes/appvms/personal" include_in_backups="True"
  285. installed_by_rpm="False" internal="False" kernel="3.2.7-10"
  286. kernelopts="" label="yellow" maxmem="4063" memory="400" name="personal"
  287. netvm_qid="3" pcidevs="[]" private_img="private.img" qid="6"
  288. root_img="root.img" services="{&apos;meminfo-writer&apos;: True}"
  289. template_qid="1" uses_default_kernel="True"
  290. uses_default_kernelopts="True" uses_default_netvm="True" vcpus="2"
  291. volatile_img="volatile.img"/>
  292. <QubesAppVm
  293. conf_file="banking.conf" debug="False" default_user="user"
  294. dir_path="/var/lib/qubes/appvms/banking" include_in_backups="True"
  295. installed_by_rpm="False" internal="False" kernel="3.2.7-10"
  296. kernelopts="" label="green" maxmem="4063" memory="400" name="banking"
  297. netvm_qid="3" pcidevs="[]" private_img="private.img" qid="7"
  298. root_img="root.img" services="{&apos;meminfo-writer&apos;: True}"
  299. template_qid="1" uses_default_kernel="True"
  300. uses_default_kernelopts="True" uses_default_netvm="True" vcpus="2"
  301. volatile_img="volatile.img"/>
  302. <QubesAppVm
  303. conf_file="untrusted.conf" debug="False" default_user="user"
  304. dir_path="/var/lib/qubes/appvms/untrusted" include_in_backups="True"
  305. installed_by_rpm="False" internal="False" kernel="3.2.7-10"
  306. kernelopts="" label="red" maxmem="4063" memory="400" name="untrusted"
  307. netvm_qid="3" pcidevs="[]" private_img="private.img" qid="8"
  308. root_img="root.img" services="{&apos;meminfo-writer&apos;: True}"
  309. template_qid="1" uses_default_kernel="True"
  310. uses_default_kernelopts="True" uses_default_netvm="True" vcpus="2"
  311. volatile_img="volatile.img"/>
  312. <QubesAppVm
  313. conf_file="test-standalonevm.conf" debug="False" default_user="user"
  314. dir_path="/var/lib/qubes/appvms/test-standalonevm"
  315. include_in_backups="True" installed_by_rpm="False" internal="False"
  316. kernel="None" kernelopts="" label="red" maxmem="4063" memory="400"
  317. name="test-standalonevm" netvm_qid="3" pcidevs="[]"
  318. private_img="private.img" qid="9" root_img="root.img"
  319. services="{&apos;meminfo-writer&apos;: True}" template_qid="none"
  320. uses_default_kernel="False" uses_default_kernelopts="True"
  321. uses_default_netvm="True" vcpus="2" volatile_img="volatile.img"/>
  322. <QubesAppVm
  323. conf_file="test-testvm.conf" debug="False" default_user="user"
  324. dir_path="/var/lib/qubes/appvms/test-testvm" include_in_backups="True"
  325. installed_by_rpm="False" internal="False" kernel="3.2.7-10"
  326. kernelopts="" label="red" mac="00:16:3E:5E:6C:55" maxmem="4063"
  327. memory="400" name="test-testvm" netvm_qid="3" pcidevs="[]"
  328. private_img="private.img" qid="10" root_img="root.img"
  329. services="{&apos;meminfo-writer&apos;: True}" template_qid="1"
  330. uses_default_kernel="True" uses_default_kernelopts="True"
  331. uses_default_netvm="True" vcpus="2" volatile_img="volatile.img"/>
  332. <QubesTemplateVm
  333. conf_file="test-template-clone.conf" debug="False" default_user="user"
  334. dir_path="/var/lib/qubes/vm-templates/test-template-clone"
  335. include_in_backups="True" installed_by_rpm="False" internal="False"
  336. kernel="3.2.7-10" kernelopts="" label="gray" maxmem="4063" memory="400"
  337. name="test-template-clone" netvm_qid="3" pcidevs="[]"
  338. private_img="private.img" qid="11" root_img="root.img"
  339. services="{&apos;meminfo-writer&apos;: True}" template_qid="none"
  340. uses_default_kernel="True" uses_default_kernelopts="True"
  341. uses_default_netvm="True" vcpus="2" volatile_img="volatile.img"/>
  342. <QubesAppVm
  343. conf_file="test-custom-template-appvm.conf" debug="False"
  344. default_user="user"
  345. dir_path="/var/lib/qubes/appvms/test-custom-template-appvm"
  346. include_in_backups="True" installed_by_rpm="False" internal="False"
  347. kernel="3.2.7-10" kernelopts="" label="yellow" maxmem="4063"
  348. memory="400" name="test-custom-template-appvm" netvm_qid="3"
  349. pcidevs="[]" private_img="private.img" qid="12" root_img="root.img"
  350. services="{&apos;meminfo-writer&apos;: True}" template_qid="11"
  351. uses_default_kernel="True" uses_default_kernelopts="True"
  352. uses_default_netvm="True" vcpus="2" volatile_img="volatile.img"/>
  353. <QubesProxyVm
  354. conf_file="test-testproxy.conf" debug="False" default_user="user"
  355. dir_path="/var/lib/qubes/servicevms/test-testproxy"
  356. include_in_backups="True" installed_by_rpm="False" internal="False"
  357. kernel="3.2.7-10" kernelopts="" label="yellow" maxmem="4063"
  358. memory="200" name="test-testproxy" netid="3" netvm_qid="2" pcidevs="[]"
  359. private_img="private.img" qid="13" root_img="root.img"
  360. services="{&apos;meminfo-writer&apos;: True}" template_qid="1"
  361. uses_default_kernel="True" uses_default_kernelopts="True" vcpus="2"
  362. volatile_img="volatile.img"/>
  363. </QubesVmCollection>
  364. '''
  365. class TC_00_BackupCompatibility(qubes.tests.BackupTestsMixin, unittest.TestCase):
  366. def create_whitelisted_appmenus(self, filename):
  367. f = open(filename, "w")
  368. f.write("gnome-terminal.desktop\n")
  369. f.write("nautilus.desktop\n")
  370. f.write("firefox.desktop\n")
  371. f.write("mozilla-thunderbird.desktop\n")
  372. f.write("libreoffice-startcenter.desktop\n")
  373. f.close()
  374. def create_appmenus(self, dir, template, list):
  375. for name in list:
  376. f = open(os.path.join(dir, name + ".desktop"), "w")
  377. f.write(template.format(name=name, comment=name, command=name))
  378. f.close()
  379. def create_private_img(self, filename):
  380. self.create_sparse(filename, 2*2**30)
  381. subprocess.check_call(["/usr/sbin/mkfs.ext4", "-q", "-F", filename])
  382. def create_volatile_img(self, filename):
  383. self.create_sparse(filename, 11.5*2**30)
  384. sfdisk_input="0,1024,S\n,10240,L\n"
  385. p = subprocess.Popen(["/usr/sbin/sfdisk", "--no-reread", "-u",
  386. "M",
  387. filename], stdout=open("/dev/null","w"),
  388. stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
  389. p.communicate(input=sfdisk_input)
  390. self.assertEqual(p.returncode, 0, "sfdisk failed with code %d" % p
  391. .returncode)
  392. # TODO: mkswap
  393. def fullpath(self, name):
  394. return os.path.join(self.backupdir, name)
  395. def create_v1_files(self, r2b2=False):
  396. appmenus_list = [
  397. "firefox", "gnome-terminal", "evince", "evolution",
  398. "mozilla-thunderbird", "libreoffice-startcenter", "nautilus",
  399. "gedit", "gpk-update-viewer", "gpk-application"
  400. ]
  401. os.mkdir(self.fullpath("appvms"))
  402. os.mkdir(self.fullpath("servicevms"))
  403. os.mkdir(self.fullpath("vm-templates"))
  404. # normal AppVM
  405. os.mkdir(self.fullpath("appvms/test-work"))
  406. self.create_whitelisted_appmenus(self.fullpath(
  407. "appvms/test-work/whitelisted-appmenus.list"))
  408. os.symlink("/usr/share/qubes/icons/green.png",
  409. self.fullpath("appvms/test-work/icon.png"))
  410. self.create_private_img(self.fullpath("appvms/test-work/private.img"))
  411. # StandaloneVM
  412. os.mkdir(self.fullpath("appvms/test-standalonevm"))
  413. self.create_whitelisted_appmenus(self.fullpath(
  414. "appvms/test-standalonevm/whitelisted-appmenus.list"))
  415. os.symlink("/usr/share/qubes/icons/blue.png",
  416. self.fullpath("appvms/test-standalonevm/icon.png"))
  417. self.create_private_img(self.fullpath(
  418. "appvms/test-standalonevm/private.img"))
  419. self.create_sparse(
  420. self.fullpath("appvms/test-standalonevm/root.img"), 10*2**30)
  421. self.fill_image(self.fullpath("appvms/test-standalonevm/root.img"),
  422. 100*1024*1024, True)
  423. os.mkdir(self.fullpath("appvms/test-standalonevm/apps.templates"))
  424. self.create_appmenus(self.fullpath("appvms/test-standalonevm/apps"
  425. ".templates"),
  426. APPTEMPLATE_R2B2,
  427. appmenus_list)
  428. os.mkdir(self.fullpath("appvms/test-standalonevm/kernels"))
  429. for k_file in ["initramfs", "vmlinuz", "modules.img"]:
  430. self.fill_image(self.fullpath("appvms/test-standalonevm/kernels/"
  431. + k_file), 10*1024*1024)
  432. # VM based on custom template
  433. subprocess.check_call(
  434. ["/bin/cp", "-a", self.fullpath("appvms/test-work"),
  435. self.fullpath("appvms/test-custom-template-appvm")])
  436. # HVM
  437. if r2b2:
  438. subprocess.check_call(
  439. ["/bin/cp", "-a", self.fullpath("appvms/test-standalonevm"),
  440. self.fullpath("appvms/test-testhvm")])
  441. # ProxyVM
  442. os.mkdir(self.fullpath("servicevms/test-testproxy"))
  443. self.create_whitelisted_appmenus(self.fullpath(
  444. "servicevms/test-testproxy/whitelisted-appmenus.list"))
  445. self.create_private_img(
  446. self.fullpath("servicevms/test-testproxy/private.img"))
  447. # Custom template
  448. os.mkdir(self.fullpath("vm-templates/test-template-clone"))
  449. self.create_private_img(
  450. self.fullpath("vm-templates/test-template-clone/private.img"))
  451. self.create_sparse(self.fullpath(
  452. "vm-templates/test-template-clone/root-cow.img"), 10*2**30)
  453. self.create_sparse(self.fullpath(
  454. "vm-templates/test-template-clone/root.img"), 10*2**30)
  455. self.fill_image(self.fullpath(
  456. "vm-templates/test-template-clone/root.img"), 1*2**30, True)
  457. self.create_volatile_img(self.fullpath(
  458. "vm-templates/test-template-clone/volatile.img"))
  459. subprocess.check_call([
  460. "/bin/tar", "cS",
  461. "-f", self.fullpath(
  462. "vm-templates/test-template-clone/clean-volatile.img.tar"),
  463. "-C", self.fullpath("vm-templates/test-template-clone"),
  464. "volatile.img"])
  465. self.create_whitelisted_appmenus(self.fullpath(
  466. "vm-templates/test-template-clone/whitelisted-appmenus.list"))
  467. self.create_whitelisted_appmenus(self.fullpath(
  468. "vm-templates/test-template-clone/vm-whitelisted-appmenus.list"))
  469. if r2b2:
  470. self.create_whitelisted_appmenus(self.fullpath(
  471. "vm-templates/test-template-clone/netvm-whitelisted-appmenus"
  472. ".list"))
  473. os.symlink("/usr/share/qubes/icons/green.png",
  474. self.fullpath("vm-templates/test-template-clone/icon.png"))
  475. os.mkdir(
  476. self.fullpath("vm-templates/test-template-clone/apps.templates"))
  477. self.create_appmenus(
  478. self.fullpath("vm-templates/test-template-clone/apps.templates"),
  479. APPTEMPLATE_R2B2,
  480. appmenus_list)
  481. os.mkdir(self.fullpath("vm-templates/test-template-clone/apps"))
  482. self.create_appmenus(
  483. self.fullpath("vm-templates/test-template-clone/apps"),
  484. APPTEMPLATE_R2B2.replace("%VMNAME%", "test-template-clone")
  485. .replace("%VMDIR%", self.fullpath(
  486. "vm-templates/test-template-clone")),
  487. appmenus_list)
  488. def test_100_r1(self):
  489. self.create_v1_files(r2b2=False)
  490. f = open(self.fullpath("qubes.xml"), "w")
  491. f.write(QUBESXML_R1)
  492. f.close()
  493. self.restore_backup(self.backupdir, options={
  494. 'use-default-template': True,
  495. })
  496. self.assertIsNotNone(self.qc.get_vm_by_name("test-template-clone"))
  497. self.assertIsNotNone(self.qc.get_vm_by_name("test-testproxy"))
  498. self.assertIsNotNone(self.qc.get_vm_by_name("test-work"))
  499. self.assertIsNotNone(self.qc.get_vm_by_name("test-standalonevm"))
  500. self.assertIsNotNone(self.qc.get_vm_by_name(
  501. "test-custom-template-appvm"))
  502. self.assertEqual(self.qc.get_vm_by_name("test-custom-template-appvm")
  503. .template,
  504. self.qc.get_vm_by_name("test-template-clone"))
  505. def test_200_r2b2(self):
  506. self.create_v1_files(r2b2=True)
  507. f = open(self.fullpath("qubes.xml"), "w")
  508. f.write(QUBESXML_R2B2)
  509. f.close()
  510. self.restore_backup(self.backupdir, options={
  511. 'use-default-template': True,
  512. })
  513. self.assertIsNotNone(self.qc.get_vm_by_name("test-template-clone"))
  514. self.assertIsNotNone(self.qc.get_vm_by_name("test-testproxy"))
  515. self.assertIsNotNone(self.qc.get_vm_by_name("test-work"))
  516. self.assertIsNotNone(self.qc.get_vm_by_name("test-testhvm"))
  517. self.assertIsNotNone(self.qc.get_vm_by_name("test-standalonevm"))
  518. self.assertIsNotNone(self.qc.get_vm_by_name(
  519. "test-custom-template-appvm"))
  520. self.assertEqual(self.qc.get_vm_by_name("test-custom-template-appvm")
  521. .template,
  522. self.qc.get_vm_by_name("test-template-clone"))