summaryrefslogtreecommitdiffstats
path: root/func
diff options
context:
space:
mode:
authorAdrian Likins <alikins@redhat.com>2008-07-24 16:17:47 -0400
committerAdrian Likins <alikins@redhat.com>2008-07-24 16:17:47 -0400
commitcedd9198d92ed606fe47bb64cfbe8e0a4aa07ec8 (patch)
treee8df842dd72404a2ff7f1ac5974d098af6cbe1db /func
parent01f597a670b3554e96cb3f27b68ad4655d66a50b (diff)
parent2cf553e9375110f7c15b1785bc95b37c07592750 (diff)
Merge branch 'unduping_code'
Diffstat (limited to 'func')
-rw-r--r--func/SSLCommon.py121
-rw-r--r--func/SSLConnection.py165
-rw-r--r--func/certs.py139
-rwxr-xr-xfunc/codes.py1
-rw-r--r--func/commonconfig.py2
-rw-r--r--func/config.py478
-rw-r--r--func/minion/AuthedXMLRPCServer.py2
-rwxr-xr-xfunc/minion/server.py12
-rwxr-xr-xfunc/minion/utils.py95
-rwxr-xr-xfunc/overlord/client.py2
-rwxr-xr-xfunc/utils.py43
11 files changed, 9 insertions, 1051 deletions
diff --git a/func/SSLCommon.py b/func/SSLCommon.py
deleted file mode 100644
index 6959749..0000000
--- a/func/SSLCommon.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 Library General Public License for more details.
-#
-# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# Copyright 2005 Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
-
-import os, sys
-from OpenSSL import SSL
-import SSLConnection
-import httplib
-import socket
-import SocketServer
-
-def our_verify(connection, x509, errNum, errDepth, preverifyOK):
- # print "Verify: errNum = %s, errDepth = %s, preverifyOK = %s" % (errNum, errDepth, preverifyOK)
-
- # preverifyOK should tell us whether or not the client's certificate
- # correctly authenticates against the CA chain
- return preverifyOK
-
-
-def CreateSSLContext(pkey, cert, ca_cert):
- for f in pkey, cert, ca_cert:
- if f and not os.access(f, os.R_OK):
- print "%s does not exist or is not readable." % f
- os._exit(1)
-
- ctx = SSL.Context(SSL.SSLv3_METHOD) # SSLv3 only
- ctx.use_certificate_file(cert)
- ctx.use_privatekey_file(pkey)
- ctx.load_client_ca(ca_cert)
- ctx.load_verify_locations(ca_cert)
- verify = SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT
- ctx.set_verify(verify, our_verify)
- ctx.set_verify_depth(10)
- ctx.set_options(SSL.OP_NO_SSLv2 | SSL.OP_NO_TLSv1)
- return ctx
-
-
-
-class BaseServer(SocketServer.TCPServer):
- allow_reuse_address = 1
-
- def __init__(self, server_addr, req_handler):
- self._quit = False
- self.allow_reuse_address = 1
- SocketServer.TCPServer.__init__(self, server_addr, req_handler)
-
- def stop(self):
- self._quit = True
-
- def serve_forever(self):
- while not self._quit:
- self.handle_request()
- self.server_close()
-
-
-class BaseSSLServer(BaseServer):
- """ SSL-enabled variant """
-
- def __init__(self, server_address, req_handler, pkey, cert, ca_cert, timeout=None):
- self._timeout = timeout
- self.ssl_ctx = CreateSSLContext(pkey, cert, ca_cert)
-
- BaseServer.__init__(self, server_address, req_handler)
-
- sock = socket.socket(self.address_family, self.socket_type)
- con = SSL.Connection(self.ssl_ctx, sock)
- self.socket = SSLConnection.SSLConnection(con)
- if sys.version_info[:3] >= (2, 3, 0):
- self.socket.settimeout(self._timeout)
- self.server_bind()
- self.server_activate()
-
- host, port = self.socket.getsockname()[:2]
- self.server_name = socket.getfqdn(host)
- self.server_port = port
-
-
-class HTTPSConnection(httplib.HTTPConnection):
- "This class allows communication via SSL."
-
- response_class = httplib.HTTPResponse
-
- def __init__(self, host, port=None, ssl_context=None, strict=None, timeout=None):
- httplib.HTTPConnection.__init__(self, host, port, strict)
- self.ssl_ctx = ssl_context
- self._timeout = timeout
-
- def connect(self):
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- con = SSL.Connection(self.ssl_ctx, sock)
- self.sock = SSLConnection.SSLConnection(con)
- if sys.version_info[:3] >= (2, 3, 0):
- self.sock.settimeout(self._timeout)
- self.sock.connect((self.host, self.port))
-
-
-class HTTPS(httplib.HTTP):
- """Compatibility with 1.5 httplib interface
-
- Python 1.5.2 did not have an HTTPS class, but it defined an
- interface for sending http requests that is also useful for
- https.
- """
-
- _connection_class = HTTPSConnection
-
- def __init__(self, host='', port=None, ssl_context=None, strict=None, timeout=None):
- self._setup(self._connection_class(host, port, ssl_context, strict, timeout))
-
diff --git a/func/SSLConnection.py b/func/SSLConnection.py
deleted file mode 100644
index 98ed8a0..0000000
--- a/func/SSLConnection.py
+++ /dev/null
@@ -1,165 +0,0 @@
-# Higher-level SSL objects used by rpclib
-#
-# Copyright (c) 2002 Red Hat, Inc.
-#
-# Author: Mihai Ibanescu <misa@redhat.com>
-# Modifications by Dan Williams <dcbw@redhat.com>
-
-
-from OpenSSL import SSL
-import time, socket, select
-from func.CommonErrors import canIgnoreSSLError
-
-
-class SSLConnection:
- """
- This whole class exists just to filter out a parameter
- passed in to the shutdown() method in SimpleXMLRPC.doPOST()
- """
-
- DEFAULT_TIMEOUT = 20
-
- def __init__(self, conn):
- """
- Connection is not yet a new-style class,
- so I'm making a proxy instead of subclassing.
- """
- self.__dict__["conn"] = conn
- self.__dict__["close_refcount"] = 0
- self.__dict__["closed"] = False
- self.__dict__["timeout"] = self.DEFAULT_TIMEOUT
-
- def __del__(self):
- self.__dict__["conn"].close()
-
- def __getattr__(self,name):
- return getattr(self.__dict__["conn"], name)
-
- def __setattr__(self,name, value):
- setattr(self.__dict__["conn"], name, value)
-
- def settimeout(self, timeout):
- if timeout == None:
- self.__dict__["timeout"] = self.DEFAULT_TIMEOUT
- else:
- self.__dict__["timeout"] = timeout
- self.__dict__["conn"].settimeout(timeout)
-
- def shutdown(self, how=1):
- """
- SimpleXMLRpcServer.doPOST calls shutdown(1),
- and Connection.shutdown() doesn't take
- an argument. So we just discard the argument.
- """
- self.__dict__["conn"].shutdown()
-
- def accept(self):
- """
- This is the other part of the shutdown() workaround.
- Since servers create new sockets, we have to infect
- them with our magic. :)
- """
- c, a = self.__dict__["conn"].accept()
- return (SSLConnection(c), a)
-
- def makefile(self, mode, bufsize):
- """
- We need to use socket._fileobject Because SSL.Connection
- doesn't have a 'dup'. Not exactly sure WHY this is, but
- this is backed up by comments in socket.py and SSL/connection.c
-
- Since httplib.HTTPSResponse/HTTPConnection depend on the
- socket being duplicated when they close it, we refcount the
- socket object and don't actually close until its count is 0.
- """
- self.__dict__["close_refcount"] = self.__dict__["close_refcount"] + 1
- return PlgFileObject(self, mode, bufsize)
-
- def close(self):
- if self.__dict__["closed"]:
- return
- self.__dict__["close_refcount"] = self.__dict__["close_refcount"] - 1
- if self.__dict__["close_refcount"] == 0:
- self.shutdown()
- self.__dict__["conn"].close()
- self.__dict__["closed"] = True
-
- def sendall(self, data, flags=0):
- """
- - Use select() to simulate a socket timeout without setting the socket
- to non-blocking mode.
- - Don't use pyOpenSSL's sendall() either, since it just loops on WantRead
- or WantWrite, consuming 100% CPU, and never times out.
- """
- timeout = self.__dict__["timeout"]
- con = self.__dict__["conn"]
- (read, write, excpt) = select.select([], [con], [], timeout)
- if not con in write:
- raise socket.timeout((110, "Operation timed out."))
-
- starttime = time.time()
- origlen = len(data)
- sent = -1
- while len(data):
- curtime = time.time()
- if curtime - starttime > timeout:
- raise socket.timeout((110, "Operation timed out."))
-
- try:
- sent = con.send(data, flags)
- except SSL.SysCallError, e:
- if e[0] == 32: # Broken Pipe
- self.close()
- sent = 0
- else:
- raise socket.error(e)
- except (SSL.WantWriteError, SSL.WantReadError):
- time.sleep(0.2)
- continue
-
- data = data[sent:]
- return origlen - len(data)
-
- def recv(self, bufsize, flags=0):
- """
- Use select() to simulate a socket timeout without setting the socket
- to non-blocking mode
- """
- timeout = self.__dict__["timeout"]
- con = self.__dict__["conn"]
- (read, write, excpt) = select.select([con], [], [], timeout)
- if not con in read:
- raise socket.timeout((110, "Operation timed out."))
-
- starttime = time.time()
- while True:
- curtime = time.time()
- if curtime - starttime > timeout:
- raise socket.timeout((110, "Operation timed out."))
-
- try:
- return con.recv(bufsize, flags)
- except SSL.ZeroReturnError:
- return None
- except SSL.WantReadError:
- time.sleep(0.2)
- except Exception, e:
- if canIgnoreSSLError(e):
- return None
- else:
- raise e
- return None
-
-
-class PlgFileObject(socket._fileobject):
- def close(self):
- """
- socket._fileobject doesn't actually _close_ the socket,
- which we want it to do, so we have to override.
- """
- try:
- if self._sock:
- self.flush()
- self._sock.close()
- finally:
- self._sock = None
diff --git a/func/certs.py b/func/certs.py
deleted file mode 100644
index 4d6bf15..0000000
--- a/func/certs.py
+++ /dev/null
@@ -1,139 +0,0 @@
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 Library General Public License for more details.
-#
-# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-# Copyright (c) 2007 Red Hat, inc
-#- Written by Seth Vidal skvidal @ fedoraproject.org
-
-from OpenSSL import crypto
-import socket
-import os
-import utils
-
-def_country = 'UN'
-def_state = 'FC'
-def_local = 'Func-ytown'
-def_org = 'func'
-def_ou = 'slave-key'
-
-
-def make_keypair(dest=None):
- pkey = crypto.PKey()
- pkey.generate_key(crypto.TYPE_RSA, 2048)
- if dest:
- destfd = os.open(dest, os.O_RDWR|os.O_CREAT, 0600)
- os.write(destfd, (crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey)))
- os.close(destfd)
-
- return pkey
-
-
-def make_csr(pkey, dest=None, cn=None):
- req = crypto.X509Req()
- req.get_subject()
- subj = req.get_subject()
- subj.C = def_country
- subj.ST = def_state
- subj.L = def_local
- subj.O = def_org
- subj.OU = def_ou
- if cn:
- subj.CN = cn
- else:
- subj.CN = utils.get_hostname()
- subj.emailAddress = 'root@%s' % subj.CN
-
- req.set_pubkey(pkey)
- req.sign(pkey, 'md5')
- if dest:
- destfd = os.open(dest, os.O_RDWR|os.O_CREAT, 0644)
- os.write(destfd, crypto.dump_certificate_request(crypto.FILETYPE_PEM, req))
- os.close(destfd)
-
- return req
-
-
-def retrieve_key_from_file(keyfile):
- fo = open(keyfile, 'r')
- buf = fo.read()
- keypair = crypto.load_privatekey(crypto.FILETYPE_PEM, buf)
- return keypair
-
-
-def retrieve_csr_from_file(csrfile):
- fo = open(csrfile, 'r')
- buf = fo.read()
- csrreq = crypto.load_certificate_request(crypto.FILETYPE_PEM, buf)
- return csrreq
-
-
-def retrieve_cert_from_file(certfile):
- fo = open(certfile, 'r')
- buf = fo.read()
- cert = crypto.load_certificate(crypto.FILETYPE_PEM, buf)
- return cert
-
-
-def create_ca(CN="Func Certificate Authority", ca_key_file=None, ca_cert_file=None):
- cakey = make_keypair(dest=ca_key_file)
- careq = make_csr(cakey, cn=CN)
- cacert = crypto.X509()
- cacert.set_serial_number(0)
- cacert.gmtime_adj_notBefore(0)
- cacert.gmtime_adj_notAfter(60*60*24*365*10) # 10 yrs - hard to beat this kind of cert!
- cacert.set_issuer(careq.get_subject())
- cacert.set_subject(careq.get_subject())
- cacert.set_pubkey(careq.get_pubkey())
- cacert.sign(cakey, 'md5')
- if ca_cert_file:
- destfo = open(ca_cert_file, 'w')
- destfo.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cacert))
- destfo.close()
-
-
-def _get_serial_number(cadir):
- serial = '%s/serial.txt' % cadir
- i = 1
- if os.path.exists(serial):
- f = open(serial, 'r').read()
- f = f.replace('\n','')
- try:
- i = int(f)
- i+=1
- except ValueError, e:
- i = 1
-
- _set_serial_number(cadir, i)
- return i
-
-
-def _set_serial_number(cadir, last):
- serial = '%s/serial.txt' % cadir
- f = open(serial, 'w')
- f.write(str(last) + '\n')
- f.close()
-
-
-def create_slave_certificate(csr, cakey, cacert, cadir, slave_cert_file=None):
- cert = crypto.X509()
- cert.set_serial_number(_get_serial_number(cadir))
- cert.gmtime_adj_notBefore(0)
- cert.gmtime_adj_notAfter(60*60*24*365*10) # 10 yrs - hard to beat this kind of cert!
- cert.set_issuer(cacert.get_subject())
- cert.set_subject(csr.get_subject())
- cert.set_pubkey(csr.get_pubkey())
- cert.sign(cakey, 'md5')
- if slave_cert_file:
- destfo = open(slave_cert_file, 'w')
- destfo.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
- destfo.close()
- return cert
diff --git a/func/codes.py b/func/codes.py
index c6bcb61..ac61ffe 100755
--- a/func/codes.py
+++ b/func/codes.py
@@ -1,3 +1,4 @@
+#!/usr/bin/python
"""
func
diff --git a/func/commonconfig.py b/func/commonconfig.py
index 0f5ea55..9eaaa88 100644
--- a/func/commonconfig.py
+++ b/func/commonconfig.py
@@ -14,7 +14,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
"""
-from config import BaseConfig, BoolOption, Option
+from certmaster.config import BaseConfig, BoolOption, Option
class FuncdConfig(BaseConfig):
diff --git a/func/config.py b/func/config.py
deleted file mode 100644
index e859f4a..0000000
--- a/func/config.py
+++ /dev/null
@@ -1,478 +0,0 @@
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 Library General Public License for more details.
-#
-# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-# Copyright 2002 Duke University
-# filched from yum - menno smits wrote this - he rocks
-
-
-import os
-import sys
-import warnings
-import copy
-import urlparse
-from ConfigParser import NoSectionError, NoOptionError, ConfigParser
-from ConfigParser import ParsingError
-import exceptions
-
-CONFIG_FILE = "/etc/certmaster/certmaster.conf"
-
-class ConfigError(exceptions.Exception):
- def __init__(self, value=None):
- exceptions.Exception.__init__(self)
- self.value = value
- def __str__(self):
- return "%s" %(self.value,)
-
-
-class Option(object):
- '''
- This class handles a single Yum configuration file option. Create
- subclasses for each type of supported configuration option.
-
- Python descriptor foo (__get__ and __set__) is used to make option
- definition easy and consise.
- '''
-
- def __init__(self, default=None):
- self._setattrname()
- self.inherit = False
- self.default = default
-
- def _setattrname(self):
- '''Calculate the internal attribute name used to store option state in
- configuration instances.
- '''
- self._attrname = '__opt%d' % id(self)
-
- def __get__(self, obj, objtype):
- '''Called when the option is read (via the descriptor protocol).
-
- @param obj: The configuration instance to modify.
- @param objtype: The type of the config instance (not used).
- @return: The parsed option value or the default value if the value
- wasn't set in the configuration file.
- '''
- if obj is None:
- return self
-
- return getattr(obj, self._attrname, None)
-
- def __set__(self, obj, value):
- '''Called when the option is set (via the descriptor protocol).
-
- @param obj: The configuration instance to modify.
- @param value: The value to set the option to.
- @return: Nothing.
- '''
- # Only try to parse if its a string
- if isinstance(value, basestring):
- try:
- value = self.parse(value)
- except ValueError, e:
- # Add the field name onto the error
- raise ValueError('Error parsing %r: %s' % (value, str(e)))
-
- setattr(obj, self._attrname, value)
-
- def setup(self, obj, name):
- '''Initialise the option for a config instance.
- This must be called before the option can be set or retrieved.
-
- @param obj: BaseConfig (or subclass) instance.
- @param name: Name of the option.
- '''
- setattr(obj, self._attrname, copy.copy(self.default))
-
- def clone(self):
- '''Return a safe copy of this Option instance
- '''
- new = copy.copy(self)
- new._setattrname()
- return new
-
- def parse(self, s):
- '''Parse the string value to the Option's native value.
-
- @param s: Raw string value to parse.
- @return: Validated native value.
-
- Will raise ValueError if there was a problem parsing the string.
- Subclasses should override this.
- '''
- return s
-
- def tostring(self, value):
- '''Convert the Option's native value to a string value.
-
- @param value: Native option value.
- @return: String representation of input.
-
- This does the opposite of the parse() method above.
- Subclasses should override this.
- '''
- return str(value)
-
-
-def Inherit(option_obj):
- '''Clone an Option instance for the purposes of inheritance. The returned
- instance has all the same properties as the input Option and shares items
- such as the default value. Use this to avoid redefinition of reused
- options.
-
- @param option_obj: Option instance to inherit.
- @return: New Option instance inherited from the input.
- '''
- new_option = option_obj.clone()
- new_option.inherit = True
- return new_option
-
-
-class ListOption(Option):
-
- def __init__(self, default=None):
- if default is None:
- default = []
- super(ListOption, self).__init__(default)
-
- def parse(self, s):
- """Converts a string from the config file to a workable list
-
- Commas and spaces are used as separators for the list
- """
- # we need to allow for the '\n[whitespace]' continuation - easier
- # to sub the \n with a space and then read the lines
- s = s.replace('\n', ' ')
- s = s.replace(',', ' ')
- return s.split()
-
- def tostring(self, value):
- return '\n '.join(value)
-
-
-class UrlOption(Option):
- '''
- This option handles lists of URLs with validation of the URL scheme.
- '''
-
- def __init__(self, default=None, schemes=('http', 'ftp', 'file', 'https'),
- allow_none=False):
- super(UrlOption, self).__init__(default)
- self.schemes = schemes
- self.allow_none = allow_none
-
- def parse(self, url):
- url = url.strip()
-
- # Handle the "_none_" special case
- if url.lower() == '_none_':
- if self.allow_none:
- return None
- else:
- raise ValueError('"_none_" is not a valid value')
-
- # Check that scheme is valid
- (s,b,p,q,f,o) = urlparse.urlparse(url)
- if s not in self.schemes:
- raise ValueError('URL must be %s not "%s"' % (self._schemelist(), s))
-
- return url
-
- def _schemelist(self):
- '''Return a user friendly list of the allowed schemes
- '''
- if len(self.schemes) < 1:
- return 'empty'
- elif len(self.schemes) == 1:
- return self.schemes[0]
- else:
- return '%s or %s' % (', '.join(self.schemes[:-1]), self.schemes[-1])
-
-
-class UrlListOption(ListOption):
- '''
- Option for handling lists of URLs with validation of the URL scheme.
- '''
-
- def __init__(self, default=None, schemes=('http', 'ftp', 'file', 'https')):
- super(UrlListOption, self).__init__(default)
-
- # Hold a UrlOption instance to assist with parsing
- self._urloption = UrlOption(schemes=schemes)
-
- def parse(self, s):
- out = []
- for url in super(UrlListOption, self).parse(s):
- out.append(self._urloption.parse(url))
- return out
-
-
-class IntOption(Option):
- def parse(self, s):
- try:
- return int(s)
- except (ValueError, TypeError), e:
- raise ValueError('invalid integer value')
-
-
-class BoolOption(Option):
- def parse(self, s):
- s = s.lower()
- if s in ('0', 'no', 'false'):
- return False
- elif s in ('1', 'yes', 'true'):
- return True
- else:
- raise ValueError('invalid boolean value')
-
- def tostring(self, value):
- if value:
- return "1"
- else:
- return "0"
-
-
-class FloatOption(Option):
- def parse(self, s):
- try:
- return float(s.strip())
- except (ValueError, TypeError):
- raise ValueError('invalid float value')
-
-
-class SelectionOption(Option):
- '''Handles string values where only specific values are allowed
- '''
- def __init__(self, default=None, allowed=()):
- super(SelectionOption, self).__init__(default)
- self._allowed = allowed
-
- def parse(self, s):
- if s not in self._allowed:
- raise ValueError('"%s" is not an allowed value' % s)
- return s
-
-class BytesOption(Option):
-
- # Multipliers for unit symbols
- MULTS = {
- 'k': 1024,
- 'm': 1024*1024,
- 'g': 1024*1024*1024,
- }
-
- def parse(self, s):
- """Parse a friendly bandwidth option to bytes
-
- The input should be a string containing a (possibly floating point)
- number followed by an optional single character unit. Valid units are
- 'k', 'M', 'G'. Case is ignored.
-
- Valid inputs: 100, 123M, 45.6k, 12.4G, 100K, 786.3, 0
- Invalid inputs: -10, -0.1, 45.6L, 123Mb
-
- Return value will always be an integer
-
- 1k = 1024 bytes.
-
- ValueError will be raised if the option couldn't be parsed.
- """
- if len(s) < 1:
- raise ValueError("no value specified")
-
- if s[-1].isalpha():
- n = s[:-1]
- unit = s[-1].lower()
- mult = self.MULTS.get(unit, None)
- if not mult:
- raise ValueError("unknown unit '%s'" % unit)
- else:
- n = s
- mult = 1
-
- try:
- n = float(n)
- except ValueError:
- raise ValueError("couldn't convert '%s' to number" % n)
-
- if n < 0:
- raise ValueError("bytes value may not be negative")
-
- return int(n * mult)
-
-
-class ThrottleOption(BytesOption):
-
- def parse(self, s):
- """Get a throttle option.
-
- Input may either be a percentage or a "friendly bandwidth value" as
- accepted by the BytesOption.
-
- Valid inputs: 100, 50%, 80.5%, 123M, 45.6k, 12.4G, 100K, 786.0, 0
- Invalid inputs: 100.1%, -4%, -500
-
- Return value will be a int if a bandwidth value was specified or a
- float if a percentage was given.
-
- ValueError will be raised if input couldn't be parsed.
- """
- if len(s) < 1:
- raise ValueError("no value specified")
-
- if s[-1] == '%':
- n = s[:-1]
- try:
- n = float(n)
- except ValueError:
- raise ValueError("couldn't convert '%s' to number" % n)
- if n < 0 or n > 100:
- raise ValueError("percentage is out of range")
- return n / 100.0
- else:
- return BytesOption.parse(self, s)
-
-
-class BaseConfig(object):
- '''
- Base class for storing configuration definitions. Subclass when creating
- your own definitons.
- '''
-
- def __init__(self):
- self._section = None
-
- for name in self.iterkeys():
- option = self.optionobj(name)
- option.setup(self, name)
-
- def __str__(self):
- out = []
- out.append('[%s]' % self._section)
- for name, value in self.iteritems():
- out.append('%s: %r' % (name, value))
- return '\n'.join(out)
-
- def populate(self, parser, section, parent=None):
- '''Set option values from a INI file section.
-
- @param parser: ConfParser instance (or subclass)
- @param section: INI file section to read use.
- @param parent: Optional parent BaseConfig (or subclass) instance to use
- when doing option value inheritance.
- '''
- self.cfg = parser
- self._section = section
-
- for name in self.iterkeys():
- option = self.optionobj(name)
- value = None
- try:
- value = parser.get(section, name)
- except (NoSectionError, NoOptionError):
- # No matching option in this section, try inheriting
- if parent and option.inherit:
- value = getattr(parent, name)
-
- if value is not None:
- setattr(self, name, value)
-
- def optionobj(cls, name):
- '''Return the Option instance for the given name
- '''
- obj = getattr(cls, name, None)
- if isinstance(obj, Option):
- return obj
- else:
- raise KeyError
- optionobj = classmethod(optionobj)
-
- def isoption(cls, name):
- '''Return True if the given name refers to a defined option
- '''
- try:
- cls.optionobj(name)
- return True
- except KeyError:
- return False
- isoption = classmethod(isoption)
-
- def iterkeys(self):
- '''Yield the names of all defined options in the instance.
- '''
- for name, item in self.iteritems():
- yield name
-
- def iteritems(self):
- '''Yield (name, value) pairs for every option in the instance.
-
- The value returned is the parsed, validated option value.
- '''
- # Use dir() so that we see inherited options too
- for name in dir(self):
- if self.isoption(name):
- yield (name, getattr(self, name))
-
- def write(self, fileobj, section=None, always=()):
- '''Write out the configuration to a file-like object
-
- @param fileobj: File-like object to write to
- @param section: Section name to use. If not-specified the section name
- used during parsing will be used.
- @param always: A sequence of option names to always write out.
- Options not listed here will only be written out if they are at
- non-default values. Set to None to dump out all options.
- '''
- # Write section heading
- if section is None:
- if self._section is None:
- raise ValueError("not populated, don't know section")
- section = self._section
-
- # Updated the ConfigParser with the changed values
- cfgOptions = self.cfg.options(section)
- for name,value in self.iteritems():
- option = self.optionobj(name)
- if always is None or name in always or option.default != value or name in cfgOptions :
- self.cfg.set(section,name, option.tostring(value))
- # write the updated ConfigParser to the fileobj.
- self.cfg.write(fileobj)
-
- def getConfigOption(self, option, default=None):
- warnings.warn('getConfigOption() will go away in a future version of Yum.\n'
- 'Please access option values as attributes or using getattr().',
- DeprecationWarning)
- if hasattr(self, option):
- return getattr(self, option)
- return default
-
- def setConfigOption(self, option, value):
- warnings.warn('setConfigOption() will go away in a future version of Yum.\n'
- 'Please set option values as attributes or using setattr().',
- DeprecationWarning)
- if hasattr(self, option):
- setattr(self, option, value)
- else:
- raise ConfigError, 'No such option %s' % option
-
-
-def read_config(config_file, BaseConfigDerived):
- confparser = ConfigParser()
- opts = BaseConfigDerived()
- if os.path.exists(config_file):
- try:
- confparser.read(config_file)
- except ParsingError, e:
- print >> sys.stderr, "Error reading config file: %s" % e
- sys.exit(1)
- opts.populate(confparser, 'main')
- return opts
diff --git a/func/minion/AuthedXMLRPCServer.py b/func/minion/AuthedXMLRPCServer.py
index 8545d15..dc5d23e 100644
--- a/func/minion/AuthedXMLRPCServer.py
+++ b/func/minion/AuthedXMLRPCServer.py
@@ -18,7 +18,7 @@
import sys
import socket
import SimpleXMLRPCServer
-from func import SSLCommon
+from certmaster import SSLCommon
import OpenSSL
import SocketServer
diff --git a/func/minion/server.py b/func/minion/server.py
index 2750afc..36f3262 100755
--- a/func/minion/server.py
+++ b/func/minion/server.py
@@ -27,15 +27,13 @@ from func.config import read_config
from func.commonconfig import FuncdConfig
from certmaster.commonconfig import CMConfig
from func import logger
-from func import certs
+from certmaster import certs
import func.jobthing as jobthing
# our modules
import AuthedXMLRPCServer
import codes
import module_loader
-import func.utils as futils
-import func.minion.utils as fmutils
import func.minion.acls as acls_mod
from certmaster import utils
@@ -139,11 +137,11 @@ class FuncApiMethod:
except codes.FuncException, e:
self.__log_exc()
(t, v, tb) = sys.exc_info()
- rc = futils.nice_exception(t,v,tb)
+ rc = utils.nice_exception(t,v,tb)
except:
self.__log_exc()
(t, v, tb) = sys.exc_info()
- rc = futils.nice_exception(t,v,tb)
+ rc = utils.nice_exception(t,v,tb)
self.logger.debug("Return code for %s: %s" % (self.__name, rc))
return rc
@@ -235,7 +233,7 @@ class FuncSSLXMLRPCServer(AuthedXMLRPCServer.AuthedSSLXMLRPCServer,
return jobthing.minion_async_run(self.get_dispatch_method, method, params)
except:
(t, v, tb) = sys.exc_info()
- rc = futils.nice_exception(t, v, tb)
+ rc = utils.nice_exception(t, v, tb)
return rc
def auth_cb(self, request, client_address):
@@ -250,7 +248,7 @@ def main(argv):
"""
if "daemon" in sys.argv or "--daemon" in sys.argv:
- futils.daemonize("/var/run/funcd.pid")
+ utils.daemonize("/var/run/funcd.pid")
else:
print "serving...\n"
diff --git a/func/minion/utils.py b/func/minion/utils.py
deleted file mode 100755
index e8d1b39..0000000
--- a/func/minion/utils.py
+++ /dev/null
@@ -1,95 +0,0 @@
-"""
-Copyright 2007, Red Hat, Inc
-see AUTHORS
-
-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 os
-import socket
-import string
-import sys
-import time
-import traceback
-import xmlrpclib
-import glob
-
-import codes
-from func import certs
-from func.config import read_config
-from certmaster.commonconfig import MinionConfig
-from func import logger
-
-# "localhost" is a lame hostname to use for a key, so try to get
-# a more meaningful hostname. We do this by connecting to the certmaster
-# and seeing what interface/ip it uses to make that connection, and looking
-# up the hostname for that.
-def get_hostname():
-
- # FIXME: this code ignores http proxies (which granted, we don't
- # support elsewhere either. It also hardcodes the port number
- # for the certmaster for now
- hostname = None
- hostname = socket.gethostname()
- try:
- ip = socket.gethostbyname(hostname)
- except:
- return hostname
- if ip != "127.0.0.1":
- return hostname
-
-
- config_file = '/etc/certmaster/minion.conf'
- minion_config = read_config(config_file, MinionConfig)
-
- server = minion_config.certmaster
- port = 51235
-
- try:
- s = socket.socket()
- s.settimeout(5)
- s.connect((server, port))
- (intf, port) = s.getsockname()
- hostname = socket.gethostbyaddr(intf)[0]
- s.close()
- except:
- s.close()
- raise
-
- return hostname
-
-
-
-# this is kind of handy, so keep it around for now
-# but we really need to fix out server side logging and error
-# reporting so we don't need it
-def trace_me():
- x = traceback.extract_stack()
- bar = string.join(traceback.format_list(x))
- return bar
-
-
-def daemonize(pidfile=None):
- """
- Daemonize this process with the UNIX double-fork trick.
- Writes the new PID to the provided file name if not None.
- """
-
- print pidfile
- pid = os.fork()
- if pid > 0:
- sys.exit(0)
- os.setsid()
- os.umask(0)
- pid = os.fork()
-
-
- if pid > 0:
- if pidfile is not None:
- open(pidfile, "w").write(str(pid))
- sys.exit(0)
diff --git a/func/overlord/client.py b/func/overlord/client.py
index 4cb8216..79ead06 100755
--- a/func/overlord/client.py
+++ b/func/overlord/client.py
@@ -19,6 +19,7 @@ import os
import func.yaml as yaml
from certmaster.commonconfig import CMConfig
+from certmaster import utils
from func.config import read_config, CONFIG_FILE
import sslclient
@@ -28,7 +29,6 @@ import groups
import delegation_tools as dtools
import func.forkbomb as forkbomb
import func.jobthing as jobthing
-import func.utils as utils
from func.CommonErrors import *
# ===================================
diff --git a/func/utils.py b/func/utils.py
index 9577bd9..0e4b4d5 100755
--- a/func/utils.py
+++ b/func/utils.py
@@ -18,49 +18,6 @@ import socket
REMOTE_ERROR = "REMOTE_ERROR"
-def trace_me():
- x = traceback.extract_stack()
- bar = string.join(traceback.format_list(x))
- return bar
-
-def daemonize(pidfile=None):
- """
- Daemonize this process with the UNIX double-fork trick.
- Writes the new PID to the provided file name if not None.
- """
-
- print pidfile
- pid = os.fork()
- if pid > 0:
- sys.exit(0)
- os.setsid()
- os.umask(0)
- pid = os.fork()
-
- if pid > 0:
- if pidfile is not None:
- open(pidfile, "w").write(str(pid))
- sys.exit(0)
-
-def nice_exception(etype, evalue, etb):
- etype = str(etype)
- try:
- lefti = etype.index("'") + 1
- righti = etype.rindex("'")
- nicetype = etype[lefti:righti]
- except:
- nicetype = etype
- nicestack = string.join(traceback.format_list(traceback.extract_tb(etb)))
- return [ REMOTE_ERROR, nicetype, str(evalue), nicestack ]
-
-def get_hostname():
- fqdn = socket.getfqdn()
- host = socket.gethostname()
- if fqdn.find(host) != -1:
- return fqdn
- else:
- return host
-
def is_error(result):
if type(result) != list: