1
#============================================================================
2
# This library is free software; you can redistribute it and/or
3
# modify it under the terms of version 2.1 of the GNU Lesser General Public
4
# License as published by the Free Software Foundation.
6
# This library is distributed in the hope that it will be useful,
7
# but WITHOUT ANY WARRANTY; without even the implied warranty of
8
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9
# Lesser General Public License for more details.
11
# You should have received a copy of the GNU Lesser General Public
12
# License along with this library; if not, write to the Free Software
13
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14
#============================================================================
15
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
16
# Copyright (C) 2005 XenSource Ltd
17
#============================================================================
20
Creates the servers and handles configuration.
22
Other classes get config variables by importing this module,
23
using instance() to get a XendOptions instance, and then
24
the config functions (e.g. get_xend_port()) to get
33
from xen.xend import sxp, osdep, XendLogging
34
from xen.xend.XendError import XendError
35
from xen.util import auxbin
37
if os.uname()[0] == 'SunOS':
38
from xen.lowlevel import scf
41
"""Configuration options."""
43
"""Where network control scripts live."""
44
network_script_dir = auxbin.scripts_dir()
46
"""Where block control scripts live."""
47
block_script_dir = auxbin.scripts_dir()
49
"""Default path to the log file. """
50
logfile_default = "/var/log/xen/xend.log"
52
"""Default level of information to be logged."""
53
loglevel_default = 'DEBUG'
55
"""Default Xen-API server configuration. """
56
xen_api_server_default = [['unix']]
58
"""Default for the flag indicating whether xend should run an http server
60
xend_http_server_default = 'no'
62
xend_tcp_xmlrpc_server_default = 'no'
64
xend_tcp_xmlrpc_server_address_default = 'localhost'
66
xend_tcp_xmlrpc_server_port_default = 8006
68
xend_unix_xmlrpc_server_default = 'yes'
70
"""Default interface address xend listens at. """
71
xend_address_default = ''
73
"""Default for the flag indicating whether xend should run a relocation server."""
74
xend_relocation_server_default = 'no'
76
"""Default for the flag indicating whether xend should run a ssl relocation server."""
77
xend_relocation_ssl_server_default = 'no'
79
"""Default for the flag indicating whether xend should run a udev event server."""
80
xend_udev_event_server_default = 'no'
82
"""Default interface address the xend relocation server listens at. """
83
xend_relocation_address_default = ''
85
"""Default port xend serves HTTP at. """
86
xend_port_default = 8000
88
"""Default port xend serves relocation at. """
89
xend_relocation_port_default = 8002
91
"""Default port xend serves ssl relocation at. """
92
xend_relocation_ssl_port_default = 8003
94
xend_relocation_hosts_allow_default = ''
96
"""Default for the flag indicating whether xend should run a unix-domain
97
server (deprecated)."""
98
xend_unix_server_default = 'no'
100
"""Default external migration tool """
101
external_migration_tool_default = ''
103
"""Default path the unix-domain server listens at."""
104
xend_unix_path_default = '/var/lib/xend/xend-socket'
106
dom0_min_mem_default = 0
108
reserved_memory_default = 0
110
dom0_vcpus_default = 0
112
vncpasswd_default = None
114
"""Default interface to listen for VNC connections on"""
115
xend_vnc_listen_default = '127.0.0.1'
117
"""Use of TLS mode in QEMU VNC server"""
120
"""x509 certificate directory for QEMU VNC server"""
121
xend_vnc_x509_cert_dir = auxbin.xen_configdir() + "/vnc"
123
"""Verify incoming client x509 certs"""
124
xend_vnc_x509_verify = 0
126
"""Default session storage path."""
127
xend_domains_path_default = '/var/lib/xend/domains'
129
"""Default xend management state storage."""
130
xend_state_path_default = '/var/lib/xend/state'
132
"""Default xend QCoW storage repository location."""
133
xend_storage_path_default = '/var/lib/xend/storage'
135
"""Default xend security state storage path."""
136
xend_security_path_default = '/var/lib/xend/security'
138
"""Default script to configure a backend network interface"""
139
vif_script = osdep.vif_script
141
"""Default Xen Security Module"""
142
xsm_module_default = 'dummy'
144
"""Default rotation count of qemu-dm log file."""
145
qemu_dm_logrotate_count = 10
147
"""Default timeout for device creation."""
148
device_create_timeout_default = 100
150
"""Default timeout for device destruction."""
151
device_destroy_timeout_default = 100
153
"""By default, we use the strict check for HVM guest. (For PV guest, we
154
use loose check automatically if necessary."""
155
pci_dev_assign_strict_check_default = True
160
def _logError(self, fmt, *args):
161
"""Logging function to log to stderr. We use this for XendOptions log
162
messages because they may be logged before the logger has been
163
configured. Other components can safely use the logger.
165
print >>sys.stderr, "xend [ERROR]", fmt % args
170
XendLogging.init(self.get_config_string("logfile",
171
self.logfile_default),
172
self.get_config_string("loglevel",
173
self.loglevel_default))
175
def set_config(self):
176
raise NotImplementedError()
178
def get_config_bool(self, name, val=None):
179
raise NotImplementedError()
181
def get_config_int(self, name, val=None):
182
raise NotImplementedError()
184
def get_config_string(self, name, val=None):
185
raise NotImplementedError()
187
def get_xen_api_server(self):
188
raise NotImplementedError()
190
def get_xend_http_server(self):
191
"""Get the flag indicating whether xend should run an http server.
193
return self.get_config_bool("xend-http-server", self.xend_http_server_default)
195
def get_xend_tcp_xmlrpc_server(self):
196
return self.get_config_bool("xend-tcp-xmlrpc-server",
197
self.xend_tcp_xmlrpc_server_default)
199
def get_xend_tcp_xmlrpc_server_port(self):
200
return self.get_config_int("xend-tcp-xmlrpc-server-port",
201
self.xend_tcp_xmlrpc_server_port_default)
203
def get_xend_tcp_xmlrpc_server_address(self):
204
return self.get_config_string("xend-tcp-xmlrpc-server-address",
205
self.xend_tcp_xmlrpc_server_address_default)
207
def get_xend_tcp_xmlrpc_server_ssl_key_file(self):
208
name = 'xend-tcp-xmlrpc-server-ssl-key-file'
209
file = self.get_config_string(name)
210
if os.path.dirname(file) == "":
211
file = auxbin.xen_configdir() + '/' + file;
212
if not os.path.exists(file):
213
raise XendError("invalid xend config %s: directory '%s' does not exist" % (name, file))
216
def get_xend_tcp_xmlrpc_server_ssl_cert_file(self):
217
name = 'xend-tcp-xmlrpc-server-ssl-cert-file'
218
file = self.get_config_string(name)
219
if os.path.dirname(file) == "":
220
file = auxbin.xen_configdir() + '/' + file;
221
if not os.path.exists(file):
222
raise XendError("invalid xend config %s: directory '%s' does not exist" % (name, file))
225
def get_xend_unix_xmlrpc_server(self):
226
return self.get_config_bool("xend-unix-xmlrpc-server",
227
self.xend_unix_xmlrpc_server_default)
229
def get_xend_relocation_server(self):
230
"""Get the flag indicating whether xend should run a relocation server.
232
return self.get_config_bool("xend-relocation-server",
233
self.xend_relocation_server_default)
235
def get_xend_relocation_ssl_server(self):
236
"""Get the flag indicating whether xend should run a ssl relocation server.
238
return self.get_config_bool("xend-relocation-ssl-server",
239
self.xend_relocation_ssl_server_default)
241
def get_xend_relocation_server_ssl_key_file(self):
242
name = 'xend-relocation-server-ssl-key-file'
243
file = self.get_config_string(name)
244
if os.path.dirname(file) == "":
245
file = auxbin.xen_configdir() + '/' + file;
246
if not os.path.exists(file):
247
raise XendError("invalid xend config %s: directory '%s' does not exist" % (name, file))
250
def get_xend_relocation_server_ssl_cert_file(self):
251
name = 'xend-relocation-server-ssl-cert-file'
252
file = self.get_config_string(name)
253
if os.path.dirname(file) == "":
254
file = auxbin.xen_configdir() + '/' + file;
255
if not os.path.exists(file):
256
raise XendError("invalid xend config %s: directory '%s' does not exist" % (name, file))
259
def get_xend_udev_event_server(self):
260
return self.get_config_bool("xend-udev-event-server",
261
self.xend_udev_event_server_default)
263
def get_xend_port(self):
264
"""Get the port xend listens at for its HTTP interface.
266
return self.get_config_int('xend-port', self.xend_port_default)
268
def get_xend_relocation_port(self):
269
"""Get the port xend listens at for connection to its relocation server.
271
return self.get_config_int('xend-relocation-port',
272
self.xend_relocation_port_default)
274
def get_xend_relocation_ssl_port(self):
275
"""Get the port xend listens at for ssl connection to its relocation
278
return self.get_config_int('xend-relocation-ssl-port',
279
self.xend_relocation_ssl_port_default)
281
def get_xend_relocation_ssl(self):
282
"""Whether to use ssl when relocating.
284
return self.get_config_bool('xend-relocation-ssl', 'no')
286
def get_xend_relocation_hosts_allow(self):
287
return self.get_config_string("xend-relocation-hosts-allow",
288
self.xend_relocation_hosts_allow_default)
290
def get_xend_address(self):
291
"""Get the address xend listens at for its HTTP port.
292
This defaults to the empty string which allows all hosts to connect.
293
If this is set to 'localhost' only the localhost will be able to connect
296
return self.get_config_string('xend-address', self.xend_address_default)
298
def get_xend_relocation_address(self):
299
"""Get the address xend listens at for its relocation server port.
300
This defaults to the empty string which allows all hosts to connect.
301
If this is set to 'localhost' only the localhost will be able to connect
302
to the relocation port.
304
return self.get_config_string('xend-relocation-address', self.xend_relocation_address_default)
306
def get_xend_unix_server(self):
307
"""Get the flag indicating whether xend should run a unix-domain server.
309
return self.get_config_bool("xend-unix-server", self.xend_unix_server_default)
311
def get_xend_unix_path(self):
312
"""Get the path the xend unix-domain server listens at.
314
return self.get_config_string("xend-unix-path", self.xend_unix_path_default)
316
def get_xend_domains_path(self):
317
""" Get the path for persistent domain configuration storage
319
return self.get_config_string("xend-domains-path", self.xend_domains_path_default)
321
def get_xend_state_path(self):
322
""" Get the path for persistent domain configuration storage
324
return self.get_config_string("xend-state-path", self.xend_state_path_default)
326
def get_xend_storage_path(self):
327
""" Get the path for persistent domain configuration storage
329
return self.get_config_string("xend-storage-path", self.xend_storage_path_default)
331
def get_xend_security_path(self):
332
""" Get the path for security state
334
return self.get_config_string("xend-security-path", self.xend_security_path_default)
336
def get_network_script(self):
337
"""@return the script used to alter the network configuration when
338
Xend starts and stops, or None if no such script is specified."""
340
s = self.get_config_string('network-script')
343
result = s.split(" ")
344
result[0] = os.path.join(self.network_script_dir, result[0])
349
def get_external_migration_tool(self):
350
"""@return the name of the tool to handle virtual TPM migration."""
351
return self.get_config_string('external-migration-tool', self.external_migration_tool_default)
353
def get_enable_dump(self):
354
return self.get_config_bool('enable-dump', 'no')
356
def get_vif_script(self):
357
return self.get_config_string('vif-script', self.vif_script)
359
def get_dom0_min_mem(self):
360
return self.get_config_int('dom0-min-mem', self.dom0_min_mem_default)
362
def get_enable_dom0_ballooning(self):
363
enable_dom0_ballooning_default = 'yes'
364
if self.get_dom0_min_mem() == 0:
365
enable_dom0_ballooning_default = 'no'
366
return self.get_config_bool('enable-dom0-ballooning',
367
enable_dom0_ballooning_default)
369
def get_reserved_memory(self):
370
if not self.get_enable_dom0_ballooning():
371
return 0 #no ballooning of dom0 will close this item
373
return self.get_config_int('total_available_memory', self.reserved_memory_default)
376
def get_dom0_vcpus(self):
377
return self.get_config_int('dom0-cpus', self.dom0_vcpus_default)
379
def get_console_limit(self):
380
return self.get_config_int('console-limit', 1024)
382
def get_vnclisten_address(self):
383
return self.get_config_string('vnc-listen', self.xend_vnc_listen_default)
385
def get_vncpasswd_default(self):
386
return self.get_config_string('vncpasswd',
387
self.vncpasswd_default)
389
def get_keymap(self):
390
return self.get_config_string('keymap', None)
392
def get_resource_label_change_script(self):
393
s = self.get_config_string('resource-label-change-script')
395
result = s.split(" ")
396
result[0] = os.path.join(auxbin.scripts_dir(), result[0])
402
def get_vnc_tls(self):
403
return self.get_config_string('vnc-tls', self.xend_vnc_tls)
405
def get_vnc_x509_cert_dir(self):
406
name = 'vnc-x509-cert-dir'
407
vncdir = self.get_config_string(name, self.xend_vnc_x509_cert_dir)
408
if os.path.dirname(vncdir) == "":
409
vncdir = auxbin.xen_configdir() + '/' + vncdir
410
if not os.path.exists(vncdir):
411
raise XendError("invalid xend config %s: directory '%s' does not exist" % (name, vncdir))
414
def get_vnc_x509_verify(self):
415
return self.get_config_string('vnc-x509-verify', self.xend_vnc_x509_verify)
417
def get_qemu_dm_logrotate_count(self):
418
return self.get_config_int("qemu-dm-logrotate-count",
419
self.qemu_dm_logrotate_count)
421
def get_device_create_timeout(self):
422
return self.get_config_int("device-create-timeout",
423
self.device_create_timeout_default)
425
def get_device_destroy_timeout(self):
426
return self.get_config_int("device-destroy-timeout",
427
self.device_destroy_timeout_default)
429
def get_pci_dev_assign_strict_check(self):
430
return self.get_config_bool("pci-passthrough-strict-check",
431
self.pci_dev_assign_strict_check_default)
433
class XendOptionsFile(XendOptions):
435
"""Default path to the config file."""
436
config_default = auxbin.xen_configdir() + "/xend-config.sxp"
438
"""Environment variable used to override config_default."""
439
config_var = "XEND_CONFIG"
441
def set_config(self):
442
"""If the config file exists, read it. If not, ignore it.
444
The config file is a sequence of sxp forms.
446
self.config_path = os.getenv(self.config_var, self.config_default)
447
if os.path.exists(self.config_path):
449
fin = file(self.config_path, 'rb')
451
config = sxp.parse(fin)
455
config = ['xend-config']
457
config.insert(0, 'xend-config')
459
except Exception, ex:
460
self._logError('Reading config file %s: %s',
461
self.config_path, str(ex))
464
self._logError('Config file does not exist: %s',
466
self.config = ['xend-config']
468
def get_config_value(self, name, val=None):
469
"""Get the value of an atomic configuration element.
471
@param name: element name
472
@param val: default value (optional, defaults to None)
475
return sxp.child_value(self.config, name, val=val)
477
def get_config_bool(self, name, val=None):
478
v = string.lower(str(self.get_config_value(name, val)))
479
if v in ['yes', 'y', '1', 'on', 'true', 't']:
481
if v in ['no', 'n', '0', 'off', 'false', 'f']:
483
raise XendError("invalid xend config %s: expected bool: %s" % (name, v))
485
def get_config_int(self, name, val=None):
486
v = self.get_config_value(name, val)
490
raise XendError("invalid xend config %s: expected int: %s" % (name, v))
492
def get_config_string(self, name, val=None):
493
return self.get_config_value(name, val)
495
def get_xen_api_server(self):
496
"""Get the Xen-API server configuration.
498
return self.get_config_value('xen-api-server',
499
self.xen_api_server_default)
501
def get_xsm_module_name(self):
502
"""Get the Xen Security Module name.
504
return self.get_config_string('xsm_module_name', self.xsm_module_default)
506
if os.uname()[0] == 'SunOS':
507
class XendOptionsSMF(XendOptions):
509
def set_config(self):
512
def get_config_bool(self, name, val=None):
514
return scf.get_bool(name)
516
if e[0] == scf.SCF_ERROR_NOT_FOUND:
517
if val in ['yes', 'y', '1', 'on', 'true', 't']:
519
if val in ['no', 'n', '0', 'off', 'false', 'f']:
523
raise XendError("option %s: %s:%s" % (name, e[1], e[2]))
525
def get_config_int(self, name, val=None):
527
return scf.get_int(name)
529
if e[0] == scf.SCF_ERROR_NOT_FOUND:
532
raise XendError("option %s: %s:%s" % (name, e[1], e[2]))
534
def get_config_string(self, name, val=None):
536
return scf.get_string(name)
538
if e[0] == scf.SCF_ERROR_NOT_FOUND:
541
raise XendError("option %s: %s:%s" % (name, e[1], e[2]))
543
def get_xen_api_server(self):
544
# When the new server is a supported configuration, we should
549
"""Get an instance of XendOptions.
550
Use this instead of the constructor.
556
if os.uname()[0] == 'SunOS':
557
inst = XendOptionsSMF()
559
inst = XendOptionsFile()