[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] Support xend configuration via Solaris SMF
# HG changeset patch # User john.levon@xxxxxxx # Date 1167328159 28800 # Node ID 1dda9046d582d2cfb4efb00bd23124d85afcdb62 # Parent d0a640b8c84c6c10b3312233d68cbc006252d873 Enable xend to pick up properties from SMF on Solaris. Also rename XendRoot to the much clearer XendOptions. Signed-off-by: John Levon <john.levon@xxxxxxx> diff --git a/tools/python/setup.py b/tools/python/setup.py --- a/tools/python/setup.py +++ b/tools/python/setup.py @@ -30,12 +30,23 @@ xs = Extension("xs", libraries = libraries, sources = [ "xen/lowlevel/xs/xs.c" ]) +scf = Extension("scf", + extra_compile_args = extra_compile_args, + include_dirs = include_dirs + [ "xen/lowlevel/scf" ], + library_dirs = library_dirs, + libraries = libraries, + sources = [ "xen/lowlevel/scf/scf.c" ]) + acm = Extension("acm", extra_compile_args = extra_compile_args, include_dirs = include_dirs + [ "xen/lowlevel/acm" ], library_dirs = library_dirs, libraries = libraries, sources = [ "xen/lowlevel/acm/acm.c" ]) + +modules = [ xc, xs, acm ] +if os.uname()[0] == 'SunOS': + modules.append(scf) setup(name = 'xen', version = '3.0', @@ -56,7 +67,7 @@ setup(name = 'xen', 'xen.xm.tests' ], ext_package = "xen.lowlevel", - ext_modules = [ xc, xs, acm ] + ext_modules = modules ) os.chdir('logging') diff --git a/tools/python/xen/lowlevel/scf/scf.c b/tools/python/xen/lowlevel/scf/scf.c new file mode 100644 --- /dev/null +++ b/tools/python/xen/lowlevel/scf/scf.c @@ -0,0 +1,156 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <Python.h> + +#include <libscf.h> +#include <stdio.h> + +#define XEND_FMRI "svc:/system/xen/xend:default" +#define XEND_PG "config" + +static PyObject *scf_exc; + +static void * +scf_exception(const char *err, const char *value) +{ + int scferr = scf_error(); + const char *scfstrerr = scf_strerror(scferr); + PyObject *obj = Py_BuildValue("(isss)", scferr, err, scfstrerr, value); + PyErr_SetObject(scf_exc, obj); + return (NULL); +} + +static PyObject * +pyscf_get_bool(PyObject *o, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "name", NULL }; + scf_simple_prop_t *prop; + uint8_t *val; + char *name; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &name)) + return (NULL); + + prop = scf_simple_prop_get(NULL, XEND_FMRI, XEND_PG, name); + + if (prop == NULL) + return (scf_exception("scf_simple_prop_get() failed", name)); + + if ((val = scf_simple_prop_next_boolean(prop)) == NULL) + return (scf_exception("scf_simple_prop_next_boolean() failed", + name)); + + if (*val) { + scf_simple_prop_free(prop); + Py_INCREF(Py_True); + return (Py_True); + } + + scf_simple_prop_free(prop); + Py_INCREF(Py_False); + return (Py_False); +} + +static PyObject * +pyscf_get_int(PyObject *o, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "name", NULL }; + scf_simple_prop_t *prop; + PyObject *obj; + int64_t *val; + char *name; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &name)) + return (NULL); + + prop = scf_simple_prop_get(NULL, XEND_FMRI, XEND_PG, name); + + if (prop == NULL) + return (scf_exception("scf_simple_prop_get() failed", name)); + + if ((val = scf_simple_prop_next_integer(prop)) == NULL) + return (scf_exception("scf_simple_prop_next_integer() failed", + name)); + + obj = PyInt_FromLong((long)*val); + scf_simple_prop_free(prop); + return (obj); +} + +static PyObject * +pyscf_get_string(PyObject *o, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "name", NULL }; + scf_simple_prop_t *prop; + PyObject *obj; + char *name; + char *str; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &name)) + return (NULL); + + prop = scf_simple_prop_get(NULL, XEND_FMRI, XEND_PG, name); + + if (prop == NULL) + return (scf_exception("scf_simple_prop_get() failed", name)); + + if ((str = scf_simple_prop_next_astring(prop)) == NULL) { + scf_simple_prop_free(prop); + return (scf_exception("scf_simple_prop_next_astring() failed", + name)); + } + + obj = PyString_FromString(str); + scf_simple_prop_free(prop); + return (obj); +} + +PyDoc_STRVAR(pyscf_get_bool__doc__, + "get_bool(name) - get the value of the named boolean property"); +PyDoc_STRVAR(pyscf_get_int__doc__, + "get_int(name) - get the value of the named integer property"); +PyDoc_STRVAR(pyscf_get_string__doc__, + "get_string(name) - get the value of the named string property"); + +static struct PyMethodDef pyscf_module_methods[] = { + { "get_bool", (PyCFunction) pyscf_get_bool, + METH_VARARGS|METH_KEYWORDS, pyscf_get_bool__doc__ }, + { "get_int", (PyCFunction) pyscf_get_int, + METH_VARARGS|METH_KEYWORDS, pyscf_get_int__doc__ }, + { "get_string", (PyCFunction) pyscf_get_string, + METH_VARARGS|METH_KEYWORDS, pyscf_get_string__doc__ }, + { NULL, NULL, 0, NULL } +}; + +PyMODINIT_FUNC +initscf(void) +{ + PyObject *m; + m = Py_InitModule("scf", pyscf_module_methods); + + scf_exc = PyErr_NewException("scf.error", NULL, NULL); + Py_INCREF(scf_exc); + PyModule_AddObject(m, "error", scf_exc); + PyModule_AddIntConstant(m, "SCF_ERROR_NOT_FOUND", SCF_ERROR_NOT_FOUND); +} diff --git a/tools/python/xen/xend/Vifctl.py b/tools/python/xen/xend/Vifctl.py --- a/tools/python/xen/xend/Vifctl.py +++ b/tools/python/xen/xend/Vifctl.py @@ -20,7 +20,7 @@ """ import os -import XendRoot +import XendOptions def network(op): @@ -30,7 +30,7 @@ def network(op): """ if op not in ['start', 'stop']: raise ValueError('Invalid operation: ' + op) - script = XendRoot.instance().get_network_script() + script = XendOptions.instance().get_network_script() if script: script.insert(1, op) os.spawnv(os.P_WAIT, script[0], script) diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -32,7 +32,7 @@ import xen.lowlevel.xc import xen.lowlevel.xc -from xen.xend import XendRoot, XendCheckpoint, XendDomainInfo +from xen.xend import XendOptions, XendCheckpoint, XendDomainInfo from xen.xend.PrettyPrint import prettyprint from xen.xend.XendConfig import XendConfig from xen.xend.XendError import XendError, XendInvalidDomain, VmError @@ -51,7 +51,7 @@ from xen.xend import uuid from xen.xend import uuid xc = xen.lowlevel.xc.xc() -xroot = XendRoot.instance() +xoptions = XendOptions.instance() __all__ = [ "XendDomain" ] @@ -214,7 +214,7 @@ class XendDomain: @rtype: String @return: Path. """ - dom_path = xroot.get_xend_domains_path() + dom_path = xoptions.get_xend_domains_path() if domuuid: dom_path = os.path.join(dom_path, domuuid) return dom_path @@ -361,7 +361,7 @@ class XendDomain: def _setDom0CPUCount(self): """Sets the number of VCPUs dom0 has. Retreived from the - Xend configuration, L{XendRoot}. + Xend configuration, L{XendOptions}. @requires: Expects to be protected by domains_lock. @rtype: None @@ -369,7 +369,7 @@ class XendDomain: dom0 = self.privilegedDomain() # get max number of vcpus to use for dom0 from config - target = int(xroot.get_dom0_vcpus()) + target = int(xoptions.get_dom0_vcpus()) log.debug("number of vcpus to use is %d", target) # target == 0 means use all processors @@ -1154,7 +1154,7 @@ class XendDomain: dominfo.checkLiveMigrateMemory() if port == 0: - port = xroot.get_xend_relocation_port() + port = xoptions.get_xend_relocation_port() try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((dst, port)) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -38,7 +38,7 @@ from xen.util import security from xen.util import security from xen.xend import balloon, sxp, uuid, image, arch -from xen.xend import XendRoot, XendNode, XendConfig +from xen.xend import XendOptions, XendNode, XendConfig from xen.xend.XendConfig import scrub_password from xen.xend.XendBootloader import bootloader @@ -54,7 +54,7 @@ BOOTLOADER_LOOPBACK_DEVICE = '/dev/xvdp' BOOTLOADER_LOOPBACK_DEVICE = '/dev/xvdp' xc = xen.lowlevel.xc.xc() -xroot = XendRoot.instance() +xoptions = XendOptions.instance() log = logging.getLogger("xend.XendDomainInfo") #log.setLevel(logging.TRACE) @@ -734,7 +734,7 @@ class XendDomainInfo: 'domid': str(self.domid), 'vm': self.vmpath, 'name': self.info['name_label'], - 'console/limit': str(xroot.get_console_limit() * 1024), + 'console/limit': str(xoptions.get_console_limit() * 1024), 'memory/target': str(self.info['memory_static_min'] * 1024) } @@ -970,7 +970,7 @@ class XendDomainInfo: log.warn('Domain has crashed: name=%s id=%d.', self.info['name_label'], self.domid) - if xroot.get_enable_dump(): + if xoptions.get_enable_dump(): self.dumpCore() restart_reason = 'crash' diff --git a/tools/python/xen/xend/XendNode.py b/tools/python/xen/xend/XendNode.py --- a/tools/python/xen/xend/XendNode.py +++ b/tools/python/xen/xend/XendNode.py @@ -21,7 +21,7 @@ import xen.lowlevel.xc import xen.lowlevel.xc from xen.xend import uuid from xen.xend.XendError import XendError -from xen.xend.XendRoot import instance as xendroot +from xen.xend.XendOptions import instance as xendoptions from xen.xend.XendStorageRepository import XendStorageRepository from xen.xend.XendLogging import log from xen.xend.XendPIF import * @@ -42,7 +42,7 @@ class XendNode: """ self.xc = xen.lowlevel.xc.xc() - self.state_store = XendStateStore(xendroot().get_xend_state_path()) + self.state_store = XendStateStore(xendoptions().get_xend_state_path()) # load host state from XML file saved_host = self.state_store.load_state('host') diff --git a/tools/python/xen/xend/XendOptions.py b/tools/python/xen/xend/XendOptions.py new file mode 100644 --- /dev/null +++ b/tools/python/xen/xend/XendOptions.py @@ -0,0 +1,367 @@ +#============================================================================ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#============================================================================ +# Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx> +# Copyright (C) 2005 XenSource Ltd +#============================================================================ + +"""Xend root class. +Creates the servers and handles configuration. + +Other classes get config variables by importing this module, +using instance() to get a XendOptions instance, and then +the config functions (e.g. get_xend_port()) to get +configured values. +""" + +import os +import os.path +import string +import sys + +from xen.xend import sxp, osdep, XendLogging +from xen.xend.XendError import XendError + +if os.uname()[0] == 'SunOS': + from xen.lowlevel import scf + +class XendOptions: + """Root of the management classes.""" + + """Where network control scripts live.""" + network_script_dir = osdep.scripts_dir + + """Where block control scripts live.""" + block_script_dir = osdep.scripts_dir + + """Default path to the log file. """ + logfile_default = "/var/log/xen/xend.log" + + """Default level of information to be logged.""" + loglevel_default = 'DEBUG' + + """Default Xen-API server configuration. """ + xen_api_server_default = [['unix']] + + """Default for the flag indicating whether xend should run an http server + (deprecated).""" + xend_http_server_default = 'no' + + xend_tcp_xmlrpc_server_default = 'no' + + xend_unix_xmlrpc_server_default = 'yes' + + """Default interface address xend listens at. """ + xend_address_default = '' + + """Default for the flag indicating whether xend should run a relocation server.""" + xend_relocation_server_default = 'no' + + """Default interface address the xend relocation server listens at. """ + xend_relocation_address_default = '' + + """Default port xend serves HTTP at. """ + xend_port_default = 8000 + + """Default port xend serves relocation at. """ + xend_relocation_port_default = 8002 + + xend_relocation_hosts_allow_default = '' + + """Default for the flag indicating whether xend should run a unix-domain + server (deprecated).""" + xend_unix_server_default = 'no' + + """Default external migration tool """ + external_migration_tool_default = '' + + """Default path the unix-domain server listens at.""" + xend_unix_path_default = '/var/lib/xend/xend-socket' + + dom0_min_mem_default = 0 + + dom0_vcpus_default = 0 + + vncpasswd_default = None + + """Default interface to listen for VNC connections on""" + xend_vnc_listen_default = '127.0.0.1' + + """Default session storage path.""" + xend_domains_path_default = '/var/lib/xend/domains' + + """Default xend management state storage.""" + xend_state_path_default = '/var/lib/xend/state' + + def __init__(self): + self.configure() + + def _logError(self, fmt, *args): + """Logging function to log to stderr. We use this for XendOptions log + messages because they may be logged before the logger has been + configured. Other components can safely use the logger. + """ + print >>sys.stderr, "xend [ERROR]", fmt % args + + + def configure(self): + self.set_config() + XendLogging.init(self.get_config_string("logfile", + self.logfile_default), + self.get_config_string("loglevel", + self.loglevel_default)) + + def set_config(self): + raise NotImplementedError() + + def get_config_bool(self, name, val=None): + raise NotImplementedError() + + def get_config_int(self, name, val=None): + raise NotImplementedError() + + def get_config_string(self, name, val=None): + raise NotImplementedError() + + def get_xen_api_server(self): + raise NotImplementedError() + + def get_xend_http_server(self): + """Get the flag indicating whether xend should run an http server. + """ + return self.get_config_bool("xend-http-server", self.xend_http_server_default) + + def get_xend_tcp_xmlrpc_server(self): + return self.get_config_bool("xend-tcp-xmlrpc-server", + self.xend_tcp_xmlrpc_server_default) + + def get_xend_unix_xmlrpc_server(self): + return self.get_config_bool("xend-unix-xmlrpc-server", + self.xend_unix_xmlrpc_server_default) + + def get_xend_relocation_server(self): + """Get the flag indicating whether xend should run a relocation server. + """ + return self.get_config_bool("xend-relocation-server", + self.xend_relocation_server_default) + + def get_xend_port(self): + """Get the port xend listens at for its HTTP interface. + """ + return self.get_config_int('xend-port', self.xend_port_default) + + def get_xend_relocation_port(self): + """Get the port xend listens at for connection to its relocation server. + """ + return self.get_config_int('xend-relocation-port', + self.xend_relocation_port_default) + + def get_xend_relocation_hosts_allow(self): + return self.get_config_string("xend-relocation-hosts-allow", + self.xend_relocation_hosts_allow_default) + + def get_xend_address(self): + """Get the address xend listens at for its HTTP port. + This defaults to the empty string which allows all hosts to connect. + If this is set to 'localhost' only the localhost will be able to connect + to the HTTP port. + """ + return self.get_config_string('xend-address', self.xend_address_default) + + def get_xend_relocation_address(self): + """Get the address xend listens at for its relocation server port. + This defaults to the empty string which allows all hosts to connect. + If this is set to 'localhost' only the localhost will be able to connect + to the relocation port. + """ + return self.get_config_string('xend-relocation-address', self.xend_relocation_address_default) + + def get_xend_unix_server(self): + """Get the flag indicating whether xend should run a unix-domain server. + """ + return self.get_config_bool("xend-unix-server", self.xend_unix_server_default) + + def get_xend_unix_path(self): + """Get the path the xend unix-domain server listens at. + """ + return self.get_config_string("xend-unix-path", self.xend_unix_path_default) + + def get_xend_domains_path(self): + """ Get the path for persistent domain configuration storage + """ + return self.get_config_string("xend-domains-path", self.xend_domains_path_default) + + def get_xend_state_path(self): + """ Get the path for persistent domain configuration storage + """ + return self.get_config_string("xend-state-path", self.xend_state_path_default) + + def get_network_script(self): + """@return the script used to alter the network configuration when + Xend starts and stops, or None if no such script is specified.""" + + s = self.get_config_string('network-script') + + if s: + result = s.split(" ") + result[0] = os.path.join(self.network_script_dir, result[0]) + return result + else: + return None + + def get_external_migration_tool(self): + """@return the name of the tool to handle virtual TPM migration.""" + return self.get_config_string('external-migration-tool', self.external_migration_tool_default) + + def get_enable_dump(self): + return self.get_config_bool('enable-dump', 'no') + + def get_vif_script(self): + return self.get_config_string('vif-script', 'vif-bridge') + + def get_dom0_min_mem(self): + return self.get_config_int('dom0-min-mem', self.dom0_min_mem_default) + + def get_dom0_vcpus(self): + return self.get_config_int('dom0-cpus', self.dom0_vcpus_default) + + def get_console_limit(self): + return self.get_config_int('console-limit', 1024) + + def get_vnclisten_address(self): + return self.get_config_string('vnc-listen', self.xend_vnc_listen_default) + + def get_vncpasswd_default(self): + return self.get_config_string('vncpasswd', + self.vncpasswd_default) + +class XendOptionsFile(XendOptions): + + """Default path to the config file.""" + config_default = "/etc/xen/xend-config.sxp" + + """Environment variable used to override config_default.""" + config_var = "XEND_CONFIG" + + def set_config(self): + """If the config file exists, read it. If not, ignore it. + + The config file is a sequence of sxp forms. + """ + self.config_path = os.getenv(self.config_var, self.config_default) + if os.path.exists(self.config_path): + try: + fin = file(self.config_path, 'rb') + try: + config = sxp.parse(fin) + finally: + fin.close() + if config is None: + config = ['xend-config'] + else: + config.insert(0, 'xend-config') + self.config = config + except Exception, ex: + self._logError('Reading config file %s: %s', + self.config_path, str(ex)) + raise + else: + self._logError('Config file does not exist: %s', + self.config_path) + self.config = ['xend-config'] + + def get_config_value(self, name, val=None): + """Get the value of an atomic configuration element. + + @param name: element name + @param val: default value (optional, defaults to None) + @return: value + """ + return sxp.child_value(self.config, name, val=val) + + def get_config_bool(self, name, val=None): + v = string.lower(str(self.get_config_value(name, val))) + if v in ['yes', 'y', '1', 'on', 'true', 't']: + return True + if v in ['no', 'n', '0', 'off', 'false', 'f']: + return False + raise XendError("invalid xend config %s: expected bool: %s" % (name, v)) + + def get_config_int(self, name, val=None): + v = self.get_config_value(name, val) + try: + return int(v) + except Exception: + raise XendError("invalid xend config %s: expected int: %s" % (name, v)) + + def get_config_string(self, name, val=None): + return get_config_value(self, name, val) + + def get_xen_api_server(self): + """Get the Xen-API server configuration. + """ + return self.get_config_value('xen-api-server', + self.xen_api_server_default) + +if os.uname()[0] == 'SunOS': + class XendOptionsSMF(XendOptions): + + def set_config(self): + pass + + def get_config_bool(self, name, val=None): + try: + return scf.get_bool(name) + except scf.error, e: + if e[0] == scf.SCF_ERROR_NOT_FOUND: + return val + else: + raise XendError("option %s: %s:%s" % (name, e[1], e[2])) + + def get_config_int(self, name, val=None): + try: + return scf.get_int(name) + except scf.error, e: + if e[0] == scf.SCF_ERROR_NOT_FOUND: + return val + else: + raise XendError("option %s: %s:%s" % (name, e[1], e[2])) + + def get_config_string(self, name, val=None): + try: + return scf.get_string(name) + except scf.error, e: + if e[0] == scf.SCF_ERROR_NOT_FOUND: + return val + else: + raise XendError("option %s: %s:%s" % (name, e[1], e[2])) + + def get_xen_api_server(self): + # When the new server is a supported configuration, we should + # expand this. + return [["unix"]] + +def instance(): + """Get an instance of XendOptions. + Use this instead of the constructor. + """ + global inst + try: + inst + except: + if os.uname()[0] == 'SunOS': + inst = XendOptionsSMF() + else: + inst = XendOptionsFile() + return inst diff --git a/tools/python/xen/xend/XendPIF.py b/tools/python/xen/xend/XendPIF.py --- a/tools/python/xen/xend/XendPIF.py +++ b/tools/python/xen/xend/XendPIF.py @@ -20,7 +20,6 @@ import re import re import socket -from xen.xend.XendRoot import instance as xendroot from xen.xend.XendLogging import log MAC_RE = ':'.join(['[0-9a-f]{2}'] * 6) diff --git a/tools/python/xen/xend/XendProtocol.py b/tools/python/xen/xend/XendProtocol.py --- a/tools/python/xen/xend/XendProtocol.py +++ b/tools/python/xen/xend/XendProtocol.py @@ -24,7 +24,7 @@ from encode import * from encode import * from xen.xend import sxp -from xen.xend import XendRoot +from xen.xend import XendOptions DEBUG = 0 @@ -34,7 +34,7 @@ HTTP_NO_CONTENT = 2 HTTP_NO_CONTENT = 204 -xroot = XendRoot.instance() +xoptions = XendOptions.instance() class XendError(RuntimeError): @@ -218,7 +218,7 @@ class UnixXendClientProtocol(HttpXendCli def __init__(self, path=None): if path is None: - path = xroot.get_xend_unix_path() + path = xoptions.get_xend_unix_path() self.path = path def makeConnection(self, _): diff --git a/tools/python/xen/xend/XendRoot.py b/tools/python/xen/xend/XendRoot.py deleted file mode 100644 --- a/tools/python/xen/xend/XendRoot.py +++ /dev/null @@ -1,322 +0,0 @@ -#============================================================================ -# This library is free software; you can redistribute it and/or -# modify it under the terms of version 2.1 of the GNU Lesser General Public -# License as published by the Free Software Foundation. -# -# This library 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 -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -#============================================================================ -# Copyright (C) 2004, 2005 Mike Wray <mike.wray@xxxxxx> -# Copyright (C) 2005 XenSource Ltd -#============================================================================ - -"""Xend root class. -Creates the servers and handles configuration. - -Other classes get config variables by importing this module, -using instance() to get a XendRoot instance, and then -the config functions (e.g. get_xend_port()) to get -configured values. -""" - -import os -import os.path -import string -import sys - -from xen.xend import sxp, osdep, XendLogging -from xen.xend.XendError import XendError - -class XendRoot: - """Root of the management classes.""" - - """Default path to the config file.""" - config_default = "/etc/xen/xend-config.sxp" - - """Environment variable used to override config_default.""" - config_var = "XEND_CONFIG" - - """Where network control scripts live.""" - network_script_dir = osdep.scripts_dir - - """Where block control scripts live.""" - block_script_dir = osdep.scripts_dir - - """Default path to the log file. """ - logfile_default = "/var/log/xen/xend.log" - - """Default level of information to be logged.""" - loglevel_default = 'DEBUG' - - """Default Xen-API server configuration. """ - xen_api_server_default = [['unix']] - - """Default for the flag indicating whether xend should run an http server - (deprecated).""" - xend_http_server_default = 'no' - - xend_tcp_xmlrpc_server_default = 'no' - - xend_unix_xmlrpc_server_default = 'yes' - - """Default interface address xend listens at. """ - xend_address_default = '' - - """Default for the flag indicating whether xend should run a relocation server.""" - xend_relocation_server_default = 'no' - - """Default interface address the xend relocation server listens at. """ - xend_relocation_address_default = '' - - """Default port xend serves HTTP at. """ - xend_port_default = '8000' - - """Default port xend serves relocation at. """ - xend_relocation_port_default = '8002' - - xend_relocation_hosts_allow_default = '' - - """Default for the flag indicating whether xend should run a unix-domain - server (deprecated).""" - xend_unix_server_default = 'no' - - """Default external migration tool """ - external_migration_tool_default = '' - - """Default path the unix-domain server listens at.""" - xend_unix_path_default = '/var/lib/xend/xend-socket' - - dom0_min_mem_default = '0' - - dom0_vcpus_default = '0' - - vncpasswd_default = None - - """Default interface to listen for VNC connections on""" - xend_vnc_listen_default = '127.0.0.1' - - """Default session storage path.""" - xend_domains_path_default = '/var/lib/xend/domains' - - """Default xend management state storage.""" - xend_state_path_default = '/var/lib/xend/state' - - components = {} - - def __init__(self): - self.config_path = None - self.config = None - self.configure() - - - def _logError(self, fmt, *args): - """Logging function to log to stderr. We use this for XendRoot log - messages because they may be logged before the logger has been - configured. Other components can safely use the logger. - """ - print >>sys.stderr, "xend [ERROR]", fmt % args - - - def configure(self): - self.set_config() - XendLogging.init(self.get_config_value("logfile", - self.logfile_default), - self.get_config_value("loglevel", - self.loglevel_default)) - - - def set_config(self): - """If the config file exists, read it. If not, ignore it. - - The config file is a sequence of sxp forms. - """ - self.config_path = os.getenv(self.config_var, self.config_default) - if os.path.exists(self.config_path): - try: - fin = file(self.config_path, 'rb') - try: - config = sxp.parse(fin) - finally: - fin.close() - if config is None: - config = ['xend-config'] - else: - config.insert(0, 'xend-config') - self.config = config - except Exception, ex: - self._logError('Reading config file %s: %s', - self.config_path, str(ex)) - raise - else: - self._logError('Config file does not exist: %s', - self.config_path) - self.config = ['xend-config'] - - def get_config(self, name=None): - """Get the configuration element with the given name, or - the whole configuration if no name is given. - - @param name: element name (optional) - @return: config or none - """ - if name is None: - val = self.config - else: - val = sxp.child(self.config, name) - return val - - def get_config_value(self, name, val=None): - """Get the value of an atomic configuration element. - - @param name: element name - @param val: default value (optional, defaults to None) - @return: value - """ - return sxp.child_value(self.config, name, val=val) - - def get_config_bool(self, name, val=None): - v = string.lower(str(self.get_config_value(name, val))) - if v in ['yes', 'y', '1', 'on', 'true', 't']: - return True - if v in ['no', 'n', '0', 'off', 'false', 'f']: - return False - raise XendError("invalid xend config %s: expected bool: %s" % (name, v)) - - def get_config_int(self, name, val=None): - v = self.get_config_value(name, val) - try: - return int(v) - except Exception: - raise XendError("invalid xend config %s: expected int: %s" % (name, v)) - - def get_xen_api_server(self): - """Get the Xen-API server configuration. - """ - return self.get_config_value('xen-api-server', - self.xen_api_server_default) - - def get_xend_http_server(self): - """Get the flag indicating whether xend should run an http server. - """ - return self.get_config_bool("xend-http-server", self.xend_http_server_default) - - def get_xend_tcp_xmlrpc_server(self): - return self.get_config_bool("xend-tcp-xmlrpc-server", - self.xend_tcp_xmlrpc_server_default) - - def get_xend_unix_xmlrpc_server(self): - return self.get_config_bool("xend-unix-xmlrpc-server", - self.xend_unix_xmlrpc_server_default) - - def get_xend_relocation_server(self): - """Get the flag indicating whether xend should run a relocation server. - """ - return self.get_config_bool("xend-relocation-server", - self.xend_relocation_server_default) - - def get_xend_port(self): - """Get the port xend listens at for its HTTP interface. - """ - return self.get_config_int('xend-port', self.xend_port_default) - - def get_xend_relocation_port(self): - """Get the port xend listens at for connection to its relocation server. - """ - return self.get_config_int('xend-relocation-port', - self.xend_relocation_port_default) - - def get_xend_relocation_hosts_allow(self): - return self.get_config_value("xend-relocation-hosts-allow", - self.xend_relocation_hosts_allow_default) - - def get_xend_address(self): - """Get the address xend listens at for its HTTP port. - This defaults to the empty string which allows all hosts to connect. - If this is set to 'localhost' only the localhost will be able to connect - to the HTTP port. - """ - return self.get_config_value('xend-address', self.xend_address_default) - - def get_xend_relocation_address(self): - """Get the address xend listens at for its relocation server port. - This defaults to the empty string which allows all hosts to connect. - If this is set to 'localhost' only the localhost will be able to connect - to the relocation port. - """ - return self.get_config_value('xend-relocation-address', self.xend_relocation_address_default) - - def get_xend_unix_server(self): - """Get the flag indicating whether xend should run a unix-domain server. - """ - return self.get_config_bool("xend-unix-server", self.xend_unix_server_default) - - def get_xend_unix_path(self): - """Get the path the xend unix-domain server listens at. - """ - return self.get_config_value("xend-unix-path", self.xend_unix_path_default) - - def get_xend_domains_path(self): - """ Get the path for persistent domain configuration storage - """ - return self.get_config_value("xend-domains-path", self.xend_domains_path_default) - - def get_xend_state_path(self): - """ Get the path for persistent domain configuration storage - """ - return self.get_config_value("xend-state-path", self.xend_state_path_default) - - def get_network_script(self): - """@return the script used to alter the network configuration when - Xend starts and stops, or None if no such script is specified.""" - - s = self.get_config_value('network-script') - - if s: - result = s.split(" ") - result[0] = os.path.join(self.network_script_dir, result[0]) - return result - else: - return None - - def get_external_migration_tool(self): - """@return the name of the tool to handle virtual TPM migration.""" - return self.get_config_value('external-migration-tool', self.external_migration_tool_default) - - def get_enable_dump(self): - return self.get_config_bool('enable-dump', 'no') - - def get_vif_script(self): - return self.get_config_value('vif-script', 'vif-bridge') - - def get_dom0_min_mem(self): - return self.get_config_int('dom0-min-mem', self.dom0_min_mem_default) - - def get_dom0_vcpus(self): - return self.get_config_int('dom0-cpus', self.dom0_vcpus_default) - - def get_console_limit(self): - return self.get_config_int('console-limit', 1024) - - def get_vnclisten_address(self): - return self.get_config_value('vnc-listen', self.xend_vnc_listen_default) - - def get_vncpasswd_default(self): - return self.get_config_value('vncpasswd', - self.vncpasswd_default) - -def instance(): - """Get an instance of XendRoot. - Use this instead of the constructor. - """ - global inst - try: - inst - except: - inst = XendRoot() - return inst diff --git a/tools/python/xen/xend/balloon.py b/tools/python/xen/xend/balloon.py --- a/tools/python/xen/xend/balloon.py +++ b/tools/python/xen/xend/balloon.py @@ -22,7 +22,7 @@ import xen.lowlevel.xc import xen.lowlevel.xc import XendDomain -import XendRoot +import XendOptions from XendLogging import log from XendError import VmError @@ -107,11 +107,11 @@ def free(need_mem): # usage, so we recheck the required alloc each time around the loop, but # track the last used value so that we don't trigger too many watches. - xroot = XendRoot.instance() + xoptions = XendOptions.instance() xc = xen.lowlevel.xc.xc() try: - dom0_min_mem = xroot.get_dom0_min_mem() * 1024 + dom0_min_mem = xoptions.get_dom0_min_mem() * 1024 retries = 0 sleep_time = SLEEP_TIME_GROWTH diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py +++ b/tools/python/xen/xend/image.py @@ -459,14 +459,14 @@ class HVMImageHandler(ImageHandler): vnclisten = imageConfig.get('vnclisten') if not(vnclisten): - vnclisten = (xen.xend.XendRoot.instance(). + vnclisten = (xen.xend.XendOptions.instance(). get_vnclisten_address()) if vnclisten: ret += ['-vnclisten', vnclisten] vncpasswd = vncpasswd_vmconfig if vncpasswd is None: - vncpasswd = (xen.xend.XendRoot.instance(). + vncpasswd = (xen.xend.XendOptions.instance(). get_vncpasswd_default()) if vncpasswd is None: raise VmError('vncpasswd is not set up in ' + diff --git a/tools/python/xen/xend/server/DevController.py b/tools/python/xen/xend/server/DevController.py --- a/tools/python/xen/xend/server/DevController.py +++ b/tools/python/xen/xend/server/DevController.py @@ -19,7 +19,7 @@ from threading import Event from threading import Event import types -from xen.xend import sxp, XendRoot +from xen.xend import sxp, XendOptions from xen.xend.XendError import VmError from xen.xend.XendLogging import log @@ -50,7 +50,7 @@ xenbusState = { 'Closed' : 6, } -xroot = XendRoot.instance() +xoptions = XendOptions.instance() xenbusState.update(dict(zip(xenbusState.values(), xenbusState.keys()))) @@ -324,7 +324,7 @@ class DevController: Make sure that the migration has finished and only then return from the call. """ - tool = xroot.get_external_migration_tool() + tool = xoptions.get_external_migration_tool() if tool: log.info("Calling external migration tool for step %d" % step) fd = os.popen("%s -type %s -step %d -host %s -domname %s" % @@ -341,7 +341,7 @@ class DevController: """ Recover from device migration. The given step was the last one that was successfully executed. """ - tool = xroot.get_external_migration_tool() + tool = xoptions.get_external_migration_tool() if tool: log.info("Calling external migration tool") fd = os.popen("%s -type %s -step %d -host %s -domname %s -recover" % diff --git a/tools/python/xen/xend/server/SrvRoot.py b/tools/python/xen/xend/server/SrvRoot.py --- a/tools/python/xen/xend/server/SrvRoot.py +++ b/tools/python/xen/xend/server/SrvRoot.py @@ -25,7 +25,7 @@ class SrvRoot(SrvDir): """Server sub-components. Each entry is (name, class), where 'name' is the entry name and 'class' is the name of its class. """ - #todo Get this list from the XendRoot config. + #todo Get this list from the XendOptions config. subdirs = [ ('node', 'SrvNode' ), ('domain', 'SrvDomainDir' ), diff --git a/tools/python/xen/xend/server/SrvServer.py b/tools/python/xen/xend/server/SrvServer.py --- a/tools/python/xen/xend/server/SrvServer.py +++ b/tools/python/xen/xend/server/SrvServer.py @@ -48,7 +48,7 @@ from threading import Thread from xen.web.httpserver import HttpServer, UnixHttpServer -from xen.xend import XendRoot, XendAPI +from xen.xend import XendOptions, XendAPI from xen.xend import Vifctl from xen.xend.XendLogging import log from xen.xend.XendClient import XEN_API_SOCKET @@ -57,7 +57,7 @@ from SrvRoot import SrvRoot from SrvRoot import SrvRoot from XMLRPCServer import XMLRPCServer -xroot = XendRoot.instance() +xoptions = XendOptions.instance() class XendServers: @@ -163,7 +163,7 @@ class XendServers: log.info("Restarting all XML-RPC and Xen-API servers...") self.cleaningUp = False self.reloadingConfig = False - xroot.set_config() + xoptions.set_config() new_servers = [x for x in self.servers if isinstance(x, HttpServer)] self.servers = new_servers @@ -172,16 +172,16 @@ class XendServers: break def _loadConfig(servers, root, reload): - if not reload and xroot.get_xend_http_server(): + if not reload and xoptions.get_xend_http_server(): servers.add(HttpServer(root, - xroot.get_xend_address(), - xroot.get_xend_port())) - if not reload and xroot.get_xend_unix_server(): - path = xroot.get_xend_unix_path() + xoptions.get_xend_address(), + xoptions.get_xend_port())) + if not reload and xoptions.get_xend_unix_server(): + path = xoptions.get_xend_unix_path() log.info('unix path=' + path) servers.add(UnixHttpServer(root, path)) - api_cfg = xroot.get_xen_api_server() + api_cfg = xoptions.get_xen_api_server() if api_cfg: try: addrs = [(str(x[0]).split(':'), @@ -216,10 +216,10 @@ def _loadConfig(servers, root, reload): except TypeError, exn: log.error('Xen-API server configuration %s is invalid.', api_cfg) - if xroot.get_xend_tcp_xmlrpc_server(): + if xoptions.get_xend_tcp_xmlrpc_server(): servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False, True)) - if xroot.get_xend_unix_xmlrpc_server(): + if xoptions.get_xend_unix_xmlrpc_server(): servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False)) diff --git a/tools/python/xen/xend/server/netif.py b/tools/python/xen/xend/server/netif.py --- a/tools/python/xen/xend/server/netif.py +++ b/tools/python/xen/xend/server/netif.py @@ -24,10 +24,10 @@ import random import random import re -from xen.xend import XendRoot +from xen.xend import XendOptions from xen.xend.server.DevController import DevController -xroot = XendRoot.instance() +xoptions = XendOptions.instance() def randomMAC(): """Generate a random MAC address. @@ -138,8 +138,8 @@ class NetifController(DevController): def getDeviceDetails(self, config): """@see DevController.getDeviceDetails""" - script = os.path.join(xroot.network_script_dir, - config.get('script', xroot.get_vif_script())) + script = os.path.join(xoptions.network_script_dir, + config.get('script', xoptions.get_vif_script())) typ = config.get('type') bridge = config.get('bridge') mac = config.get('mac') @@ -190,7 +190,7 @@ class NetifController(DevController): (script, ip, bridge, mac, typ, vifname, rate, uuid) = devinfo if script: - network_script_dir = xroot.network_script_dir + os.sep + network_script_dir = xoptions.network_script_dir + os.sep result['script'] = script.replace(network_script_dir, "") if ip: result['ip'] = ip diff --git a/tools/python/xen/xend/server/relocate.py b/tools/python/xen/xend/server/relocate.py --- a/tools/python/xen/xend/server/relocate.py +++ b/tools/python/xen/xend/server/relocate.py @@ -24,7 +24,7 @@ from xen.web import protocol, tcp, unix from xen.xend import sxp from xen.xend import XendDomain -from xen.xend import XendRoot +from xen.xend import XendOptions from xen.xend.XendError import XendError from xen.xend.XendLogging import log @@ -114,15 +114,15 @@ class RelocationProtocol(protocol.Protoc def listenRelocation(): - xroot = XendRoot.instance() - if xroot.get_xend_unix_server(): + xoptions = XendOptions.instance() + if xoptions.get_xend_unix_server(): path = '/var/lib/xend/relocation-socket' unix.UnixListener(path, RelocationProtocol) - if xroot.get_xend_relocation_server(): - port = xroot.get_xend_relocation_port() - interface = xroot.get_xend_relocation_address() + if xoptions.get_xend_relocation_server(): + port = xoptions.get_xend_relocation_port() + interface = xoptions.get_xend_relocation_address() - hosts_allow = xroot.get_xend_relocation_hosts_allow() + hosts_allow = xoptions.get_xend_relocation_hosts_allow() if hosts_allow == '': hosts_allow = None else: diff --git a/tools/python/xen/xend/server/tests/test_controllers.py b/tools/python/xen/xend/server/tests/test_controllers.py --- a/tools/python/xen/xend/server/tests/test_controllers.py +++ b/tools/python/xen/xend/server/tests/test_controllers.py @@ -2,9 +2,9 @@ import re import re import unittest -import xen.xend.XendRoot +import xen.xend.XendOptions -xen.xend.XendRoot.XendRoot.config_default = '/dev/null' +xen.xend.XendOptions.XendOptions.config_default = '/dev/null' from xen.xend.server import netif @@ -13,7 +13,7 @@ FAKE_DEVID = 63 FAKE_DEVID = 63 -xroot = xen.xend.XendRoot.instance() +xoptions = xen.xend.XendOptions.instance() class test_controllers(unittest.TestCase): @@ -36,8 +36,8 @@ class test_controllers(unittest.TestCase self.assertEqual(backdets['handle'], str(FAKE_DEVID)) self.assertEqual(backdets['script'], - os.path.join(xroot.network_script_dir, - xroot.get_vif_script())) + os.path.join(xoptions.network_script_dir, + xoptions.get_vif_script())) self.assertValidMac(backdets['mac'], expectedMac) self.assertEqual(frontdets['handle'], str(FAKE_DEVID)) diff --git a/tools/python/xen/xend/server/tpmif.py b/tools/python/xen/xend/server/tpmif.py --- a/tools/python/xen/xend/server/tpmif.py +++ b/tools/python/xen/xend/server/tpmif.py @@ -20,7 +20,7 @@ """Support for virtual TPM interfaces.""" -from xen.xend import XendRoot +from xen.xend import XendOptions from xen.xend.XendLogging import log from xen.xend.XendError import XendError from xen.xend.XendConstants import DEV_MIGRATE_TEST, VTPM_DELETE_SCRIPT @@ -29,7 +29,7 @@ import os import os import re -xroot = XendRoot.instance() +xoptions = XendOptions.instance() def destroy_vtpmstate(name): if os.path.exists(VTPM_DELETE_SCRIPT): @@ -88,7 +88,7 @@ class TPMifController(DevController): def migrate(self, deviceConfig, network, dst, step, domName): """@see DevContoller.migrate""" if network: - tool = xroot.get_external_migration_tool() + tool = xoptions.get_external_migration_tool() if tool != '': log.info("Request to network-migrate device to %s. step=%d.", dst, step) @@ -116,7 +116,7 @@ class TPMifController(DevController): def recover_migrate(self, deviceConfig, network, dst, step, domName): """@see DevContoller.recover_migrate""" if network: - tool = xroot.get_external_migration_tool() + tool = xoptions.get_external_migration_tool() if tool != '': log.info("Request to recover network-migrated device. last good step=%d.", step) diff --git a/tools/python/xen/xend/server/vfbif.py b/tools/python/xen/xend/server/vfbif.py --- a/tools/python/xen/xend/server/vfbif.py +++ b/tools/python/xen/xend/server/vfbif.py @@ -52,7 +52,7 @@ class VfbifController(DevController): if config.has_key("vncpasswd"): passwd = config["vncpasswd"] else: - passwd = xen.xend.XendRoot.instance().get_vncpasswd_default() + passwd = xen.xend.XendOptions.instance().get_vncpasswd_default() if passwd: self.vm.storeVm("vncpasswd", passwd) log.debug("Stored a VNC password for vfb access") @@ -66,7 +66,7 @@ class VfbifController(DevController): elif config.has_key("vncdisplay"): args += ["--vncport", "%d" % (5900 + config["vncdisplay"])] vnclisten = config.get("vnclisten", - xen.xend.XendRoot.instance().get_vnclisten_address()) + xen.xend.XendOptions.instance().get_vnclisten_address()) args += [ "--listen", vnclisten ] spawn_detached(args[0], args + std_args, os.environ) elif t == "sdl": diff --git a/tools/python/xen/xm/tests/test_create.py b/tools/python/xen/xm/tests/test_create.py --- a/tools/python/xen/xm/tests/test_create.py +++ b/tools/python/xen/xm/tests/test_create.py @@ -3,9 +3,9 @@ import tempfile import tempfile import unittest -import xen.xend.XendRoot - -xen.xend.XendRoot.XendRoot.config_default = '/dev/null' +import xen.xend.XendOptions + +xen.xend.XendOptions.XendOptions.config_default = '/dev/null' import xen.xm.create _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |