2015-03-26 16:44:24 +03:00
# Copyright (C) 2006-2007, 2012-2015 Red Hat, Inc.
2007-04-12 23:36:04 +04:00
# Copyright (C) 2006 Hugh O. Brock <hbrock@redhat.com>
#
2018-04-04 16:35:41 +03:00
# This work is licensed under the GNU GPLv2 or later.
2018-03-20 22:00:02 +03:00
# See the COPYING file in the top-level directory.
2007-04-12 23:36:04 +04:00
2009-07-14 17:25:39 +04:00
import logging
import traceback
2012-05-14 17:24:56 +04:00
from gi . repository import Gtk
from gi . repository import Gdk
2009-07-14 17:25:39 +04:00
2018-04-24 22:40:33 +03:00
from virtinst import ( DeviceChannel , DeviceConsole ,
DeviceController , DeviceDisk , DeviceGraphics , DeviceHostdev ,
DeviceInput , DeviceInterface , DevicePanic , DeviceParallel ,
DeviceRedirdev , DeviceRng , DeviceSerial , DeviceSmartcard ,
2018-12-14 17:34:20 +03:00
DeviceSound , DeviceTpm , DeviceVideo , DeviceVsock , DeviceWatchdog )
2007-04-12 23:36:04 +04:00
2014-09-13 00:10:45 +04:00
from . import uiutil
from . fsdetails import vmmFSDetails
from . gfxdetails import vmmGraphicsDetails
from . netlist import vmmNetworkList
from . asyncjob import vmmAsyncJob
from . storagebrowse import vmmStorageBrowser
from . baseclass import vmmGObjectUI
from . addstorage import vmmAddStorage
2018-12-14 17:34:20 +03:00
from . vsockdetails import vmmVsockDetails
2007-04-12 23:36:04 +04:00
2019-04-14 03:45:21 +03:00
( PAGE_DISK ,
2017-09-07 12:03:04 +03:00
PAGE_CONTROLLER ,
PAGE_NETWORK ,
PAGE_INPUT ,
PAGE_GRAPHICS ,
PAGE_SOUND ,
PAGE_HOSTDEV ,
PAGE_CHAR ,
PAGE_VIDEO ,
PAGE_WATCHDOG ,
PAGE_FILESYSTEM ,
PAGE_SMARTCARD ,
PAGE_USBREDIR ,
PAGE_TPM ,
PAGE_RNG ,
2018-12-14 17:34:20 +03:00
PAGE_PANIC ,
2019-04-14 03:45:21 +03:00
PAGE_VSOCK ) = range ( 17 )
2009-07-14 17:25:39 +04:00
2013-06-26 05:45:09 +04:00
2018-04-24 22:40:33 +03:00
def _build_combo ( combo , values , default_value = None , sort = True ) :
"""
Helper to build a combo with model schema [ xml value , label ]
"""
model = Gtk . ListStore ( object , str )
combo . set_model ( model )
uiutil . init_combo_text_column ( combo , 1 )
if sort :
model . set_sort_column_id ( 1 , Gtk . SortType . ASCENDING )
for xmlval , label in values :
model . append ( [ xmlval , label ] )
if default_value :
uiutil . set_list_selection ( combo , default_value )
elif len ( model ) :
combo . set_active ( 0 )
2010-12-09 01:26:19 +03:00
class vmmAddHardware ( vmmGObjectUI ) :
2019-05-08 23:50:08 +03:00
def __init__ ( self , vm ) :
2013-09-23 00:10:16 +04:00
vmmGObjectUI . __init__ ( self , " addhardware.ui " , " vmm-add-hardware " )
2010-12-09 01:26:19 +03:00
2007-04-12 23:36:04 +04:00
self . vm = vm
2011-07-23 00:43:26 +04:00
self . conn = vm . conn
2008-11-19 01:01:22 +03:00
2015-05-19 22:18:30 +03:00
self . _storagebrowser = None
2009-03-09 23:19:39 +03:00
2014-06-16 07:48:22 +04:00
self . _remove_usb_controller = None
self . _selected_model = None
2009-07-14 17:25:39 +04:00
2015-05-19 22:18:30 +03:00
self . _gfxdetails = vmmGraphicsDetails (
2014-01-29 03:44:40 +04:00
self . vm , self . builder , self . topwin )
2015-05-19 22:18:30 +03:00
self . widget ( " graphics-align " ) . add ( self . _gfxdetails . top_box )
2014-01-29 03:44:40 +04:00
2015-05-19 22:18:30 +03:00
self . _fsdetails = vmmFSDetails ( self . vm , self . builder , self . topwin )
self . widget ( " fs-box " ) . add ( self . _fsdetails . top_box )
2014-01-29 01:53:11 +04:00
2015-05-19 22:18:30 +03:00
self . _netlist = vmmNetworkList ( self . conn , self . builder , self . topwin )
self . widget ( " network-source-label-align " ) . add ( self . _netlist . top_label )
self . widget ( " network-source-ui-align " ) . add ( self . _netlist . top_box )
self . widget ( " network-vport-align " ) . add ( self . _netlist . top_vport )
2014-01-27 20:03:59 +04:00
2014-01-29 01:53:11 +04:00
self . addstorage = vmmAddStorage ( self . conn , self . builder , self . topwin )
2015-09-14 01:01:39 +03:00
self . widget ( " storage-align " ) . add ( self . addstorage . top_box )
2014-01-29 01:53:11 +04:00
self . addstorage . connect ( " browse-clicked " , self . _browse_storage_cb )
2018-12-14 17:34:20 +03:00
self . _vsockdetails = vmmVsockDetails ( self . vm , self . builder , self . topwin )
self . widget ( " vsock-align " ) . add ( self . _vsockdetails . top_box )
2013-02-16 22:31:46 +04:00
self . builder . connect_signals ( {
2017-08-05 09:39:32 +03:00
" on_create_cancel_clicked " : self . close ,
" on_vmm_create_delete_event " : self . close ,
" on_create_finish_clicked " : self . _finish ,
2019-04-14 03:45:21 +03:00
" on_hw_list_changed " : self . _hw_selected_cb ,
2009-11-24 21:14:55 +03:00
2015-09-14 01:01:39 +03:00
" on_storage_devtype_changed " : self . _change_storage_devtype ,
2009-11-24 21:14:55 +03:00
2017-08-05 09:39:32 +03:00
" on_mac_address_clicked " : self . _change_macaddr_use ,
2009-11-24 21:14:55 +03:00
2015-05-19 22:18:30 +03:00
" on_char_device_type_changed " : self . _change_char_device_type ,
" on_char_target_name_changed " : self . _change_char_target_name ,
" on_char_auto_socket_toggled " : self . _change_char_auto_socket ,
2009-07-14 17:25:39 +04:00
2015-05-19 22:18:30 +03:00
" on_tpm_device_type_changed " : self . _change_tpm_device_type ,
2013-06-26 05:45:09 +04:00
2015-05-19 22:18:30 +03:00
" on_usbredir_type_changed " : self . _change_usbredir_type ,
2013-09-23 17:39:57 +04:00
2018-04-24 22:40:33 +03:00
" on_controller_type_changed " : self . _change_controller_type ,
2012-11-08 17:15:02 +04:00
} )
2011-04-18 19:25:28 +04:00
self . bind_escape_key_close ( )
2007-04-12 23:36:04 +04:00
2015-05-19 22:18:30 +03:00
self . _set_initial_state ( )
2013-09-22 20:18:49 +04:00
2011-04-14 16:47:42 +04:00
def show ( self , parent ) :
2012-02-01 03:16:54 +04:00
logging . debug ( " Showing addhw " )
2015-05-19 22:18:30 +03:00
self . _reset_state ( )
2011-04-14 16:47:42 +04:00
self . topwin . set_transient_for ( parent )
2007-04-12 23:36:04 +04:00
self . topwin . present ( )
2013-07-07 19:06:15 +04:00
self . conn . schedule_priority_tick ( pollnet = True ,
pollpool = True , polliface = True ,
2015-04-07 20:56:48 +03:00
pollnodedev = True )
2007-04-12 23:36:04 +04:00
2010-11-29 22:06:43 +03:00
def close ( self , ignore1 = None , ignore2 = None ) :
2019-04-14 00:03:16 +03:00
if self . is_visible ( ) :
2015-05-03 23:56:45 +03:00
logging . debug ( " Closing addhw " )
self . topwin . hide ( )
2015-05-19 22:18:30 +03:00
if self . _storagebrowser :
self . _storagebrowser . close ( )
2011-04-12 02:35:21 +04:00
2009-11-24 20:43:54 +03:00
return 1
2011-07-24 05:16:54 +04:00
def _cleanup ( self ) :
self . vm = None
self . conn = None
2011-04-12 02:35:21 +04:00
2015-05-19 22:18:30 +03:00
if self . _storagebrowser :
self . _storagebrowser . cleanup ( )
self . _storagebrowser = None
2011-04-12 02:35:21 +04:00
2015-05-19 22:18:30 +03:00
self . _gfxdetails . cleanup ( )
self . _gfxdetails = None
self . _fsdetails . cleanup ( )
self . _fsdetails = None
self . _netlist . cleanup ( )
self . _netlist = None
2014-01-29 01:53:11 +04:00
self . addstorage . cleanup ( )
self . addstorage = None
2018-12-14 17:34:20 +03:00
self . _vsockdetails . cleanup ( )
self . _vsockdetails = None
2014-01-21 13:05:30 +04:00
2009-11-24 20:43:54 +03:00
##########################
# Initialization methods #
##########################
2015-05-19 22:18:30 +03:00
def _set_initial_state ( self ) :
2019-04-14 03:45:21 +03:00
self . widget ( " create-pages " ) . set_show_tabs ( False )
self . widget ( " top-pages " ) . set_show_tabs ( False )
2007-04-12 23:36:04 +04:00
2013-09-27 19:18:52 +04:00
blue = Gdk . color_parse ( " #0072A8 " )
self . widget ( " page-title-box " ) . modify_bg ( Gtk . StateType . NORMAL , blue )
2007-04-12 23:36:04 +04:00
2016-02-05 18:18:16 +03:00
hw_col = Gtk . TreeViewColumn ( _ ( " Hardware " ) )
2010-12-11 20:32:04 +03:00
hw_col . set_spacing ( 6 )
hw_col . set_min_width ( 165 )
2012-05-14 17:24:56 +04:00
icon = Gtk . CellRendererPixbuf ( )
icon . set_property ( " stock-size " , Gtk . IconSize . BUTTON )
text = Gtk . CellRendererText ( )
2009-07-20 23:09:32 +04:00
text . set_property ( " xpad " , 6 )
2010-12-11 20:32:04 +03:00
hw_col . pack_start ( icon , False )
hw_col . pack_start ( text , True )
hw_col . add_attribute ( icon , ' icon-name ' , 1 )
hw_col . add_attribute ( text , ' text ' , 0 )
hw_col . add_attribute ( text , ' sensitive ' , 3 )
2019-04-14 03:45:21 +03:00
self . widget ( " hw-list " ) . append_column ( hw_col )
2009-07-09 02:49:25 +04:00
2018-04-24 22:40:33 +03:00
# Individual HW page UI
self . build_disk_bus_combo ( self . vm , self . widget ( " storage-bustype " ) )
self . _build_disk_device_combo ( )
self . build_disk_cache_combo ( self . vm , self . widget ( " storage-cache " ) )
2018-09-06 10:49:30 +03:00
self . build_disk_io_combo ( self . vm , self . widget ( " storage-io " ) )
2018-08-24 02:38:07 +03:00
self . build_disk_discard_combo ( self . vm , self . widget ( " storage-discard " ) )
2018-08-24 02:40:18 +03:00
self . build_disk_detect_zeroes_combo ( self . vm ,
self . widget ( " storage-detect-zeroes " ) )
2018-04-24 22:40:33 +03:00
self . build_network_model_combo ( self . vm , self . widget ( " net-model " ) )
self . _build_input_combo ( )
self . build_sound_combo ( self . vm , self . widget ( " sound-model " ) )
self . _build_hostdev_treeview ( )
self . build_video_combo ( self . vm , self . widget ( " video-model " ) )
_build_combo ( self . widget ( " char-device-type " ) , [ ] )
self . _build_char_target_type_combo ( )
self . _build_char_target_name_combo ( )
self . build_watchdogmodel_combo ( self . vm , self . widget ( " watchdog-model " ) )
self . build_watchdogaction_combo ( self . vm , self . widget ( " watchdog-action " ) )
self . build_smartcard_mode_combo ( self . vm , self . widget ( " smartcard-mode " ) )
self . _build_redir_type_combo ( )
self . _build_tpm_type_combo ( )
self . _build_panic_model_combo ( )
_build_combo ( self . widget ( " controller-model " ) , [ ] )
self . _build_controller_type_combo ( )
2009-03-09 23:20:23 +03:00
2014-04-26 18:40:17 +04:00
2010-12-11 23:55:31 +03:00
# Available HW options
2010-03-04 23:35:34 +03:00
is_local = not self . conn . is_remote ( )
is_storage_capable = self . conn . is_storage_capable ( )
2010-12-11 23:55:31 +03:00
have_storage = ( is_local or is_storage_capable )
storage_tooltip = None
if not have_storage :
storage_tooltip = _ ( " Connection does not support storage "
" management. " )
2019-04-14 03:45:21 +03:00
# Name, icon name, page number, is sensitive, tooltip, icon size,
# device type (serial/parallel)...
model = Gtk . ListStore ( str , str , int , bool , str , str )
self . widget ( " hw-list " ) . set_model ( model )
2010-12-11 23:55:31 +03:00
def add_hw_option ( name , icon , page , sensitive , errortxt , devtype = None ) :
model . append ( [ name , icon , page , sensitive , errortxt , devtype ] )
2016-02-05 18:18:16 +03:00
add_hw_option ( _ ( " Storage " ) , " drive-harddisk " , PAGE_DISK , have_storage ,
2010-12-11 23:55:31 +03:00
have_storage and storage_tooltip or None )
2016-02-05 18:18:16 +03:00
add_hw_option ( _ ( " Controller " ) , " device_pci " , PAGE_CONTROLLER , True , None )
add_hw_option ( _ ( " Network " ) , " network-idle " , PAGE_NETWORK , True , None )
add_hw_option ( _ ( " Input " ) , " input-mouse " , PAGE_INPUT , self . vm . is_hvm ( ) ,
2010-12-11 23:55:31 +03:00
_ ( " Not supported for this guest type. " ) )
2016-02-05 18:18:16 +03:00
add_hw_option ( _ ( " Graphics " ) , " video-display " , PAGE_GRAPHICS ,
2010-12-11 23:55:31 +03:00
True , None )
2016-02-05 18:18:16 +03:00
add_hw_option ( _ ( " Sound " ) , " audio-card " , PAGE_SOUND ,
2010-12-11 23:55:31 +03:00
self . vm . is_hvm ( ) ,
_ ( " Not supported for this guest type. " ) )
2016-02-05 18:18:16 +03:00
add_hw_option ( _ ( " Serial " ) , Gtk . STOCK_CONNECT , PAGE_CHAR ,
2010-12-11 23:55:31 +03:00
self . vm . is_hvm ( ) ,
_ ( " Not supported for this guest type. " ) ,
" serial " )
2016-02-05 18:18:16 +03:00
add_hw_option ( _ ( " Parallel " ) , Gtk . STOCK_CONNECT , PAGE_CHAR ,
2010-12-11 23:55:31 +03:00
self . vm . is_hvm ( ) ,
_ ( " Not supported for this guest type. " ) ,
" parallel " )
2016-02-05 18:18:16 +03:00
add_hw_option ( _ ( " Console " ) , Gtk . STOCK_CONNECT , PAGE_CHAR ,
2013-10-05 19:28:41 +04:00
True , None , " console " )
2016-02-05 18:18:16 +03:00
add_hw_option ( _ ( " Channel " ) , Gtk . STOCK_CONNECT , PAGE_CHAR ,
2011-04-05 03:35:32 +04:00
self . vm . is_hvm ( ) ,
_ ( " Not supported for this guest type. " ) ,
" channel " )
2016-02-05 18:18:16 +03:00
add_hw_option ( _ ( " USB Host Device " ) , " system-run " , PAGE_HOSTDEV ,
2011-04-12 02:35:21 +04:00
self . conn . is_nodedev_capable ( ) ,
2010-12-11 23:55:31 +03:00
_ ( " Connection does not support host device enumeration " ) ,
" usb " )
2015-12-23 15:01:29 +03:00
nodedev_enabled = self . conn . is_nodedev_capable ( )
nodedev_errstr = _ ( " Connection does not support "
" host device enumeration " )
if self . vm . is_container ( ) :
nodedev_enabled = False
nodedev_errstr = _ ( " Not supported for containers " )
2016-02-05 18:18:16 +03:00
add_hw_option ( _ ( " PCI Host Device " ) , " system-run " , PAGE_HOSTDEV ,
2015-12-23 15:01:29 +03:00
nodedev_enabled , nodedev_errstr , " pci " )
2016-02-05 18:18:16 +03:00
add_hw_option ( _ ( " Video " ) , " video-display " , PAGE_VIDEO , True ,
2010-12-11 23:55:31 +03:00
_ ( " Libvirt version does not support video devices. " ) )
2016-02-05 18:18:16 +03:00
add_hw_option ( _ ( " Watchdog " ) , " device_pci " , PAGE_WATCHDOG ,
2010-12-11 23:55:31 +03:00
self . vm . is_hvm ( ) ,
_ ( " Not supported for this guest type. " ) )
2018-09-06 18:36:54 +03:00
add_hw_option ( _ ( " Filesystem " ) , " folder " , PAGE_FILESYSTEM , True , None )
2016-02-05 18:18:16 +03:00
add_hw_option ( _ ( " Smartcard " ) , " device_serial " , PAGE_SMARTCARD ,
2011-06-23 19:42:03 +04:00
True , None )
2016-02-05 18:18:16 +03:00
add_hw_option ( _ ( " USB Redirection " ) , " device_usb " , PAGE_USBREDIR ,
2011-09-02 05:23:28 +04:00
True , None )
2016-02-05 18:18:16 +03:00
add_hw_option ( _ ( " TPM " ) , " device_cpu " , PAGE_TPM ,
2013-06-26 05:45:09 +04:00
True , None )
2016-02-05 18:18:16 +03:00
add_hw_option ( _ ( " RNG " ) , " system-run " , PAGE_RNG , True , None )
add_hw_option ( _ ( " Panic Notifier " ) , " system-run " , PAGE_PANIC ,
2018-09-01 04:06:18 +03:00
bool ( DevicePanic . get_models ( self . vm . get_xmlobj ( ) . os ) ) ,
2017-10-27 10:47:38 +03:00
_ ( " Not supported for this hypervisor/libvirt/arch combination. " ) )
2018-12-14 17:34:20 +03:00
add_hw_option ( _ ( " Virtio VSOCK " ) , " network-idle " , PAGE_VSOCK ,
self . vm . is_hvm ( ) ,
_ ( " Not supported for this hypervisor/libvirt/arch combination. " ) )
2010-12-11 23:55:31 +03:00
2018-04-24 22:40:33 +03:00
2015-05-19 22:18:30 +03:00
def _reset_state ( self ) :
2018-04-24 22:40:33 +03:00
# Hide all notebook pages, otherwise the wizard window is as large
# as the largest page
2019-04-14 03:45:21 +03:00
for page in range ( self . widget ( " create-pages " ) . get_n_pages ( ) ) :
widget = self . widget ( " create-pages " ) . get_nth_page ( page )
2018-04-24 22:40:33 +03:00
widget . hide ( )
2019-04-14 03:45:21 +03:00
self . _set_hw_selection ( 0 )
2018-04-24 22:40:33 +03:00
# Storage params
2015-09-14 01:01:39 +03:00
self . widget ( " storage-devtype " ) . set_active ( 0 )
self . widget ( " storage-devtype " ) . emit ( " changed " )
2018-01-19 21:14:01 +03:00
self . widget ( " storage-cache " ) . set_active ( 0 )
self . widget ( " disk-advanced-expander " ) . set_expanded ( False )
2014-01-29 01:53:11 +04:00
self . addstorage . reset_state ( )
2007-04-12 23:36:04 +04:00
2018-04-24 22:40:33 +03:00
2009-07-09 02:49:25 +04:00
# Network init
2018-04-24 22:40:33 +03:00
newmac = DeviceInterface . generate_mac ( self . conn . get_backend ( ) )
2011-07-14 21:13:13 +04:00
self . widget ( " mac-address " ) . set_active ( bool ( newmac ) )
self . widget ( " create-mac-address " ) . set_text ( newmac )
2015-05-19 22:18:30 +03:00
self . _change_macaddr_use ( )
2009-11-24 21:14:55 +03:00
2015-05-19 22:18:30 +03:00
self . _netlist . reset_state ( )
2009-11-30 20:51:25 +03:00
2011-07-14 21:13:13 +04:00
netmodel = self . widget ( " net-model " )
2014-01-27 02:09:07 +04:00
self . populate_network_model_combo ( self . vm , netmodel )
2009-01-23 01:00:10 +03:00
2010-12-10 19:47:07 +03:00
2009-07-14 17:25:39 +04:00
# Char parameters
2011-07-14 21:13:13 +04:00
self . widget ( " char-path " ) . set_text ( " " )
2014-03-25 18:42:34 +04:00
self . widget ( " char-channel " ) . set_text ( " " )
2013-10-05 21:54:28 +04:00
self . widget ( " char-auto-socket " ) . set_active ( True )
2009-07-14 17:25:39 +04:00
2010-12-11 22:51:08 +03:00
2013-09-23 17:39:57 +04:00
# RNG params
2017-06-27 22:43:06 +03:00
default_rng = " /dev/random "
2019-06-07 23:06:52 +03:00
if self . conn . support . conn_rng_urandom ( ) :
2017-06-27 22:43:06 +03:00
default_rng = " /dev/urandom "
self . widget ( " rng-device " ) . set_text ( default_rng )
2014-01-27 02:09:07 +04:00
2018-04-24 22:40:33 +03:00
# Remaining devices
self . _fsdetails . reset_state ( )
self . widget ( " tpm-device-path " ) . set_text ( " /dev/tpm0 " )
self . _gfxdetails . reset_state ( )
2018-12-14 17:34:20 +03:00
self . _vsockdetails . reset_state ( )
2014-01-27 02:09:07 +04:00
@staticmethod
2018-04-24 22:40:33 +03:00
def change_config_helper ( define_func , define_args , vm , err ,
devobj = None , hotplug_args = None ) :
"""
UI helper that handles the logic and reports errors for the
requested VM define and hotplug changes
2014-01-27 02:09:07 +04:00
2018-04-24 22:40:33 +03:00
Used here and in details . py
"""
hotplug_args = hotplug_args or { }
2014-01-27 02:09:07 +04:00
2018-04-24 22:40:33 +03:00
# Persistent config change
try :
if devobj :
# Device XML editing
define_func ( devobj = devobj , do_hotplug = False , * * define_args )
else :
# Guest XML editing
define_func ( * * define_args )
except Exception as e :
err . show_err ( ( _ ( " Error changing VM configuration: %s " ) %
str ( e ) ) )
return False
2014-01-27 02:09:07 +04:00
2018-04-24 22:40:33 +03:00
if not vm . is_active ( ) :
return True
2014-01-27 02:09:07 +04:00
2018-04-24 22:40:33 +03:00
# Hotplug change
hotplug_err = None
did_hotplug = False
try :
if devobj :
define_func ( devobj = devobj , do_hotplug = True , * * define_args )
did_hotplug = True
elif hotplug_args :
did_hotplug = True
vm . hotplug ( * * hotplug_args )
except Exception as e :
did_hotplug = True
logging . debug ( " Hotplug failed: %s " , str ( e ) )
hotplug_err = ( ( str ( e ) , " " . join ( traceback . format_exc ( ) ) ) )
2014-01-27 02:09:07 +04:00
2018-04-24 22:40:33 +03:00
if did_hotplug and not hotplug_err :
return True
2014-01-27 02:09:07 +04:00
2018-04-24 22:40:33 +03:00
if len ( define_args ) > 1 :
msg = _ ( " Some changes may require a guest shutdown "
" to take effect. " )
else :
msg = _ ( " These changes will take effect after "
" the next guest shutdown. " )
2014-01-27 02:09:07 +04:00
2018-04-24 22:40:33 +03:00
dtype = ( hotplug_err and
Gtk . MessageType . WARNING or Gtk . MessageType . INFO )
hotplug_msg = " "
if hotplug_err :
hotplug_msg + = ( hotplug_err [ 0 ] + " \n \n " +
hotplug_err [ 1 ] + " \n " )
2014-01-27 02:09:07 +04:00
2018-04-24 22:40:33 +03:00
err . show_err ( msg ,
details = hotplug_msg ,
buttons = Gtk . ButtonsType . OK ,
dialog_type = dtype )
2014-01-27 02:09:07 +04:00
2018-04-24 22:40:33 +03:00
return True
2014-01-27 02:09:07 +04:00
2018-04-24 22:40:33 +03:00
#########################
# UI init/reset helpers #
#########################
2014-01-27 02:09:07 +04:00
2018-04-24 22:40:33 +03:00
def _build_disk_device_combo ( self ) :
target_list = self . widget ( " storage-devtype " )
# [device, icon, label]
target_model = Gtk . ListStore ( str , str , str )
target_list . set_model ( target_model )
icon = Gtk . CellRendererPixbuf ( )
icon . set_property ( " stock-size " , Gtk . IconSize . BUTTON )
target_list . pack_start ( icon , False )
target_list . add_attribute ( icon , ' icon-name ' , 1 )
text = Gtk . CellRendererText ( )
text . set_property ( " xpad " , 6 )
target_list . pack_start ( text , True )
target_list . add_attribute ( text , ' text ' , 2 )
target_model . append ( [ DeviceDisk . DEVICE_DISK ,
" drive-harddisk " , _ ( " Disk device " ) ] )
target_model . append ( [ DeviceDisk . DEVICE_CDROM ,
2018-10-06 20:04:45 +03:00
" media-optical " , _ ( " CDROM device " ) ] )
2018-04-24 22:40:33 +03:00
target_model . append ( [ DeviceDisk . DEVICE_FLOPPY ,
" media-floppy " , _ ( " Floppy device " ) ] )
if self . conn . is_qemu ( ) or self . conn . is_test ( ) :
target_model . append ( [ DeviceDisk . DEVICE_LUN ,
" drive-harddisk " , _ ( " LUN Passthrough " ) ] )
target_list . set_active ( 0 )
2014-01-27 02:09:07 +04:00
@staticmethod
2018-04-24 22:40:33 +03:00
def build_disk_cache_combo ( _vm , combo ) :
values = [ [ None , _ ( " Hypervisor default " ) ] ]
2018-09-06 23:45:44 +03:00
for m in DeviceDisk . CACHE_MODES :
2018-04-24 22:40:33 +03:00
values . append ( [ m , m ] )
_build_combo ( combo , values , sort = False )
2014-01-27 02:09:07 +04:00
2018-09-06 10:49:29 +03:00
@staticmethod
def build_disk_io_combo ( _vm , combo ) :
values = [ [ None , _ ( " Hypervisor default " ) ] ]
2018-09-06 23:45:44 +03:00
for m in DeviceDisk . IO_MODES :
2018-09-06 10:49:29 +03:00
values . append ( [ m , m ] )
_build_combo ( combo , values , sort = False )
2018-08-24 02:38:07 +03:00
@staticmethod
def build_disk_discard_combo ( _vm , combo ) :
values = [ [ None , _ ( " Hypervisor default " ) ] ]
2018-09-06 23:45:44 +03:00
for m in DeviceDisk . DISCARD_MODES :
2018-08-24 02:38:07 +03:00
values . append ( [ m , m ] )
_build_combo ( combo , values , sort = False )
2018-08-24 02:40:18 +03:00
@staticmethod
def build_disk_detect_zeroes_combo ( _vm , combo ) :
values = [ [ None , _ ( " Hypervisor default " ) ] ]
2018-09-06 23:45:44 +03:00
for m in DeviceDisk . DETECT_ZEROES_MODES :
2018-08-24 02:40:18 +03:00
values . append ( [ m , m ] )
_build_combo ( combo , values , sort = False )
2014-01-27 02:09:07 +04:00
@staticmethod
2018-04-24 22:40:33 +03:00
def build_disk_bus_combo ( _vm , combo ) :
_build_combo ( combo , [ ] )
2014-01-27 02:09:07 +04:00
2015-04-08 02:31:30 +03:00
@staticmethod
2015-08-03 19:52:06 +03:00
def populate_disk_bus_combo ( vm , devtype , model ) :
2017-01-20 18:07:53 +03:00
domcaps = vm . get_domain_capabilities ( )
2018-09-06 23:40:49 +03:00
buses = DeviceDisk . get_recommended_buses ( vm . xmlobj , domcaps , devtype )
2015-04-08 02:31:30 +03:00
model . clear ( )
2018-09-06 23:40:49 +03:00
for bus in buses :
model . append ( [ bus , DeviceDisk . pretty_disk_bus ( bus ) ] )
2015-04-08 02:31:30 +03:00
2018-04-24 22:40:33 +03:00
2014-04-26 18:41:31 +04:00
@staticmethod
2018-04-24 22:40:33 +03:00
def populate_network_model_combo ( vm , combo ) :
2014-04-26 18:41:31 +04:00
model = combo . get_model ( )
model . clear ( )
2018-04-24 22:40:33 +03:00
# [xml value, label]
2015-05-19 19:50:39 +03:00
model . append ( [ None , _ ( " Hypervisor default " ) ] )
2018-09-02 03:36:53 +03:00
for netmodel in DeviceInterface . get_models ( vm . xmlobj ) :
model . append ( [ netmodel , netmodel ] )
uiutil . set_list_selection (
combo , DeviceInterface . default_model ( vm . xmlobj ) )
2015-05-19 19:50:39 +03:00
2015-05-19 22:18:30 +03:00
@staticmethod
2018-04-24 22:40:33 +03:00
def build_network_model_combo ( vm , combo ) :
_build_combo ( combo , [ ] )
vmmAddHardware . populate_network_model_combo ( vm , combo )
2015-05-19 22:18:30 +03:00
2018-04-24 22:40:33 +03:00
def _build_input_combo ( self ) :
devices = [
( DeviceInput . TYPE_TABLET , DeviceInput . BUS_USB ) ,
( DeviceInput . TYPE_MOUSE , DeviceInput . BUS_USB ) ,
( DeviceInput . TYPE_KEYBOARD , DeviceInput . BUS_USB ) ,
( DeviceInput . TYPE_KEYBOARD , DeviceInput . BUS_VIRTIO ) ,
( DeviceInput . TYPE_TABLET , DeviceInput . BUS_VIRTIO ) ,
]
2015-05-19 22:18:30 +03:00
2018-04-24 22:40:33 +03:00
cvals = [ ( ( t , b ) , DeviceInput . pretty_name ( t , b ) ) for t , b in devices ]
_build_combo ( self . widget ( " input-type " ) , cvals )
2014-01-27 02:09:07 +04:00
2009-07-14 17:25:39 +04:00
2018-04-24 22:40:33 +03:00
@staticmethod
def build_sound_combo ( vm , combo ) :
values = [ ]
2018-09-06 18:56:23 +03:00
for m in DeviceSound . get_recommended_models ( vm . xmlobj ) :
2018-04-24 22:40:33 +03:00
values . append ( [ m , DeviceSound . pretty_model ( m ) ] )
2015-03-26 16:44:24 +03:00
2018-09-02 00:16:13 +03:00
default = DeviceSound . default_model ( vm . xmlobj )
_build_combo ( combo , values , default_value = default )
2014-01-13 01:52:26 +04:00
2015-04-09 20:36:40 +03:00
2018-04-24 22:40:33 +03:00
def _build_hostdev_treeview ( self ) :
host_dev = self . widget ( " host-device " )
# [ xmlobj, label]
host_dev_model = Gtk . ListStore ( object , str )
host_dev . set_model ( host_dev_model )
host_col = Gtk . TreeViewColumn ( )
text = Gtk . CellRendererText ( )
host_col . pack_start ( text , True )
host_col . add_attribute ( text , ' text ' , 1 )
host_dev_model . set_sort_column_id ( 1 , Gtk . SortType . ASCENDING )
host_dev . append_column ( host_col )
2009-11-24 20:43:54 +03:00
2018-10-13 19:18:50 +03:00
def _populate_hostdev_model ( self , devtype ) :
2011-07-14 21:13:13 +04:00
devlist = self . widget ( " host-device " )
2010-12-11 23:55:31 +03:00
model = devlist . get_model ( )
2009-11-24 20:43:54 +03:00
model . clear ( )
2018-10-13 19:18:50 +03:00
devs = self . conn . filter_nodedevs ( devtype )
netdevs = self . conn . filter_nodedevs ( " net " )
2009-11-24 20:43:54 +03:00
for dev in devs :
2019-06-05 22:39:09 +03:00
if dev . xmlobj . is_usb_linux_root_hub ( ) :
2018-10-13 19:18:50 +03:00
continue
2019-06-05 22:29:10 +03:00
if dev . xmlobj . is_pci_bridge ( ) :
2018-10-13 19:19:31 +03:00
continue
2015-04-07 21:12:00 +03:00
prettyname = dev . xmlobj . pretty_name ( )
2009-11-24 20:43:54 +03:00
2018-10-13 19:18:50 +03:00
if devtype == " pci " :
for subdev in netdevs :
if dev . xmlobj . name == subdev . xmlobj . parent :
prettyname + = " ( %s ) " % subdev . xmlobj . pretty_name ( )
2009-11-24 20:43:54 +03:00
2018-04-24 22:40:33 +03:00
model . append ( [ dev . xmlobj , prettyname ] )
2009-11-24 20:43:54 +03:00
if len ( model ) == 0 :
2018-04-24 22:40:33 +03:00
model . append ( [ None , _ ( " No Devices Available " ) ] )
2015-05-20 01:13:33 +03:00
uiutil . set_list_selection_by_number ( devlist , 0 )
2009-11-24 20:43:54 +03:00
2014-04-26 18:40:17 +04:00
2018-04-24 22:40:33 +03:00
@staticmethod
2018-09-02 00:01:46 +03:00
def build_video_combo ( vm , combo ) :
2018-04-24 22:40:33 +03:00
values = [ ]
2018-09-06 21:43:45 +03:00
for m in DeviceVideo . get_recommended_models ( vm . xmlobj ) :
2018-04-24 22:40:33 +03:00
values . append ( [ m , DeviceVideo . pretty_model ( m ) ] )
2018-09-06 21:43:45 +03:00
if not values :
values . append ( [ None , _ ( " Hypervisor default " ) ] )
2018-09-02 00:01:46 +03:00
default = DeviceVideo . default_model ( vm . xmlobj )
_build_combo ( combo , values , default_value = default )
2014-04-26 18:41:31 +04:00
2014-06-16 07:50:04 +04:00
2018-04-24 22:40:33 +03:00
def _build_char_target_type_combo ( self ) :
values = [ ]
if self . conn . is_qemu ( ) :
values . append ( [ " virtio " , " VirtIO " ] )
2014-06-16 07:48:22 +04:00
else :
2018-04-24 22:40:33 +03:00
values . append ( [ None , _ ( " Hypervisor default " ) ] )
_build_combo ( self . widget ( " char-target-type " ) , values )
2014-04-26 18:41:31 +04:00
2018-04-24 22:40:33 +03:00
def _build_char_target_name_combo ( self ) :
values = [ ]
for n in DeviceChannel . CHANNEL_NAMES :
values . append ( [ n , n ] )
_build_combo ( self . widget ( " char-target-name " ) , values )
2014-04-26 18:41:31 +04:00
2018-04-24 22:40:33 +03:00
def _populate_char_device_type_combo ( self ) :
char_class = self . _get_char_class ( )
2018-09-06 19:43:08 +03:00
model = self . widget ( " char-device-type " ) . get_model ( )
model . clear ( )
2013-09-23 17:39:57 +04:00
2018-09-06 19:43:08 +03:00
for t in char_class . get_recommended_types ( self . vm . xmlobj ) :
model . append ( [ t , char_class . pretty_type ( t ) + " ( %s ) " % t ] )
uiutil . set_list_selection ( self . widget ( " char-device-type " ) , " pty " )
2013-09-23 17:39:57 +04:00
2018-04-24 22:40:33 +03:00
@staticmethod
def build_watchdogmodel_combo ( _vm , combo ) :
values = [ ]
for m in DeviceWatchdog . MODELS :
values . append ( [ m , m . upper ( ) ] )
_build_combo ( combo , values , default_value = DeviceWatchdog . MODEL_I6300 )
@staticmethod
def build_watchdogaction_combo ( _vm , combo ) :
values = [ ]
for m in DeviceWatchdog . ACTIONS :
values . append ( [ m , DeviceWatchdog . get_action_desc ( m ) ] )
_build_combo ( combo , values , default_value = DeviceWatchdog . ACTION_RESET )
2013-09-23 17:39:57 +04:00
2018-04-24 22:40:33 +03:00
@staticmethod
def build_smartcard_mode_combo ( _vm , combo ) :
values = [
[ " passthrough " , _ ( " Passthrough " ) ] ,
[ " host " , _ ( " Host " ) ] ,
]
_build_combo ( combo , values )
def _build_redir_type_combo ( self ) :
values = [ [ " spicevmc " , _ ( " Spice channel " ) ] ]
_build_combo ( self . widget ( " usbredir-list " ) , values )
def _build_tpm_type_combo ( self ) :
values = [ ]
for t in DeviceTpm . TYPES :
values . append ( [ t , DeviceTpm . get_pretty_type ( t ) ] )
_build_combo ( self . widget ( " tpm-type " ) , values )
2018-06-09 00:42:39 +03:00
values = [ ]
for t in DeviceTpm . MODELS :
values . append ( [ t , DeviceTpm . get_pretty_model ( t ) ] )
_build_combo ( self . widget ( " tpm-model " ) , values )
2018-06-09 00:42:42 +03:00
values = [ ]
for t in DeviceTpm . VERSIONS :
values . append ( [ t , t ] )
2019-05-17 22:57:53 +03:00
_build_combo ( self . widget ( " tpm-version " ) , values ,
default_value = DeviceTpm . VERSION_2_0 )
2018-04-24 22:40:33 +03:00
2018-06-09 00:42:44 +03:00
@staticmethod
def _get_tpm_model_list ( vm , tpmversion ) :
mod_list = [ ]
if vm . is_hvm ( ) :
mod_list . append ( " tpm-tis " )
if tpmversion != ' 1.2 ' :
mod_list . append ( " tpm-crb " )
mod_list . sort ( )
return mod_list
@staticmethod
def populate_tpm_model_combo ( vm , combo , tpmversion ) :
model = combo . get_model ( )
model . clear ( )
mod_list = vmmAddHardware . _get_tpm_model_list ( vm , tpmversion )
for m in mod_list :
model . append ( [ m , DeviceTpm . get_pretty_model ( m ) ] )
combo . set_active ( 0 )
@staticmethod
def build_tpm_model_combo ( vm , combo , tpmversion ) :
_build_combo ( combo , [ ] )
vmmAddHardware . populate_tpm_model_combo ( vm , combo , tpmversion )
2018-04-24 22:40:33 +03:00
def _build_panic_model_combo ( self ) :
values = [ ]
for m in DevicePanic . get_models ( self . vm . get_xmlobj ( ) . os ) :
values . append ( [ m , DevicePanic . get_pretty_model ( m ) ] )
2018-09-01 22:58:26 +03:00
default = DevicePanic . get_default_model ( self . vm . get_xmlobj ( ) )
2018-04-24 22:40:33 +03:00
_build_combo ( self . widget ( " panic-model " ) , values , default_value = default )
def _build_controller_type_combo ( self ) :
values = [ ]
2018-09-06 23:05:12 +03:00
for t in DeviceController . get_recommended_types ( self . vm . xmlobj ) :
2018-04-24 22:40:33 +03:00
values . append ( [ t , DeviceController . pretty_type ( t ) ] )
2013-09-23 17:39:57 +04:00
2018-04-24 22:40:33 +03:00
_build_combo ( self . widget ( " controller-type " ) , values ,
default_value = DeviceController . TYPE_SCSI )
2013-09-23 17:39:57 +04:00
2018-04-24 22:40:33 +03:00
@staticmethod
def populate_controller_model_combo ( combo , controller_type ) :
model = combo . get_model ( )
model . clear ( )
2013-09-23 17:39:57 +04:00
2018-09-06 23:05:12 +03:00
rows = [ ]
2018-04-24 22:40:33 +03:00
if controller_type == DeviceController . TYPE_USB :
2018-10-04 16:53:36 +03:00
rows . append ( [ " usb3 " , " USB 3 " ] )
2018-09-06 23:05:12 +03:00
rows . append ( [ " ich9-ehci1 " , " USB 2 " ] )
2018-04-24 22:40:33 +03:00
elif controller_type == DeviceController . TYPE_SCSI :
2018-09-06 23:05:12 +03:00
rows . append ( [ " virtio-scsi " , " VirtIO SCSI " ] )
rows . append ( [ None , _ ( " Hypervisor default " ) ] )
2015-05-19 22:18:30 +03:00
2018-09-06 23:05:12 +03:00
for row in rows :
model . append ( row )
uiutil . set_list_selection ( combo , rows [ 0 ] [ 0 ] )
2014-01-10 13:37:56 +04:00
2007-09-26 04:05:45 +04:00
2015-05-19 22:18:30 +03:00
#########################
# Internal misc helpers #
#########################
2009-01-23 01:00:10 +03:00
2015-05-19 22:18:30 +03:00
def _get_char_class ( self ) :
row = self . _get_hw_selection ( )
label = " serial "
2013-09-23 17:39:57 +04:00
2015-05-19 22:18:30 +03:00
if row :
label = row [ 5 ]
2013-09-23 17:39:57 +04:00
2015-05-19 22:18:30 +03:00
if label == " parallel " :
2018-03-20 19:18:35 +03:00
return DeviceParallel
2015-05-19 22:18:30 +03:00
elif label == " channel " :
2018-03-20 19:18:35 +03:00
return DeviceChannel
2015-05-19 22:18:30 +03:00
elif label == " console " :
2018-03-20 19:18:35 +03:00
return DeviceConsole
return DeviceSerial
2013-09-23 17:39:57 +04:00
2015-05-19 22:18:30 +03:00
def _set_hw_selection ( self , page ) :
2015-05-20 01:13:33 +03:00
uiutil . set_list_selection_by_number ( self . widget ( " hw-list " ) , page )
2013-09-23 17:39:57 +04:00
2015-05-19 22:18:30 +03:00
def _get_hw_selection ( self ) :
2015-05-20 00:17:53 +03:00
return uiutil . get_list_selected_row ( self . widget ( " hw-list " ) )
2014-04-26 18:40:17 +04:00
2019-04-14 03:45:21 +03:00
def _set_error_page ( self , msg = None ) :
self . widget ( " top-pages " ) . set_current_page ( 1 )
self . widget ( " error-label " ) . set_text ( msg or " Hardware selection error. " )
self . widget ( " create-finish " ) . set_sensitive ( False )
2014-04-26 18:40:17 +04:00
2009-11-24 20:43:54 +03:00
################
# UI listeners #
################
2019-04-14 03:45:21 +03:00
def _hw_selected_cb ( self , src ) :
self . widget ( " create-finish " ) . set_sensitive ( True )
2009-11-24 20:43:54 +03:00
2015-05-19 22:18:30 +03:00
row = self . _get_hw_selection ( )
2019-04-14 03:45:21 +03:00
if not row or not row [ 3 ] :
self . _set_error_page ( row and row [ 4 ] or None )
2010-12-11 20:32:04 +03:00
return
2009-11-24 21:32:14 +03:00
2010-12-11 20:32:04 +03:00
page = row [ 2 ]
2010-03-04 23:29:33 +03:00
2010-12-11 20:32:04 +03:00
if page == PAGE_CHAR :
2015-05-19 22:18:30 +03:00
# Need to do this here, since we share the char page between
# multiple different HW options
2018-04-24 22:40:33 +03:00
self . _populate_char_device_type_combo ( )
2013-10-05 21:27:11 +04:00
self . widget ( " char-device-type " ) . emit ( " changed " )
self . widget ( " char-target-name " ) . emit ( " changed " )
2009-07-14 17:25:39 +04:00
2010-12-11 23:55:31 +03:00
if page == PAGE_HOSTDEV :
2015-05-19 22:18:30 +03:00
# Need to do this here, since we share the hostdev page
# between two different HW options
row = self . _get_hw_selection ( )
2018-10-13 19:18:50 +03:00
devtype = " usb_device "
2015-05-19 22:18:30 +03:00
if row and row [ 5 ] == " pci " :
2018-10-13 19:18:50 +03:00
devtype = " pci "
self . _populate_hostdev_model ( devtype )
2018-04-24 22:40:33 +03:00
if page == PAGE_CONTROLLER :
# We need to trigger this as it can desensitive 'finish'
self . widget ( " controller-type " ) . emit ( " changed " )
2010-12-11 23:55:31 +03:00
2015-05-19 22:18:30 +03:00
self . _set_page_title ( page )
2019-04-14 03:45:21 +03:00
self . widget ( " create-pages " ) . get_nth_page ( page ) . show ( )
self . widget ( " create-pages " ) . set_current_page ( page )
self . widget ( " top-pages " ) . set_current_page ( 0 )
2007-04-12 23:36:04 +04:00
2015-05-19 22:18:30 +03:00
def _dev_to_title ( self , page ) :
2010-12-11 21:05:07 +03:00
if page == PAGE_DISK :
return _ ( " Storage " )
2014-04-26 18:40:17 +04:00
if page == PAGE_CONTROLLER :
return _ ( " Controller " )
2010-12-11 21:05:07 +03:00
if page == PAGE_NETWORK :
return _ ( " Network " )
if page == PAGE_INPUT :
return _ ( " Input " )
if page == PAGE_GRAPHICS :
return _ ( " Graphics " )
if page == PAGE_SOUND :
return _ ( " Sound " )
if page == PAGE_VIDEO :
return _ ( " Video Device " )
if page == PAGE_WATCHDOG :
return _ ( " Watchdog Device " )
2011-05-20 02:17:58 +04:00
if page == PAGE_FILESYSTEM :
return _ ( " Filesystem Passthrough " )
2011-06-23 19:42:03 +04:00
if page == PAGE_SMARTCARD :
return _ ( " Smartcard " )
2011-09-02 05:23:28 +04:00
if page == PAGE_USBREDIR :
return _ ( " USB Redirection " )
2013-06-26 05:45:09 +04:00
if page == PAGE_TPM :
return _ ( " TPM " )
2013-09-23 17:39:57 +04:00
if page == PAGE_RNG :
return _ ( " Random Number Generator " )
2014-01-10 13:37:56 +04:00
if page == PAGE_PANIC :
return _ ( " Panic Notifier " )
2018-12-14 17:34:20 +03:00
if page == PAGE_VSOCK :
return _ ( " VM Sockets " )
2010-12-11 21:05:07 +03:00
2010-12-11 23:55:31 +03:00
if page == PAGE_CHAR :
2018-03-21 01:59:14 +03:00
devclass = self . _get_char_class ( ) ( self . conn . get_backend ( ) )
return _ ( " %s Device " ) % devclass . DEVICE_TYPE . capitalize ( )
2010-12-11 23:55:31 +03:00
if page == PAGE_HOSTDEV :
2015-05-19 22:18:30 +03:00
row = self . _get_hw_selection ( )
if row and row [ 5 ] == " pci " :
return _ ( " PCI Device " )
return _ ( " USB Device " )
2010-12-11 23:55:31 +03:00
raise RuntimeError ( " Unknown page %s " % page )
2010-12-11 21:05:07 +03:00
2015-05-19 22:18:30 +03:00
def _set_page_title ( self , page ) :
title = self . _dev_to_title ( page )
2013-09-27 19:18:52 +04:00
markup = " <span size= ' large ' color= ' white ' > %s </span> " % title
2011-07-14 21:13:13 +04:00
self . widget ( " page-title-label " ) . set_markup ( markup )
2009-07-14 17:25:39 +04:00
2015-05-19 22:18:30 +03:00
#########################
# Device page listeners #
#########################
2018-04-24 22:40:33 +03:00
def _refresh_disk_bus ( self , devtype ) :
widget = self . widget ( " storage-bustype " )
model = widget . get_model ( )
self . populate_disk_bus_combo ( self . vm , devtype , model )
# By default, select bus of the first disk assigned to the VM
default_bus = None
for i in self . vm . xmlobj . devices . disk :
if i . device == devtype :
default_bus = i . bus
break
if default_bus :
uiutil . set_list_selection ( widget , default_bus )
elif len ( model ) > 0 :
widget . set_active ( 0 )
2015-05-19 22:18:30 +03:00
def _change_storage_devtype ( self , ignore ) :
devtype = uiutil . get_list_selection (
2015-09-14 01:01:39 +03:00
self . widget ( " storage-devtype " ) )
2015-05-19 22:18:30 +03:00
self . _refresh_disk_bus ( devtype )
2018-10-10 12:50:35 +03:00
# Reset the status of disk-pr-checkbox to inactive
self . widget ( " disk-pr-checkbox " ) . set_active ( False )
is_lun = devtype == " lun "
uiutil . set_grid_row_visible ( self . widget ( " disk-pr-checkbox " ) , is_lun )
2015-05-19 22:18:30 +03:00
allow_create = devtype not in [ " cdrom " , " floppy " ]
2015-09-14 01:01:39 +03:00
self . addstorage . widget ( " storage-create-box " ) . set_sensitive (
2015-05-19 22:18:30 +03:00
allow_create )
if not allow_create :
2015-09-14 01:01:39 +03:00
self . addstorage . widget ( " storage-select " ) . set_active ( True )
2015-05-19 22:18:30 +03:00
def _change_macaddr_use ( self , ignore = None ) :
if self . widget ( " mac-address " ) . get_active ( ) :
self . widget ( " create-mac-address " ) . set_sensitive ( True )
else :
self . widget ( " create-mac-address " ) . set_sensitive ( False )
def _change_tpm_device_type ( self , src ) :
2015-05-20 00:17:53 +03:00
devtype = uiutil . get_list_selection ( src )
2014-01-27 05:21:12 +04:00
if devtype is None :
2013-06-26 05:45:09 +04:00
return
2019-04-15 00:17:13 +03:00
dev = DeviceTpm ( self . conn . get_backend ( ) )
dev . type = devtype
2013-06-26 05:45:09 +04:00
2019-05-13 21:06:32 +03:00
uiutil . set_grid_row_visible ( self . widget ( " tpm-device-path-label " ) ,
devtype == dev . TYPE_PASSTHROUGH )
uiutil . set_grid_row_visible ( self . widget ( " tpm-version-label " ) ,
devtype == dev . TYPE_EMULATOR )
2013-06-26 05:45:09 +04:00
2015-05-19 22:18:30 +03:00
def _change_char_auto_socket ( self , src ) :
2013-10-05 21:54:28 +04:00
if not src . get_visible ( ) :
return
doshow = not src . get_active ( )
2014-01-27 03:15:50 +04:00
uiutil . set_grid_row_visible ( self . widget ( " char-path-label " ) , doshow )
2013-10-05 21:54:28 +04:00
2015-05-19 22:18:30 +03:00
def _change_char_target_name ( self , src ) :
2013-10-05 21:27:11 +04:00
if not src . get_visible ( ) :
return
text = src . get_child ( ) . get_text ( )
settype = None
2018-03-20 19:18:35 +03:00
if text == DeviceChannel . CHANNEL_NAME_SPICE :
2013-10-05 21:27:11 +04:00
settype = " spicevmc "
2018-03-20 19:18:35 +03:00
elif text == DeviceChannel . CHANNEL_NAME_SPICE_WEBDAV :
2014-03-25 18:42:34 +04:00
settype = " spiceport "
self . widget ( " char-channel " ) . set_text ( text )
2018-03-20 19:18:35 +03:00
elif ( text == DeviceChannel . CHANNEL_NAME_QEMUGA or
text == DeviceChannel . CHANNEL_NAME_LIBGUESTFS ) :
2013-10-05 21:27:11 +04:00
settype = " unix "
2015-05-20 01:11:00 +03:00
if settype :
2015-05-20 01:13:33 +03:00
uiutil . set_list_selection (
2015-05-20 01:11:00 +03:00
self . widget ( " char-device-type " ) , settype )
2013-10-05 21:27:11 +04:00
2015-05-19 22:18:30 +03:00
def _change_char_device_type ( self , src ) :
2015-05-20 00:17:53 +03:00
devtype = uiutil . get_list_selection ( src )
2014-01-27 05:21:12 +04:00
if devtype is None :
2011-04-05 03:35:32 +04:00
return
2009-07-14 17:25:39 +04:00
2015-05-19 22:18:30 +03:00
char_class = self . _get_char_class ( )
2018-09-06 19:43:08 +03:00
dev = char_class ( self . conn . get_backend ( ) )
dev . type = devtype
2009-07-14 17:25:39 +04:00
2018-09-06 19:43:08 +03:00
ischan = dev . DEVICE_TYPE == " channel "
iscon = dev . DEVICE_TYPE == " console "
show_auto = devtype == " unix " and ischan
2018-03-21 01:59:14 +03:00
2019-05-13 21:06:32 +03:00
supports_path = [ dev . TYPE_FILE , dev . TYPE_UNIX ,
dev . TYPE_DEV , dev . TYPE_PIPE ]
supports_channel = [ dev . TYPE_SPICEPORT ]
2018-09-06 19:43:08 +03:00
uiutil . set_grid_row_visible ( self . widget ( " char-path-label " ) ,
2019-05-13 21:06:32 +03:00
devtype in supports_path )
2018-09-06 19:43:08 +03:00
uiutil . set_grid_row_visible ( self . widget ( " char-channel-label " ) ,
2019-05-13 21:06:32 +03:00
devtype in supports_channel )
2009-07-14 17:25:39 +04:00
2014-01-27 03:15:50 +04:00
uiutil . set_grid_row_visible (
2013-10-05 21:33:55 +04:00
self . widget ( " char-target-name-label " ) , ischan )
2014-01-27 03:15:50 +04:00
uiutil . set_grid_row_visible (
2013-10-05 21:33:55 +04:00
self . widget ( " char-target-type-label " ) , iscon )
2014-01-27 03:15:50 +04:00
uiutil . set_grid_row_visible (
2013-10-05 21:54:28 +04:00
self . widget ( " char-auto-socket-label " ) , show_auto )
self . widget ( " char-auto-socket " ) . emit ( " toggled " )
2013-10-05 21:33:55 +04:00
2015-05-19 22:18:30 +03:00
def _change_usbredir_type ( self , src ) :
2018-04-24 21:16:41 +03:00
pass
2011-09-02 05:23:28 +04:00
2018-04-24 22:40:33 +03:00
def _change_controller_type ( self , src ) :
ignore = src
combo = self . widget ( " controller-model " )
def show_tooltip ( model_tooltip , show ) :
vmname = self . vm . get_name ( )
tooltip = ( _ ( " %s already has a USB controller attached. \n "
" Adding more than one USB controller is not supported. \n "
" You can change the USB controller type in the VM details screen. " )
% vmname )
model_tooltip . set_visible ( show )
model_tooltip . set_tooltip_text ( tooltip )
controller_type = uiutil . get_list_selection (
self . widget ( " controller-type " ) )
combo . set_sensitive ( True )
model_tooltip = self . widget ( " controller-tooltip " )
show_tooltip ( model_tooltip , False )
controllers = self . vm . xmlobj . devices . controller
if controller_type == DeviceController . TYPE_USB :
usb_controllers = [ x for x in controllers if
( x . type == DeviceController . TYPE_USB ) ]
if ( len ( usb_controllers ) == 0 ) :
self . widget ( " create-finish " ) . set_sensitive ( True )
elif ( len ( usb_controllers ) == 1 and
usb_controllers [ 0 ] . model == " none " ) :
self . _remove_usb_controller = usb_controllers [ 0 ]
self . widget ( " create-finish " ) . set_sensitive ( True )
else :
show_tooltip ( model_tooltip , True )
self . widget ( " create-finish " ) . set_sensitive ( False )
else :
self . widget ( " create-finish " ) . set_sensitive ( True )
self . populate_controller_model_combo ( combo , controller_type )
uiutil . set_grid_row_visible ( combo , len ( combo . get_model ( ) ) > 1 )
2008-08-21 23:58:35 +04:00
2009-11-24 20:43:54 +03:00
######################
# Add device methods #
######################
2007-04-12 23:36:04 +04:00
2019-04-15 00:17:13 +03:00
def _setup_device ( self , asyncjob , dev ) :
if dev . DEVICE_TYPE != " disk " :
2018-09-03 23:44:38 +03:00
return
2015-03-27 02:08:04 +03:00
poolname = None
2019-04-15 00:17:13 +03:00
if ( dev . wants_storage_creation ( ) and
dev . get_parent_pool ( ) ) :
poolname = dev . get_parent_pool ( ) . name ( )
2015-03-27 02:08:04 +03:00
2019-04-15 00:17:13 +03:00
logging . debug ( " Running build_storage() for device= %s " , dev )
dev . build_storage ( meter = asyncjob . get_meter ( ) )
2018-09-03 23:44:38 +03:00
logging . debug ( " build_storage() complete " )
2015-03-27 02:08:04 +03:00
if poolname :
try :
pool = self . conn . get_pool ( poolname )
self . idle_add ( pool . refresh )
2017-07-24 11:26:48 +03:00
except Exception :
2015-03-27 02:08:04 +03:00
logging . debug ( " Error looking up pool= %s for refresh after "
" storage creation. " , poolname , exc_info = True )
2008-03-14 20:18:44 +03:00
2019-04-15 00:17:13 +03:00
def _add_device ( self , dev ) :
xml = dev . get_xml ( )
2018-03-02 11:01:23 +03:00
logging . debug ( " Adding device: \n %s " , xml )
2007-11-17 01:12:37 +03:00
2014-06-16 07:48:22 +04:00
if self . _remove_usb_controller :
kwargs = { }
kwargs [ " model " ] = self . _selected_model
self . change_config_helper ( self . vm . define_controller ,
2015-04-11 00:14:08 +03:00
kwargs , self . vm , self . err ,
devobj = self . _remove_usb_controller )
2014-06-16 07:48:22 +04:00
self . _remove_usb_controller = None
self . _selected_model = None
return
2019-04-15 00:17:13 +03:00
controller = getattr ( dev , " vmm_controller " , None )
2012-12-07 14:21:38 +04:00
if controller is not None :
logging . debug ( " Adding controller: \n %s " ,
2018-08-31 23:52:02 +03:00
controller . get_xml ( ) )
2009-11-24 20:43:54 +03:00
# Hotplug device
attach_err = False
try :
2012-12-07 14:21:38 +04:00
if controller is not None :
2014-01-29 01:53:11 +04:00
self . vm . attach_device ( controller )
2019-04-15 00:17:13 +03:00
self . vm . attach_device ( dev )
2017-05-05 19:47:21 +03:00
except Exception as e :
2012-01-17 07:04:40 +04:00
logging . debug ( " Device could not be hotplugged: %s " , str ( e ) )
2010-12-02 01:48:07 +03:00
attach_err = ( str ( e ) , " " . join ( traceback . format_exc ( ) ) )
2007-11-17 01:12:37 +03:00
2009-11-24 20:43:54 +03:00
if attach_err :
2010-12-02 01:48:07 +03:00
res = self . err . show_err (
_ ( " Are you sure you want to add this device? " ) ,
2011-04-06 19:22:03 +04:00
details = ( attach_err [ 0 ] + " \n \n " + attach_err [ 1 ] ) ,
2010-12-02 01:48:07 +03:00
text2 = (
_ ( " This device could not be attached to the running machine. "
" Would you like to make the device available after the "
2011-07-15 01:16:57 +04:00
" next guest shutdown? " ) ) ,
2012-05-14 17:24:56 +04:00
dialog_type = Gtk . MessageType . WARNING ,
buttons = Gtk . ButtonsType . YES_NO ,
2013-09-07 04:16:37 +04:00
modal = True )
2010-12-02 01:48:07 +03:00
if not res :
2013-09-07 04:59:01 +04:00
return False
2008-03-14 17:55:12 +03:00
2009-11-24 20:43:54 +03:00
# Alter persistent config
try :
2012-12-07 14:21:38 +04:00
if controller is not None :
2014-01-29 01:53:11 +04:00
self . vm . add_device ( controller )
2019-04-15 00:17:13 +03:00
self . vm . add_device ( dev )
2017-05-05 19:47:21 +03:00
except Exception as e :
2015-06-02 15:21:58 +03:00
self . err . show_err ( _ ( " Error adding device: %s " ) % str ( e ) )
2013-09-07 04:59:01 +04:00
return True
return False
2019-04-15 00:17:13 +03:00
def _finish_cb ( self , error , details , dev ) :
2013-09-07 04:59:01 +04:00
failure = True
if not error :
try :
2019-04-15 00:17:13 +03:00
failure = self . _add_device ( dev )
2017-05-05 19:47:21 +03:00
except Exception as e :
2013-09-07 04:59:01 +04:00
failure = True
error = _ ( " Unable to add device: %s " ) % str ( e )
details = " " . join ( traceback . format_exc ( ) )
if error is not None :
self . err . show_err ( error , details = details )
2017-04-27 22:00:17 +03:00
self . reset_finish_cursor ( )
2013-09-07 04:59:01 +04:00
if not failure :
self . close ( )
2010-02-06 23:59:52 +03:00
2015-05-19 22:18:30 +03:00
def _finish ( self , ignore = None ) :
2013-09-07 04:59:01 +04:00
try :
2019-04-15 03:48:36 +03:00
dev = self . _build_device ( )
if self . _validate_device ( dev ) is False :
2013-09-07 04:59:01 +04:00
return
2017-05-05 19:47:21 +03:00
except Exception as e :
2018-04-25 14:38:28 +03:00
self . err . show_err (
_ ( " Error validating device parameters: %s " ) % str ( e ) )
2013-09-07 04:59:01 +04:00
return
2017-04-27 22:00:17 +03:00
self . set_finish_cursor ( )
2019-04-15 00:17:13 +03:00
progWin = vmmAsyncJob ( self . _setup_device , [ dev ] ,
self . _finish_cb , [ dev ] ,
2013-09-07 04:59:01 +04:00
_ ( " Creating device " ) ,
_ ( " Depending on the device, this may take "
" a few minutes to complete. " ) ,
self . topwin )
progWin . run ( )
2009-11-24 20:43:54 +03:00
2009-03-09 23:20:23 +03:00
2009-11-24 20:43:54 +03:00
###########################
2019-04-15 03:48:36 +03:00
# Device build/validation #
2009-11-24 20:43:54 +03:00
###########################
2019-04-15 03:48:36 +03:00
def _validate_hostdev_collision ( self , dev ) :
names = [ ]
nodedev = getattr ( dev , " vmm_nodedev " , None )
if not nodedev :
return
for vm in self . conn . list_vms ( ) :
for hostdev in vm . xmlobj . devices . hostdev :
if nodedev . compare_to_hostdev ( hostdev ) :
names . append ( vm . get_name ( ) )
if names :
res = self . err . yes_no (
_ ( ' The device is already in use by other guests %s ' ) %
( names ) ,
_ ( " Do you really want to use the device? " ) )
if not res :
return False
def _validate_device ( self , dev ) :
dev . validate ( )
if dev . DEVICE_TYPE == " disk " :
if self . addstorage . validate_device ( dev ) is False :
return False
if dev . DEVICE_TYPE == " network " :
self . _netlist . validate_device ( dev )
if dev . DEVICE_TYPE == " hostdev " :
self . _validate_hostdev_collision ( dev )
2015-05-19 22:18:30 +03:00
2019-04-15 03:48:36 +03:00
def _build_device ( self ) :
2018-09-29 21:27:34 +03:00
# pylint: disable=assignment-from-no-return
2019-04-15 03:48:36 +03:00
page_num = self . widget ( " create-pages " ) . get_current_page ( )
2019-04-14 03:45:21 +03:00
if page_num == PAGE_DISK :
2019-04-15 03:48:36 +03:00
dev = self . _build_storage ( )
2014-04-26 18:40:17 +04:00
elif page_num == PAGE_CONTROLLER :
2019-04-15 03:48:36 +03:00
dev = self . _build_controller ( )
2009-11-24 20:43:54 +03:00
elif page_num == PAGE_NETWORK :
2019-04-15 03:48:36 +03:00
dev = self . _build_network ( )
2009-11-24 20:43:54 +03:00
elif page_num == PAGE_INPUT :
2019-04-15 03:48:36 +03:00
dev = self . _build_input ( )
2009-11-24 20:43:54 +03:00
elif page_num == PAGE_GRAPHICS :
2019-04-15 03:48:36 +03:00
dev = self . _build_graphics ( )
2009-11-24 20:43:54 +03:00
elif page_num == PAGE_SOUND :
2019-04-15 03:48:36 +03:00
dev = self . _build_sound ( )
2009-03-09 23:20:23 +03:00
elif page_num == PAGE_HOSTDEV :
2019-04-15 03:48:36 +03:00
dev = self . _build_hostdev ( )
2009-11-24 20:43:54 +03:00
elif page_num == PAGE_CHAR :
2019-04-15 03:48:36 +03:00
dev = self . _build_char ( )
2009-11-24 20:43:54 +03:00
elif page_num == PAGE_VIDEO :
2019-04-15 03:48:36 +03:00
dev = self . _build_video ( )
2010-03-24 07:22:17 +03:00
elif page_num == PAGE_WATCHDOG :
2019-04-15 03:48:36 +03:00
dev = self . _build_watchdog ( )
2011-05-20 02:17:58 +04:00
elif page_num == PAGE_FILESYSTEM :
2019-04-15 03:48:36 +03:00
dev = self . _build_filesystem ( )
2011-06-23 19:42:03 +04:00
elif page_num == PAGE_SMARTCARD :
2019-04-15 03:48:36 +03:00
dev = self . _build_smartcard ( )
2011-09-02 05:23:28 +04:00
elif page_num == PAGE_USBREDIR :
2019-04-15 03:48:36 +03:00
dev = self . _build_usbredir ( )
2013-06-26 05:45:09 +04:00
elif page_num == PAGE_TPM :
2019-04-15 03:48:36 +03:00
dev = self . _build_tpm ( )
2013-09-23 17:39:57 +04:00
elif page_num == PAGE_RNG :
2019-04-15 03:48:36 +03:00
dev = self . _build_rng ( )
2014-01-10 13:37:56 +04:00
elif page_num == PAGE_PANIC :
2019-04-15 03:48:36 +03:00
dev = self . _build_panic ( )
2018-12-14 17:34:20 +03:00
elif page_num == PAGE_VSOCK :
2019-04-15 03:48:36 +03:00
dev = self . _build_vsock ( )
2009-03-09 23:20:23 +03:00
2019-04-15 03:48:36 +03:00
dev . set_defaults ( self . vm . get_xmlobj ( ) )
2019-04-15 00:17:13 +03:00
return dev
2013-10-06 20:55:21 +04:00
2014-02-12 18:58:40 +04:00
def _set_disk_controller ( self , disk , controller_model , used_disks ) :
2014-01-29 01:53:11 +04:00
# Add a SCSI controller with model virtio-scsi if needed
disk . vmm_controller = None
if controller_model != " virtio-scsi " :
2014-02-12 18:58:40 +04:00
return None
2014-01-29 01:53:11 +04:00
2014-02-12 18:58:40 +04:00
# Get SCSI controllers
2018-03-21 21:42:50 +03:00
controllers = self . vm . xmlobj . devices . controller
2014-01-29 01:53:11 +04:00
ctrls_scsi = [ x for x in controllers if
2018-03-20 19:18:35 +03:00
( x . type == DeviceController . TYPE_SCSI ) ]
2014-01-29 01:53:11 +04:00
2014-02-12 18:58:40 +04:00
# Create possible new controller
2018-03-20 19:18:35 +03:00
controller = DeviceController ( self . conn . get_backend ( ) )
2014-01-29 01:53:11 +04:00
controller . type = " scsi "
controller . model = controller_model
2014-02-12 18:58:40 +04:00
# And set its index
controller . index = 0
if ctrls_scsi :
controller . index = max ( [ x . index for x in ctrls_scsi ] ) + 1
# Take only virtio-scsi ones
ctrls_scsi = [ x for x in ctrls_scsi
if x . model == controller_model ]
# Save occupied places per controller
2017-11-22 22:58:12 +03:00
occupied = { }
2014-02-12 18:58:40 +04:00
for d in used_disks :
2017-11-06 15:52:07 +03:00
if ( d . get_target_prefix ( ) == disk . get_target_prefix ( ) and
d . bus == " scsi " ) :
2018-04-24 22:40:33 +03:00
num = DeviceDisk . target_to_num ( d . target )
2017-11-22 22:58:12 +03:00
idx = num / / 7
if idx not in occupied :
occupied [ idx ] = [ ]
if d . target not in occupied [ idx ] :
occupied [ idx ] . append ( d . target )
2014-02-12 18:58:40 +04:00
for c in ctrls_scsi :
2017-11-22 22:58:12 +03:00
if c . index not in occupied or len ( occupied [ c . index ] ) < 7 :
2014-02-12 18:58:40 +04:00
controller = c
2014-01-29 01:53:11 +04:00
break
2014-02-12 18:58:40 +04:00
else :
disk . vmm_controller = controller
2014-01-29 01:53:11 +04:00
2014-02-12 18:58:40 +04:00
return controller . index
2014-01-29 01:53:11 +04:00
2019-04-15 03:48:36 +03:00
def _build_storage ( self ) :
2015-05-19 22:18:30 +03:00
bus = uiutil . get_list_selection (
2015-09-14 01:01:39 +03:00
self . widget ( " storage-bustype " ) )
2015-05-19 22:18:30 +03:00
device = uiutil . get_list_selection (
2015-09-14 01:01:39 +03:00
self . widget ( " storage-devtype " ) )
2015-05-19 22:18:30 +03:00
cache = uiutil . get_list_selection (
2015-09-14 01:01:39 +03:00
self . widget ( " storage-cache " ) )
2018-09-06 10:49:30 +03:00
io = uiutil . get_list_selection (
self . widget ( " storage-io " ) )
2018-09-05 11:15:07 +03:00
discard = uiutil . get_list_selection (
self . widget ( " storage-discard " ) )
2018-09-05 11:15:08 +03:00
detect_zeroes = uiutil . get_list_selection (
self . widget ( " storage-detect-zeroes " ) )
2018-10-10 12:50:35 +03:00
if device == " lun " :
reservations_managed = self . widget ( " disk-pr-checkbox " ) . get_active ( )
2013-07-05 16:59:58 +04:00
2014-01-29 01:53:11 +04:00
controller_model = None
2015-08-03 19:52:07 +03:00
if ( bus == " scsi " and
self . vm . get_hv_type ( ) in [ " qemu " , " kvm " , " test " ] and
2019-03-04 19:11:18 +03:00
not any ( [ c . type == " scsi "
2018-03-21 21:42:50 +03:00
for c in self . vm . xmlobj . devices . controller ] ) ) :
2013-02-07 00:41:43 +04:00
controller_model = " virtio-scsi "
2009-11-24 20:43:54 +03:00
2019-04-15 03:48:36 +03:00
collidelist = [ d . path for d in self . vm . xmlobj . devices . disk ]
disk = self . addstorage . build_device ( self . vm . get_name ( ) ,
collidelist = collidelist , device = device )
used = [ ]
disk . bus = bus
if cache :
disk . driver_cache = cache
if io :
disk . driver_io = io
if discard :
disk . driver_discard = discard
if detect_zeroes :
disk . driver_detect_zeroes = detect_zeroes
if device == " lun " and reservations_managed :
disk . reservations_managed = " yes "
# Generate target
disks = ( self . vm . xmlobj . devices . disk +
self . vm . get_xmlobj ( inactive = True ) . devices . disk )
for d in disks :
if d . target not in used :
used . append ( d . target )
prefer_ctrl = self . _set_disk_controller (
disk , controller_model , disks )
disk . generate_target ( used , prefer_ctrl )
2019-04-15 00:17:13 +03:00
return disk
2009-12-01 20:35:04 +03:00
2019-04-15 03:48:36 +03:00
def _build_network ( self ) :
2015-05-20 00:54:53 +03:00
model = uiutil . get_list_selection ( self . widget ( " net-model " ) )
2015-05-19 22:18:30 +03:00
mac = None
if self . widget ( " mac-address " ) . get_active ( ) :
mac = self . widget ( " create-mac-address " ) . get_text ( )
2009-11-24 20:43:54 +03:00
2019-04-15 02:46:51 +03:00
dev = self . _netlist . build_device ( mac , model )
2019-04-15 00:17:13 +03:00
return dev
2009-07-14 17:25:39 +04:00
2019-04-15 03:48:36 +03:00
def _build_input ( self ) :
2018-04-24 22:40:33 +03:00
typ , bus = uiutil . get_list_selection ( self . widget ( " input-type " ) )
2019-04-15 00:17:13 +03:00
dev = DeviceInput ( self . conn . get_backend ( ) )
dev . type = typ
dev . bus = bus
return dev
2010-02-06 23:33:32 +03:00
2019-04-15 03:48:36 +03:00
def _build_graphics ( self ) :
2018-04-25 14:38:28 +03:00
( gtype , port , tlsport , listen ,
addr , passwd , keymap , gl , rendernode ) = self . _gfxdetails . get_values ( )
2019-04-15 00:17:13 +03:00
dev = DeviceGraphics ( self . conn . get_backend ( ) )
dev . type = gtype
dev . passwd = passwd
dev . gl = gl
dev . rendernode = rendernode
2018-04-25 14:38:28 +03:00
if not listen or listen == " none " :
2019-04-15 00:17:13 +03:00
dev . listen = " none "
2018-04-25 14:38:28 +03:00
elif listen == " address " :
2019-04-15 00:17:13 +03:00
dev . listen = addr
dev . port = port
dev . tlsPort = tlsport
2018-04-25 14:38:28 +03:00
else :
raise ValueError ( _ ( " invalid listen type " ) )
if keymap :
2019-04-15 00:17:13 +03:00
dev . keymap = keymap
return dev
2009-11-24 20:43:54 +03:00
2019-04-15 03:48:36 +03:00
def _build_sound ( self ) :
2015-05-20 00:17:53 +03:00
smodel = uiutil . get_list_selection ( self . widget ( " sound-model " ) )
2019-04-15 00:17:13 +03:00
dev = DeviceSound ( self . conn . get_backend ( ) )
dev . model = smodel
return dev
2009-07-14 17:25:39 +04:00
2019-04-15 03:48:36 +03:00
def _build_hostdev ( self ) :
2018-04-24 22:40:33 +03:00
nodedev = uiutil . get_list_selection ( self . widget ( " host-device " ) )
2018-04-25 14:38:28 +03:00
dev = DeviceHostdev ( self . conn . get_backend ( ) )
dev . set_from_nodedev ( nodedev )
2019-04-15 03:48:36 +03:00
setattr ( dev , " vmm_nodedev " , nodedev )
2019-04-15 00:17:13 +03:00
return dev
2007-04-12 23:36:04 +04:00
2019-04-15 03:48:36 +03:00
def _build_char ( self ) :
2015-05-19 22:18:30 +03:00
char_class = self . _get_char_class ( )
2018-09-06 19:43:08 +03:00
devtype = uiutil . get_list_selection ( self . widget ( " char-device-type " ) )
2009-01-23 01:00:10 +03:00
2018-09-06 19:43:08 +03:00
typebox = self . widget ( " char-target-type " )
2011-07-14 21:13:13 +04:00
source_path = self . widget ( " char-path " ) . get_text ( )
2014-03-25 18:42:34 +04:00
source_channel = self . widget ( " char-channel " ) . get_text ( )
2013-10-05 21:27:11 +04:00
target_name = self . widget ( " char-target-name " ) . get_child ( ) . get_text ( )
2015-05-20 00:17:53 +03:00
target_type = uiutil . get_list_selection ( typebox )
2009-01-23 01:00:10 +03:00
2019-05-13 21:06:32 +03:00
if not self . widget ( " char-path " ) . get_visible ( ) :
source_path = None
if not self . widget ( " char-channel " ) . get_visible ( ) :
source_channel = None
2013-10-06 21:04:21 +04:00
if not self . widget ( " char-target-name " ) . get_visible ( ) :
target_name = None
if not typebox . get_visible ( ) :
target_type = None
2009-07-20 23:09:32 +04:00
2019-04-15 00:17:13 +03:00
dev = char_class ( self . conn . get_backend ( ) )
dev . type = devtype
2019-05-13 21:23:27 +03:00
dev . source . path = source_path
dev . source . channel = source_channel
2019-05-13 21:06:32 +03:00
dev . target_name = target_name
dev . target_type = target_type
2019-04-15 00:17:13 +03:00
return dev
2007-09-26 04:05:45 +04:00
2019-04-15 03:48:36 +03:00
def _build_video ( self ) :
2015-05-20 00:17:53 +03:00
model = uiutil . get_list_selection ( self . widget ( " video-model " ) )
2019-04-15 00:17:13 +03:00
dev = DeviceVideo ( self . conn . get_backend ( ) )
dev . model = model
return dev
2010-03-24 07:22:17 +03:00
2019-04-15 03:48:36 +03:00
def _build_watchdog ( self ) :
2015-05-20 00:17:53 +03:00
model = uiutil . get_list_selection ( self . widget ( " watchdog-model " ) )
action = uiutil . get_list_selection ( self . widget ( " watchdog-action " ) )
2019-04-15 00:17:13 +03:00
dev = DeviceWatchdog ( self . conn . get_backend ( ) )
dev . model = model
dev . action = action
return dev
2009-01-23 01:00:26 +03:00
2019-04-15 03:48:36 +03:00
def _build_filesystem ( self ) :
2015-05-19 22:18:30 +03:00
if self . _fsdetails . validate_page_filesystem ( ) is False :
2014-01-27 20:03:59 +04:00
return False
2019-04-15 00:17:13 +03:00
return self . _fsdetails . get_dev ( )
2011-12-21 09:58:54 +04:00
2019-04-15 03:48:36 +03:00
def _build_smartcard ( self ) :
2015-05-20 00:17:53 +03:00
mode = uiutil . get_list_selection ( self . widget ( " smartcard-mode " ) )
2019-04-15 00:17:13 +03:00
dev = DeviceSmartcard ( self . conn . get_backend ( ) )
dev . mode = mode
return dev
2011-09-02 05:23:28 +04:00
2019-04-15 03:48:36 +03:00
def _build_usbredir ( self ) :
2015-05-20 00:17:53 +03:00
stype = uiutil . get_list_selection ( self . widget ( " usbredir-list " ) )
2019-04-15 00:17:13 +03:00
dev = DeviceRedirdev ( self . conn . get_backend ( ) )
dev . type = stype
return dev
2011-06-23 19:42:03 +04:00
2019-04-15 03:48:36 +03:00
def _build_tpm ( self ) :
2015-05-20 00:17:53 +03:00
typ = uiutil . get_list_selection ( self . widget ( " tpm-type " ) )
2018-06-09 00:42:39 +03:00
model = uiutil . get_list_selection ( self . widget ( " tpm-model " ) )
2013-06-26 05:45:09 +04:00
device_path = self . widget ( " tpm-device-path " ) . get_text ( )
2018-06-09 00:42:42 +03:00
version = uiutil . get_list_selection ( self . widget ( " tpm-version " ) )
2019-05-13 21:06:32 +03:00
if not self . widget ( " tpm-device-path " ) . get_visible ( ) :
device_path = None
if not self . widget ( " tpm-version " ) . get_visible ( ) :
version = None
2018-06-09 00:42:42 +03:00
2019-04-15 00:17:13 +03:00
dev = DeviceTpm ( self . conn . get_backend ( ) )
2019-05-13 21:06:32 +03:00
dev . type = typ
dev . model = model
dev . device_path = device_path
dev . version = version
2019-04-15 00:17:13 +03:00
return dev
2009-03-09 23:20:23 +03:00
2019-04-15 03:48:36 +03:00
def _build_panic ( self ) :
2017-09-04 19:40:34 +03:00
model = uiutil . get_list_selection ( self . widget ( " panic-model " ) )
2019-04-15 00:17:13 +03:00
dev = DevicePanic ( self . conn . get_backend ( ) )
dev . model = model
return dev
2014-01-10 13:37:56 +04:00
2019-04-15 03:48:36 +03:00
def _build_vsock ( self ) :
2018-12-14 17:34:20 +03:00
auto_cid , cid = self . _vsockdetails . get_values ( )
2019-04-15 00:17:13 +03:00
dev = DeviceVsock ( self . conn . get_backend ( ) )
dev . auto_cid = auto_cid
dev . cid = cid
return dev
2018-12-14 17:34:20 +03:00
2019-04-15 03:48:36 +03:00
def _build_controller ( self ) :
2015-05-19 22:18:30 +03:00
controller_type = uiutil . get_list_selection (
2015-05-20 00:17:53 +03:00
self . widget ( " controller-type " ) )
2015-05-20 00:54:53 +03:00
model = uiutil . get_list_selection ( self . widget ( " controller-model " ) )
2015-05-19 22:18:30 +03:00
2014-06-16 07:48:22 +04:00
self . _selected_model = model
2018-10-04 16:53:36 +03:00
if model == " usb3 " :
2019-04-15 00:17:13 +03:00
dev = DeviceController . get_usb3_controller (
2018-10-04 16:53:36 +03:00
self . conn . get_backend ( ) , self . vm . xmlobj )
model = None
else :
2019-04-15 00:17:13 +03:00
dev = DeviceController ( self . conn . get_backend ( ) )
2014-04-26 18:40:17 +04:00
2018-03-21 21:42:50 +03:00
controllers = self . vm . xmlobj . devices . controller
2014-04-26 18:40:17 +04:00
controller_num = [ x for x in controllers if
( x . type == controller_type ) ]
if len ( controller_num ) > 0 :
index_new = max ( [ x . index for x in controller_num ] ) + 1
2019-04-15 00:17:13 +03:00
dev . index = index_new
2014-04-26 18:40:17 +04:00
2019-04-15 00:17:13 +03:00
dev . type = controller_type
2014-04-26 18:40:17 +04:00
2018-10-04 16:53:36 +03:00
if model and model != " none " :
2019-04-15 00:17:13 +03:00
dev . model = model
return dev
2014-06-16 07:48:22 +04:00
2019-04-15 03:48:36 +03:00
def _build_rng ( self ) :
2015-05-19 22:18:30 +03:00
device = self . widget ( " rng-device " ) . get_text ( )
2019-04-15 00:17:13 +03:00
dev = DeviceRng ( self . conn . get_backend ( ) )
2019-05-13 21:42:50 +03:00
dev . backend_model = DeviceRng . TYPE_RANDOM
2019-04-15 00:17:13 +03:00
dev . device = device
return dev
2013-09-23 17:39:57 +04:00
2009-11-24 20:43:54 +03:00
####################
# Unsorted helpers #
####################
2009-03-09 23:20:23 +03:00
2014-01-29 01:53:11 +04:00
def _browse_storage_cb ( self , ignore , widget ) :
self . _browse_file ( widget )
2011-06-09 02:38:03 +04:00
def _browse_file ( self , textent , isdir = False ) :
2009-11-24 20:43:54 +03:00
def set_storage_cb ( src , path ) :
if path :
textent . set_text ( path )
2009-03-09 23:20:23 +03:00
2011-06-09 02:38:03 +04:00
reason = ( isdir and
self . config . CONFIG_DIR_FS or
self . config . CONFIG_DIR_IMAGE )
2015-05-19 22:18:30 +03:00
if self . _storagebrowser is None :
self . _storagebrowser = vmmStorageBrowser ( self . conn )
2009-03-09 23:20:23 +03:00
2015-05-19 22:18:30 +03:00
self . _storagebrowser . set_finish_cb ( set_storage_cb )
self . _storagebrowser . set_browse_reason ( reason )
2009-11-24 20:43:54 +03:00
2015-05-19 22:18:30 +03:00
self . _storagebrowser . show ( self . topwin )