diff options
-rw-r--r-- | cobbler/action_check.py | 2 | ||||
-rw-r--r-- | cobbler/api.py | 11 | ||||
-rw-r--r-- | cobbler/cobblerd.py | 170 | ||||
-rw-r--r-- | cobbler/remote.py | 107 | ||||
-rw-r--r-- | cobbler/settings.py | 3 | ||||
-rw-r--r-- | cobbler/utils.py | 7 | ||||
-rw-r--r-- | config/cobbler.conf | 9 | ||||
-rw-r--r-- | installer_templates/settings.template | 17 | ||||
-rwxr-xr-x | scripts/cobblerd | 17 | ||||
-rwxr-xr-x | scripts/index.py | 4 |
10 files changed, 101 insertions, 246 deletions
diff --git a/cobbler/action_check.py b/cobbler/action_check.py index 3835c4ce..8b88e1ea 100644 --- a/cobbler/action_check.py +++ b/cobbler/action_check.py @@ -117,7 +117,7 @@ class BootCheck: if os.path.exists("/etc/rc.d/init.d/iptables"): rc = sub_process.call("/sbin/service iptables status >/dev/null 2>/dev/null", shell=True, close_fds=True) if rc == 0: - status.append(_("since iptables may be running, ensure 69, 80, %(syslog)s, and %(xmlrpc)s are unblocked") % { "syslog" : self.settings.syslog_port, "xmlrpc" : self.settings.xmlrpc_port }) + status.append(_("since iptables may be running, ensure 69, 80, and %(xmlrpc)s are unblocked") % { "xmlrpc" : self.settings.xmlrpc_port }) def check_yum(self,status): if not os.path.exists("/usr/bin/createrepo"): diff --git a/cobbler/api.py b/cobbler/api.py index 89e792a7..0c2effc2 100644 --- a/cobbler/api.py +++ b/cobbler/api.py @@ -155,15 +155,14 @@ class BootAPI: # FIXME: take value from settings, use raw port if self.is_cobblerd: # don't signal yourself, that's asking for trouble. + self.logger.debug("I'm coming from cobblerd") return True - self.server_normal = xmlrpclib.Server("http://127.0.0.1:25151") - self.server_rw = xmlrpclib.Server("http://127.0.0.1:25152") + self.logger.debug("I'm not coming from cobblerd, here we go") + self.server = xmlrpclib.Server("http://127.0.0.1:25151") if not remove: - self.server_normal.internal_cache_update(collection_type, name) - self.server_rw.internal_cache_update(collection_type, name) + self.server.internal_cache_update(collection_type, name) else: - self.server_normal.internal_cache_remove(collection_type, name) - self.server_rw.internal_cache_remove(collection_type, name) + self.server.internal_cache_remove(collection_type, name) return False def last_modified_time(self): diff --git a/cobbler/cobblerd.py b/cobbler/cobblerd.py index 36645750..4ac711ce 100644 --- a/cobbler/cobblerd.py +++ b/cobbler/cobblerd.py @@ -41,25 +41,17 @@ import remote def main(): core(logger=None) -def core(logger=None): +def core(log_settings={}): - bootapi = cobbler_api.BootAPI() + bootapi = cobbler_api.BootAPI(log_settings=log_settings,is_cobblerd=True) settings = bootapi.settings() - syslog_port = settings.syslog_port xmlrpc_port = settings.xmlrpc_port - xmlrpc_port2 = settings.xmlrpc_rw_port pid = os.fork() regen_ss_file() - if pid == 0: - # part one: XMLRPC -- which may be just read-only or both read-only and read-write - do_xmlrpc_tasks(bootapi, settings, xmlrpc_port, xmlrpc_port2, logger) - else: - # part two: syslog, or syslog+avahi if avahi is installed - do_other_tasks(bootapi, settings, syslog_port, logger) - os.waitpid(pid, 0) + do_xmlrpc_tasks(bootapi, settings, xmlrpc_port) def regen_ss_file(): # this is only used for Kerberos auth at the moment. @@ -76,44 +68,23 @@ def regen_ss_file(): os.system("chown apache /var/lib/cobbler/web.ss") return 1 -def do_xmlrpc_tasks(bootapi, settings, xmlrpc_port, xmlrpc_port2, logger): - if str(settings.xmlrpc_rw_enabled) != "0": - pid2 = os.fork() - if pid2 == 0: - do_mandatory_xmlrpc_tasks(bootapi, settings, xmlrpc_port, logger) - else: - do_xmlrpc_rw(bootapi, settings, xmlrpc_port2, logger) - os.waitpid(pid2, 0) - else: - logger.debug("xmlrpc_rw is disabled in the settings file") - do_mandatory_xmlrpc_tasks(bootapi, settings, xmlrpc_port, logger) - -def do_mandatory_xmlrpc_tasks(bootapi,settings,xmlrpc_port,logger): - #pid3 = os.fork() - #if pid3 == 0: - # do_xmlrpc(bootapi, settings, xmlrpc_port, logger) - #else: - # # NOTE: this shouldn't be enabled unless we decide - # # to use it for something. - # # do_xmlrpc_unix(bootapi, settings, logger) - # pass - do_xmlrpc(bootapi, settings, xmlrpc_port, logger) - - -def do_other_tasks(bootapi, settings, syslog_port, logger): - - # FUTURE: this should also start the Web UI, if the dependencies - # are available. - - if os.path.exists("/usr/bin/avahi-publish-service"): - pid2 = os.fork() - if pid2 == 0: - do_syslog(bootapi, settings, syslog_port, logger) - else: - do_avahi(bootapi, settings, logger) - os.waitpid(pid2, 0) - else: - do_syslog(bootapi, settings, syslog_port, logger) +def do_xmlrpc_tasks(bootapi, settings, xmlrpc_port): + do_xmlrpc_rw(bootapi, settings, xmlrpc_port) + +#def do_other_tasks(bootapi, settings, syslog_port, logger): +# +# # FUTURE: this should also start the Web UI, if the dependencies +# # are available. +# +# if os.path.exists("/usr/bin/avahi-publish-service"): +# pid2 = os.fork() +# if pid2 == 0: +# do_syslog(bootapi, settings, syslog_port, logger) +# else: +# do_avahi(bootapi, settings, logger) +# os.waitpid(pid2, 0) +# else: +# do_syslog(bootapi, settings, syslog_port, logger) def log(logger,msg): @@ -122,59 +93,24 @@ def log(logger,msg): else: print >>sys.stderr, msg -def do_avahi(bootapi, settings, logger): - # publish via zeroconf. This command will not terminate - log(logger, "publishing avahi service") - cmd = [ "/usr/bin/avahi-publish-service", - "cobblerd", - "_http._tcp", - "%s" % settings.xmlrpc_port ] - proc = sub_process.Popen(cmd, shell=False, stderr=sub_process.PIPE, stdout=sub_process.PIPE, close_fds=True) - proc.communicate()[0] - log(logger, "avahi service terminated") - - -def do_xmlrpc(bootapi, settings, port, logger): - - # This is the simple XMLRPC API we provide to koan and other - # apps that do not need to manage Cobbler's config - - xinterface = remote.ProxiedXMLRPCInterface(bootapi,logger,remote.CobblerXMLRPCInterface,False) - - server = remote.CobblerXMLRPCServer(('', port)) - server.logRequests = 0 # don't print stuff - log(logger, "XMLRPC running on %s" % port) - server.register_instance(xinterface) - - while True: - try: - server.serve_forever() - except IOError: - # interrupted? try to serve again - time.sleep(0.5) - -def do_xmlrpc_rw(bootapi,settings,port,logger): - - xinterface = remote.ProxiedXMLRPCInterface(bootapi,logger,remote.CobblerReadWriteXMLRPCInterface,True) - server = remote.CobblerReadWriteXMLRPCServer(('127.0.0.1', port)) - server.logRequests = 0 # don't print stuff - logger.debug("XMLRPC (read-write variant) running on %s" % port) - server.register_instance(xinterface) +#def do_avahi(bootapi, settings, logger): +# # publish via zeroconf. This command will not terminate +# log(logger, "publishing avahi service") +# cmd = [ "/usr/bin/avahi-publish-service", +# "cobblerd", +# "_http._tcp", +# "%s" % settings.xmlrpc_port ] +# proc = sub_process.Popen(cmd, shell=False, stderr=sub_process.PIPE, stdout=sub_process.PIPE, close_fds=True) +# proc.communicate()[0] +# log(logger, "avahi service terminated") - while True: - try: - server.serve_forever() - except IOError: - # interrupted? try to serve again - time.sleep(0.5) -def do_xmlrpc_unix(bootapi,settings,logger): +def do_xmlrpc_rw(bootapi,settings,port): - xinterface = remote.ProxiedXMLRPCInterface(bootapi,logger,remote.CobblerReadWriteXMLRPCInterface,True) - SOCKT = "/var/lib/cobbler/sock" - server = xmlrpclib2.UnixXMLRPCServer(SOCKT) + xinterface = remote.ProxiedXMLRPCInterface(bootapi,remote.CobblerXMLRPCInterface,True) + server = remote.CobblerXMLRPCServer(('127.0.0.1', port)) server.logRequests = 0 # don't print stuff - logger.debug("XMLRPC (socket variant) available on %s" % SOCKT) + #logger.debug("XMLRPC running on %s" % port) server.register_instance(xinterface) while True: @@ -184,44 +120,6 @@ def do_xmlrpc_unix(bootapi,settings,logger): # interrupted? try to serve again time.sleep(0.5) -def do_syslog(bootapi, settings, port, logger): - - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - s.bind(("0.0.0.0", port)) - log(logger, "syslog running on %s" % port) - - buf = 1024 - - while 1: - data, addr = s.recvfrom(buf) - (ip, port) = addr - system = bootapi.systems().find(ip_address = ip) - if not system: - usename = ip - else: - usename = system.name - - if not data: - break - else: - logfile = open("/var/log/cobbler/syslog/%s" % usename, "a+") - t = time.localtime() - # write numeric time - seconds = str(time.mktime(t)) - logfile.write(seconds) - logfile.write("\t") - # write string time - timestr = str(time.asctime(t)) - logfile.write(timestr) - logfile.write("\t") - # write the IP address of the client - logfile.write(ip) - logfile.write("\t") - # write the data - logfile.write(data) - logfile.write("\n") - logfile.close() - if __name__ == "__main__": #main() diff --git a/cobbler/remote.py b/cobbler/remote.py index 3d93bbd3..e3a57b32 100644 --- a/cobbler/remote.py +++ b/cobbler/remote.py @@ -120,21 +120,23 @@ class DataCache: class CobblerXMLRPCInterface: """ - This is the interface used for all public XMLRPC methods, for instance, - as used by koan. The read-write interface which inherits from this adds - more methods, though that interface can be disabled. + This is the interface used for all XMLRPC methods, for instance, + as used by koan or CobblerWeb note: public methods take an optional parameter token that is just - here for consistancy with the ReadWrite API. The tokens for the read only - interface are intentionally /not/ validated. It's a public API. + here for consistancy with the ReadWrite API. Read write operations do + require the token. """ - def __init__(self,api,logger,enable_auth_if_relevant): + def __init__(self,api,enable_auth_if_relevant): self.api = api - self.logger = logger self.auth_enabled = enable_auth_if_relevant - self.timestamp = self.api.last_modified_time() self.cache = DataCache(self.api) + self.logger = self.api.logger + self.token_cache = TOKEN_CACHE + self.object_cache = OBJECT_CACHE + self.timestamp = self.api.last_modified_time() + random.seed(time.time()) def __sorter(self,a,b): return cmp(a["name"],b["name"]) @@ -859,51 +861,11 @@ class CobblerXMLRPCInterface: """ return self.api.status() -# ********************************************************************************* -# ********************************************************************************* - -class CobblerXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer): - def __init__(self, args): - self.allow_reuse_address = True - SimpleXMLRPCServer.SimpleXMLRPCServer.__init__(self,args) - -# ********************************************************************************* -# ********************************************************************************* - - -class ProxiedXMLRPCInterface: - - def __init__(self,api,logger,proxy_class,enable_auth_if_relevant=True): - self.logger = logger - self.proxied = proxy_class(api,logger,enable_auth_if_relevant) - - def _dispatch(self, method, params, **rest): - - if not hasattr(self.proxied, method): - self.logger.error("remote:unknown method %s" % method) - raise CX(_("Unknown remote method")) - - method_handle = getattr(self.proxied, method) - - try: - return method_handle(*params) - except Exception, e: - utils.log_exc(self.logger) - raise e - -# ********************************************************************** + ###### + # READ WRITE METHODS BELOW REQUIRE A TOKEN, use login() + # TO OBTAIN ONE + ###### -class CobblerReadWriteXMLRPCInterface(CobblerXMLRPCInterface): - - def __init__(self,api,logger,enable_auth_if_relevant): - self.api = api - self.auth_enabled = enable_auth_if_relevant - self.cache = DataCache(self.api) - self.logger = logger - self.token_cache = TOKEN_CACHE - self.object_cache = OBJECT_CACHE - self.timestamp = self.api.last_modified_time() - random.seed(time.time()) def __next_id(self,retry=0): """ @@ -1545,18 +1507,40 @@ class CobblerReadWriteXMLRPCInterface(CobblerXMLRPCInterface): return rc -# ********************************************************************* -# ********************************************************************* -class CobblerReadWriteXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer): - """ - This is just a wrapper used for launching the Read/Write XMLRPC Server. - """ + +# ********************************************************************************* +# ********************************************************************************* + +class CobblerXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer): def __init__(self, args): self.allow_reuse_address = True SimpleXMLRPCServer.SimpleXMLRPCServer.__init__(self,args) +# ********************************************************************************* +# ********************************************************************************* + + +class ProxiedXMLRPCInterface: + + def __init__(self,api,proxy_class,enable_auth_if_relevant=True): + self.proxied = proxy_class(api,enable_auth_if_relevant) + + def _dispatch(self, method, params, **rest): + + if not hasattr(self.proxied, method): + self.logger.error("remote:unknown method %s" % method) + raise CX(_("Unknown remote method")) + + method_handle = getattr(self.proxied, method) + + try: + return method_handle(*params) + except Exception, e: + utils.log_exc(self.logger) + raise e + # ********************************************************************* # ********************************************************************* @@ -1609,7 +1593,7 @@ def _test_bootstrap_restart(): def _test_remove_objects(): - api = cobbler_api.BootAPI() + api = cobbler_api.BootAPI() # local handle # from ro tests d0 = api.find_distro("distro0") @@ -1654,8 +1638,7 @@ def test_xmlrpc_ro(): # now populate with something more useful # using the non-remote API - api = cobbler_api.BootAPI() - api.deserialize() # FIXME: redundant + api = cobbler_api.BootAPI() # local handle before_distros = len(api.distros()) before_profiles = len(api.profiles()) @@ -1890,7 +1873,7 @@ def test_xmlrpc_rw(): _test_setup_modules(authn="authn_testing",authz="authz_allowall") _test_bootstrap_restart() - server = xmlrpclib.Server("http://127.0.0.1/cobbler_api_rw") # remote + server = xmlrpclib.Server("http://127.0.0.1/cobbler_api") # remote api = cobbler_api.BootAPI() # local instance, /DO/ ping cobblerd # note if authn_testing is not engaged this will not work diff --git a/cobbler/settings.py b/cobbler/settings.py index 54b5b0b9..c43987ab 100644 --- a/cobbler/settings.py +++ b/cobbler/settings.py @@ -94,15 +94,12 @@ DEFAULTS = { "run_install_triggers" : 1, "server" : "127.0.0.1", "snippetsdir" : "/var/lib/cobbler/snippets", - "syslog_port" : 25150, "tftpd_bin" : "/usr/sbin/in.tftpd", "tftpd_conf" : "/etc/xinetd.d/tftp", "tftpd_rules" : "/etc/tftpd.rules", "vsftpd_bin" : "/usr/sbin/vsftpd", "webdir" : "/var/www/cobbler", "xmlrpc_port" : 25151, - "xmlrpc_rw_enabled" : 1, - "xmlrpc_rw_port" : 25152, "yum_post_install_mirror" : 1, "yumdownloader_flags" : "--resolve", "yumreposync_flags" : "-l", diff --git a/cobbler/utils.py b/cobbler/utils.py index 94543d9c..7b7ef72f 100644 --- a/cobbler/utils.py +++ b/cobbler/utils.py @@ -453,13 +453,6 @@ def blender(api_handle,remove_hashes, root_obj): for node in tree: __consolidate(node,results) - # add in syslog to results (magic) - if settings.syslog_port != 0: - if not results.has_key("kernel_options"): - results["kernel_options"] = {} - syslog = "%s:%s" % (results["server"], settings.syslog_port) - results["kernel_options"]["syslog"] = syslog - # determine if we have room to add kssendmac to the kernel options line kernel_txt = hash_to_string(results["kernel_options"]) if len(kernel_txt) < 244: diff --git a/config/cobbler.conf b/config/cobbler.conf index 00e4913e..a63b1e90 100644 --- a/config/cobbler.conf +++ b/config/cobbler.conf @@ -16,10 +16,13 @@ ProxyRequests off ProxyPass /cobbler_api http://localhost:25151/ ProxyPassReverse /cobbler_api http://localhost:25151/ -# TO DO: SSL +# The following API endpoint is for compatibility access and +# is exactly the same as cobbler_api now as an endpoint. +# This is deprecated and may disappear in Cobbler 1.7/1.8 +# notice nothing no longer listens on 25152 -ProxyPass /cobbler_api_rw http://localhost:25152/ -ProxyPassReverse /cobbler_api_rw http://localhost:25152/ +ProxyPass /cobbler_api_rw http://localhost:25151/ +ProxyPassReverse /cobbler_api_rw http://localhost:25151/ BrowserMatch "MSIE" AuthDigestEnableQueryStringHack=On diff --git a/installer_templates/settings.template b/installer_templates/settings.template index 19e5c6d3..dbbb08de 100644 --- a/installer_templates/settings.template +++ b/installer_templates/settings.template @@ -279,13 +279,6 @@ server: $server # this directory should not be required. snippetsdir: /var/lib/cobbler/snippets -# by default, installs are set to send syslog traffic on this port -# and cobblerd will listen on this port. syslog data (for installs -# that support it... RHEL 5 and later, etc) is logged in /var/log/cobbler -# and can be used to help debug problematic installations. Syslog -# is UDP and may not be available depending on network/firewall configuration. -syslog_port: 25150 - # by default, installs are *not* set to send installation logs to the cobbler # server. With 'anamon_enabled', kickstart templates may use the pre_anamon # snippet to allow remote live monitoring of their installations from the @@ -309,16 +302,6 @@ webdir: /var/www/cobbler # port option to koan if it is not the default. xmlrpc_port: 25151 -# cobbler's read write XMLRPC is the version of XMLRPC -# used by the WebUI and some features like system registration. -# XMLRPC connections here require login information to access. -# this feature can be disabled to gain increased security but -# will disable the WebUI, registration, and potentially other -# cobbler features. Most users should leave XMLRPC RW -# enabled. The port can be relocated if needed. -xmlrpc_rw_enabled: 1 -xmlrpc_rw_port: 25152 - # "cobbler repo add" commands set cobbler up with repository # information that can be used during kickstart and is automatically # set up in the cobbler kickstart templates. By default, these diff --git a/scripts/cobblerd b/scripts/cobblerd index a9e7312d..358d7b61 100755 --- a/scripts/cobblerd +++ b/scripts/cobblerd @@ -21,12 +21,13 @@ import cobbler.cobblerd as app import logging import cobbler.utils as utils import cobbler.sub_process as sub_process +import traceback import optparse -def daemonize_self(logger): +def daemonize_self(): # daemonizing code: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012 - logger.info("cobblerd started") + # logger.info("cobblerd started") try: pid = os.fork() if pid > 0: @@ -34,7 +35,7 @@ def daemonize_self(logger): sys.exit(0) except OSError, e: print >>sys.stderr, "fork #1 failed: %d (%s)" % (e.errno, e.strerror) - utils.log_exc(logger) + #utils.log_exc(logger) sys.exit(1) # decouple from parent environment @@ -50,7 +51,7 @@ def daemonize_self(logger): sys.exit(0) except OSError, e: print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror) - utils.log_exc(logger) + #utils.log_exc(logger) sys.exit(1) dev_null = file('/dev/null','rw') @@ -80,16 +81,14 @@ def main(): if not isinstance(log_level, int): op.error('Unrecognized log level %r given') log_settings['log_level'] = log_level - api = bootapi.BootAPI(log_settings=log_settings, is_cobblerd=True) - logger = api.logger if options.daemonize: - daemonize_self(logger) + daemonize_self() try: - app.core(logger=logger) + app.core() except: - utils.log_exc(logger) + traceback.print_exc() if __name__ == "__main__": main() diff --git a/scripts/index.py b/scripts/index.py index 26b86f36..bf3b17c9 100755 --- a/scripts/index.py +++ b/scripts/index.py @@ -23,7 +23,7 @@ from cobbler.webui import CobblerWeb import cobbler.utils as utils import cobbler.yaml as yaml -XMLRPC_SERVER = "http://127.0.0.1:25152" # was http://127.0.0.1/cobbler_api_rw" +XMLRPC_SERVER = "http://127.0.0.1:25151" # FIXME: pull port from settings #======================================= @@ -110,7 +110,7 @@ def handler(req): data = fd.read() fd.close() ydata = yaml.load(data).next() - remote_port = ydata.get("xmlrpc_rw_port", 25152) + remote_port = ydata.get("xmlrpc_port", 25151) mode = form.get('mode','index') |