~ubuntu-branches/ubuntu/utopic/xen/utopic

« back to all changes in this revision

Viewing changes to tools/python/xen/xend/XendOptions.py

  • Committer: Bazaar Package Importer
  • Author(s): Bastian Blank
  • Date: 2010-05-06 15:47:38 UTC
  • mto: (1.3.1) (15.1.1 sid) (4.1.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20100506154738-agoz0rlafrh1fnq7
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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.
 
5
#
 
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.
 
10
#
 
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
#============================================================================
 
18
 
 
19
"""Xend root class.
 
20
Creates the servers and handles configuration.
 
21
 
 
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
 
25
configured values.
 
26
"""
 
27
 
 
28
import os
 
29
import os.path
 
30
import string
 
31
import sys
 
32
 
 
33
from xen.xend import sxp, osdep, XendLogging
 
34
from xen.xend.XendError import XendError
 
35
from xen.util import auxbin
 
36
 
 
37
if os.uname()[0] == 'SunOS':
 
38
    from xen.lowlevel import scf
 
39
 
 
40
class XendOptions:
 
41
    """Configuration options."""
 
42
 
 
43
    """Where network control scripts live."""
 
44
    network_script_dir = auxbin.scripts_dir()
 
45
 
 
46
    """Where block control scripts live."""
 
47
    block_script_dir = auxbin.scripts_dir()
 
48
 
 
49
    """Default path to the log file. """
 
50
    logfile_default = "/var/log/xen/xend.log"
 
51
 
 
52
    """Default level of information to be logged."""
 
53
    loglevel_default = 'DEBUG'
 
54
 
 
55
    """Default Xen-API server configuration. """
 
56
    xen_api_server_default = [['unix']]
 
57
 
 
58
    """Default for the flag indicating whether xend should run an http server
 
59
    (deprecated)."""
 
60
    xend_http_server_default = 'no'
 
61
 
 
62
    xend_tcp_xmlrpc_server_default = 'no'
 
63
 
 
64
    xend_tcp_xmlrpc_server_address_default = 'localhost'
 
65
    
 
66
    xend_tcp_xmlrpc_server_port_default = 8006
 
67
 
 
68
    xend_unix_xmlrpc_server_default = 'yes'
 
69
 
 
70
    """Default interface address xend listens at. """
 
71
    xend_address_default      = ''
 
72
 
 
73
    """Default for the flag indicating whether xend should run a relocation server."""
 
74
    xend_relocation_server_default = 'no'
 
75
 
 
76
    """Default for the flag indicating whether xend should run a ssl relocation server."""
 
77
    xend_relocation_ssl_server_default = 'no'
 
78
 
 
79
    """Default for the flag indicating whether xend should run a udev event server."""
 
80
    xend_udev_event_server_default = 'no'
 
81
 
 
82
    """Default interface address the xend relocation server listens at. """
 
83
    xend_relocation_address_default = ''
 
84
 
 
85
    """Default port xend serves HTTP at. """
 
86
    xend_port_default         = 8000
 
87
 
 
88
    """Default port xend serves relocation at. """
 
89
    xend_relocation_port_default = 8002
 
90
 
 
91
    """Default port xend serves ssl relocation at. """
 
92
    xend_relocation_ssl_port_default = 8003
 
93
 
 
94
    xend_relocation_hosts_allow_default = ''
 
95
 
 
96
    """Default for the flag indicating whether xend should run a unix-domain
 
97
    server (deprecated)."""
 
98
    xend_unix_server_default = 'no'
 
99
 
 
100
    """Default external migration tool """
 
101
    external_migration_tool_default = ''
 
102
 
 
103
    """Default path the unix-domain server listens at."""
 
104
    xend_unix_path_default = '/var/lib/xend/xend-socket'
 
105
 
 
106
    dom0_min_mem_default = 0
 
107
 
 
108
    reserved_memory_default = 0
 
109
 
 
110
    dom0_vcpus_default = 0
 
111
 
 
112
    vncpasswd_default = None
 
113
 
 
114
    """Default interface to listen for VNC connections on"""
 
115
    xend_vnc_listen_default = '127.0.0.1'
 
116
 
 
117
    """Use of TLS mode in QEMU VNC server"""
 
118
    xend_vnc_tls = 0
 
119
 
 
120
    """x509 certificate directory for QEMU VNC server"""
 
121
    xend_vnc_x509_cert_dir = auxbin.xen_configdir() + "/vnc"
 
122
 
 
123
    """Verify incoming client x509 certs"""
 
124
    xend_vnc_x509_verify = 0
 
125
 
 
126
    """Default session storage path."""
 
127
    xend_domains_path_default = '/var/lib/xend/domains'
 
128
 
 
129
    """Default xend management state storage."""
 
130
    xend_state_path_default = '/var/lib/xend/state'
 
131
 
 
132
    """Default xend QCoW storage repository location."""
 
133
    xend_storage_path_default = '/var/lib/xend/storage'
 
134
 
 
135
    """Default xend security state storage path."""
 
136
    xend_security_path_default = '/var/lib/xend/security'
 
137
 
 
138
    """Default script to configure a backend network interface"""
 
139
    vif_script = osdep.vif_script
 
140
 
 
141
    """Default Xen Security Module"""
 
142
    xsm_module_default = 'dummy'
 
143
 
 
144
    """Default rotation count of qemu-dm log file."""
 
145
    qemu_dm_logrotate_count = 10
 
146
 
 
147
    """Default timeout for device creation."""
 
148
    device_create_timeout_default = 100
 
149
 
 
150
    """Default timeout for device destruction."""
 
151
    device_destroy_timeout_default = 100
 
152
 
 
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
 
156
 
 
157
    def __init__(self):
 
158
        self.configure()
 
159
 
 
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.
 
164
        """
 
165
        print >>sys.stderr, "xend [ERROR]", fmt % args
 
166
 
 
167
 
 
168
    def configure(self):
 
169
        self.set_config()
 
170
        XendLogging.init(self.get_config_string("logfile",
 
171
                                               self.logfile_default),
 
172
                         self.get_config_string("loglevel",
 
173
                                               self.loglevel_default))
 
174
 
 
175
    def set_config(self):
 
176
        raise NotImplementedError()
 
177
 
 
178
    def get_config_bool(self, name, val=None):
 
179
        raise NotImplementedError()
 
180
         
 
181
    def get_config_int(self, name, val=None):
 
182
        raise NotImplementedError()
 
183
 
 
184
    def get_config_string(self, name, val=None):
 
185
        raise NotImplementedError()
 
186
 
 
187
    def get_xen_api_server(self):
 
188
        raise NotImplementedError()
 
189
 
 
190
    def get_xend_http_server(self):
 
191
        """Get the flag indicating whether xend should run an http server.
 
192
        """
 
193
        return self.get_config_bool("xend-http-server", self.xend_http_server_default)
 
194
 
 
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)
 
198
 
 
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)
 
202
 
 
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)
 
206
 
 
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))
 
214
        return file
 
215
 
 
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))
 
223
        return file
 
224
 
 
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)
 
228
 
 
229
    def get_xend_relocation_server(self):
 
230
        """Get the flag indicating whether xend should run a relocation server.
 
231
        """
 
232
        return self.get_config_bool("xend-relocation-server",
 
233
                                    self.xend_relocation_server_default)
 
234
 
 
235
    def get_xend_relocation_ssl_server(self):
 
236
        """Get the flag indicating whether xend should run a ssl relocation server.
 
237
        """
 
238
        return self.get_config_bool("xend-relocation-ssl-server",
 
239
                                    self.xend_relocation_ssl_server_default)
 
240
 
 
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))
 
248
        return file
 
249
 
 
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))
 
257
        return file
 
258
 
 
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)
 
262
 
 
263
    def get_xend_port(self):
 
264
        """Get the port xend listens at for its HTTP interface.
 
265
        """
 
266
        return self.get_config_int('xend-port', self.xend_port_default)
 
267
 
 
268
    def get_xend_relocation_port(self):
 
269
        """Get the port xend listens at for connection to its relocation server.
 
270
        """
 
271
        return self.get_config_int('xend-relocation-port',
 
272
                                   self.xend_relocation_port_default)
 
273
 
 
274
    def get_xend_relocation_ssl_port(self):
 
275
        """Get the port xend listens at for ssl connection to its relocation
 
276
        server.
 
277
        """
 
278
        return self.get_config_int('xend-relocation-ssl-port',
 
279
                                   self.xend_relocation_ssl_port_default)
 
280
 
 
281
    def get_xend_relocation_ssl(self):
 
282
        """Whether to use ssl when relocating.
 
283
        """
 
284
        return self.get_config_bool('xend-relocation-ssl', 'no')
 
285
 
 
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)
 
289
 
 
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
 
294
        to the HTTP port.
 
295
        """
 
296
        return self.get_config_string('xend-address', self.xend_address_default)
 
297
 
 
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.
 
303
        """
 
304
        return self.get_config_string('xend-relocation-address', self.xend_relocation_address_default)
 
305
 
 
306
    def get_xend_unix_server(self):
 
307
        """Get the flag indicating whether xend should run a unix-domain server.
 
308
        """
 
309
        return self.get_config_bool("xend-unix-server", self.xend_unix_server_default)
 
310
 
 
311
    def get_xend_unix_path(self):
 
312
        """Get the path the xend unix-domain server listens at.
 
313
        """
 
314
        return self.get_config_string("xend-unix-path", self.xend_unix_path_default)
 
315
 
 
316
    def get_xend_domains_path(self):
 
317
        """ Get the path for persistent domain configuration storage
 
318
        """
 
319
        return self.get_config_string("xend-domains-path", self.xend_domains_path_default)
 
320
 
 
321
    def get_xend_state_path(self):
 
322
        """ Get the path for persistent domain configuration storage
 
323
        """
 
324
        return self.get_config_string("xend-state-path", self.xend_state_path_default)
 
325
 
 
326
    def get_xend_storage_path(self):
 
327
        """ Get the path for persistent domain configuration storage
 
328
        """
 
329
        return self.get_config_string("xend-storage-path", self.xend_storage_path_default)        
 
330
 
 
331
    def get_xend_security_path(self):
 
332
        """ Get the path for security state
 
333
        """
 
334
        return self.get_config_string("xend-security-path", self.xend_security_path_default)
 
335
 
 
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."""
 
339
        
 
340
        s = self.get_config_string('network-script')
 
341
 
 
342
        if s:
 
343
            result = s.split(" ")
 
344
            result[0] = os.path.join(self.network_script_dir, result[0])
 
345
            return result
 
346
        else:
 
347
            return None
 
348
 
 
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)
 
352
 
 
353
    def get_enable_dump(self):
 
354
        return self.get_config_bool('enable-dump', 'no')
 
355
 
 
356
    def get_vif_script(self):
 
357
        return self.get_config_string('vif-script', self.vif_script)
 
358
 
 
359
    def get_dom0_min_mem(self):
 
360
        return self.get_config_int('dom0-min-mem', self.dom0_min_mem_default)
 
361
 
 
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)
 
368
 
 
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
 
372
        else:
 
373
            return self.get_config_int('total_available_memory', self.reserved_memory_default)
 
374
 
 
375
 
 
376
    def get_dom0_vcpus(self):
 
377
        return self.get_config_int('dom0-cpus', self.dom0_vcpus_default)
 
378
 
 
379
    def get_console_limit(self):
 
380
        return self.get_config_int('console-limit', 1024)
 
381
 
 
382
    def get_vnclisten_address(self):
 
383
        return self.get_config_string('vnc-listen', self.xend_vnc_listen_default)
 
384
 
 
385
    def get_vncpasswd_default(self):
 
386
        return self.get_config_string('vncpasswd',
 
387
                                     self.vncpasswd_default)
 
388
 
 
389
    def get_keymap(self):
 
390
        return self.get_config_string('keymap', None)
 
391
 
 
392
    def get_resource_label_change_script(self):
 
393
        s = self.get_config_string('resource-label-change-script')
 
394
        if s:
 
395
            result = s.split(" ")
 
396
            result[0] = os.path.join(auxbin.scripts_dir(), result[0])
 
397
            return result
 
398
        else:
 
399
            return None
 
400
 
 
401
 
 
402
    def get_vnc_tls(self):
 
403
        return self.get_config_string('vnc-tls', self.xend_vnc_tls)
 
404
 
 
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))
 
412
        return vncdir
 
413
 
 
414
    def get_vnc_x509_verify(self):
 
415
        return self.get_config_string('vnc-x509-verify', self.xend_vnc_x509_verify)
 
416
 
 
417
    def get_qemu_dm_logrotate_count(self):
 
418
        return self.get_config_int("qemu-dm-logrotate-count",
 
419
                                   self.qemu_dm_logrotate_count)
 
420
 
 
421
    def get_device_create_timeout(self):
 
422
        return self.get_config_int("device-create-timeout",
 
423
                                   self.device_create_timeout_default)
 
424
 
 
425
    def get_device_destroy_timeout(self):
 
426
        return self.get_config_int("device-destroy-timeout",
 
427
                                   self.device_destroy_timeout_default)
 
428
 
 
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)
 
432
 
 
433
class XendOptionsFile(XendOptions):
 
434
 
 
435
    """Default path to the config file."""
 
436
    config_default = auxbin.xen_configdir() + "/xend-config.sxp"
 
437
 
 
438
    """Environment variable used to override config_default."""
 
439
    config_var     = "XEND_CONFIG"
 
440
 
 
441
    def set_config(self):
 
442
        """If the config file exists, read it. If not, ignore it.
 
443
 
 
444
        The config file is a sequence of sxp forms.
 
445
        """
 
446
        self.config_path = os.getenv(self.config_var, self.config_default)
 
447
        if os.path.exists(self.config_path):
 
448
            try:
 
449
                fin = file(self.config_path, 'rb')
 
450
                try:
 
451
                    config = sxp.parse(fin)
 
452
                finally:
 
453
                    fin.close()
 
454
                if config is None:
 
455
                    config = ['xend-config']
 
456
                else:
 
457
                    config.insert(0, 'xend-config')
 
458
                self.config = config
 
459
            except Exception, ex:
 
460
                self._logError('Reading config file %s: %s',
 
461
                               self.config_path, str(ex))
 
462
                raise
 
463
        else:
 
464
            self._logError('Config file does not exist: %s',
 
465
                           self.config_path)
 
466
            self.config = ['xend-config']
 
467
 
 
468
    def get_config_value(self, name, val=None):
 
469
        """Get the value of an atomic configuration element.
 
470
 
 
471
        @param name: element name
 
472
        @param val:  default value (optional, defaults to None)
 
473
        @return: value
 
474
        """
 
475
        return sxp.child_value(self.config, name, val=val)
 
476
 
 
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']:
 
480
            return True
 
481
        if v in ['no',  'n', '0', 'off', 'false', 'f']:
 
482
            return False
 
483
        raise XendError("invalid xend config %s: expected bool: %s" % (name, v))
 
484
 
 
485
    def get_config_int(self, name, val=None):
 
486
        v = self.get_config_value(name, val)
 
487
        try:
 
488
            return int(v)
 
489
        except Exception:
 
490
            raise XendError("invalid xend config %s: expected int: %s" % (name, v))
 
491
 
 
492
    def get_config_string(self, name, val=None):
 
493
        return self.get_config_value(name, val)
 
494
 
 
495
    def get_xen_api_server(self):
 
496
        """Get the Xen-API server configuration.
 
497
        """
 
498
        return self.get_config_value('xen-api-server',
 
499
                                     self.xen_api_server_default)
 
500
 
 
501
    def get_xsm_module_name(self):
 
502
        """Get the Xen Security Module name.
 
503
        """
 
504
        return self.get_config_string('xsm_module_name', self.xsm_module_default)
 
505
 
 
506
if os.uname()[0] == 'SunOS':
 
507
    class XendOptionsSMF(XendOptions):
 
508
 
 
509
        def set_config(self):
 
510
            pass
 
511
 
 
512
        def get_config_bool(self, name, val=None):
 
513
            try:
 
514
                return scf.get_bool(name)
 
515
            except scf.error, e:
 
516
                if e[0] == scf.SCF_ERROR_NOT_FOUND:
 
517
                    if val in ['yes', 'y', '1', 'on',  'true',  't']:
 
518
                        return True
 
519
                    if val in ['no',  'n', '0', 'off', 'false', 'f']:
 
520
                        return False
 
521
                    return val
 
522
                else:
 
523
                    raise XendError("option %s: %s:%s" % (name, e[1], e[2]))
 
524
 
 
525
        def get_config_int(self, name, val=None):
 
526
            try:
 
527
                return scf.get_int(name)
 
528
            except scf.error, e:
 
529
                if e[0] == scf.SCF_ERROR_NOT_FOUND:
 
530
                    return val
 
531
                else:
 
532
                    raise XendError("option %s: %s:%s" % (name, e[1], e[2]))
 
533
 
 
534
        def get_config_string(self, name, val=None):
 
535
            try:
 
536
                return scf.get_string(name)
 
537
            except scf.error, e:
 
538
                if e[0] == scf.SCF_ERROR_NOT_FOUND:
 
539
                    return val
 
540
                else:
 
541
                    raise XendError("option %s: %s:%s" % (name, e[1], e[2]))
 
542
 
 
543
        def get_xen_api_server(self):
 
544
            # When the new server is a supported configuration, we should
 
545
            # expand this.
 
546
            return [["unix"]]
 
547
 
 
548
def instance():
 
549
    """Get an instance of XendOptions.
 
550
    Use this instead of the constructor.
 
551
    """
 
552
    global inst
 
553
    try:
 
554
        inst
 
555
    except:
 
556
        if os.uname()[0] == 'SunOS':
 
557
            inst = XendOptionsSMF()
 
558
        else:
 
559
            inst = XendOptionsFile()
 
560
    return inst