2013-03-18 01:06:52 +04:00
#
# Common code for all guests
#
2015-02-24 15:32:51 +03:00
# Copyright 2006-2009, 2013, 2014, 2015 Red Hat, Inc.
2013-03-18 01:06:52 +04:00
# Jeremy Katz <katzj@redhat.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
2013-10-28 00:59:47 +04:00
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
2013-03-18 01:06:52 +04:00
#
# 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA.
import logging
2015-09-06 20:42:07 +03:00
import os
2013-03-18 01:06:52 +04:00
import libvirt
2015-04-06 22:42:40 +03:00
from virtcli import CLIConfig
2013-10-03 02:06:52 +04:00
2014-09-12 23:59:22 +04:00
from . import util
from . import support
2015-04-04 19:04:11 +03:00
from . osdict import OSDB
2014-09-12 23:59:22 +04:00
from . clock import Clock
from . cpu import CPU
from . device import VirtualDevice
from . deviceaudio import VirtualAudio
from . devicechar import VirtualChannelDevice , VirtualConsoleDevice
from . devicecontroller import VirtualController
2015-06-06 23:56:03 +03:00
from . devicedisk import VirtualDisk
2014-09-12 23:59:22 +04:00
from . devicegraphics import VirtualGraphics
from . deviceinput import VirtualInputDevice
from . deviceredirdev import VirtualRedirDevice
from . devicevideo import VirtualVideoDevice
from . distroinstaller import DistroInstaller
from . domainblkiotune import DomainBlkiotune
from . domainfeatures import DomainFeatures
from . domainmemorybacking import DomainMemorybacking
from . domainmemorytune import DomainMemorytune
from . domainnumatune import DomainNumatune
from . domainresource import DomainResource
2015-02-18 23:16:48 +03:00
from . domcapabilities import DomainCapabilities
2014-09-12 23:59:22 +04:00
from . idmap import IdMap
from . osxml import OSXML
from . pm import PM
from . seclabel import Seclabel
from . xmlbuilder import XMLBuilder , XMLProperty , XMLChildProperty
2013-03-18 01:06:52 +04:00
2013-07-14 02:56:09 +04:00
class Guest ( XMLBuilder ) :
2013-08-09 22:16:59 +04:00
@staticmethod
def check_vm_collision ( conn , name , do_remove ) :
"""
Remove the existing VM with the same name if requested , or error
if there is a collision .
"""
vm = None
try :
vm = conn . lookupByName ( name )
except libvirt . libvirtError :
pass
if vm is None :
return
if not do_remove :
raise RuntimeError ( _ ( " Domain named %s already exists! " ) % name )
try :
logging . debug ( " Explicitly replacing guest ' %s ' " , name )
if vm . ID ( ) != - 1 :
logging . info ( " Destroying guest ' %s ' " , name )
vm . destroy ( )
logging . info ( " Undefining guest ' %s ' " , name )
vm . undefine ( )
except libvirt . libvirtError , e :
raise RuntimeError ( _ ( " Could not remove old vm ' %s ' : %s " ) %
( str ( e ) ) )
@staticmethod
2014-01-18 03:44:26 +04:00
def validate_name ( conn , name , check_collision , validate = True ) :
if validate :
util . validate_name ( _ ( " Guest " ) , name )
2013-08-09 22:16:59 +04:00
if not check_collision :
return
try :
conn . lookupByName ( name )
except :
return
raise ValueError ( _ ( " Guest name ' %s ' is already in use. " ) % name )
2013-07-18 01:58:24 +04:00
2013-09-11 19:47:09 +04:00
_XML_ROOT_NAME = " domain "
2013-09-24 14:56:16 +04:00
_XML_PROP_ORDER = [ " type " , " name " , " uuid " , " title " , " description " ,
2014-06-05 04:52:24 +04:00
" maxmemory " , " memory " , " blkiotune " , " memtune " , " memoryBacking " ,
2015-04-08 02:51:52 +03:00
" vcpus " , " curvcpus " , " numatune " , " bootloader " , " os " , " idmap " ,
" features " , " cpu " , " clock " , " on_poweroff " , " on_reboot " , " on_crash " ,
" resource " , " pm " , " emulator " , " _devices " , " seclabel " ]
2013-07-18 01:58:24 +04:00
2013-09-11 19:47:09 +04:00
def __init__ ( self , * args , * * kwargs ) :
XMLBuilder . __init__ ( self , * args , * * kwargs )
2013-08-09 19:04:01 +04:00
2013-07-18 01:58:24 +04:00
self . autostart = False
self . replace = False
2013-03-18 01:06:52 +04:00
2013-10-03 02:06:52 +04:00
# Allow virt-manager to override the default graphics type
2015-04-06 22:42:40 +03:00
self . default_graphics_type = CLIConfig . default_graphics
2013-10-03 02:06:52 +04:00
2013-10-06 17:41:37 +04:00
self . skip_default_console = False
self . skip_default_channel = False
2014-02-05 21:49:16 +04:00
self . skip_default_sound = False
2014-02-05 21:58:53 +04:00
self . skip_default_usbredir = False
2014-02-08 01:07:32 +04:00
self . skip_default_graphics = False
2014-02-05 22:51:53 +04:00
self . x86_cpu_default = self . cpu . SPECIAL_MODE_HOST_MODEL_ONLY
2013-10-06 17:41:37 +04:00
2015-04-04 17:16:58 +03:00
self . __os_object = None
2013-07-25 22:36:13 +04:00
self . _random_uuid = None
2015-06-06 23:56:03 +03:00
self . _install_cdrom_device = None
2015-04-07 23:38:52 +03:00
self . _defaults_are_set = False
2013-03-18 01:06:52 +04:00
# The libvirt virDomain object we 'Create'
self . domain = None
2015-07-10 13:06:48 +03:00
# This is set via Capabilities.build_virtinst_guest
self . capsinfo = None
2014-09-12 23:59:22 +04:00
self . installer = DistroInstaller ( self . conn )
2013-03-18 01:06:52 +04:00
######################
# Property accessors #
######################
2013-07-18 01:58:24 +04:00
def _validate_name ( self , val ) :
if val == self . name :
return
2013-08-09 22:16:59 +04:00
self . validate_name ( self . conn , val , check_collision = not self . replace )
2013-09-19 21:27:30 +04:00
name = XMLProperty ( " ./name " , validate_cb = _validate_name )
2013-03-18 01:06:52 +04:00
2013-07-18 01:58:24 +04:00
def _set_memory ( self , val ) :
if val is None :
return None
2013-03-18 01:06:52 +04:00
if self . maxmemory is None or self . maxmemory < val :
self . maxmemory = val
return val
2013-09-19 21:27:30 +04:00
memory = XMLProperty ( " ./currentMemory " , is_int = True ,
2013-07-18 01:58:24 +04:00
default_cb = lambda s : 1 ,
set_converter = _set_memory )
2013-09-19 21:27:30 +04:00
maxmemory = XMLProperty ( " ./memory " , is_int = True )
2013-03-18 01:06:52 +04:00
2013-07-18 01:58:24 +04:00
def _set_vcpus ( self , val ) :
if val is None :
return None
2013-03-18 01:06:52 +04:00
2013-07-18 01:58:24 +04:00
# Don't force set curvcpus unless already specified
if self . curvcpus is not None and self . curvcpus > val :
self . curvcpus = val
return val
2013-09-19 21:27:30 +04:00
vcpus = XMLProperty ( " ./vcpu " , is_int = True ,
2013-07-18 01:58:24 +04:00
set_converter = _set_vcpus ,
default_cb = lambda s : 1 )
2013-09-19 21:27:30 +04:00
curvcpus = XMLProperty ( " ./vcpu/@current " , is_int = True )
2013-07-18 01:58:24 +04:00
def _validate_cpuset ( self , val ) :
2013-03-18 01:06:52 +04:00
DomainNumatune . validate_cpuset ( self . conn , val )
2013-09-19 21:27:30 +04:00
cpuset = XMLProperty ( " ./vcpu/@cpuset " ,
2013-07-18 01:58:24 +04:00
validate_cb = _validate_cpuset )
2013-07-25 22:36:13 +04:00
def _get_default_uuid ( self ) :
if self . _random_uuid is None :
self . _random_uuid = util . generate_uuid ( self . conn )
return self . _random_uuid
2013-09-19 21:27:30 +04:00
uuid = XMLProperty ( " ./uuid " ,
2013-07-25 22:36:13 +04:00
validate_cb = lambda s , v : util . validate_uuid ( v ) ,
default_cb = _get_default_uuid )
2013-09-24 05:27:42 +04:00
id = XMLProperty ( " ./@id " , is_int = True )
2013-09-19 21:27:30 +04:00
type = XMLProperty ( " ./@type " , default_cb = lambda s : " xen " )
bootloader = XMLProperty ( " ./bootloader " )
description = XMLProperty ( " ./description " )
2013-09-24 14:56:16 +04:00
title = XMLProperty ( " ./title " )
2013-09-19 21:27:30 +04:00
emulator = XMLProperty ( " ./devices/emulator " )
2013-07-18 01:58:24 +04:00
2013-09-19 21:27:30 +04:00
on_poweroff = XMLProperty ( " ./on_poweroff " ,
2013-07-18 01:58:24 +04:00
default_cb = lambda s : " destroy " )
2015-04-08 02:51:52 +03:00
on_reboot = XMLProperty ( " ./on_reboot " , default_cb = lambda s : " restart " )
on_crash = XMLProperty ( " ./on_crash " , default_cb = lambda s : " restart " )
2015-10-07 13:50:13 +03:00
on_lockfailure = XMLProperty ( " ./on_lockfailure " )
2013-07-18 01:58:24 +04:00
2015-05-04 01:08:10 +03:00
seclabel = XMLChildProperty ( Seclabel )
2013-09-11 19:47:09 +04:00
os = XMLChildProperty ( OSXML , is_single = True )
features = XMLChildProperty ( DomainFeatures , is_single = True )
clock = XMLChildProperty ( Clock , is_single = True )
cpu = XMLChildProperty ( CPU , is_single = True )
numatune = XMLChildProperty ( DomainNumatune , is_single = True )
2014-02-03 01:12:29 +04:00
pm = XMLChildProperty ( PM , is_single = True )
2014-02-06 18:41:00 +04:00
blkiotune = XMLChildProperty ( DomainBlkiotune , is_single = True )
2014-02-25 06:02:31 +04:00
memtune = XMLChildProperty ( DomainMemorytune , is_single = True )
2014-03-22 14:15:46 +04:00
memoryBacking = XMLChildProperty ( DomainMemorybacking , is_single = True )
2014-02-09 19:25:25 +04:00
idmap = XMLChildProperty ( IdMap , is_single = True )
2014-06-04 06:08:05 +04:00
resource = XMLChildProperty ( DomainResource , is_single = True )
2013-09-11 19:47:09 +04:00
2013-07-18 01:58:24 +04:00
###############################
# Distro detection properties #
###############################
2015-04-04 17:16:58 +03:00
def _set_os_object ( self , variant ) :
2015-04-04 19:04:11 +03:00
obj = OSDB . lookup_os ( variant )
2015-04-04 17:16:58 +03:00
if not obj :
2015-04-04 19:04:11 +03:00
obj = OSDB . lookup_os ( " generic " )
2015-04-04 17:16:58 +03:00
self . __os_object = obj
def _get_os_object ( self ) :
if not self . __os_object :
self . _set_os_object ( None )
return self . __os_object
_os_object = property ( _get_os_object )
2013-08-11 02:48:43 +04:00
def _get_os_variant ( self ) :
2015-04-04 17:16:58 +03:00
return self . _os_object . name
2013-08-11 02:48:43 +04:00
def _set_os_variant ( self , val ) :
2014-09-07 19:57:04 +04:00
if val :
val = val . lower ( )
2015-04-04 19:04:11 +03:00
if OSDB . lookup_os ( val ) is None :
2014-09-07 19:57:04 +04:00
raise ValueError (
_ ( " Distro ' %s ' does not exist in our dictionary " ) % val )
2013-11-10 03:33:49 +04:00
logging . debug ( " Setting Guest.os_variant to ' %s ' " , val )
2015-04-04 17:16:58 +03:00
self . _set_os_object ( val )
2013-08-11 02:48:43 +04:00
os_variant = property ( _get_os_variant , _set_os_variant )
2013-03-18 01:06:52 +04:00
########################################
# Device Add/Remove Public API methods #
########################################
2013-07-25 22:11:09 +04:00
def add_device ( self , dev ) :
2013-03-18 01:06:52 +04:00
"""
Add the passed device to the guest ' s device list.
@param dev : VirtualDevice instance to attach to guest
"""
2015-09-04 22:45:45 +03:00
self . add_child ( dev )
2013-07-24 16:46:55 +04:00
2013-09-11 02:32:10 +04:00
def remove_device ( self , dev ) :
"""
Remove the passed device from the guest ' s device list
@param dev : VirtualDevice instance
"""
2015-09-04 22:45:45 +03:00
self . remove_child ( dev )
2013-03-18 01:06:52 +04:00
def get_devices ( self , devtype ) :
"""
Return a list of devices of type ' devtype ' that will installed on
the guest .
@param devtype : Device type to search for ( one of
VirtualDevice . virtual_device_types )
"""
2013-09-11 02:32:10 +04:00
newlist = [ ]
for i in self . _devices :
if devtype == " all " or i . virtual_device_type == devtype :
newlist . append ( i )
return newlist
2015-09-04 22:45:45 +03:00
2013-09-11 02:32:10 +04:00
_devices = XMLChildProperty (
[ VirtualDevice . virtual_device_classes [ _n ]
2013-09-11 19:47:09 +04:00
for _n in VirtualDevice . virtual_device_types ] ,
relative_xpath = " ./devices " )
2013-03-18 01:06:52 +04:00
def get_all_devices ( self ) :
"""
Return a list of all devices being installed with the guest
"""
retlist = [ ]
for devtype in VirtualDevice . virtual_device_types :
retlist . extend ( self . get_devices ( devtype ) )
return retlist
############################
# Install Helper functions #
############################
def _prepare_install ( self , meter , dry = False ) :
ignore = dry
# Fetch install media, prepare installer devices
2014-09-07 21:35:34 +04:00
self . installer . prepare ( self , meter )
2013-03-18 01:06:52 +04:00
# Initialize install device list
2015-06-06 23:56:03 +03:00
if self . _install_cdrom_device :
self . _install_cdrom_device . path = self . installer . cdrom_path ( )
self . _install_cdrom_device . validate ( )
2013-03-18 01:06:52 +04:00
2013-07-18 01:58:24 +04:00
def _prepare_get_xml ( self ) :
2015-04-07 23:38:52 +03:00
# We do a shallow copy of the OS block here, so that we can
# set the install time properties but not permanently overwrite
# any config the user explicitly requested.
2015-04-08 02:51:52 +03:00
data = ( self . os , self . on_crash , self . on_reboot )
2013-07-17 21:06:01 +04:00
try :
2013-09-11 19:47:09 +04:00
self . _propstore [ " os " ] = self . os . copy ( )
2013-07-18 01:58:24 +04:00
except :
self . _finish_get_xml ( data )
raise
return data
def _finish_get_xml ( self , data ) :
2015-04-08 02:51:52 +03:00
( self . _propstore [ " os " ] ,
self . on_crash ,
self . on_reboot ) = data
2013-07-17 21:06:01 +04:00
2015-04-07 23:38:52 +03:00
def _get_install_xml ( self , * args , * * kwargs ) :
2013-07-24 19:32:30 +04:00
data = self . _prepare_get_xml ( )
try :
return self . _do_get_install_xml ( * args , * * kwargs )
finally :
self . _finish_get_xml ( data )
def _do_get_install_xml ( self , install = True , disk_boot = False ) :
2013-03-18 01:06:52 +04:00
"""
Return the full Guest xml configuration .
@param install : Whether we want the ' OS install ' configuration or
2014-09-07 21:42:56 +04:00
the ' post-install ' configuration . ( Some installs ,
like an import or livecd may not have an ' install '
2013-03-18 01:06:52 +04:00
config . )
@type install : C { bool }
@param disk_boot : Whether we should boot off the harddisk , regardless
of our position in the install process ( this is
used for 2 stage installs , where the second stage
boots off the disk . You probably don ' t need to touch
this . )
@type disk_boot : C { bool }
"""
2013-07-17 21:06:01 +04:00
osblob_install = install and not disk_boot
2013-03-18 01:06:52 +04:00
if osblob_install and not self . installer . has_install_phase ( ) :
return None
2015-04-07 23:38:52 +03:00
self . installer . alter_bootconfig ( self , osblob_install )
2015-06-06 21:52:21 +03:00
if not install :
self . _remove_cdrom_install_media ( )
2013-07-18 01:58:24 +04:00
2015-04-08 02:51:52 +03:00
if install :
self . on_reboot = " destroy "
self . on_crash = " destroy "
2013-07-18 01:58:24 +04:00
2015-04-07 23:38:52 +03:00
self . _set_osxml_defaults ( )
2013-07-18 01:58:24 +04:00
self . bootloader = None
2013-07-17 21:06:01 +04:00
if ( not install and
self . os . is_xenpv ( ) and
not self . os . kernel ) :
2013-07-18 01:58:24 +04:00
self . bootloader = " /usr/bin/pygrub "
self . os . clear ( )
2013-07-24 19:32:30 +04:00
return self . get_xml_config ( )
2013-03-18 01:06:52 +04:00
2015-04-07 23:38:52 +03:00
2015-09-06 20:42:07 +03:00
###########################
# Private install helpers #
###########################
def _build_meter ( self , meter , is_initial ) :
if is_initial :
meter_label = _ ( " Creating domain... " )
else :
meter_label = _ ( " Starting domain... " )
2015-09-06 21:26:50 +03:00
meter = util . ensure_meter ( meter )
2015-09-06 20:42:07 +03:00
meter . start ( size = None , text = meter_label )
return meter
def _build_xml ( self , is_initial ) :
log_label = is_initial and " install " or " continue "
disk_boot = not is_initial
start_xml = self . _get_install_xml ( install = True , disk_boot = disk_boot )
final_xml = self . _get_install_xml ( install = False )
logging . debug ( " Generated %s XML: %s " ,
log_label ,
( start_xml and ( " \n " + start_xml ) or " None required " ) )
logging . debug ( " Generated boot XML: \n %s " , final_xml )
return start_xml , final_xml
def _create_guest ( self , meter ,
start_xml , final_xml , is_initial , noboot ) :
"""
Actually do the XML logging , guest defining / creating
@param is_initial : If running initial guest creation , else we
are continuing the install
@param noboot : Don ' t boot guest if no install phase
"""
meter = self . _build_meter ( meter , is_initial )
doboot = not noboot or self . installer . has_install_phase ( )
if is_initial and doboot :
dom = self . conn . createLinux ( start_xml or final_xml , 0 )
else :
dom = self . conn . defineXML ( start_xml or final_xml )
if doboot :
dom . create ( )
self . domain = dom
meter . end ( 0 )
self . domain = self . conn . defineXML ( final_xml )
if is_initial :
try :
logging . debug ( " XML fetched from libvirt object: \n %s " ,
dom . XMLDesc ( 0 ) )
except Exception , e :
logging . debug ( " Error fetching XML from libvirt object: %s " , e )
return self . domain
def _flag_autostart ( self ) :
"""
Set the autostart flag for self . domain if the user requested it
"""
if not self . autostart :
return
try :
self . domain . setAutostart ( True )
except libvirt . libvirtError , e :
if util . is_error_nosupport ( e ) :
logging . warn ( " Could not set autostart flag: libvirt "
" connection does not support autostart. " )
else :
raise e
2015-04-07 23:38:52 +03:00
##############
# Public API #
##############
2013-03-18 01:06:52 +04:00
def get_continue_inst ( self ) :
"""
Return True if this guest requires a call to ' continue_install ' ,
which means the OS requires a 2 stage install ( windows )
"""
# If we are doing an 'import' or 'liveCD' install, there is
# no true install process, so continue install has no meaning
if not self . installer . has_install_phase ( ) :
return False
2015-04-04 17:44:54 +03:00
return self . _os_object . is_windows ( )
2013-03-18 01:06:52 +04:00
2013-08-09 22:16:59 +04:00
def start_install ( self , meter = None ,
2013-08-09 19:25:05 +04:00
dry = False , return_xml = False , noboot = False ) :
2013-03-18 01:06:52 +04:00
"""
Begin the guest install ( stage1 ) .
@param return_xml : Don ' t create the guest, just return generated XML
"""
2013-07-14 03:43:52 +04:00
if self . domain is not None :
raise RuntimeError ( _ ( " Domain has already been started! " ) )
2013-03-18 01:06:52 +04:00
2013-07-14 03:43:52 +04:00
is_initial = True
2015-04-07 23:38:52 +03:00
self . set_install_defaults ( )
2013-03-18 01:06:52 +04:00
self . _prepare_install ( meter , dry )
try :
# Create devices if required (disk images, etc.)
if not dry :
2013-08-15 03:43:02 +04:00
for dev in self . get_all_devices ( ) :
dev . setup ( meter )
2013-03-18 01:06:52 +04:00
start_xml , final_xml = self . _build_xml ( is_initial )
if return_xml :
return ( start_xml , final_xml )
if dry :
return
# Remove existing VM if requested
2013-08-09 22:16:59 +04:00
self . check_vm_collision ( self . conn , self . name ,
do_remove = self . replace )
2013-03-18 01:06:52 +04:00
2013-08-09 19:25:05 +04:00
self . domain = self . _create_guest ( meter ,
2013-03-18 01:06:52 +04:00
start_xml , final_xml , is_initial ,
noboot )
# Set domain autostart flag if requested
self . _flag_autostart ( )
return self . domain
finally :
2013-08-15 03:43:02 +04:00
self . installer . cleanup ( )
2013-03-18 01:06:52 +04:00
2013-08-09 19:25:05 +04:00
def continue_install ( self , meter = None ,
2013-03-18 01:06:52 +04:00
dry = False , return_xml = False ) :
"""
Continue with stage 2 of a guest install . Only required for
guests which have the ' continue ' flag set ( accessed via
get_continue_inst )
"""
is_initial = False
start_xml , final_xml = self . _build_xml ( is_initial )
if return_xml :
return ( start_xml , final_xml )
if dry :
return
2013-08-09 19:25:05 +04:00
return self . _create_guest ( meter ,
2013-03-18 01:06:52 +04:00
start_xml , final_xml , is_initial , False )
2015-09-06 21:42:55 +03:00
def get_created_disks ( self ) :
return [ d for d in self . get_devices ( " disk " ) if d . storage_was_created ]
2015-09-06 20:42:07 +03:00
def cleanup_created_disks ( self , meter ) :
2013-03-18 01:06:52 +04:00
"""
2015-09-06 20:42:07 +03:00
Remove any disks we created as part of the install . Only ever
called by clients .
2013-03-18 01:06:52 +04:00
"""
2015-09-06 21:42:55 +03:00
clean_disks = self . get_created_disks ( )
2015-09-06 20:42:07 +03:00
if not clean_disks :
return
2013-03-18 01:06:52 +04:00
2015-09-06 20:42:07 +03:00
for disk in clean_disks :
logging . debug ( " Removing created disk path= %s vol_object= %s " ,
disk . path , disk . get_vol_object ( ) )
name = os . path . basename ( disk . path )
2013-03-18 01:06:52 +04:00
try :
2015-09-06 20:42:07 +03:00
meter . start ( size = None , text = _ ( " Removing disk ' %s ' " ) % name )
2013-03-18 01:06:52 +04:00
2015-09-06 20:42:07 +03:00
if disk . get_vol_object ( ) :
disk . get_vol_object ( ) . delete ( )
else :
os . unlink ( disk . path )
2013-03-18 01:06:52 +04:00
2015-09-06 20:42:07 +03:00
meter . end ( 0 )
except Exception , e :
logging . debug ( " Failed to remove disk ' %s ' " ,
name , exc_info = True )
logging . error ( " Failed to remove disk ' %s ' : %s " , name , e )
2013-03-18 01:06:52 +04:00
2015-02-18 23:16:48 +03:00
###########################
# XML convenience helpers #
###########################
def set_uefi_default ( self ) :
"""
Configure UEFI for the VM , but only if libvirt is advertising
a known UEFI binary path .
"""
domcaps = DomainCapabilities . build_from_guest ( self )
if not domcaps . supports_uefi_xml ( ) :
raise RuntimeError ( _ ( " Libvirt version does not support UEFI. " ) )
2015-02-22 19:02:55 +03:00
if not domcaps . arch_can_uefi ( ) :
2015-02-18 23:16:48 +03:00
raise RuntimeError (
_ ( " Don ' t know how to setup UEFI for arch ' %s ' " ) %
self . os . arch )
2015-02-22 19:02:55 +03:00
path = domcaps . find_uefi_path_for_arch ( )
2015-02-18 23:16:48 +03:00
if not path :
raise RuntimeError ( _ ( " Did not find any UEFI binary path for "
" arch ' %s ' " ) % self . os . arch )
self . os . loader_ro = True
self . os . loader_type = " pflash "
self . os . loader = path
2013-03-18 01:06:52 +04:00
###################
# Device defaults #
###################
2015-04-07 23:38:52 +03:00
def set_install_defaults ( self ) :
"""
Allow API users to set defaults ahead of time if they want it .
Used by vmmDomainVirtinst so the ' Customize before install ' dialog
shows accurate values .
If the user doesn ' t explicitly call this, it will be called by
start_install ( )
"""
if self . _defaults_are_set :
return
self . _set_defaults ( )
self . _defaults_are_set = True
2015-03-25 16:04:51 +03:00
def stable_defaults ( self , * args , * * kwargs ) :
return self . conn . stable_defaults ( self . emulator , * args , * * kwargs )
2015-03-23 23:43:39 +03:00
2013-07-25 22:36:13 +04:00
def add_default_input_device ( self ) :
if self . os . is_container ( ) :
return
2013-08-18 16:59:19 +04:00
if not self . os . is_x86 ( ) :
return
2013-10-06 16:30:33 +04:00
if self . get_devices ( " input " ) :
return
2014-09-12 23:59:22 +04:00
self . add_device ( VirtualInputDevice ( self . conn ) )
2013-07-25 22:36:13 +04:00
2013-08-18 16:59:19 +04:00
def add_default_sound_device ( self ) :
if not self . os . is_hvm ( ) :
return
if not self . os . is_x86 ( ) :
return
2014-09-12 23:59:22 +04:00
self . add_device ( VirtualAudio ( self . conn ) )
2013-08-18 16:59:19 +04:00
2013-07-25 22:36:13 +04:00
def add_default_console_device ( self ) :
2013-10-06 17:41:37 +04:00
if self . skip_default_console :
return
2013-10-06 16:30:33 +04:00
if self . get_devices ( " console " ) or self . get_devices ( " serial " ) :
return
2014-09-12 23:59:22 +04:00
dev = VirtualConsoleDevice ( self . conn )
2013-07-25 22:36:13 +04:00
dev . type = dev . TYPE_PTY
self . add_device ( dev )
2013-08-18 16:59:19 +04:00
def add_default_video_device ( self ) :
if self . os . is_container ( ) :
return
2013-10-06 16:30:33 +04:00
if self . get_devices ( " video " ) :
return
if not self . get_devices ( " graphics " ) :
return
2014-09-12 23:59:22 +04:00
self . add_device ( VirtualVideoDevice ( self . conn ) )
2013-08-18 16:59:19 +04:00
2013-10-02 23:51:01 +04:00
def add_default_usb_controller ( self ) :
if self . os . is_container ( ) :
return
if not self . os . is_x86 ( ) :
return
2013-10-06 16:30:33 +04:00
if any ( [ d . type == " usb " for d in self . get_devices ( " controller " ) ] ) :
return
2013-10-06 18:08:04 +04:00
if not self . conn . check_support (
2013-10-02 23:51:01 +04:00
self . conn . SUPPORT_CONN_DEFAULT_USB2 ) :
return
2014-09-12 23:59:22 +04:00
for dev in VirtualController . get_usb2_controllers ( self . conn ) :
2013-10-02 23:51:01 +04:00
self . add_device ( dev )
2013-10-06 17:19:59 +04:00
def add_default_channels ( self ) :
2013-10-06 17:41:37 +04:00
if self . skip_default_channel :
return
2013-10-06 17:19:59 +04:00
if self . get_devices ( " channel " ) :
return
2014-01-12 23:58:43 +04:00
# Skip qemu-ga on ARM where virtio slots are currently limited
2013-10-06 17:19:59 +04:00
if ( self . conn . is_qemu ( ) and
2014-01-12 23:58:43 +04:00
not self . os . is_arm ( ) and
2015-04-04 17:44:54 +03:00
self . _os_object . supports_qemu_ga ( ) and
2013-10-06 18:08:04 +04:00
self . conn . check_support ( self . conn . SUPPORT_CONN_AUTOSOCKET ) ) :
2014-09-12 23:59:22 +04:00
dev = VirtualChannelDevice ( self . conn )
2013-10-06 17:19:59 +04:00
dev . type = " unix "
dev . target_type = " virtio "
dev . target_name = dev . CHANNEL_NAME_QEMUGA
self . add_device ( dev )
2014-02-08 01:07:32 +04:00
def add_default_graphics ( self ) :
if self . skip_default_graphics :
return
if self . get_devices ( " graphics " ) :
return
if self . os . is_container ( ) :
return
2015-01-05 05:16:18 +03:00
if self . os . arch not in [ " x86_64 " , " i686 " , " ppc64 " , " ppc64le " , " ia64 " ] :
2014-02-08 01:07:32 +04:00
return
2014-09-12 23:59:22 +04:00
self . add_device ( VirtualGraphics ( self . conn ) )
2014-02-08 01:07:32 +04:00
def add_default_devices ( self ) :
self . add_default_graphics ( )
self . add_default_video_device ( )
self . add_default_input_device ( )
self . add_default_console_device ( )
self . add_default_usb_controller ( )
self . add_default_channels ( )
2015-06-06 23:56:03 +03:00
def _add_install_cdrom ( self ) :
if self . _install_cdrom_device :
return
if not self . installer . needs_cdrom ( ) :
return
dev = VirtualDisk ( self . conn )
dev . device = dev . DEVICE_CDROM
setattr ( dev , " installer_media " , not self . installer . livecd )
self . _install_cdrom_device = dev
self . add_device ( dev )
2015-06-06 21:52:21 +03:00
def _remove_cdrom_install_media ( self ) :
for dev in self . get_devices ( " disk " ) :
# Keep the install cdrom device around, but with no media attached.
2013-07-18 01:58:24 +04:00
# But only if we are a distro that doesn't have a multi
# stage install (aka not Windows)
2015-06-06 21:52:21 +03:00
if ( dev . is_cdrom ( ) and
getattr ( dev , " installer_media " , False ) and
not self . get_continue_inst ( ) ) :
2013-07-18 01:58:24 +04:00
dev . path = None
2013-07-24 19:32:30 +04:00
def _set_defaults ( self ) :
2015-06-06 23:56:03 +03:00
self . _add_install_cdrom ( )
2015-04-03 01:04:06 +03:00
# some options check for has_spice() which is resolved after this:
self . _set_graphics_defaults ( )
2013-07-25 22:36:13 +04:00
self . _set_clock_defaults ( )
2013-07-18 01:58:24 +04:00
self . _set_emulator_defaults ( )
self . _set_cpu_defaults ( )
2013-07-25 22:36:13 +04:00
self . _set_feature_defaults ( )
2015-04-12 01:02:45 +03:00
self . _set_pm_defaults ( )
2013-07-18 01:58:24 +04:00
2013-07-25 22:36:13 +04:00
for dev in self . get_all_devices ( ) :
2013-10-06 21:17:35 +04:00
dev . set_defaults ( self )
2013-09-02 18:56:53 +04:00
self . _check_address_multi ( )
2013-07-25 22:36:13 +04:00
self . _set_disk_defaults ( )
2014-11-20 19:27:09 +03:00
self . _add_implied_controllers ( )
2013-07-25 22:36:13 +04:00
self . _set_net_defaults ( )
self . _set_input_defaults ( )
self . _set_video_defaults ( )
2014-02-05 21:49:16 +04:00
self . _set_sound_defaults ( )
2013-07-18 01:58:24 +04:00
2014-09-23 23:09:35 +04:00
def _is_full_os_container ( self ) :
2014-03-10 18:25:14 +04:00
if not self . os . is_container ( ) :
return False
for fs in self . get_devices ( " filesystem " ) :
if fs . target == " / " :
return True
return False
2013-07-18 01:58:24 +04:00
def _set_osxml_defaults ( self ) :
if self . os . is_container ( ) and not self . os . init :
2014-09-23 23:09:35 +04:00
if self . _is_full_os_container ( ) :
2014-03-10 18:25:14 +04:00
self . os . init = " /sbin/init "
2013-07-18 01:58:24 +04:00
self . os . init = self . os . init or " /bin/sh "
if not self . os . loader and self . os . is_hvm ( ) and self . type == " xen " :
self . os . loader = " /usr/lib/xen/boot/hvmloader "
if self . os . os_type == " xen " and self . type == " xen " :
# Use older libvirt 'linux' value for back compat
self . os . os_type = " linux "
if self . os . kernel or self . os . init :
self . os . bootorder = [ ]
2013-07-25 22:36:13 +04:00
def _set_clock_defaults ( self ) :
if not self . os . is_hvm ( ) :
return
2013-03-18 01:06:52 +04:00
2013-04-13 22:34:52 +04:00
if self . clock . offset is None :
2015-04-04 17:44:54 +03:00
self . clock . offset = self . _os_object . get_clock ( )
2013-03-18 01:06:52 +04:00
2013-10-06 01:02:26 +04:00
if self . clock . timers :
return
if not self . os . is_x86 ( ) :
return
2013-10-06 18:08:04 +04:00
if not self . conn . check_support (
2013-10-06 01:02:26 +04:00
self . conn . SUPPORT_CONN_ADVANCED_CLOCK ) :
return
# Set clock policy that maps to qemu options:
# -no-hpet -no-kvm-pit-reinjection -rtc driftfix=slew
#
# hpet: Is unneeded and has a performance penalty
# pit: While it has no effect on windows, it doesn't hurt and
# is beneficial for linux
#
2014-07-07 02:46:16 +04:00
# If libvirt/qemu supports it and using a windows VM, also
# specify hypervclock.
#
2013-10-06 01:02:26 +04:00
# This is what has been recommended by the RH qemu guys :)
rtc = self . clock . add_timer ( )
rtc . name = " rtc "
rtc . tickpolicy = " catchup "
pit = self . clock . add_timer ( )
pit . name = " pit "
pit . tickpolicy = " delay "
hpet = self . clock . add_timer ( )
hpet . name = " hpet "
hpet . present = False
2015-07-20 20:06:34 +03:00
hv_clock = self . conn . check_support ( self . conn . SUPPORT_CONN_HYPERV_CLOCK )
hv_clock_rhel = self . conn . check_support ( self . conn . SUPPORT_CONN_HYPERV_CLOCK_RHEL )
if ( self . _os_object . is_windows ( ) and self . _hv_supported ( ) and
( hv_clock or ( self . stable_defaults ( ) and hv_clock_rhel ) ) ) :
2014-07-07 02:46:16 +04:00
hyperv = self . clock . add_timer ( )
hyperv . name = " hypervclock "
hyperv . present = True
2013-07-25 22:36:13 +04:00
def _set_emulator_defaults ( self ) :
if self . os . is_xenpv ( ) :
self . emulator = None
return
if self . emulator :
return
2013-03-18 01:06:52 +04:00
2013-07-25 22:36:13 +04:00
if self . os . is_hvm ( ) and self . type == " xen " :
2014-01-18 22:23:30 +04:00
if self . conn . caps . host . cpu . arch == " x86_64 " :
2013-07-25 22:36:13 +04:00
self . emulator = " /usr/lib64/xen/bin/qemu-dm "
else :
self . emulator = " /usr/lib/xen/bin/qemu-dm "
2013-03-18 01:06:52 +04:00
2013-07-25 22:36:13 +04:00
def _set_cpu_defaults ( self ) :
self . cpu . set_topology_defaults ( self . vcpus )
2013-03-18 01:06:52 +04:00
2014-09-24 00:16:35 +04:00
if not self . conn . is_test ( ) and not self . conn . is_qemu ( ) :
2014-02-05 22:51:53 +04:00
return
2015-03-24 00:46:09 +03:00
if ( self . cpu . get_xml_config ( ) . strip ( ) or
self . cpu . special_mode_was_set ) :
2014-09-24 00:16:35 +04:00
# User already configured CPU
2014-02-05 22:51:53 +04:00
return
2014-09-24 00:16:35 +04:00
if self . os . is_arm_machvirt ( ) and self . type == " kvm " :
2015-04-23 17:14:58 +03:00
self . cpu . mode = self . cpu . SPECIAL_MODE_HOST_PASSTHROUGH
2014-09-24 00:16:35 +04:00
elif self . os . is_arm64 ( ) and self . os . is_arm_machvirt ( ) :
# -M virt defaults to a 32bit CPU, even if using aarch64
self . cpu . model = " cortex-a57 "
elif self . os . is_x86 ( ) and self . type == " kvm " :
if self . os . arch != self . conn . caps . host . cpu . arch :
return
2015-11-03 19:15:26 +03:00
2014-09-24 00:16:35 +04:00
self . cpu . set_special_mode ( self . x86_cpu_default )
2015-11-03 19:15:26 +03:00
if self . _os_object . broken_x2apic ( ) :
self . cpu . add_feature ( " x2apic " , policy = " disable " )
2014-02-05 22:51:53 +04:00
2015-01-26 18:52:03 +03:00
def _hv_supported ( self ) :
if ( self . os . loader_type == " pflash " and
self . os_variant in ( " win2k8r2 " , " win7 " ) ) :
return False
return True
2015-05-20 19:27:13 +03:00
def check_defaults ( self ) :
# This is used only by virt-manager to reset any defaults that may have
# changed through manual intervention via the customize wizard.
if not self . _hv_supported ( ) :
self . features . hyperv_relaxed = None
self . features . hyperv_vapic = None
self . features . hyperv_spinlocks = None
self . features . hyperv_spinlocks_retries = None
for i in self . clock . timers :
if i . name == " hypervclock " :
self . clock . remove_timer ( i )
2013-07-18 01:58:24 +04:00
def _set_feature_defaults ( self ) :
if self . os . is_container ( ) :
self . features . acpi = None
self . features . apic = None
self . features . pae = None
2014-09-23 23:09:35 +04:00
if self . _is_full_os_container ( ) :
2014-03-10 18:25:14 +04:00
self . features . privnet = True
2013-07-18 01:58:24 +04:00
return
if not self . os . is_hvm ( ) :
return
2013-08-18 01:53:17 +04:00
default = True
2015-04-04 17:44:54 +03:00
if ( self . _os_object . need_old_xen_disable_acpi ( ) and
2014-02-11 01:14:39 +04:00
not self . conn . check_support ( support . SUPPORT_CONN_CAN_ACPI ) ) :
2013-08-18 01:53:17 +04:00
default = False
2013-09-27 23:08:44 +04:00
if self . features . acpi == " default " :
2015-07-10 13:06:49 +03:00
if default :
self . features . acpi = self . capsinfo . guest . supports_acpi ( )
else :
self . features . acpi = False
2013-09-27 23:08:44 +04:00
if self . features . apic == " default " :
2015-07-10 13:06:49 +03:00
self . features . apic = self . capsinfo . guest . supports_apic ( )
2013-09-27 23:08:44 +04:00
if self . features . pae == " default " :
2015-11-03 15:11:19 +03:00
if ( self . os . is_hvm ( ) and
self . type == " xen " and
self . os . arch == " x86_64 " ) :
self . features . pae = True
else :
self . features . pae = self . capsinfo . guest . supports_pae ( )
2013-07-18 01:58:24 +04:00
2015-04-03 01:04:07 +03:00
if ( self . features . vmport == " default " and
2015-09-04 19:14:22 +03:00
self . os . is_x86 ( ) and
2015-04-03 01:04:07 +03:00
self . has_spice ( ) and
self . conn . check_support ( self . conn . SUPPORT_CONN_VMPORT ) ) :
self . features . vmport = False
2015-04-04 17:44:54 +03:00
if ( self . _os_object . is_windows ( ) and
2015-01-26 18:52:03 +03:00
self . _hv_supported ( ) and
2014-07-07 02:46:16 +04:00
self . conn . check_support ( self . conn . SUPPORT_CONN_HYPERV_VAPIC ) ) :
if self . features . hyperv_relaxed is None :
self . features . hyperv_relaxed = True
if self . features . hyperv_vapic is None :
self . features . hyperv_vapic = True
if self . features . hyperv_spinlocks is None :
self . features . hyperv_spinlocks = True
if self . features . hyperv_spinlocks_retries is None :
self . features . hyperv_spinlocks_retries = 8191
2015-04-12 01:02:45 +03:00
def _set_pm_defaults ( self ) :
# When the suspend feature is exposed to VMs, an ACPI shutdown
# event triggers a suspend in the guest, which causes a lot of
# user confusion (especially compounded with the face that suspend
# is often buggy so VMs can get hung, etc).
#
# We've been disabling this in virt-manager for a while, but lets
# do it here too for consistency.
if ( self . os . is_x86 ( ) and
self . conn . check_support ( self . conn . SUPPORT_CONN_PM_DISABLE ) ) :
if self . pm . suspend_to_mem is None :
self . pm . suspend_to_mem = False
if self . pm . suspend_to_disk is None :
self . pm . suspend_to_disk = False
2013-07-25 22:36:13 +04:00
def _add_implied_controllers ( self ) :
2014-11-20 19:27:09 +03:00
has_spapr_scsi = False
has_virtio_scsi = False
has_any_scsi = False
for dev in self . get_devices ( " controller " ) :
if dev . type == " scsi " :
has_any_scsi = True
if dev . address . type == " spapr-vio " :
has_spapr_scsi = True
if dev . model == " virtio " :
has_virtio_scsi = True
# Add spapr-vio controller if needed
if not has_spapr_scsi :
for dev in self . get_devices ( " disk " ) :
if dev . address . type == " spapr-vio " :
ctrl = VirtualController ( self . conn )
ctrl . type = " scsi "
ctrl . address . set_addrstr ( " spapr-vio " )
self . add_device ( ctrl )
break
# Add virtio-scsi controller if needed
if ( self . os . is_arm_machvirt ( ) and
not has_any_scsi and
not has_virtio_scsi ) :
for dev in self . get_devices ( " disk " ) :
if dev . bus == " scsi " :
ctrl = VirtualController ( self . conn )
ctrl . type = " scsi "
ctrl . model = " virtio-scsi "
self . add_device ( ctrl )
break
2013-07-18 01:58:24 +04:00
2013-09-02 18:56:53 +04:00
def _check_address_multi ( self ) :
addresses = { }
2013-09-20 18:47:36 +04:00
for d in self . get_all_devices ( ) :
2013-09-02 18:56:53 +04:00
if d . address . type != d . address . ADDRESS_TYPE_PCI :
continue
addr = d . address
addrstr = " %d %d %d " % ( d . address . domain ,
d . address . bus ,
d . address . slot )
if addrstr not in addresses :
addresses [ addrstr ] = { }
if addr . function in addresses [ addrstr ] :
raise ValueError ( _ ( " Duplicate address for devices %s and %s " ) %
( str ( d ) , str ( addresses [ addrstr ] [ addr . function ] ) ) )
addresses [ addrstr ] [ addr . function ] = d
for devs in addresses . values ( ) :
if len ( devs ) > 1 and 0 in devs :
devs [ 0 ] . address . multifunction = True
2015-04-04 17:44:54 +03:00
def _hv_only_supports_virtio ( self ) :
# Only supports virtio so we need to force it
return self . conn . is_qemu ( ) and self . os . is_arm_machvirt ( )
def _hv_supports_virtio ( self ) :
2013-08-18 01:59:17 +04:00
if not self . conn . is_qemu ( ) :
2013-08-18 01:53:17 +04:00
return False
2014-09-23 23:12:02 +04:00
2015-04-04 17:44:54 +03:00
if self . _hv_only_supports_virtio ( ) :
2014-09-23 23:12:02 +04:00
return True
2013-08-18 16:59:19 +04:00
if self . os . is_x86 ( ) :
return True
2014-09-23 23:12:02 +04:00
2013-08-18 16:59:19 +04:00
if ( self . os . is_arm_vexpress ( ) and
self . os . dtb and
2015-04-04 17:44:54 +03:00
self . _os_object . supports_virtiommio ( ) and
2013-10-06 18:08:04 +04:00
self . conn . check_support ( support . SUPPORT_CONN_VIRTIO_MMIO ) ) :
2013-08-18 16:59:19 +04:00
return True
return False
2013-08-18 01:53:17 +04:00
2015-06-06 23:56:03 +03:00
def _set_disk_defaults ( self ) :
disks = self . get_devices ( " disk " )
2015-04-07 23:38:52 +03:00
2013-07-25 22:36:13 +04:00
def set_disk_bus ( d ) :
2013-08-17 22:21:30 +04:00
if d . is_floppy ( ) :
2013-07-25 22:36:13 +04:00
d . bus = " fdc "
return
if self . os . is_xenpv ( ) :
d . bus = " xen "
return
2013-08-17 22:21:30 +04:00
if not self . os . is_hvm ( ) :
2015-04-06 20:43:18 +03:00
# This likely isn't correct, but it's kind of a catch all
# for virt types we don't know how to handle.
2013-08-17 22:21:30 +04:00
d . bus = " ide "
return
2013-03-18 01:06:52 +04:00
2014-11-20 23:39:53 +03:00
if self . os . is_arm_machvirt ( ) :
# We prefer virtio-scsi for machvirt, gets us hotplug
d . bus = " scsi "
2015-04-04 17:44:54 +03:00
elif ( d . is_disk ( ) and
( self . _hv_only_supports_virtio ( ) or
( self . _hv_supports_virtio ( ) and
self . _os_object . supports_virtiodisk ( ) ) ) ) :
2013-08-18 01:53:17 +04:00
d . bus = " virtio "
elif self . os . is_pseries ( ) :
2013-08-17 22:21:30 +04:00
d . bus = " scsi "
2013-08-18 16:59:19 +04:00
elif self . os . is_arm ( ) :
d . bus = " sd "
2015-04-06 20:43:18 +03:00
elif self . os . is_q35 ( ) :
d . bus = " sata "
2015-07-13 14:35:24 +03:00
elif self . os . is_s390x ( ) :
d . bus = " virtio "
2013-08-17 22:21:30 +04:00
else :
d . bus = " ide "
2013-03-18 01:06:52 +04:00
2015-04-07 23:38:52 +03:00
# Generate disk targets
2013-03-18 01:06:52 +04:00
used_targets = [ ]
2015-04-07 23:38:52 +03:00
for disk in disks :
2013-03-18 01:06:52 +04:00
if not disk . bus :
2013-07-25 22:36:13 +04:00
set_disk_bus ( disk )
2015-06-06 23:56:03 +03:00
for disk in disks :
if ( disk . target and
not getattr ( disk , " cli_generated_target " , False ) ) :
2013-03-18 01:06:52 +04:00
used_targets . append ( disk . target )
2015-06-06 23:56:03 +03:00
else :
2015-04-07 23:38:52 +03:00
disk . cli_generated_target = False
2013-03-18 01:06:52 +04:00
used_targets . append ( disk . generate_target ( used_targets ) )
2013-07-25 22:36:13 +04:00
def _set_net_defaults ( self ) :
2015-02-25 14:26:45 +03:00
net_model = None
2013-07-25 22:36:13 +04:00
if not self . os . is_hvm ( ) :
net_model = None
2015-04-04 17:44:54 +03:00
elif ( self . _hv_only_supports_virtio ( ) or
( self . _hv_supports_virtio ( ) and
self . _os_object . supports_virtionet ( ) ) ) :
2013-08-18 01:53:17 +04:00
net_model = " virtio "
2015-04-04 17:44:54 +03:00
else :
net_model = self . _os_object . default_netmodel ( )
2015-02-25 14:26:45 +03:00
if net_model :
for net in self . get_devices ( " interface " ) :
if not net . model :
net . model = net_model
2013-07-25 22:36:13 +04:00
def _set_input_defaults ( self ) :
2015-09-29 02:01:44 +03:00
def _usb_disabled ( ) :
controllers = [ c for c in self . get_devices ( " controller " ) if
c . type == " usb " ]
if not controllers :
return False
return all ( [ c . model == " none " for c in controllers ] )
2015-04-04 17:44:54 +03:00
input_type = self . _os_object . default_inputtype ( )
input_bus = self . _os_object . default_inputbus ( )
2013-07-25 22:36:13 +04:00
if self . os . is_xenpv ( ) :
2014-09-12 23:59:22 +04:00
input_type = VirtualInputDevice . TYPE_MOUSE
input_bus = VirtualInputDevice . BUS_XEN
2015-09-29 02:01:44 +03:00
elif _usb_disabled ( ) and input_bus == " usb " :
input_bus = " ps2 "
if input_type == " tablet " :
input_type = " mouse "
2013-07-25 22:36:13 +04:00
for inp in self . get_devices ( " input " ) :
if ( inp . type == inp . TYPE_DEFAULT and
inp . bus == inp . BUS_DEFAULT ) :
inp . type = input_type
inp . bus = input_bus
def _set_sound_defaults ( self ) :
2013-10-06 18:08:04 +04:00
if self . conn . check_support (
2013-10-03 00:41:23 +04:00
support . SUPPORT_CONN_SOUND_ICH6 ) :
2013-08-11 23:29:31 +04:00
default = " ich6 "
2013-10-06 18:08:04 +04:00
elif self . conn . check_support (
2013-10-03 00:41:23 +04:00
support . SUPPORT_CONN_SOUND_AC97 ) :
2013-08-11 23:29:31 +04:00
default = " ac97 "
else :
default = " es1370 "
2013-07-24 16:46:55 +04:00
for sound in self . get_devices ( " sound " ) :
2013-03-18 01:06:52 +04:00
if sound . model == sound . MODEL_DEFAULT :
2013-08-11 23:29:31 +04:00
sound . model = default
2013-03-18 01:06:52 +04:00
2013-10-03 02:06:52 +04:00
def _set_graphics_defaults ( self ) :
2015-04-12 00:35:40 +03:00
def _set_type ( gfx ) :
2013-10-03 02:06:52 +04:00
gtype = self . default_graphics_type
logging . debug ( " Using default_graphics= %s " , gtype )
if ( gtype == " spice " and not
2013-10-06 18:08:04 +04:00
self . conn . check_support (
2013-10-03 02:06:52 +04:00
self . conn . SUPPORT_CONN_GRAPHICS_SPICE ) ) :
logging . debug ( " spice requested but HV doesn ' t support it. "
" Using vnc. " )
gtype = " vnc "
2015-04-12 00:35:40 +03:00
2013-10-03 02:06:52 +04:00
gfx . type = gtype
2015-04-12 00:35:40 +03:00
for dev in self . get_devices ( " graphics " ) :
if dev . type == " default " :
_set_type ( dev )
if ( dev . type == " spice " and
not self . conn . is_remote ( ) and
self . conn . check_support (
self . conn . SUPPORT_CONN_SPICE_COMPRESSION ) ) :
logging . debug ( " Local connection, disabling spice image "
" compression. " )
if dev . image_compression is None :
dev . image_compression = " off "
2013-10-03 02:06:52 +04:00
def _add_spice_channels ( self ) :
2013-10-06 17:41:37 +04:00
if self . skip_default_channel :
return
2014-02-05 21:49:16 +04:00
for chn in self . get_devices ( " channel " ) :
if chn . type == chn . TYPE_SPICEVMC :
return
if self . conn . check_support ( self . conn . SUPPORT_CONN_CHAR_SPICEVMC ) :
2014-09-12 23:59:22 +04:00
agentdev = VirtualChannelDevice ( self . conn )
2013-10-03 02:06:52 +04:00
agentdev . type = agentdev . TYPE_SPICEVMC
self . add_device ( agentdev )
2014-02-05 21:49:16 +04:00
def _add_spice_sound ( self ) :
if self . skip_default_sound :
return
if self . get_devices ( " sound " ) :
return
self . add_default_sound_device ( )
2014-02-05 21:58:53 +04:00
def _add_spice_usbredir ( self ) :
if self . skip_default_usbredir :
return
if self . get_devices ( " redirdev " ) :
return
if not self . conn . check_support ( self . conn . SUPPORT_CONN_USBREDIR ) :
return
2014-09-21 04:16:31 +04:00
# If we use 4 devices here, we fill up all the emulated USB2 slots,
# and directly assigned devices are forced to fall back to USB1
# https://bugzilla.redhat.com/show_bug.cgi?id=1135488
for ignore in range ( 2 ) :
2014-09-12 23:59:22 +04:00
dev = VirtualRedirDevice ( self . conn )
2014-02-05 21:58:53 +04:00
dev . bus = " usb "
dev . type = " spicevmc "
self . add_device ( dev )
2014-09-06 20:58:59 +04:00
def has_spice ( self ) :
for gfx in self . get_devices ( " graphics " ) :
if gfx . type == gfx . TYPE_SPICE :
return True
2013-10-03 02:06:52 +04:00
2014-09-06 20:58:59 +04:00
def _set_video_defaults ( self ) :
if self . has_spice ( ) :
2013-10-03 02:06:52 +04:00
self . _add_spice_channels ( )
2014-02-05 21:49:16 +04:00
self . _add_spice_sound ( )
2014-02-05 21:58:53 +04:00
self . _add_spice_usbredir ( )
2013-12-19 01:17:01 +04:00
2015-04-04 17:44:54 +03:00
video_model = self . _os_object . default_videomodel ( self )
2015-03-25 16:04:51 +03:00
if video_model == ' vmvga ' and self . stable_defaults ( force = True ) :
2015-02-24 21:00:38 +03:00
video_model = ' vga '
2015-03-25 16:04:51 +03:00
2013-07-24 16:46:55 +04:00
for video in self . get_devices ( " video " ) :
2013-07-15 19:07:40 +04:00
if video . model == video . MODEL_DEFAULT :
video . model = video_model