2013-03-18 01:06:52 +04:00
#
2013-10-28 00:59:46 +04:00
# Copyright 2009, 2013 Red Hat, Inc.
2013-03-18 01:06:52 +04:00
#
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.
2013-03-18 01:06:52 +04:00
2018-03-20 19:18:35 +03:00
from . device import Device
2019-05-13 21:23:27 +03:00
from . . xmlbuilder import XMLBuilder , XMLChildProperty , XMLProperty
from . . import util
def _set_host_helper ( obj , hostparam , portparam , val ) :
def parse_host ( val ) :
host , ignore , port = ( val or " " ) . partition ( " : " )
return host or None , port or None
host , port = parse_host ( val )
if not host :
host = " 127.0.0.1 "
if host :
util . set_prop_path ( obj , hostparam , host )
if port :
util . set_prop_path ( obj , portparam , port )
class CharSource ( XMLBuilder ) :
XML_NAME = " source "
_XML_PROP_ORDER = [ " bind_host " , " bind_service " ,
" mode " , " connect_host " , " connect_service " ,
" path " , " channel " ]
def set_friendly_connect ( self , val ) :
_set_host_helper ( self , " connect_host " , " connect_service " , val )
def set_friendly_bind ( self , val ) :
_set_host_helper ( self , " bind_host " , " bind_service " , val )
path = XMLProperty ( " ./@path " )
channel = XMLProperty ( " ./@channel " )
master = XMLProperty ( " ./@master " )
slave = XMLProperty ( " ./@slave " )
mode = XMLProperty ( " ./@mode " )
# Convenience source helpers for setting connect/bind host and service
connect_host = XMLProperty ( " ./../source[@mode= ' connect ' ]/@host " )
connect_service = XMLProperty (
" ./../source[@mode= ' connect ' ]/@service " , is_int = True )
bind_host = XMLProperty ( " ./../source[@mode= ' bind ' ]/@host " )
bind_service = XMLProperty ( " ./../source[@mode= ' bind ' ]/@service " , is_int = True )
2013-03-18 01:06:52 +04:00
2013-04-13 22:34:52 +04:00
2018-03-20 19:18:35 +03:00
class _DeviceChar ( Device ) :
2013-03-18 01:06:52 +04:00
"""
Base class for all character devices . Shouldn ' t be instantiated
directly .
"""
2013-07-16 17:14:37 +04:00
TYPE_PTY = " pty "
TYPE_DEV = " dev "
TYPE_STDIO = " stdio "
TYPE_PIPE = " pipe "
TYPE_FILE = " file "
TYPE_VC = " vc "
TYPE_NULL = " null "
TYPE_TCP = " tcp "
TYPE_UDP = " udp "
TYPE_UNIX = " unix "
TYPE_SPICEVMC = " spicevmc "
2014-03-25 18:42:33 +04:00
TYPE_SPICEPORT = " spiceport "
2016-08-24 23:37:36 +03:00
TYPE_NMDM = " nmdm "
2014-03-25 18:42:33 +04:00
2013-10-05 21:27:11 +04:00
CHANNEL_NAME_SPICE = " com.redhat.spice.0 "
CHANNEL_NAME_QEMUGA = " org.qemu.guest_agent.0 "
CHANNEL_NAME_LIBGUESTFS = " org.libguestfs.channel.0 "
2014-03-25 18:42:33 +04:00
CHANNEL_NAME_SPICE_WEBDAV = " org.spice-space.webdav.0 "
2013-10-05 21:27:11 +04:00
CHANNEL_NAMES = [ CHANNEL_NAME_SPICE ,
CHANNEL_NAME_QEMUGA ,
2014-03-25 18:42:33 +04:00
CHANNEL_NAME_LIBGUESTFS ,
CHANNEL_NAME_SPICE_WEBDAV ]
2013-10-05 21:27:11 +04:00
2018-09-06 19:43:08 +03:00
@classmethod
def get_recommended_types ( cls , _guest ) :
if cls . XML_NAME == " console " :
return [ cls . TYPE_PTY ]
ret = [ cls . TYPE_PTY , cls . TYPE_FILE , cls . TYPE_UNIX ]
if cls . XML_NAME == " channel " :
ret = [ cls . TYPE_SPICEVMC , cls . TYPE_SPICEPORT ] + ret
return ret
2013-10-05 22:04:49 +04:00
@staticmethod
def pretty_channel_name ( val ) :
2018-03-20 19:18:35 +03:00
if val == _DeviceChar . CHANNEL_NAME_SPICE :
2013-10-05 22:04:49 +04:00
return " spice "
2018-03-20 19:18:35 +03:00
if val == _DeviceChar . CHANNEL_NAME_QEMUGA :
2013-10-05 22:04:49 +04:00
return " qemu-ga "
2018-03-20 19:18:35 +03:00
if val == _DeviceChar . CHANNEL_NAME_LIBGUESTFS :
2013-10-05 22:04:49 +04:00
return " libguestfs "
2018-03-20 19:18:35 +03:00
if val == _DeviceChar . CHANNEL_NAME_SPICE_WEBDAV :
2014-03-25 18:42:33 +04:00
return " spice-webdav "
2013-10-05 22:04:49 +04:00
return None
2013-07-16 17:14:37 +04:00
@staticmethod
def pretty_type ( ctype ) :
2013-03-18 01:06:52 +04:00
"""
Return a human readable description of the passed char type
"""
desc = " "
2018-03-20 19:18:35 +03:00
if ctype == _DeviceChar . TYPE_PTY :
2013-03-18 01:06:52 +04:00
desc = _ ( " Pseudo TTY " )
2018-03-20 19:18:35 +03:00
elif ctype == _DeviceChar . TYPE_DEV :
2013-03-18 01:06:52 +04:00
desc = _ ( " Physical host character device " )
2018-03-20 19:18:35 +03:00
elif ctype == _DeviceChar . TYPE_STDIO :
2013-03-18 01:06:52 +04:00
desc = _ ( " Standard input/output " )
2018-03-20 19:18:35 +03:00
elif ctype == _DeviceChar . TYPE_PIPE :
2013-03-18 01:06:52 +04:00
desc = _ ( " Named pipe " )
2018-03-20 19:18:35 +03:00
elif ctype == _DeviceChar . TYPE_FILE :
2013-03-18 01:06:52 +04:00
desc = _ ( " Output to a file " )
2018-03-20 19:18:35 +03:00
elif ctype == _DeviceChar . TYPE_VC :
2013-03-18 01:06:52 +04:00
desc = _ ( " Virtual console " )
2018-03-20 19:18:35 +03:00
elif ctype == _DeviceChar . TYPE_NULL :
2013-03-18 01:06:52 +04:00
desc = _ ( " Null device " )
2018-03-20 19:18:35 +03:00
elif ctype == _DeviceChar . TYPE_TCP :
2013-03-18 01:06:52 +04:00
desc = _ ( " TCP net console " )
2018-03-20 19:18:35 +03:00
elif ctype == _DeviceChar . TYPE_UDP :
2013-03-18 01:06:52 +04:00
desc = _ ( " UDP net console " )
2018-03-20 19:18:35 +03:00
elif ctype == _DeviceChar . TYPE_UNIX :
2013-03-18 01:06:52 +04:00
desc = _ ( " Unix socket " )
2018-03-20 19:18:35 +03:00
elif ctype == _DeviceChar . TYPE_SPICEVMC :
2013-03-18 01:06:52 +04:00
desc = _ ( " Spice agent " )
2018-03-20 19:18:35 +03:00
elif ctype == _DeviceChar . TYPE_SPICEPORT :
2014-03-25 18:42:33 +04:00
desc = _ ( " Spice port " )
2013-03-18 01:06:52 +04:00
return desc
2014-01-19 22:56:06 +04:00
def set_friendly_target ( self , val ) :
2019-05-13 21:23:27 +03:00
_set_host_helper ( self , " target_address " , " target_port " , val )
2013-07-16 17:14:37 +04:00
2019-05-13 21:23:27 +03:00
_XML_PROP_ORDER = [ " type " , " source " ,
2018-07-04 11:10:38 +03:00
" target_type " , " target_name " , " target_state " ]
2013-07-16 17:14:37 +04:00
2018-02-23 04:44:09 +03:00
type = XMLProperty ( " ./@type " )
2019-05-13 21:23:27 +03:00
source = XMLChildProperty ( CharSource , is_single = True )
2013-09-24 17:25:05 +04:00
2019-05-13 18:31:18 +03:00
target_address = XMLProperty ( " ./target/@address " )
target_port = XMLProperty ( " ./target/@port " , is_int = True )
target_type = XMLProperty ( " ./target/@type " )
target_name = XMLProperty ( " ./target/@name " )
target_state = XMLProperty ( " ./target/@state " )
protocol = XMLProperty ( " ./protocol/@type " )
log_file = XMLProperty ( " ./log/@file " )
log_append = XMLProperty ( " ./log/@append " , is_onoff = True )
2013-04-13 22:34:52 +04:00
2018-09-03 23:18:03 +03:00
##################
# Default config #
##################
def set_defaults ( self , _guest ) :
2019-05-13 21:23:27 +03:00
if ( not self . source . mode and
2019-05-13 20:18:41 +03:00
self . type in [ self . TYPE_UNIX , self . TYPE_TCP ] ) :
2019-05-13 21:23:27 +03:00
self . source . mode = " bind "
2018-09-03 23:18:03 +03:00
if not self . target_type and self . DEVICE_TYPE == " channel " :
2018-09-06 18:49:09 +03:00
self . target_type = " virtio "
2018-09-03 23:18:03 +03:00
if not self . target_name and self . type == self . TYPE_SPICEVMC :
self . target_name = self . CHANNEL_NAME_SPICE
2018-03-20 19:18:35 +03:00
class DeviceConsole ( _DeviceChar ) :
2018-03-21 17:53:34 +03:00
XML_NAME = " console "
2013-04-13 22:34:52 +04:00
2018-03-20 19:18:35 +03:00
class DeviceSerial ( _DeviceChar ) :
2018-03-21 17:53:34 +03:00
XML_NAME = " serial "
2013-03-18 01:06:52 +04:00
2013-04-13 22:34:52 +04:00
2018-03-20 19:18:35 +03:00
class DeviceParallel ( _DeviceChar ) :
2018-03-21 17:53:34 +03:00
XML_NAME = " parallel "
2013-04-13 22:34:52 +04:00
2018-03-20 19:18:35 +03:00
class DeviceChannel ( _DeviceChar ) :
2018-03-21 17:53:34 +03:00
XML_NAME = " channel "