@@ -637,7 +637,169 @@ def test_100_property_migrate_default_fw_netvm(self):
637637 app .close ()
638638 del app
639639
640- def test_101_property_migrate_label (self ):
640+ def test_101_property_migrate_disposable_template (self ):
641+ xml_template = """<?xml version="1.0" encoding="utf-8" ?>
642+ <qubes version="3.0">
643+ <properties>
644+ <property name="default_template"></property>
645+ <property name="default_dispvm">{app_default_dispvm}</property>
646+ <property name="management_dispvm">{app_management_dispvm}</property>
647+ </properties>
648+ <labels>
649+ <label id="label-1" color="#cc0000">red</label>
650+ </labels>
651+ <pools>
652+ <pool driver="file" dir_path="/tmp/qubes-test" name="default"/>
653+ </pools>
654+ <domains>
655+
656+ <domain class="AdminVM" id="domain-0">
657+ <properties>
658+ <property name="default_dispvm">{adminvm_default_dispvm}</property>
659+ </properties>
660+ </domain>
661+
662+ <domain class="StandaloneVM" id="domain-1">
663+ <properties>
664+ <property name="qid">1</property>
665+ <property name="name">work</property>
666+ <property name="label" ref="label-1" />
667+ <property name="uuid">2fcfc1f4-b2fe-4361-931a-c5294b35edfa</property>
668+ <property name="management_dispvm">{work_management_dispvm}</property>
669+ </properties>
670+ <features/>
671+ <devices class="pci"/>
672+ </domain>
673+
674+ <domain class="StandaloneVM" id="domain-2">
675+ <properties>
676+ <property name="qid">3</property>
677+ <property name="name">disp-template</property>
678+ <property name="label" ref="label-1" />
679+ <property name="uuid">2ccfc1f4-b2fe-4361-931a-c5294b35edfa</property>
680+ <property name="template_for_dispvms">True</property>
681+ </properties>
682+ </domain>
683+
684+ </domains>
685+ </qubes>
686+ """
687+
688+ with self .subTest ("default" ):
689+ with open ("/tmp/qubestest.xml" , "w" , encoding = "ascii" ) as xml_file :
690+ xml_file .write (
691+ xml_template .format (
692+ app_default_dispvm = "disp-template" ,
693+ app_management_dispvm = "disp-template" ,
694+ adminvm_default_dispvm = "disp-template" ,
695+ work_management_dispvm = "disp-template" ,
696+ )
697+ )
698+ app = qubes .Qubes ("/tmp/qubestest.xml" , offline_mode = True )
699+ adminvm = app .domains ["dom0" ]
700+ work = app .domains ["work" ]
701+ disp_template = app .domains ["disp-template" ]
702+
703+ self .assertFalse (app .property_is_default ("default_dispvm" ))
704+ self .assertEqual (app .default_dispvm , disp_template )
705+ self .assertFalse (app .property_is_default ("management_dispvm" ))
706+ self .assertEqual (app .management_dispvm , disp_template )
707+
708+ self .assertFalse (adminvm .property_is_default ("default_dispvm" ))
709+ self .assertEqual (adminvm .default_dispvm , disp_template )
710+
711+ self .assertTrue (work .property_is_default ("default_dispvm" ))
712+ self .assertEqual (work .default_dispvm , disp_template )
713+ self .assertFalse (work .property_is_default ("management_dispvm" ))
714+ self .assertEqual (work .management_dispvm , disp_template )
715+
716+ self .assertTrue (disp_template .property_is_default ("default_dispvm" ))
717+ self .assertEqual (disp_template .default_dispvm , disp_template )
718+ self .assertTrue (
719+ disp_template .property_is_default ("management_dispvm" )
720+ )
721+ self .assertEqual (disp_template .management_dispvm , disp_template )
722+
723+ app .close ()
724+ del app
725+
726+ with self .subTest ("invalid-system" ):
727+ with open ("/tmp/qubestest.xml" , "w" , encoding = "ascii" ) as xml_file :
728+ xml_file .write (
729+ xml_template .format (
730+ app_default_dispvm = "work" ,
731+ app_management_dispvm = "work" ,
732+ adminvm_default_dispvm = "disp-template" ,
733+ work_management_dispvm = "disp-template" ,
734+ )
735+ )
736+ app = qubes .Qubes ("/tmp/qubestest.xml" , offline_mode = True )
737+ adminvm = app .domains ["dom0" ]
738+ work = app .domains ["work" ]
739+ disp_template = app .domains ["disp-template" ]
740+
741+ self .assertFalse (app .property_is_default ("default_dispvm" ))
742+ self .assertEqual (app .default_dispvm , None )
743+ self .assertFalse (app .property_is_default ("management_dispvm" ))
744+ self .assertEqual (app .management_dispvm , None )
745+
746+ self .assertFalse (adminvm .property_is_default ("default_dispvm" ))
747+ self .assertEqual (adminvm .default_dispvm , disp_template )
748+
749+ self .assertTrue (work .property_is_default ("default_dispvm" ))
750+ self .assertEqual (work .default_dispvm , None )
751+ self .assertFalse (work .property_is_default ("management_dispvm" ))
752+ self .assertEqual (work .management_dispvm , disp_template )
753+
754+ self .assertTrue (disp_template .property_is_default ("default_dispvm" ))
755+ self .assertEqual (disp_template .default_dispvm , None )
756+ self .assertTrue (
757+ disp_template .property_is_default ("management_dispvm" )
758+ )
759+ self .assertEqual (disp_template .management_dispvm , None )
760+
761+ app .close ()
762+ del app
763+
764+ with self .subTest ("invalid-per-qube" ):
765+ with open ("/tmp/qubestest.xml" , "w" , encoding = "ascii" ) as xml_file :
766+ xml_file .write (
767+ xml_template .format (
768+ app_default_dispvm = "disp-template" ,
769+ app_management_dispvm = "disp-template" ,
770+ adminvm_default_dispvm = "work" ,
771+ work_management_dispvm = "work" ,
772+ )
773+ )
774+ app = qubes .Qubes ("/tmp/qubestest.xml" , offline_mode = True )
775+ adminvm = app .domains ["dom0" ]
776+ work = app .domains ["work" ]
777+ disp_template = app .domains ["disp-template" ]
778+
779+ self .assertFalse (app .property_is_default ("default_dispvm" ))
780+ self .assertEqual (app .default_dispvm , disp_template )
781+ self .assertFalse (app .property_is_default ("management_dispvm" ))
782+ self .assertEqual (app .management_dispvm , disp_template )
783+
784+ self .assertFalse (adminvm .property_is_default ("default_dispvm" ))
785+ self .assertEqual (adminvm .default_dispvm , None )
786+
787+ self .assertTrue (work .property_is_default ("default_dispvm" ))
788+ self .assertEqual (work .default_dispvm , disp_template )
789+ self .assertFalse (work .property_is_default ("management_dispvm" ))
790+ self .assertEqual (work .management_dispvm , None )
791+
792+ self .assertTrue (disp_template .property_is_default ("default_dispvm" ))
793+ self .assertEqual (disp_template .default_dispvm , disp_template )
794+ self .assertTrue (
795+ disp_template .property_is_default ("management_dispvm" )
796+ )
797+ self .assertEqual (disp_template .management_dispvm , disp_template )
798+
799+ app .close ()
800+ del app
801+
802+ def test_102_property_migrate_label (self ):
641803 xml_template = """<?xml version="1.0" encoding="utf-8" ?>
642804 <qubes version="3.0">
643805 <labels>
@@ -1053,27 +1215,32 @@ def test_203_remove_default_dispvm(self):
10531215 appvm = self .app .add_new_vm (
10541216 "AppVM" , name = "test-appvm" , template = self .template , label = "red"
10551217 )
1218+ appvm .template_for_dispvms = True
10561219 self .app .default_dispvm = appvm
10571220 with mock .patch .object (self .app , "vmm" ):
10581221 with self .assertRaises (qubes .exc .QubesVMInUseError ):
10591222 del self .app .domains [appvm ]
10601223
1061- def test_204_remove_appvm_dispvm (self ):
1062- dispvm = self .app .add_new_vm (
1063- "AppVM" , name = "test-appvm" , template = self .template , label = "red"
1224+ def test_204_remove_appvm_used_as_default_dispvm (self ):
1225+ appvm = self .app .add_new_vm (
1226+ "AppVM" ,
1227+ name = "test-appvm" ,
1228+ template = self .template ,
1229+ label = "red" ,
1230+ template_for_dispvms = True ,
10641231 )
10651232 self .app .add_new_vm (
10661233 "AppVM" ,
10671234 name = "test-appvm2" ,
10681235 template = self .template ,
1069- default_dispvm = dispvm ,
1236+ default_dispvm = appvm ,
10701237 label = "red" ,
10711238 )
10721239 with mock .patch .object (self .app , "vmm" ):
10731240 with self .assertRaises (qubes .exc .QubesVMInUseError ):
1074- del self .app .domains [dispvm ]
1241+ del self .app .domains [appvm ]
10751242
1076- def test_205_remove_appvm_dispvm (self ):
1243+ def test_205_remove_appvm_used_as_template_of_dispvm (self ):
10771244 appvm = self .app .add_new_vm (
10781245 "AppVM" ,
10791246 name = "test-appvm" ,
@@ -1257,6 +1424,20 @@ def test_303_preload_default_dispvm_change_partial_noop(self):
12571424 "domain-preload-dispvm-start" , reason = mock .ANY
12581425 )
12591426
1427+ def test_304_event_default_dispvm (self ):
1428+ self .appvm .template_for_dispvms = False
1429+ with self .assertRaises (qubes .exc .QubesPropertyValueError ):
1430+ self .app .default_dispvm = self .appvm
1431+ self .appvm .template_for_dispvms = True
1432+ self .app .default_dispvm = self .appvm
1433+
1434+ def test_305_event_management_dispvm (self ):
1435+ self .appvm .template_for_dispvms = False
1436+ with self .assertRaises (qubes .exc .QubesPropertyValueError ):
1437+ self .app .management_dispvm = self .appvm
1438+ self .appvm .template_for_dispvms = True
1439+ self .app .management_dispvm = self .appvm
1440+
12601441 @qubes .tests .skipUnlessGit
12611442 def test_900_example_xml_in_doc (self ):
12621443 path = os .path .join (qubes .tests .in_git , "doc/example.xml" )
0 commit comments