Skip to content

Commit 8c4cd25

Browse files
committed
Add free-form text to qube for notes, comments, ...
qubesadmin part of adding free-form text to each qube for comments, notes, descriptions, remarks, reminders, etc. fixes: QubesOS/qubes-issues#899 requires: QubesOS/qubes-core-admin-client#334
1 parent 02c9f0e commit 8c4cd25

File tree

5 files changed

+57
-0
lines changed

5 files changed

+57
-0
lines changed

icons/notes.svg

Lines changed: 1 addition & 0 deletions
Loading

qubesmanager/settings.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
153153
('devices', 3),
154154
('applications', 4),
155155
('services', 5),
156+
('notes', 6),
156157
))
157158

158159
# pylint: disable=too-many-positional-arguments
@@ -273,6 +274,9 @@ def __init__(self, vm_name, init_page="basic", qapp=None, qubesapp=None,
273274
self.warn_template_missing_apps.setVisible(
274275
self.app_list_manager.has_missing)
275276

277+
####### notes tab
278+
self.__init_notes_tab__()
279+
276280
def setup_application(self):
277281
self.qapp.setApplicationName(self.tr("Qube Settings"))
278282
self.qapp.setWindowIcon(QtGui.QIcon.fromTheme("qubes-manager"))
@@ -354,6 +358,9 @@ def __save_changes__(self):
354358
ret_tmp = self.__apply_services_tab__()
355359
if ret_tmp:
356360
ret += [self.tr("Sevices tab:")] + ret_tmp
361+
ret_tmp = self.__apply_notes_tab__()
362+
if ret_tmp:
363+
ret += [self.tr("Notes tab:")] + ret_tmp
357364
except qubesadmin.exc.QubesException as qex:
358365
ret.append(self.tr('Error while saving changes: ') + str(qex))
359366
except Exception as ex: # pylint: disable=broad-except
@@ -1587,6 +1594,23 @@ def __init_services_tab__(self):
15871594
self.service_line_edit.addItem(self.tr('(custom...)'))
15881595
self.service_line_edit.setEditText("")
15891596

1597+
def __init_notes_tab__(self):
1598+
try:
1599+
self.notes.setPlainText(self.vm.get_notes())
1600+
except qubesadmin.exc.QubesException:
1601+
self.notes.setPlainText(
1602+
"Could not retrieve notes for this qube "
1603+
)
1604+
self.notes.setEnabled(False)
1605+
1606+
def __apply_notes_tab__(self):
1607+
try:
1608+
if self.notes.isEnabled():
1609+
if self.notes.toPlainText() != self.vm.get_notes():
1610+
self.vm.set_notes(self.notes.toPlainText())
1611+
except qubesadmin.exc.QubesException as ex:
1612+
return str(ex)
1613+
15901614
def __add_service__(self):
15911615
srv = str(self.service_line_edit.currentText()).strip()
15921616

qubesmanager/tests/test_vm_settings.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ def settings_fixture(request, qapp, test_qubes_app) -> Tuple[
143143
page = 'basic'
144144
with mock.patch('subprocess.check_output') as mock_subprocess:
145145
mock_subprocess.side_effect = mock_subprocess_complex
146+
expected_call = (vm.name, 'admin.vm.notes.Get', None, None)
147+
test_qubes_app.expected_calls[expected_call] = b'0\x00Some Notes\x00'
146148
vms = vm_settings.VMSettingsWindow(vm, page, qapp,
147149
test_qubes_app)
148150

@@ -1313,6 +1315,7 @@ def test_306_firewall_unlimit(settings_fixture):
13131315
def test_307_open_with_limit(mock_subprocess, qapp, test_qubes_app):
13141316
# this test is supposed to check if the settings open even when there is
13151317
# an unlimited FW access set
1318+
# It also checks if inaccessible qube note is disabled
13161319
mock_subprocess.result = []
13171320

13181321
# add 2 minutes to now
@@ -1330,6 +1333,9 @@ def test_307_open_with_limit(mock_subprocess, qapp, test_qubes_app):
13301333
name="test-vm-fw", qapp=test_qubes_app, label="green",
13311334
firewall_rules=fw_rules
13321335
)
1336+
expected_call = ("test-vm-fw", 'admin.vm.notes.Get', None, None)
1337+
test_qubes_app.expected_calls[expected_call] = \
1338+
'2\0QubesNotesException\0\0Notes not available!\0'
13331339
test_qubes_app.update_vm_calls()
13341340

13351341
settings_window = vm_settings.VMSettingsWindow(
@@ -1341,6 +1347,7 @@ def test_307_open_with_limit(mock_subprocess, qapp, test_qubes_app):
13411347

13421348
assert settings_window.temp_full_access.isChecked()
13431349
assert settings_window.tempFullAccessWidget.isEnabled()
1350+
assert not settings_window.notes.isEnabled()
13441351

13451352

13461353
@check_errors

resources.qrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
<file alias="killvm">icons/kill.svg</file>
1919
<file alias="log">icons/log.svg</file>
2020
<file alias="networking">icons/netvm.svg</file>
21+
<file alias="notes">icons/notes.svg</file>
2122
<file alias="obsolete.svg">icons/obsolete.svg</file>
2223
<file alias="outdated">icons/outdated.svg</file>
2324
<file alias="paused">icons/paused.svg</file>

ui/settingsdlg.ui

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1866,6 +1866,30 @@ The qube must be running to disable seamless mode. This setting is not persisten
18661866
</item>
18671867
</layout>
18681868
</widget>
1869+
<widget class="QWidget" name="notes_tab">
1870+
<attribute name="icon">
1871+
<iconset resource="../resources.qrc">
1872+
<normaloff>:/notes</normaloff>:/notes</iconset>
1873+
</attribute>
1874+
<attribute name="title">
1875+
<string>Notes</string>
1876+
</attribute>
1877+
<layout class="QVBoxLayout" name="verticalLayout_notes_tab">
1878+
<item>
1879+
<layout class="QVBoxLayout" name="verticalLayout_notes">
1880+
<item>
1881+
<widget class="QPlainTextEdit" name="notes">
1882+
<property name="placeholderText">
1883+
<string>Notes and comments (up to 256KB of clear text)
1884+
For user reference only.
1885+
</string>
1886+
</property>
1887+
</widget>
1888+
</item>
1889+
</layout>
1890+
</item>
1891+
</layout>
1892+
</widget>
18691893
</widget>
18701894
</item>
18711895
<item>

0 commit comments

Comments
 (0)