summaryrefslogtreecommitdiffstats
path: root/server/server.py
diff options
context:
space:
mode:
Diffstat (limited to 'server/server.py')
-rwxr-xr-xserver/server.py215
1 files changed, 215 insertions, 0 deletions
diff --git a/server/server.py b/server/server.py
new file mode 100755
index 0000000..d297b06
--- /dev/null
+++ b/server/server.py
@@ -0,0 +1,215 @@
+#!/usr/bin/python
+"""
+Virt-factory backend code.
+
+Copyright 2006, Red Hat, Inc
+Michael DeHaan <mdehaan@redhat.com>
+Scott Seago <sseago@redhat.com>
+Adrian Likins <alikins@redhat.com>
+
+This software may be freely redistributed under the terms of the GNU
+general public license.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+"""
+
+import SimpleXMLRPCServer
+import os
+import subprocess
+import socket
+
+SERVE_ON = (None,None)
+
+# FIXME: logrotate
+
+from codes import *
+
+import config_data
+import logger
+import module_loader
+import utils
+
+
+MODULE_PATH="modules/"
+modules = module_loader.load_modules(MODULE_PATH)
+print "modules", modules
+
+
+#from busrpc.services import RPCDispatcher
+#from busrpc.config import DeploymentConfig
+
+from rhpl.translate import _, N_, textdomain, utf8
+I18N_DOMAIN = "vf_server"
+
+
+class Singleton(object):
+ def __new__(type, *args, **kwargs):
+ if not '_the_instance' in type.__dict__:
+ type._the_instance = object.__new__(type, *args, **kwargs)
+ type._the_instance.init(*args, **kwargs)
+ return type._the_instance
+
+class XmlRpcInterface(Singleton):
+
+ def init(self):
+ """
+ Constructor sets up SQLAlchemy (database ORM) and logging.
+ """
+ config_obj = config_data.Config()
+ self.config = config_obj.get()
+
+ self.tables = {}
+ self.tokens = []
+
+ self.logger = logger.Logger().logger
+
+ self.__setup_handlers()
+
+ def __setup_handlers(self):
+ """
+ Add RPC functions from each class to the global list so they can be called.
+ FIXME: eventually calling most functions should go from here through getattr.
+ """
+ self.handlers = {}
+ print "ffffffffffff", modules.keys()
+ for x in modules.keys():
+ print "x", x
+ try:
+ modules[x].register_rpc(self.handlers)
+ self.logger.debug("adding %s" % x)
+ except AttributeError, e:
+ self.logger.warning("module %s could not be loaded, it did not have a register_rpc method" % modules[x])
+
+
+ # FIXME: find some more elegant way to surface the handlers?
+ # FIXME: aforementioned login/session token requirement
+
+ def get_dispatch_method(self, method):
+ if method in self.handlers:
+ return FuncApiMethod(self.logger, method,
+ self.handlers[method])
+
+ else:
+ self.logger.info("Unhandled method call for method: %s " % method)
+ raise InvalidMethodException
+
+ def _dispatch(self, method, params):
+ """
+ the SimpleXMLRPCServer class will call _dispatch if it doesn't
+ find a handler method
+ """
+ return self.get_dispatch_method(method)(*params)
+
+class BusRpcWrapper:
+
+ def __init__(self, config):
+ self.rpc_interface = None
+
+ def __getattr__(self, name):
+ if self.rpc_interface == None:
+ self.rpc_interface = XmlRpcInterface()
+ return self.rpc_interface.get_dispatch_method(name)
+
+ def __repr__(self):
+ return ("<BusRpcWrapper>")
+
+class FuncApiMethod:
+ def __init__(self, logger, name, method):
+ self.logger = logger
+ self.__method = method
+ self.__name = name
+
+ def __log_exc(self):
+ """
+ Log an exception.
+ """
+ (t, v, tb) = sys.exc_info()
+ self.logger.info("Exception occured: %s" % t )
+ self.logger.info("Exception value: %s" % v)
+ self.logger.info("Exception Info:\n%s" % string.join(traceback.format_list(traceback.extract_tb(tb))))
+
+ def __call__(self, *args):
+ self.logger.debug("(X) -------------------------------------------")
+ try:
+ rc = self.__method(*args)
+ except FuncException, e:
+ self.__log_exc()
+ rc = e
+ except:
+ self.logger.debug("Not a virt-factory specific exception")
+ self.__log_exc()
+ raise
+ rc = rc.to_datastruct()
+ self.logger.debug("Return code for %s: %s" % (self.__name, rc))
+ return rc
+
+
+def serve(websvc):
+ """
+ Code for starting the XMLRPC service.
+ FIXME: make this HTTPS (see RRS code) and make accompanying Rails changes..
+ """
+ server =FuncXMLRPCServer(('', 51234))
+ server.register_instance(websvc)
+ server.serve_forever()
+
+def serve_qpid(config_path, register_with_bridge=False, is_bridge_server=False):
+ """
+ Code for starting the QPID RPC service.
+ """
+ config = DeploymentConfig(config_path)
+ dispatcher = RPCDispatcher(config, register_with_bridge, is_bridge_server=is_bridge_server)
+
+ try:
+ dispatcher.start()
+ except KeyboardInterrupt:
+ dispatcher.stop()
+ print "Exiting..."
+
+class FuncXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer):
+ def __init__(self, args):
+ self.allow_reuse_address = True
+ SimpleXMLRPCServer.SimpleXMLRPCServer.__init__(self, args)
+
+def main(argv):
+ """
+ Start things up.
+ """
+
+ websvc = XmlRpcInterface()
+
+ for arg in sys.argv:
+ if arg == "import" or arg == "--import":
+ prov_obj = provisioning.Provisioning()
+ prov_obj.init(None, {})
+ return
+ elif arg == "sync" or arg == "--sync":
+ prov_obj = provisioning.Provisioning()
+ prov_obj.sync(None, {}) # just for testing
+ return
+ if "qpid" in sys.argv or "--qpid" in sys.argv:
+ if "daemon" in sys.argv or "--daemon" in sys.argv:
+ utils.daemonize("/var/run/vf_server_qpid.pid")
+ else:
+ print "serving...\n"
+ serve_qpid("/etc/virt-factory/qpid.conf")
+ else:
+ if "daemon" in sys.argv or "--daemon" in sys.argv:
+ utils.daemonize("/var/run/vf_server.pid")
+ else:
+ print "serving...\n"
+ # daemonize only if --daemonize, because I forget to type "debug" -- MPD
+ serve(websvc)
+
+# FIXME: upgrades? database upgrade logic would be nice to have here, as would general creation (?)
+# FIXME: command line way to add a distro would be nice to have in the future, rsync import is a bit heavy handed.
+# (and might not be enough for RHEL, but is good for Fedora/Centos)
+
+
+if __name__ == "__main__":
+ textdomain(I18N_DOMAIN)
+ main(sys.argv)
+
+