summaryrefslogtreecommitdiffstats
path: root/src/sbin/Bcfg2Server
diff options
context:
space:
mode:
authorNarayan Desai <desai@mcs.anl.gov>2006-01-23 22:35:40 +0000
committerNarayan Desai <desai@mcs.anl.gov>2006-01-23 22:35:40 +0000
commitedca0b698637c3fd0a70af7e4752a46afca938d3 (patch)
tree658fad717833200ccb4e3725c811ccce7c10fc8d /src/sbin/Bcfg2Server
parent8ca8a153dfc6bd81ede9f5cff1ee3f111ae053ee (diff)
downloadbcfg2-edca0b698637c3fd0a70af7e4752a46afca938d3.tar.gz
bcfg2-edca0b698637c3fd0a70af7e4752a46afca938d3.tar.bz2
bcfg2-edca0b698637c3fd0a70af7e4752a46afca938d3.zip
last step of repo switches
git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@1716 ce84e21b-d406-0410-9b95-82705330c041
Diffstat (limited to 'src/sbin/Bcfg2Server')
-rw-r--r--src/sbin/Bcfg2Server289
1 files changed, 0 insertions, 289 deletions
diff --git a/src/sbin/Bcfg2Server b/src/sbin/Bcfg2Server
deleted file mode 100644
index c1b93644b..000000000
--- a/src/sbin/Bcfg2Server
+++ /dev/null
@@ -1,289 +0,0 @@
-#!/usr/bin/env python
-
-'''The XML-RPC Bcfg2 Server'''
-__revision__ = '$Revision:$'
-
-from getopt import getopt, GetoptError
-from sys import argv, exc_info
-from syslog import openlog, LOG_LOCAL0, syslog, LOG_INFO, LOG_ERR
-from Bcfg2.Server.Core import Core, CoreInitError
-from Bcfg2.Server.Metadata import MetadataConsistencyError
-from Bcfg2.Server.Component import Component
-from threading import Lock
-from select import select, error as selecterror
-from signal import signal, SIGINT, SIGTERM
-from traceback import extract_tb
-from xmlrpclib import Fault
-from socket import gethostbyaddr, herror
-from lxml.etree import XML, Element, tostring
-from M2Crypto.SSL import SSLError
-
-import os, sys
-
-def daemonize(filename):
- '''Do the double fork/setsession dance'''
- # Fork once
- if os.fork() != 0:
- os._exit(0)
- os.setsid() # Create new session
- pid = os.fork()
- if pid != 0:
- pidfile = open(filename, "w")
- pidfile.write("%i" % pid)
- pidfile.close()
- os._exit(0)
- os.chdir("/")
- os.umask(0)
-
- null = open("/dev/null", "w+")
-
- os.dup2(null.fileno(), sys.__stdin__.fileno())
- os.dup2(null.fileno(), sys.__stdout__.fileno())
- os.dup2(null.fileno(), sys.__stderr__.fileno())
-
-
-def critical_error(operation):
- '''Print tracebacks in unexpected cases'''
- syslog(LOG_ERR, "Traceback information (please include in any bug report):")
- (ttype, value, trace) = exc_info()
- for line in extract_tb(trace):
- syslog(LOG_ERR, "File %s, line %i, in %s\n %s" % (line))
- syslog(LOG_ERR, "%s: %s" % (ttype, value))
- warning_error("An unexpected failure occurred in %s" % (operation) )
- raise Fault, (7, "Critical unexpected failure: %s" % (operation))
-
-def fatal_error(message):
- '''Signal a fatal error'''
- syslog(LOG_ERR, "Fatal error: %s" % (message))
- raise SystemExit, 1
-
-def warning_error(message):
- '''Warn about a problem but continue'''
- syslog(LOG_ERR,"Warning: %s\n" % (message))
-
-def usage_error(message, opt, vopt, descs, argDescs):
- '''Die because script was called the wrong way'''
- print "Usage error: %s" % (message)
- print_usage(opt, vopt, descs, argDescs)
- raise SystemExit, 2
-
-verboseMode = False
-
-def verbose(message):
- '''Conditionally output information in verbose mode'''
- global verboseMode
-
- if(verboseMode == True):
- syslog(LOG_INFO, "%s" % (message))
-
-def print_usage(opt, vopt, descs, argDescs):
- print "Bcfg2Server usage:"
- for arg in opt.iteritems():
- print " -%s\t\t\t%s" % (arg[0], descs[arg[0]])
- for arg in vopt.iteritems():
- print " -%s %s\t%s" % (arg[0], argDescs[arg[0]], descs[arg[0]])
-
-def dgetopt(arglist, opt, vopt, descs, argDescs):
- '''parse options into a dictionary'''
- global verboseMode
-
- ret = {}
- for optname in opt.values() + vopt.values():
- ret[optname] = False
-
- gstr = "".join(opt.keys()) + "".join([optionkey + ':' for optionkey in vopt.keys()])
- try:
- ginfo = getopt(arglist, gstr)
- except GetoptError, gerr:
- usage_error(gerr, opt, vopt, descs, argDescs)
-
- for (gopt, garg) in ginfo[0]:
- option = gopt[1:]
- if opt.has_key(option):
- ret[opt[option]] = True
- else:
- ret[vopt[option]] = garg
-
- if ret["help"] == True:
- print_usage(opt, vopt, descs, argDescs)
- raise SystemExit, 0
-
- if ret["verbose"] == True:
- verboseMode = True
-
- return ret
-
-class Bcfg2(Component):
- """The Bcfg2 Server component providing XML-RPC access to Bcfg methods"""
- __name__ = 'bcfg2'
- __implementation__ = 'bcfg2'
-
- request_queue_size = 15
-
- def __init__(self, setup):
- Component.__init__(self, setup)
- self.shut = False
- # set shutdown handlers for sigint and sigterm
- signal(SIGINT, self.start_shutdown)
- signal(SIGTERM, self.start_shutdown)
- try:
- self.Core = Core(setup, setup['configfile'])
- self.CoreLock = Lock()
- except CoreInitError, msg:
- fatal_error(msg)
-
- self.funcs.update({
- "GetConfig": self.Bcfg2GetConfig,
- "GetProbes": self.Bcfg2GetProbes,
- "RecvProbeData": self.Bcfg2RecvProbeData,
- "RecvStats": self.Bcfg2RecvStats
- })
- for plugin in self.Core.plugins.values():
- for method in plugin.__rmi__:
- self.register_function(getattr(self.Core.plugins[plugin.__name__], method),
- "%s.%s" % (plugin.__name__, method))
-
- def get_request(self):
- '''We need to do work between requests, so select with timeout instead of blocking in accept'''
- rsockinfo = []
- famfd = self.Core.fam.fileno()
- while self.socket not in rsockinfo:
- if self.shut:
- raise SSLError
- try:
- rsockinfo = select([self.socket, famfd], [], [], 15)[0]
- except selecterror:
- raise SSLError
-
- if famfd in rsockinfo:
- self.Core.fam.Service()
- if self.socket in rsockinfo:
- # workaround for m2crypto 0.15 bug
- self.socket.postConnectionCheck = None
- return self.socket.accept()
-
- def serve_forever(self):
- """Handle one request at a time until doomsday."""
- while not self.shut:
- self.handle_request()
-
- def start_shutdown(self, signum, frame):
- '''Shutdown on unexpected signals'''
- self.shut = True
-
- def handle_error(self):
- '''Catch error path for clean exit'''
- return False
-
- def resolve_client(self, client):
- try:
- return gethostbyaddr(client)[0]
- except herror:
- warning = "host resolution error for %s" % (client)
- warning_error(warning)
- raise Fault, (5, warning)
-
- def Bcfg2GetProbes(self, address):
- '''Fetch probes for a particular client'''
- client = self.resolve_client(address[0])
- resp = Element('probes')
-
- try:
- meta = self.Core.metadata.FetchMetadata(client)
-
- for generator in self.Core.generators:
- for probe in generator.GetProbes(meta):
- resp.append(probe)
- return tostring(resp)
- except MetadataConsistencyError:
- warning = 'metadata consistency error'
- warning_error(warning)
- raise Fault, (6, warning)
- except:
- critical_error("determining client probes")
-
-
- def Bcfg2RecvProbeData(self, address, probedata):
- '''Receive probe data from clients'''
- client = self.resolve_client(address[0])
-
- for data in probedata:
- try:
- [generator] = [gen for gen in self.Core.generators if gen.__name__ == data.get('source')]
- generator.ReceiveData(client, data)
- except IndexError:
- warning_error("Failed to locate plugin %s" % (data.get('source')))
- except:
- critical_error("probe data receipt")
- return True
-
- def Bcfg2GetConfig(self, address, image=False, profile=False):
- '''Build config for a client'''
- client = self.resolve_client(address[0])
-
- if image and profile:
- try:
- self.Core.metadata.set_group(client, profile)
- except MetadataConsistencyError:
- warning = 'metadata consistency error'
- warning_error(warning)
- raise Fault, (6, warning)
- return tostring(self.Core.BuildConfiguration(client))
-
- def Bcfg2RecvStats(self, address, stats):
- '''Act on statistics upload'''
- sdata = XML(stats)
- state = sdata.find(".//Statistics")
- # Versioned stats to prevent tied client/server upgrade
- if state.get('version') >= '2.0':
- client = self.resolve_client(address[0])
-
- # Update statistics
- self.Core.stats.updateStats(sdata, client)
-
- verbose("Client %s reported state %s" %
- (client, state.attrib['state']))
- return "<ok/>"
-
-if __name__ == '__main__':
- openlog("Bcfg2", 0, LOG_LOCAL0)
- options = {
- 'v':'verbose',
- 'd':'debug',
- 'h':'help'
- }
- doptions = {
- 'D':'daemon',
- 'c':'configfile',
- 'C':'client'
- }
-
- descriptions = {
- 'v': "enable verbose output",
- 'd': "enable debugging output",
- 'D': "daemonise the server, storing PID",
- 'c': "set the server's config file",
- 'C': "always return the given client's config (debug only)",
- 'h': "display this usage information"
- }
-
- argDescriptions = {
- 'D': "<PID file> ",
- 'c': "<config file>",
- 'C': "<client hostname>"
- }
-
- ssetup = dgetopt(argv[1:], options, doptions,
- descriptions, argDescriptions)
- if ssetup['daemon']:
- daemonize(ssetup['daemon'])
- if not ssetup['configfile']:
- ssetup['configfile'] = '/etc/bcfg2.conf'
- s = Bcfg2(ssetup)
- while not s.shut:
- try:
- s.serve_forever()
- except:
- critical_error("service loop")
-
- syslog(LOG_INFO, "Shutting down")