From cb06dcf5fa4d33519d84528088cdd8c7ae395f50 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Tue, 15 Jul 2014 15:37:48 -0500 Subject: Reporting: Fix prune items import and display Signed-off-by: Sol Jerome --- src/lib/Bcfg2/Reporting/Storage/DjangoORM.py | 2 +- src/lib/Bcfg2/Reporting/templates/config_items/item.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/lib/Bcfg2/Reporting') diff --git a/src/lib/Bcfg2/Reporting/Storage/DjangoORM.py b/src/lib/Bcfg2/Reporting/Storage/DjangoORM.py index 2530d2b2b..0bb3111ae 100644 --- a/src/lib/Bcfg2/Reporting/Storage/DjangoORM.py +++ b/src/lib/Bcfg2/Reporting/Storage/DjangoORM.py @@ -167,7 +167,7 @@ class DjangoORM(StorageBase): # TODO - vcs output act_dict['detail_type'] = PathEntry.DETAIL_UNUSED if path_type == 'directory' and entry.get('prune', 'false') == 'true': - unpruned_elist = [e.get('path') for e in entry.findall('Prune')] + unpruned_elist = [e.get('name') for e in entry.findall('Prune')] if unpruned_elist: act_dict['detail_type'] = PathEntry.DETAIL_PRUNED act_dict['details'] = "\n".join(unpruned_elist) diff --git a/src/lib/Bcfg2/Reporting/templates/config_items/item.html b/src/lib/Bcfg2/Reporting/templates/config_items/item.html index b03d48045..c6e6df020 100644 --- a/src/lib/Bcfg2/Reporting/templates/config_items/item.html +++ b/src/lib/Bcfg2/Reporting/templates/config_items/item.html @@ -107,7 +107,7 @@ div.entry_list h3 { {{ item.details|syntaxhilight }} {% else %} - {{ item.details }} + {{ item.details|linebreaks }} {% endif %} {% endif %} -- cgit v1.2.3-1-g7c22 From a516f116501737a86e2eaf99a631727d4be9ecd7 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Thu, 14 Aug 2014 08:11:46 -0500 Subject: Reporting: Remove duplicate method Signed-off-by: Sol Jerome --- src/lib/Bcfg2/Reporting/models.py | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/lib/Bcfg2/Reporting') diff --git a/src/lib/Bcfg2/Reporting/models.py b/src/lib/Bcfg2/Reporting/models.py index fc9523067..71fa66086 100644 --- a/src/lib/Bcfg2/Reporting/models.py +++ b/src/lib/Bcfg2/Reporting/models.py @@ -715,9 +715,6 @@ class PathEntry(SuccessEntry): def has_detail(self): return self.detail_type != PathEntry.DETAIL_UNUSED - def is_sensitive(self): - return self.detail_type == PathEntry.DETAIL_SENSITIVE - def is_diff(self): return self.detail_type == PathEntry.DETAIL_DIFF -- cgit v1.2.3-1-g7c22 From a42933a1ddfde4f9164e0e0818c559f8f7c9a5a1 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Fri, 5 Sep 2014 07:54:48 -0500 Subject: Version bump to 1.3.5 Signed-off-by: Sol Jerome --- src/lib/Bcfg2/Reporting/templates/base.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib/Bcfg2/Reporting') diff --git a/src/lib/Bcfg2/Reporting/templates/base.html b/src/lib/Bcfg2/Reporting/templates/base.html index ef6799c2b..a367d8ccb 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
-- cgit v1.2.3-1-g7c22 From 788ac2be910d0cef1c888c31e9465a26f4e45090 Mon Sep 17 00:00:00 2001 From: Michael Fenn Date: Wed, 10 Sep 2014 12:15:37 -0400 Subject: Use older nested try syntax for finally for python 2.4 compat --- src/lib/Bcfg2/Reporting/Storage/DjangoORM.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/lib/Bcfg2/Reporting') diff --git a/src/lib/Bcfg2/Reporting/Storage/DjangoORM.py b/src/lib/Bcfg2/Reporting/Storage/DjangoORM.py index 0bb3111ae..98226dc4e 100644 --- a/src/lib/Bcfg2/Reporting/Storage/DjangoORM.py +++ b/src/lib/Bcfg2/Reporting/Storage/DjangoORM.py @@ -367,10 +367,11 @@ class DjangoORM(StorageBase): """Import the data into the backend""" try: - self._import_interaction(interaction) - except: - self.logger.error("Failed to import interaction: %s" % - traceback.format_exc().splitlines()[-1]) + try: + self._import_interaction(interaction) + except: + self.logger.error("Failed to import interaction: %s" % + traceback.format_exc().splitlines()[-1]) finally: self.logger.debug("%s: Closing database connection" % self.__class__.__name__) -- cgit v1.2.3-1-g7c22 From 43ab15a3d25667a7908ee2ef892dbf4ddff9b445 Mon Sep 17 00:00:00 2001 From: Matt Kemp Date: Wed, 1 Oct 2014 17:16:56 +0000 Subject: Attempt to break the pid lock during startup. This commit attempts to break the pidfilelock during startup in cases where the process may have exited without successfully cleaning up the lockfile. It also attempts to grab the lock before opening the context. Also applied to the Collector module, which may have been looking for the wrong exception since it does not rely on a timeout. --- src/lib/Bcfg2/Reporting/Collector.py | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) (limited to 'src/lib/Bcfg2/Reporting') diff --git a/src/lib/Bcfg2/Reporting/Collector.py b/src/lib/Bcfg2/Reporting/Collector.py index 8ca145f16..50bb49f78 100644 --- a/src/lib/Bcfg2/Reporting/Collector.py +++ b/src/lib/Bcfg2/Reporting/Collector.py @@ -7,7 +7,7 @@ import traceback import threading # pylint: disable=E0611 -from lockfile import LockFailed, LockTimeout +from lockfile import LockFailed, LockTimeout, AlreadyLocked try: from lockfile.pidlockfile import PIDLockFile from lockfile import Error as PIDFileError @@ -118,25 +118,43 @@ class ReportingCollector(object): if self.setup['daemon']: self.logger.debug("Daemonizing") + self.context.pidfile = PIDLockFile(self.setup['daemon']) try: - self.context.pidfile = PIDLockFile(self.setup['daemon']) - self.context.open() + self.context.pidfile.acquire() except LockFailed: self.logger.error("Failed to daemonize: %s" % sys.exc_info()[1]) self.shutdown() return + except AlreadyLocked: + try: # attempt to break the lock + os.kill(self.context.pidfile.read_pid(), 0) + except OSError: # No process with locked PID + self.context.pidfile.break_lock() + else: + self.logger.error("Failed to daemonize: " + "Failed to acquire lock on %s" % + self.setup['daemon']) + self.shutdown() + return except LockTimeout: - self.logger.error("Failed to daemonize: " - "Failed to acquire lock on %s" % - self.setup['daemon']) - self.shutdown() - return + try: # attempt to break the lock + os.kill(self.context.pidfile.read_pid(), 0) + except OSError: # No process with locked PID + self.context.pidfile.break_lock() + else: + self.logger.error("Failed to daemonize: " + "Failed to acquire lock on %s" % + self.setup['daemon']) + self.shutdown() + return except PIDFileError: self.logger.error("Error writing pid file: %s" % traceback.format_exc().splitlines()[-1]) self.shutdown() return + + self.context.open() self.logger.info("Starting daemon") self.transport.start_monitor(self) -- cgit v1.2.3-1-g7c22 From 5d7e50dd4f55026390f9a545d0893c3ca51c7a96 Mon Sep 17 00:00:00 2001 From: Matt Kemp Date: Wed, 1 Oct 2014 21:19:20 +0000 Subject: Fixes to ensure pidfile can be opened or broken if stale. --- src/lib/Bcfg2/Reporting/Collector.py | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) (limited to 'src/lib/Bcfg2/Reporting') diff --git a/src/lib/Bcfg2/Reporting/Collector.py b/src/lib/Bcfg2/Reporting/Collector.py index 50bb49f78..336604daa 100644 --- a/src/lib/Bcfg2/Reporting/Collector.py +++ b/src/lib/Bcfg2/Reporting/Collector.py @@ -1,3 +1,4 @@ +import os import sys import atexit import daemon @@ -6,13 +7,12 @@ import time import traceback import threading +from lockfile import LockFailed, LockTimeout # pylint: disable=E0611 -from lockfile import LockFailed, LockTimeout, AlreadyLocked try: - from lockfile.pidlockfile import PIDLockFile - from lockfile import Error as PIDFileError + from daemon.pidfile import TimeoutPIDLockFile except ImportError: - from daemon.pidlockfile import PIDLockFile, PIDFileError + from daemon.pidlockfile import TimeoutPIDLockFile # pylint: enable=E0611 import Bcfg2.Logger @@ -118,7 +118,9 @@ class ReportingCollector(object): if self.setup['daemon']: self.logger.debug("Daemonizing") - self.context.pidfile = PIDLockFile(self.setup['daemon']) + self.context.pidfile = TimeoutPIDLockFile(self.setup['daemon'], + acquire_timeout=5) + # Attempt to ensure lockfile is able to be created and not stale try: self.context.pidfile.acquire() except LockFailed: @@ -126,17 +128,6 @@ class ReportingCollector(object): sys.exc_info()[1]) self.shutdown() return - except AlreadyLocked: - try: # attempt to break the lock - os.kill(self.context.pidfile.read_pid(), 0) - except OSError: # No process with locked PID - self.context.pidfile.break_lock() - else: - self.logger.error("Failed to daemonize: " - "Failed to acquire lock on %s" % - self.setup['daemon']) - self.shutdown() - return except LockTimeout: try: # attempt to break the lock os.kill(self.context.pidfile.read_pid(), 0) @@ -144,8 +135,8 @@ class ReportingCollector(object): self.context.pidfile.break_lock() else: self.logger.error("Failed to daemonize: " - "Failed to acquire lock on %s" % - self.setup['daemon']) + "Failed to acquire lock on %s" % + self.setup['daemon']) self.shutdown() return except PIDFileError: @@ -153,6 +144,8 @@ class ReportingCollector(object): traceback.format_exc().splitlines()[-1]) self.shutdown() return + else: + self.context.pidfile.release() self.context.open() self.logger.info("Starting daemon") -- cgit v1.2.3-1-g7c22 From 5038a6278a1700671141ec58ea4a3cc5ce799e3b Mon Sep 17 00:00:00 2001 From: Matt Kemp Date: Thu, 2 Oct 2014 18:15:59 +0000 Subject: Catch possible typeerror resulting from None being returned when reading the pid. --- src/lib/Bcfg2/Reporting/Collector.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib/Bcfg2/Reporting') diff --git a/src/lib/Bcfg2/Reporting/Collector.py b/src/lib/Bcfg2/Reporting/Collector.py index 336604daa..2ff09d483 100644 --- a/src/lib/Bcfg2/Reporting/Collector.py +++ b/src/lib/Bcfg2/Reporting/Collector.py @@ -131,7 +131,7 @@ class ReportingCollector(object): except LockTimeout: try: # attempt to break the lock os.kill(self.context.pidfile.read_pid(), 0) - except OSError: # No process with locked PID + except (OSError, TypeError): # No process with locked PID self.context.pidfile.break_lock() else: self.logger.error("Failed to daemonize: " -- cgit v1.2.3-1-g7c22 From d1b630dc6edb77f248c2c5bcaddf7526210a55da Mon Sep 17 00:00:00 2001 From: Matt Kemp Date: Thu, 2 Oct 2014 18:16:24 +0000 Subject: Remove PIDFileError as it does not always exist in the package and is rarely used. --- src/lib/Bcfg2/Reporting/Collector.py | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src/lib/Bcfg2/Reporting') diff --git a/src/lib/Bcfg2/Reporting/Collector.py b/src/lib/Bcfg2/Reporting/Collector.py index 2ff09d483..8e2fe1cb1 100644 --- a/src/lib/Bcfg2/Reporting/Collector.py +++ b/src/lib/Bcfg2/Reporting/Collector.py @@ -139,11 +139,6 @@ class ReportingCollector(object): self.setup['daemon']) self.shutdown() return - except PIDFileError: - self.logger.error("Error writing pid file: %s" % - traceback.format_exc().splitlines()[-1]) - self.shutdown() - return else: self.context.pidfile.release() -- cgit v1.2.3-1-g7c22 From 885e8d1ae2027fb3d62356fdc2a5cf53347df568 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Sun, 12 Oct 2014 17:38:27 +0200 Subject: Reporting: fix filter urls The regex match for the filter urls were to strict. They disallowed some charaters, that are valid in group names and so the django reverse mechanism for building urls failed. --- src/lib/Bcfg2/Reporting/utils.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/lib/Bcfg2/Reporting') diff --git a/src/lib/Bcfg2/Reporting/utils.py b/src/lib/Bcfg2/Reporting/utils.py index 0d394fcd8..694f38824 100755 --- a/src/lib/Bcfg2/Reporting/utils.py +++ b/src/lib/Bcfg2/Reporting/utils.py @@ -96,12 +96,12 @@ def filteredUrls(pattern, view, kwargs=None, name=None): tail = mtail.group(1) pattern = pattern[:len(pattern) - len(tail)] for filter in ('/state/(?P\w+)', - '/group/(?P[\w\-\.]+)', - '/group/(?P[\w\-\.]+)/(?P[A-Za-z]+)', - '/server/(?P[\w\-\.]+)', - '/server/(?P[\w\-\.]+)/(?P[A-Za-z]+)', - '/server/(?P[\w\-\.]+)/group/(?P[\w\-\.]+)', - '/server/(?P[\w\-\.]+)/group/(?P[\w\-\.]+)/(?P[A-Za-z]+)'): + '/group/(?P[^/]+)', + '/group/(?P[^/]+)/(?P[A-Za-z]+)', + '/server/(?P[^/]+)', + '/server/(?P[^/]+)/(?P[A-Za-z]+)', + '/server/(?P[^/]+)/group/(?P[^/]+)', + '/server/(?P[^/]+)/group/(?P[^/]+)/(?P[A-Za-z]+)'): results += [(pattern + filter + tail, view, kwargs)] return results -- cgit v1.2.3-1-g7c22 From 99f4fb302bddf6dea291ee505f90748e9c54bc71 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Sun, 12 Oct 2014 17:42:41 +0200 Subject: Reporting: better exception handling Try to keep the try-except-blocks as small as possible. --- src/lib/Bcfg2/Reporting/templatetags/bcfg2_tags.py | 77 ++++++++++++---------- 1 file changed, 44 insertions(+), 33 deletions(-) (limited to 'src/lib/Bcfg2/Reporting') diff --git a/src/lib/Bcfg2/Reporting/templatetags/bcfg2_tags.py b/src/lib/Bcfg2/Reporting/templatetags/bcfg2_tags.py index 489682f30..0ee5cd0d6 100644 --- a/src/lib/Bcfg2/Reporting/templatetags/bcfg2_tags.py +++ b/src/lib/Bcfg2/Reporting/templatetags/bcfg2_tags.py @@ -111,47 +111,58 @@ def filter_navigator(context): try: path = context['request'].META['PATH_INFO'] view, args, kwargs = resolve(path) + except (Resolver404, KeyError): + return dict() - # Strip any page limits and numbers - if 'page_number' in kwargs: - del kwargs['page_number'] - if 'page_limit' in kwargs: - del kwargs['page_limit'] - - # get a query string - qs = context['request'].GET.urlencode() - if qs: - qs = '?' + qs - - filters = [] - for filter in filter_list: - if filter == 'group': - continue - if filter in kwargs: - myargs = kwargs.copy() - del myargs[filter] + # Strip any page limits and numbers + if 'page_number' in kwargs: + del kwargs['page_number'] + if 'page_limit' in kwargs: + del kwargs['page_limit'] + + # get a query string + qs = context['request'].GET.urlencode() + if qs: + qs = '?' + qs + + filters = [] + for filter in filter_list: + if filter == 'group': + continue + if filter in kwargs: + myargs = kwargs.copy() + del myargs[filter] + try: filters.append((filter, reverse(view, args=args, kwargs=myargs) + qs)) - filters.sort(key=lambda x: x[0]) - - myargs = kwargs.copy() - selected = True - if 'group' in myargs: - del myargs['group'] - selected = False - groups = [('---', - reverse(view, args=args, kwargs=myargs) + qs, - selected)] - for group in Group.objects.values('name'): + except NoReverseMatch: + pass + filters.sort(key=lambda x: x[0]) + + myargs = kwargs.copy() + selected = True + if 'group' in myargs: + del myargs['group'] + selected = False + + groups = [] + try: + groups.append(('---', + reverse(view, args=args, kwargs=myargs) + qs, + selected)) + except NoReverseMatch: + pass + + for group in Group.objects.values('name'): + try: myargs['group'] = group['name'] groups.append((group['name'], reverse(view, args=args, kwargs=myargs) + qs, group['name'] == kwargs.get('group', ''))) + except NoReverseMatch: + pass - return {'filters': filters, 'groups': groups} - except (Resolver404, NoReverseMatch, ValueError, KeyError): - pass - return dict() + return {'filters': filters, 'groups': groups} def _subtract_or_na(mdict, x, y): -- cgit v1.2.3-1-g7c22