Skip to content

Commit 4e6e73c

Browse files
committed
Merge remote-tracking branch 'origin/pr/414'
* origin/pr/414: Hide `prohibit-start` qubes from list of `Running` qubes Add `prohibit-start` to Qube Settings GUI.
2 parents 1ac028a + 69f6810 commit 4e6e73c

File tree

4 files changed

+94
-4
lines changed

4 files changed

+94
-4
lines changed

qubesmanager/qube_manager.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,8 @@ def helpEvent(self, event, view, option, index):
198198
QToolTip.showText(event.globalPos(),
199199
self.tr(
200200
"The qube is prohibited from starting\n"
201-
"See `qvm-features` manual for more information"
201+
"Prohibition rationale is available in qube settings "
202+
"-> Advanced tab"
202203
),
203204
view
204205
)
@@ -721,7 +722,7 @@ def filterAcceptsRow(self, sourceRow, sourceParent):
721722
return super().filterAcceptsRow(sourceRow, sourceParent)
722723

723724
if self.window.show_running.isChecked() and \
724-
vm.state['power'] != 'Halted':
725+
not vm.state['power'] in ['Halted', 'Blocked']:
725726
return super().filterAcceptsRow(sourceRow, sourceParent)
726727
if self.window.show_halted.isChecked() and \
727728
vm.state['power'] == 'Halted':

qubesmanager/settings.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,6 +1020,18 @@ def __init_advanced_tab__(self):
10201020
self.run_in_debug_mode.setVisible(False)
10211021
self.run_in_debug_mode.setEnabled(False)
10221022

1023+
rationale = utils.get_feature(self.vm, "prohibit-start", "")
1024+
if rationale:
1025+
self.prohibit_start_rationale.setText(rationale)
1026+
self.prohibit_start_rationale.setVisible(bool(rationale))
1027+
self.prohibit_start_rationale.textEdited.connect(
1028+
self.prohibit_start_rationale_edited
1029+
)
1030+
self.prohibit_start_checkbox.setChecked(bool(rationale))
1031+
self.prohibit_start_checkbox.clicked.connect(
1032+
self.prohibit_start_checked
1033+
)
1034+
10231035
utils.initialize_widget(
10241036
widget=self.allow_fullscreen,
10251037
choices=[
@@ -1041,6 +1053,16 @@ def __init_advanced_tab__(self):
10411053
'gui-allow-utf8-titles'))
10421054
self.allow_utf8_initial = self.allow_utf8.currentIndex()
10431055

1056+
def prohibit_start_checked(self, status):
1057+
self.prohibit_start_rationale.setVisible(bool(status))
1058+
self.prohibit_start_rationale.setFocus()
1059+
1060+
def prohibit_start_rationale_edited(self, text):
1061+
self.prohibit_start_checkbox.setChecked(bool(text))
1062+
self.prohibit_start_rationale.setStyleSheet(
1063+
"" if bool(text) else "#prohibit_start_rationale { color: red;}"
1064+
)
1065+
10441066
def enable_seamless(self):
10451067
try:
10461068
self.vm.run_service_for_stdio("qubes.SetGuiMode", input=b'SEAMLESS')
@@ -1146,6 +1168,17 @@ def __apply_advanced_tab__(self):
11461168
except qubesadmin.exc.QubesException as ex:
11471169
msg.append(str(ex))
11481170

1171+
rationale = self.vm.features.get("prohibit-start", "")
1172+
if (self.prohibit_start_checkbox.isChecked() != bool(rationale)) or (
1173+
bool(rationale)
1174+
and self.prohibit_start_rationale.text() != rationale
1175+
):
1176+
rationale = self.prohibit_start_rationale.text()
1177+
if bool(rationale) and self.prohibit_start_checkbox.isChecked():
1178+
self.vm.features["prohibit-start"] = rationale
1179+
else:
1180+
del self.vm.features["prohibit-start"]
1181+
11491182
if self.allow_fullscreen_initial !=\
11501183
self.allow_fullscreen.currentIndex():
11511184
try:

qubesmanager/tests/test_vm_settings.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,6 +1028,41 @@ def test_215_bootmode_appvm_nondefault(settings_fixture):
10281028
"Boot mode not changed"
10291029

10301030

1031+
@check_errors
1032+
@pytest.mark.parametrize("settings_fixture", TEST_VMS, indirect=True)
1033+
def test_213_prohibit_start(settings_fixture):
1034+
settings_window, page, vm_name = settings_fixture
1035+
vm = settings_window.qubesapp.domains[vm_name]
1036+
1037+
r = vm.features.get("prohibit-start", "")
1038+
assert settings_window.prohibit_start_checkbox.isChecked() == bool(r)
1039+
if r:
1040+
assert settings_window.prohibit_start_rationale.text() == r
1041+
1042+
settings_window.prohibit_start_checkbox.setChecked(not bool(r))
1043+
1044+
if bool(r):
1045+
settings_window.prohibit_start_rationale.setText("")
1046+
expected_call = (
1047+
vm.name,
1048+
"admin.vm.feature.Remove",
1049+
"prohibit-start",
1050+
None,
1051+
)
1052+
else:
1053+
settings_window.prohibit_start_rationale.setText("RATIONALE")
1054+
expected_call = (
1055+
vm.name,
1056+
"admin.vm.feature.Set",
1057+
"prohibit-start",
1058+
"RATIONALE".encode(),
1059+
)
1060+
1061+
assert expected_call not in settings_window.qubesapp.actual_calls
1062+
settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
1063+
settings_window.accept()
1064+
1065+
10311066
# FIREWALL TAB
10321067

10331068
@check_errors

ui/settingsdlg.ui

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -742,14 +742,35 @@ border-width: 1px;</string>
742742
<property name="topMargin">
743743
<number>15</number>
744744
</property>
745-
<item row="2" column="0">
745+
<item row="2" column="0" colspan="2">
746+
<layout class="QHBoxLayout" name="horizontalLayout_prohibit_start">
747+
<item>
748+
<widget class="QCheckBox" name="prohibit_start_checkbox">
749+
<property name="text">
750+
<string>Prohibit start</string>
751+
</property>
752+
</widget>
753+
</item>
754+
<item>
755+
<widget class="QLineEdit" name="prohibit_start_rationale">
756+
<property name="text">
757+
<string>Rationale for start prohibition...</string>
758+
</property>
759+
<property name="placeholderText">
760+
<string>Start prohibition rationale is mandatory!</string>
761+
</property>
762+
</widget>
763+
</item>
764+
</layout>
765+
</item>
766+
<item row="3" column="0">
746767
<widget class="QCheckBox" name="provides_network_checkbox">
747768
<property name="text">
748769
<string>Provides network</string>
749770
</property>
750771
</widget>
751772
</item>
752-
<item row="3" column="0">
773+
<item row="4" column="0">
753774
<widget class="QCheckBox" name="dvm_template_checkbox">
754775
<property name="toolTip">
755776
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Allows using this qube as a template for disposables. Disposables will inherit the qube's state (configuration, installed programs, etc.), but their state will not persist between restarts. &lt;/p&gt;&lt;p&gt;Setting this option will cause this qube to be listed as an option in the &amp;quot;Default disposable template&amp;quot; list for all other qubes.&lt;/p&gt;&lt;p&gt;Only AppVMs and StandaloneVMs could be turned in to Disposable Templates&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>

0 commit comments

Comments
 (0)