diff options
author | Chris St. Pierre <chris.a.st.pierre@gmail.com> | 2013-11-11 15:46:09 -0500 |
---|---|---|
committer | Chris St. Pierre <chris.a.st.pierre@gmail.com> | 2013-11-11 15:46:09 -0500 |
commit | e30c785c94c5aa399c44fff386fa2279f64f1acc (patch) | |
tree | e72c636dcae00a6ea0c668cfbee7d3e6b4e6a3fe /src/lib/Bcfg2 | |
parent | 7aa15c4c5507e311ff66264bc31e6758a80eb337 (diff) | |
parent | 103b1b5198828876fa0684296900769018075f1b (diff) | |
download | bcfg2-e30c785c94c5aa399c44fff386fa2279f64f1acc.tar.gz bcfg2-e30c785c94c5aa399c44fff386fa2279f64f1acc.tar.bz2 bcfg2-e30c785c94c5aa399c44fff386fa2279f64f1acc.zip |
Merge branch 'maint'
Conflicts:
src/lib/Bcfg2/Server/Admin/Compare.py
src/lib/Bcfg2/Server/Admin/Snapshots.py
src/lib/Bcfg2/Server/MultiprocessingCore.py
src/lib/Bcfg2/Server/Plugins/Probes.py
src/sbin/bcfg2-crypt
src/sbin/bcfg2-reports
tools/upgrade/1.3/migrate_configs.py
tools/upgrade/1.3/migrate_perms_to_mode.py
Diffstat (limited to 'src/lib/Bcfg2')
-rw-r--r-- | src/lib/Bcfg2/Reporting/templates/base.html | 2 | ||||
-rwxr-xr-x | src/lib/Bcfg2/Server/Encryption.py | 34 | ||||
-rw-r--r-- | src/lib/Bcfg2/Server/MultiprocessingCore.py | 35 | ||||
-rw-r--r-- | src/lib/Bcfg2/Server/Plugins/Probes.py | 14 | ||||
-rw-r--r-- | src/lib/Bcfg2/version.py | 2 |
5 files changed, 53 insertions, 34 deletions
diff --git a/src/lib/Bcfg2/Reporting/templates/base.html b/src/lib/Bcfg2/Reporting/templates/base.html index 0b2b7dd36..7edf3a949 100644 --- a/src/lib/Bcfg2/Reporting/templates/base.html +++ b/src/lib/Bcfg2/Reporting/templates/base.html @@ -93,7 +93,7 @@ This is needed for Django versions less than 1.5 <div style='clear:both'></div> </div><!-- document --> <div id="footer"> - <span>Bcfg2 Version 1.3.2</span> + <span>Bcfg2 Version 1.3.3</span> </div> <div id="calendar_div" style='position:absolute; visibility:hidden; background-color:white; layer-background-color:white;'></div> diff --git a/src/lib/Bcfg2/Server/Encryption.py b/src/lib/Bcfg2/Server/Encryption.py index c0c2816ac..02c7a0eb8 100755 --- a/src/lib/Bcfg2/Server/Encryption.py +++ b/src/lib/Bcfg2/Server/Encryption.py @@ -197,6 +197,33 @@ def bruteforce_decrypt(crypted, passphrases=None, algorithm=None): raise EVPError("Failed to decrypt") +def print_xml(element, keep_text=False): + """ Render an XML element for error output. This prefixes the + line number and removes children for nicer display. + + :param element: The element to render + :type element: lxml.etree._Element + :param keep_text: Do not discard text content from the element for + display + :type keep_text: boolean + """ + xml = None + if len(element) or element.text: + el = copy.copy(element) + if el.text and not keep_text: + el.text = '...' + for child in el.iterchildren(): + el.remove(child) + xml = lxml.etree.tostring( + el, + xml_declaration=False).decode("UTF-8").strip() + else: + xml = lxml.etree.tostring( + element, + xml_declaration=False).decode("UTF-8").strip() + return "%s (line %s)" % (xml, element.sourceline) + + class PassphraseError(Exception): """ Exception raised when there's a problem determining the passphrase to encrypt or decrypt with """ @@ -403,6 +430,7 @@ class PropertiesEncryptor(Encryptor, PropertiesCryptoMixin): except PassphraseError: self.logger.error(str(sys.exc_info()[1])) return False + self.logger.debug("Encrypting %s" % print_xml(elt)) elt.text = ssl_encrypt(elt.text, passphrase).strip() elt.set("encrypted", pname) return xdata @@ -423,10 +451,14 @@ class PropertiesDecryptor(Decryptor, PropertiesCryptoMixin): except PassphraseError: self.logger.error(str(sys.exc_info()[1])) return False - decrypted = ssl_decrypt(elt.text, passphrase).strip() + self.logger.debug("Decrypting %s" % print_xml(elt)) try: + decrypted = ssl_decrypt(elt.text, passphrase).strip() elt.text = decrypted.encode('ascii', 'xmlcharrefreplace') elt.set("encrypted", pname) + except Bcfg2.Encryption.EVPError: + self.logger.error("Could not decrypt %s, skipping" % + print_xml(elt)) except UnicodeDecodeError: # we managed to decrypt the value, but it contains # content that can't even be encoded into xml diff --git a/src/lib/Bcfg2/Server/MultiprocessingCore.py b/src/lib/Bcfg2/Server/MultiprocessingCore.py index 58a05c85d..f58d53c42 100644 --- a/src/lib/Bcfg2/Server/MultiprocessingCore.py +++ b/src/lib/Bcfg2/Server/MultiprocessingCore.py @@ -19,7 +19,7 @@ import Bcfg2.Options import Bcfg2.Server.Cache import Bcfg2.Server.Plugin from itertools import cycle -from Bcfg2.Compat import Queue, Empty, wraps +from Bcfg2.Compat import Empty, wraps from Bcfg2.Server.Core import Core, exposed from Bcfg2.Server.BuiltinCore import BuiltinCore from multiprocessing.connection import Listener, Client @@ -41,8 +41,7 @@ class RPCQueue(Bcfg2.Server.Plugin.Debuggable): Bcfg2.Server.Plugin.Debuggable.__init__(self) self._terminate = threading.Event() self._queues = dict() - self._available_listeners = Queue() - self._blocking_listeners = [] + self._listeners = [] def add_subscriber(self, name): """ Add a subscriber to the queue. This returns the @@ -63,23 +62,14 @@ class RPCQueue(Bcfg2.Server.Plugin.Debuggable): :class:`multiprocessing.connection.Listener` and passes the Listener address to the child as part of the RPC call, so that the child can connect to the Listener to submit its results. - - Listeners are reused when possible to minimize overhead. """ - try: - listener = self._available_listeners.get_nowait() - self.logger.debug("Reusing existing RPC listener at %s" % - listener.address) - except Empty: - listener = Listener() - self.logger.debug("Created new RPC listener at %s" % - listener.address) - self._blocking_listeners.append(listener) + listener = Listener() + self.logger.debug("Created new RPC listener at %s" % listener.address) + self._listeners.append(listener) try: self._queues[dest].put((listener.address, (method, args or [], kwargs or dict()))) conn = listener.accept() - self._blocking_listeners.remove(listener) try: while not self._terminate.is_set(): if conn.poll(self.poll_wait): @@ -87,7 +77,8 @@ class RPCQueue(Bcfg2.Server.Plugin.Debuggable): finally: conn.close() finally: - self._available_listeners.put(listener) + listener.close() + self._listeners.remove(listener) def close(self): """ Close queues and connections. """ @@ -99,21 +90,11 @@ class RPCQueue(Bcfg2.Server.Plugin.Debuggable): # close any listeners that are waiting for connections self.logger.debug("Closing RPC connections") - for listener in self._blocking_listeners: + for listener in self._listeners: self.logger.debug("Closing RPC connection at %s" % listener.address) listener.close() - self.logger.debug("Closing RPC listeners") - try: - while True: - listener = self._available_listeners.get_nowait() - self.logger.debug("Closing RPC listener at %s" % - listener.address) - listener.close() - except Empty: - pass - class DualEvent(object): """ DualEvent is a clone of :class:`threading.Event` that diff --git a/src/lib/Bcfg2/Server/Plugins/Probes.py b/src/lib/Bcfg2/Server/Plugins/Probes.py index ec5c1ab9f..9f2375fcd 100644 --- a/src/lib/Bcfg2/Server/Plugins/Probes.py +++ b/src/lib/Bcfg2/Server/Plugins/Probes.py @@ -175,9 +175,16 @@ class DBProbeStore(ProbeStore, Bcfg2.Server.Plugin.DatabaseBacked): expire_metadata = False for probe, pdata in data.items(): self._datacache[hostname][probe] = pdata - record, created = ProbesDataModel.objects.get_or_create( - hostname=hostname, - probe=probe) + try: + record, created = ProbesDataModel.objects.get_or_create( + hostname=hostname, + probe=probe) + except ProbesDataModel.MultipleObjectsReturned: + ProbesDataModel.objects.filter(hostname=hostname, + probe=probe).delete() + record, created = ProbesDataModel.objects.get_or_create( + hostname=hostname, + probe=probe) expire_metadata |= created if record.data != pdata: record.data = pdata @@ -447,7 +454,6 @@ class Probes(Bcfg2.Server.Plugin.Probing, def GetProbes(self, metadata): return self.probes.get_probe_data(metadata) - @track_statistics() def ReceiveData(self, client, datalist): cgroups = set() cdata = dict() diff --git a/src/lib/Bcfg2/version.py b/src/lib/Bcfg2/version.py index 140fb6937..35d4cfa0a 100644 --- a/src/lib/Bcfg2/version.py +++ b/src/lib/Bcfg2/version.py @@ -2,7 +2,7 @@ import re -__version__ = "1.3.2" +__version__ = "1.3.3" class Bcfg2VersionInfo(tuple): # pylint: disable=E0012,R0924 |