qubesmanager/utils
This commit is contained in:
parent
ea28980717
commit
6462ae88b7
@ -32,6 +32,7 @@ import subprocess
|
||||
import qubesadmin
|
||||
import qubesadmin.tools
|
||||
|
||||
from . import utils
|
||||
|
||||
from .ui_settingsdlg import *
|
||||
from .appmenu_select import *
|
||||
@ -186,7 +187,7 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
|
||||
if len(ret) > 0 :
|
||||
thread_monitor.set_error_msg('\n'.join(ret))
|
||||
|
||||
thread_monitor.set_finished()
|
||||
utils.debug('\n'.join(ret))
|
||||
|
||||
|
||||
def current_tab_changed(self, idx):
|
||||
@ -201,11 +202,10 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
|
||||
"a working Firewall VM.").format(vm=self.vm.name))
|
||||
|
||||
|
||||
|
||||
######### basic tab
|
||||
|
||||
# TODO LISTENERS
|
||||
# - vm start/shutdown -> setEnabled on fields: template
|
||||
# - vm start/shutdown -> setEnabled on fields: template labels
|
||||
# - vm create/delete -> choices lists, whole window deactiv (if self.vm)
|
||||
# - property-set -> individual fields
|
||||
|
||||
@ -213,45 +213,8 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
|
||||
# netvm -> networking_groupbox
|
||||
# hvm -> include_in_balancing
|
||||
|
||||
def setup_vm_choice(self, widget, propname, default, filter_function,
|
||||
allow_internal=False, allow_none=False):
|
||||
# some basic information
|
||||
oldvalue = getattr(self.vm, propname)
|
||||
is_default = self.vm.property_is_default(propname)
|
||||
idx = -1
|
||||
|
||||
vmlist = filter(filter_function, self.app.domains)
|
||||
if not allow_internal:
|
||||
vmlist = filter((lambda vm: not vm.features.get('internal', False)),
|
||||
vmlist)
|
||||
vmlist = list(vmlist)
|
||||
vmlist.insert(0, qubesadmin.DEFAULT)
|
||||
if allow_none:
|
||||
vmlist.append(None)
|
||||
|
||||
for i, vm in enumerate(vmlist):
|
||||
# 0: default (unset)
|
||||
if vm is qubesadmin.DEFAULT:
|
||||
text = 'default ({})'.format(
|
||||
default.name if default else 'none')
|
||||
# N+1: explicit None
|
||||
elif vm is None:
|
||||
text = 'none'
|
||||
# 1..N: choices
|
||||
else:
|
||||
text = vm.name
|
||||
|
||||
if vm is qubesadmin.DEFAULT and is_default \
|
||||
or vm is oldvalue:
|
||||
text += self.tr(' (current)')
|
||||
idx = i
|
||||
|
||||
widget.insertItem(i, text)
|
||||
|
||||
setattr(self, propname + '_idx', idx)
|
||||
setattr(self, propname + '_list', list)
|
||||
widget.setCurrentIndex(idx)
|
||||
|
||||
# TODO REMOVE
|
||||
# other_groupbox
|
||||
|
||||
def __init_basic_tab__(self):
|
||||
self.vmname.setText(self.vm.name)
|
||||
@ -261,27 +224,32 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
|
||||
if self.vm.qid == 0:
|
||||
self.vmlabel.setVisible(False)
|
||||
else:
|
||||
self.label_list, self.label_idx = utils.prepare_label_choice(
|
||||
self.vmlabel,
|
||||
self.vm, 'label',
|
||||
None,
|
||||
allow_default=False
|
||||
)
|
||||
self.vmlabel.setVisible(True)
|
||||
self.label_list = list(self.vm.app.labels)
|
||||
self.label_list.sort(key=lambda l: l.index)
|
||||
self.label_idx = 0
|
||||
for i, label in enumerate(self.label_list):
|
||||
if label == self.vm.label:
|
||||
self.label_idx = i
|
||||
self.vmlabel.insertItem(i, label.name)
|
||||
self.vmlabel.setItemIcon(i, QIcon.fromTheme(label.icon))
|
||||
self.vmlabel.setCurrentIndex(self.label_idx)
|
||||
self.vmlabel.setEnabled(not self.vm.is_running())
|
||||
self.vmlabel.setEnabled(not self.vm.is_running())
|
||||
|
||||
if isinstance(self.vm, qubesadmin.vm.AppVM):
|
||||
self.setup_vm_choice(self.template_name, 'template',
|
||||
(lambda vm: isinstance(vm, qubesadmin.vm.TemplateVM)))
|
||||
self.template_list, self.template_idx = utils.prepare_vm_choice(
|
||||
self.template_name,
|
||||
self.vm, 'template',
|
||||
self.vm.app.default_template,
|
||||
(lambda vm: isinstance(vm, qubesadmin.vm.TemplateVM)),
|
||||
allow_default=True, allow_none=False)
|
||||
else:
|
||||
self.template_name.setEnabled(False)
|
||||
self.template_idx = -1
|
||||
|
||||
self.setup_vm_choice(self.netVM, 'netvm',
|
||||
(lambda vm: vm.provides_network))
|
||||
self.netvm_list, self.netvm_idx = utils.prepare_vm_choice(
|
||||
self.netVM,
|
||||
self.vm, 'netvm',
|
||||
self.vm.app.default_netvm,
|
||||
(lambda vm: vm.provides_network),
|
||||
allow_default=True, allow_none=True)
|
||||
|
||||
self.include_in_backups.setChecked(self.vm.include_in_backups)
|
||||
|
||||
@ -463,47 +431,30 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
|
||||
except AttributeError:
|
||||
pass
|
||||
try:
|
||||
self.root_img_path.setText(self.vm.storage.root_img)
|
||||
self.root_img_path.setText('{volume.pool}:{volume.vid}'.format(
|
||||
volume=self.vm.volumes['root']))
|
||||
except AttributeError:
|
||||
self.root_img_path.setText("n/a")
|
||||
try:
|
||||
self.volatile_img_path.setText(self.vm.storage.volatile_img)
|
||||
self.volatile_img_path.setText('{volume.pool}:{volume.vid}'.format(
|
||||
volume=self.vm.volumes['volatile']))
|
||||
except AttributeError:
|
||||
self.volatile_img_path.setText('n/a')
|
||||
self.private_img_path.setText(self.vm.storage.private_img)
|
||||
self.private_img_path.setText('{volume.pool}:{volume.vid}'.format(
|
||||
volume=self.vm.volumes['private']))
|
||||
|
||||
|
||||
#kernel
|
||||
|
||||
#in case VM is HVM
|
||||
if not hasattr(self.vm, "kernel"):
|
||||
self.kernel_groupbox.setVisible(False)
|
||||
else:
|
||||
if hasattr(self.vm, "kernel"):
|
||||
self.kernel_groupbox.setVisible(True)
|
||||
# construct available kernels list
|
||||
text = "default (" + self.app.get_default_kernel() +")"
|
||||
kernel_list = [text]
|
||||
for k in os.listdir(system_path["qubes_kernels_base_dir"]):
|
||||
kernel_list.append(k)
|
||||
kernel_list.append("none")
|
||||
|
||||
self.kernel_idx = 0
|
||||
|
||||
# put available kernels to a combobox
|
||||
for (i, k) in enumerate(kernel_list):
|
||||
text = k
|
||||
# and mark the current choice
|
||||
if (text.startswith("default") and self.vm.uses_default_kernel) or ( self.vm.kernel == k and not self.vm.uses_default_kernel) or (k=="none" and self.vm.kernel==None):
|
||||
text += " (current)"
|
||||
self.kernel_idx = i
|
||||
self.kernel.insertItem(i,text)
|
||||
self.kernel.setCurrentIndex(self.kernel_idx)
|
||||
|
||||
#kernel opts
|
||||
if self.vm.uses_default_kernelopts:
|
||||
self.kernel_opts.setText(self.vm.kernelopts + " (default)")
|
||||
else:
|
||||
self.kernel_opts.setText(self.vm.kernelopts)
|
||||
self.kernel_list, self.kernel_idx = utils.prepare_kernel_choice(
|
||||
self.kernel, self.vm, 'kernel',
|
||||
self.vm.app.default_kernel,
|
||||
allow_default=True, allow_none=True)
|
||||
else:
|
||||
self.kernel_groupbox.setVisible(False)
|
||||
|
||||
if not hasattr(self.vm, "drive"):
|
||||
self.drive_groupbox.setVisible(False)
|
||||
@ -660,6 +611,8 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
|
||||
self.vm.dispvm_netvm = dispvm_netvm
|
||||
self.anything_changed = True
|
||||
except Exception as ex:
|
||||
if utils.is_debug():
|
||||
traceback.print_exc()
|
||||
msg.append(str(ex))
|
||||
|
||||
return msg
|
||||
@ -742,6 +695,8 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog):
|
||||
self.vm.pcidevs = pcidevs
|
||||
self.anything_changed = True
|
||||
except Exception as ex:
|
||||
if utils.is_debug():
|
||||
traceback.print_exc()
|
||||
msg.append(str(ex))
|
||||
|
||||
return msg
|
||||
@ -1005,13 +960,9 @@ parser = qubesadmin.tools.QubesArgumentParser(vmname_nargs=1)
|
||||
parser.add_argument('--tab', metavar='TAB',
|
||||
action='store',
|
||||
choices=VMSettingsWindow.tabs_indices.keys())
|
||||
parser.add_argument('--debug',
|
||||
action='store_true',
|
||||
help='debug mode')
|
||||
|
||||
parser.set_defaults(
|
||||
tab='basic',
|
||||
debug=os.getenv('QUBES_MANAGER_DEBUG', '0') != '0',
|
||||
)
|
||||
|
||||
def main(args=None):
|
||||
@ -1025,7 +976,7 @@ def main(args=None):
|
||||
qapp.setOrganizationDomain("https://www.qubes-os.org/")
|
||||
qapp.setApplicationName("Qubes VM Settings")
|
||||
|
||||
if not args.debug:
|
||||
if not utils.is_debug():
|
||||
sys.excepthook = handle_exception
|
||||
|
||||
settings_window = VMSettingsWindow(vm, qapp, args.tab)
|
||||
|
137
qubesmanager/utils.py
Normal file
137
qubesmanager/utils.py
Normal file
@ -0,0 +1,137 @@
|
||||
#
|
||||
# The Qubes OS Project, https://www.qubes-os.org
|
||||
#
|
||||
# Copyright (C) 2012 Agnieszka Kostrzewa <agnieszka.kostrzewa@gmail.com>
|
||||
# Copyright (C) 2012 Marek Marczykowski-Górecki
|
||||
# <marmarek@invisiblethingslab.com>
|
||||
# Copyright (C) 2017 Wojtek Porczyk <woju@invisiblethingslab.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import functools
|
||||
import os
|
||||
|
||||
import qubesadmin
|
||||
|
||||
from PyQt4.QtGui import QIcon
|
||||
|
||||
def _filter_internal(vm):
|
||||
return (not isinstance(vm, qubesadmin.vm.AdminVM)
|
||||
and not vm.features.get('internal', False))
|
||||
|
||||
def prepare_choice(widget, holder, propname, choice, default,
|
||||
filter_function=None, *,
|
||||
icon_getter=None, allow_internal=None, allow_default=False,
|
||||
allow_none=False):
|
||||
|
||||
# for newly created vms, set propname to None
|
||||
|
||||
debug(
|
||||
'prepare_choice(widget={widget!r}, '
|
||||
'holder={holder!r}, '
|
||||
'propname={propname!r}, '
|
||||
'choice={choice!r}, '
|
||||
'default={default!r}, '
|
||||
'filter_function={filter_function!r}, '
|
||||
'icon_getter={icon_getter!r}, '
|
||||
'allow_internal={allow_internal!r}, '
|
||||
'allow_default={allow_default!r}, '
|
||||
'allow_none={allow_none!r})'.format(**locals()))
|
||||
|
||||
if allow_internal is None:
|
||||
allow_internal = propname is None or not propname.endswith('vm')
|
||||
|
||||
if propname is not None:
|
||||
oldvalue = getattr(holder, propname)
|
||||
is_default = holder.property_is_default(propname)
|
||||
else:
|
||||
oldvalue = object() # won't match for identity
|
||||
is_default = False
|
||||
idx = 0
|
||||
|
||||
choice_list = list(choice)[:]
|
||||
if not allow_internal:
|
||||
choice_list = filter(_filter_internal, choice_list)
|
||||
if filter_function is not None:
|
||||
choice_list = filter(filter_function, choice_list)
|
||||
choice_list = list(choice_list)
|
||||
|
||||
if allow_default:
|
||||
choice_list.insert(0, qubesadmin.DEFAULT)
|
||||
if allow_none:
|
||||
choice_list.append(None)
|
||||
|
||||
for i, item in enumerate(choice_list):
|
||||
debug('i={} item={}'.format(i, item))
|
||||
# 0: default (unset)
|
||||
if item is qubesadmin.DEFAULT:
|
||||
text = 'default ({})'.format(
|
||||
str(default) if default is not None else 'none')
|
||||
# N+1: explicit None
|
||||
elif item is None:
|
||||
text = 'none'
|
||||
# 1..N: choices
|
||||
else:
|
||||
text = str(item)
|
||||
|
||||
if item is qubesadmin.DEFAULT and is_default \
|
||||
or item is not qubesadmin.DEFAULT and item is oldvalue:
|
||||
text += ' (current)'
|
||||
idx = i
|
||||
|
||||
widget.insertItem(i, text)
|
||||
|
||||
if icon_getter is not None:
|
||||
icon = icon_getter(item)
|
||||
if icon is not None:
|
||||
widget.setItemIcon(i, icon)
|
||||
|
||||
widget.setCurrentIndex(idx)
|
||||
|
||||
return choice_list, idx
|
||||
|
||||
def prepare_kernel_choice(widget, holder, propname, default, *args, **kwargs):
|
||||
# TODO get from storage API (pool 'linux-kernel') (suggested by @marmarta)
|
||||
return prepare_choice(widget, holder, propname,
|
||||
os.listdir('/var/lib/qubes/vm-kernels'), default, *args, **kwargs)
|
||||
|
||||
def prepare_label_choice(widget, holder, propname, default, *args, **kwargs):
|
||||
try:
|
||||
app = holder.app
|
||||
except AttributeError:
|
||||
app = holder
|
||||
|
||||
return prepare_choice(widget, holder, propname,
|
||||
sorted(app.labels, key=lambda l: l.index),
|
||||
default, *args,
|
||||
icon_getter=(lambda label: QIcon.fromTheme(label.icon)),
|
||||
**kwargs)
|
||||
|
||||
def prepare_vm_choice(widget, holder, propname, default, *args, **kwargs):
|
||||
try:
|
||||
app = holder.app
|
||||
except AttributeError:
|
||||
app = holder
|
||||
|
||||
return prepare_choice(widget, holder, propname, app.domains, default,
|
||||
*args, **kwargs)
|
||||
|
||||
def is_debug():
|
||||
return os.getenv('QUBES_MANAGER_DEBUG', '') not in ('', '0')
|
||||
|
||||
def debug(*args, **kwargs):
|
||||
if not is_debug():
|
||||
return
|
||||
print(*args, **kwargs)
|
@ -85,7 +85,10 @@ rm -rf $RPM_BUILD_ROOT
|
||||
%{python3_sitelib}/qubesmanager/informationnotes.py
|
||||
%{python3_sitelib}/qubesmanager/create_new_vm.py
|
||||
%{python3_sitelib}/qubesmanager/thread_monitor.py
|
||||
%{python3_sitelib}/qubesmanager/utils.py
|
||||
|
||||
%{python3_sitelib}/qubesmanager/resources_rc.py
|
||||
|
||||
%{python3_sitelib}/qubesmanager/ui_backupdlg.py
|
||||
%{python3_sitelib}/qubesmanager/ui_globalsettingsdlg.py
|
||||
%{python3_sitelib}/qubesmanager/ui_multiselectwidget.py
|
||||
|
Loading…
Reference in New Issue
Block a user