From 39a639a33048178d98c4b3f7972589b45afd3151 Mon Sep 17 00:00:00 2001 From: DongInn Kim Date: Sun, 24 Mar 2013 14:44:15 -0400 Subject: Make the "latest" value of the "revision" attribute update the working copy only when the working copy is not updated to the latest revision. --- src/lib/Bcfg2/Client/Tools/VCS.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Client/Tools/VCS.py b/src/lib/Bcfg2/Client/Tools/VCS.py index 1ab867215..66e76f566 100644 --- a/src/lib/Bcfg2/Client/Tools/VCS.py +++ b/src/lib/Bcfg2/Client/Tools/VCS.py @@ -103,13 +103,20 @@ class VCS(Bcfg2.Client.Tools.Tool): def Verifysvn(self, entry, _): """Verify svn repositories""" + headrev = pysvn.Revision( pysvn.opt_revision_kind.head ) client = pysvn.Client() try: cur_rev = str(client.info(entry.get('name')).revision.number) + server = client.info2(entry.get('sourceurl'), headrev, recurse=False) + if server: + server_rev = str(server[0][1].rev.number) except: self.logger.info("Repository %s does not exist" % entry.get('name')) return False + if entry.get('revision') == 'latest' and cur_rev == server_rev: + return True + if cur_rev != entry.get('revision'): self.logger.info("At revision %s need to go to revision %s" % (cur_rev, entry.get('revision'))) -- cgit v1.2.3-1-g7c22 From 84a83cab07853b83e91c40c440f65b911e3296a5 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Mon, 29 Apr 2013 07:37:38 -0500 Subject: Reports: Add support for Django 1.5 Signed-off-by: Sol Jerome --- src/lib/Bcfg2/Reporting/templates/base.html | 29 +++++++++-------- .../Bcfg2/Reporting/templates/clients/detail.html | 28 ++++++++--------- .../Reporting/templates/clients/detailed-list.html | 2 +- .../Bcfg2/Reporting/templates/clients/index.html | 4 +-- .../Bcfg2/Reporting/templates/clients/manage.html | 4 +-- .../Reporting/templates/config_items/common.html | 4 +-- .../templates/config_items/entry_status.html | 10 ++++-- .../Reporting/templates/config_items/item.html | 16 +++++----- .../Reporting/templates/config_items/listing.html | 4 +-- .../Reporting/templates/displays/summary.html | 2 +- .../Bcfg2/Reporting/templates/displays/timing.html | 10 +++--- src/lib/Bcfg2/Reporting/templatetags/bcfg2_tags.py | 36 ++++++++++++---------- .../Reporting/templatetags/syntax_coloring.py | 16 +++++----- src/lib/Bcfg2/settings.py | 3 ++ 14 files changed, 91 insertions(+), 77 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Reporting/templates/base.html b/src/lib/Bcfg2/Reporting/templates/base.html index c73339911..7f1fcba3b 100644 --- a/src/lib/Bcfg2/Reporting/templates/base.html +++ b/src/lib/Bcfg2/Reporting/templates/base.html @@ -1,4 +1,8 @@ {% load bcfg2_tags %} +{% comment %} +This is needed for Django versions less than 1.5 +{% endcomment %} +{% load url from future %} @@ -25,8 +29,9 @@ + height='115' width='300' alt='Bcfg2' + style='float:left; height: 115px' /> +
@@ -46,26 +51,26 @@
  • Overview
  • {% comment %} TODO diff --git a/src/lib/Bcfg2/Reporting/templates/clients/detail.html b/src/lib/Bcfg2/Reporting/templates/clients/detail.html index 4608ce6f1..9c0299121 100644 --- a/src/lib/Bcfg2/Reporting/templates/clients/detail.html +++ b/src/lib/Bcfg2/Reporting/templates/clients/detail.html @@ -6,19 +6,19 @@ {% block extra_header_info %} {% endblock %} @@ -30,12 +30,12 @@ span.history_links a { {% block content %}

    {{client.name}}

    - [manage] - View History | Jump to  + [manage] + View History | Jump to 
    @@ -110,7 +110,7 @@ span.history_links a { {% for entry in entry_list %} {{entry.entry_type}} - + {{entry.name}} {% endfor %} @@ -129,7 +129,7 @@ span.history_links a { {% for failure in interaction.failures.all %} {{failure.entry_type}} - + {{failure.name}} {% endfor %} @@ -140,11 +140,11 @@ span.history_links a { {% if entry_list %}
    -

    Recent Interactions

    +

    Recent Interactions

    {% include "widgets/interaction_list.inc" %} - +
    {% endif %} diff --git a/src/lib/Bcfg2/Reporting/templates/clients/detailed-list.html b/src/lib/Bcfg2/Reporting/templates/clients/detailed-list.html index fd9a545ce..2a03eede1 100644 --- a/src/lib/Bcfg2/Reporting/templates/clients/detailed-list.html +++ b/src/lib/Bcfg2/Reporting/templates/clients/detailed-list.html @@ -21,7 +21,7 @@ {% for entry in entry_list %} - {{ entry.client.name }} + {{ entry.client.name }} {{ entry.state }} {{ entry.good_count }} diff --git a/src/lib/Bcfg2/Reporting/templates/clients/index.html b/src/lib/Bcfg2/Reporting/templates/clients/index.html index d9c415c20..957cbffd2 100644 --- a/src/lib/Bcfg2/Reporting/templates/clients/index.html +++ b/src/lib/Bcfg2/Reporting/templates/clients/index.html @@ -17,9 +17,9 @@ {{ inter.client.name }} diff --git a/src/lib/Bcfg2/Reporting/templates/clients/manage.html b/src/lib/Bcfg2/Reporting/templates/clients/manage.html index 443ec8ccb..5ba3393b2 100644 --- a/src/lib/Bcfg2/Reporting/templates/clients/manage.html +++ b/src/lib/Bcfg2/Reporting/templates/clients/manage.html @@ -24,10 +24,10 @@ - {{ client.name }} + {{ client.name }} {% firstof client.expiration 'Active' %} -
    +
    {# here for no reason other then to validate #} diff --git a/src/lib/Bcfg2/Reporting/templates/config_items/common.html b/src/lib/Bcfg2/Reporting/templates/config_items/common.html index 57191ec39..0dbd52156 100644 --- a/src/lib/Bcfg2/Reporting/templates/config_items/common.html +++ b/src/lib/Bcfg2/Reporting/templates/config_items/common.html @@ -29,9 +29,9 @@ {% for item in type_list %} {{ item.ENTRY_TYPE }} - {{ item.name }} + {{ item.name }} {{ item.num_entries }} - {{ item.short_list|join:"," }} + {{ item.short_list|join:"," }} {% endfor %} diff --git a/src/lib/Bcfg2/Reporting/templates/config_items/entry_status.html b/src/lib/Bcfg2/Reporting/templates/config_items/entry_status.html index e940889ab..e3befb0eb 100644 --- a/src/lib/Bcfg2/Reporting/templates/config_items/entry_status.html +++ b/src/lib/Bcfg2/Reporting/templates/config_items/entry_status.html @@ -1,5 +1,9 @@ {% extends "base-timeview.html" %} {% load bcfg2_tags %} +{% comment %} +This is needed for Django versions less than 1.5 +{% endcomment %} +{% load url from future %} {% block title %}Bcfg2 - Entry Status{% endblock %} @@ -17,10 +21,10 @@ {% for item, inters in items %} {% for inter in inters %} - {{inter.client.name}} - {{inter.timestamp|date:"Y-m-d\&\n\b\s\p\;H:i"|safe}} + {{inter.client.name}} + {{inter.timestamp|date:"Y-m-d\&\n\b\s\p\;H:i"|safe}} {{ item.get_state_display }} - ({{item.pk}}) {{item.short_list|join:","}} + ({{item.pk}}) {{item.short_list|join:","}} {% endfor %} {% endfor %} diff --git a/src/lib/Bcfg2/Reporting/templates/config_items/item.html b/src/lib/Bcfg2/Reporting/templates/config_items/item.html index 259414399..c15a85e0a 100644 --- a/src/lib/Bcfg2/Reporting/templates/config_items/item.html +++ b/src/lib/Bcfg2/Reporting/templates/config_items/item.html @@ -9,20 +9,20 @@ {% block extra_header_info %} {% endblock%} @@ -131,9 +131,9 @@ div.entry_list h3 { {% if associated_list %} {% for inter in associated_list %} - - {% endfor %} diff --git a/src/lib/Bcfg2/Reporting/templates/config_items/listing.html b/src/lib/Bcfg2/Reporting/templates/config_items/listing.html index 864392754..fb10bb020 100644 --- a/src/lib/Bcfg2/Reporting/templates/config_items/listing.html +++ b/src/lib/Bcfg2/Reporting/templates/config_items/listing.html @@ -21,9 +21,9 @@ {% for entry in type_data %} - + - + {% endfor %}
    {{inter.client.name}}{{inter.timestamp}}
    NameCountReason
    {{entry.name}}{{entry.name}} {{entry.num_entries}}{{entry.short_list|join:","}}{{entry.short_list|join:","}}
    diff --git a/src/lib/Bcfg2/Reporting/templates/displays/summary.html b/src/lib/Bcfg2/Reporting/templates/displays/summary.html index b9847cf96..c432da95d 100644 --- a/src/lib/Bcfg2/Reporting/templates/displays/summary.html +++ b/src/lib/Bcfg2/Reporting/templates/displays/summary.html @@ -30,7 +30,7 @@ hide_tables[{{ forloop.counter0 }}] = "table_{{ summary.name }}"; {% for node in summary.nodes|sort_interactions_by_name %} - + {% endfor %}
    {{ node.client.name }}{{ node.client.name }}
    diff --git a/src/lib/Bcfg2/Reporting/templates/displays/timing.html b/src/lib/Bcfg2/Reporting/templates/displays/timing.html index ff775ded5..57806b63a 100644 --- a/src/lib/Bcfg2/Reporting/templates/displays/timing.html +++ b/src/lib/Bcfg2/Reporting/templates/displays/timing.html @@ -12,7 +12,7 @@
    {% if metrics %} - + @@ -21,15 +21,15 @@ - {% for metric in metrics|dictsort:"name" %} + {% for metric in metrics|dictsort:"name" %} + href='{% url "reports_client_detail" hostname=metric.name %}'>{{ metric.name }} {% for mitem in metric|build_metric_list %} {% endfor %} - - {% endfor %} + + {% endfor %}
    Name Parse ProbeConfig Total
    {{ metric.name }}{{ mitem }}
    {% else %}

    No metric data available

    diff --git a/src/lib/Bcfg2/Reporting/templatetags/bcfg2_tags.py b/src/lib/Bcfg2/Reporting/templatetags/bcfg2_tags.py index f5f2e7528..489682f30 100644 --- a/src/lib/Bcfg2/Reporting/templatetags/bcfg2_tags.py +++ b/src/lib/Bcfg2/Reporting/templatetags/bcfg2_tags.py @@ -5,9 +5,8 @@ from django import template from django.conf import settings from django.core.urlresolvers import resolve, reverse, \ Resolver404, NoReverseMatch -from django.template.loader import get_template, \ - get_template_from_string,TemplateDoesNotExist -from django.utils.encoding import smart_unicode, smart_str +from django.template.loader import get_template_from_string +from django.utils.encoding import smart_str from django.utils.safestring import mark_safe from datetime import datetime, timedelta from Bcfg2.Reporting.utils import filter_list @@ -133,19 +132,22 @@ def filter_navigator(context): del myargs[filter] filters.append((filter, reverse(view, args=args, kwargs=myargs) + qs)) - filters.sort(lambda x, y: cmp(x[0], y[0])) + filters.sort(key=lambda x: x[0]) myargs = kwargs.copy() - selected=True + selected = True if 'group' in myargs: del myargs['group'] - selected=False - groups = [('---', reverse(view, args=args, kwargs=myargs) + qs, selected)] + selected = False + groups = [('---', + reverse(view, args=args, kwargs=myargs) + qs, + selected)] for group in Group.objects.values('name'): myargs['group'] = group['name'] - groups.append((group['name'], reverse(view, args=args, kwargs=myargs) + qs, - group['name'] == kwargs.get('group', ''))) - + groups.append((group['name'], + reverse(view, args=args, kwargs=myargs) + qs, + group['name'] == kwargs.get('group', ''))) + return {'filters': filters, 'groups': groups} except (Resolver404, NoReverseMatch, ValueError, KeyError): pass @@ -205,7 +207,7 @@ def sort_interactions_by_name(value): Sort an interaction list by client name """ inters = list(value) - inters.sort(lambda a, b: cmp(a.client.name, b.client.name)) + inters.sort(key=lambda a: a.client.name) return inters @@ -223,7 +225,7 @@ class AddUrlFilter(template.Node): filter_value = self.filter_value.resolve(context, True) if filter_value: filter_name = smart_str(self.filter_name) - filter_value = smart_unicode(filter_value) + filter_value = smart_str(filter_value) kwargs[filter_name] = filter_value # These two don't make sense if filter_name == 'server' and 'hostname' in kwargs: @@ -306,6 +308,7 @@ def to_media_url(parser, token): return MediaTag(filter_value) + @register.filter def determine_client_state(entry): """ @@ -338,10 +341,11 @@ def do_qs(parser, token): try: tag, name, value = token.split_contents() except ValueError: - raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" \ - % token.contents.split()[0] + raise template.TemplateSyntaxError("%r tag requires exactly two arguments" + % token.contents.split()[0]) return QsNode(name, value) + class QsNode(template.Node): def __init__(self, name, value): self.name = template.Variable(name) @@ -359,7 +363,7 @@ class QsNode(template.Node): return '' except KeyError: if settings.TEMPLATE_DEBUG: - raise Exception, "'qs' tag requires context['request']" + raise Exception("'qs' tag requires context['request']") return '' except: return '' @@ -380,6 +384,7 @@ def sort_link(parser, token): return SortLinkNode(sort_key, text) + class SortLinkNode(template.Node): __TMPL__ = "{% load bcfg2_tags %}{{ text }}" @@ -420,4 +425,3 @@ class SortLinkNode(template.Node): raise raise return '' - diff --git a/src/lib/Bcfg2/Reporting/templatetags/syntax_coloring.py b/src/lib/Bcfg2/Reporting/templatetags/syntax_coloring.py index 2712d6395..22700689f 100644 --- a/src/lib/Bcfg2/Reporting/templatetags/syntax_coloring.py +++ b/src/lib/Bcfg2/Reporting/templatetags/syntax_coloring.py @@ -1,11 +1,8 @@ -import sys from django import template -from django.utils.encoding import smart_unicode +from django.utils.encoding import smart_str from django.utils.html import conditional_escape from django.utils.safestring import mark_safe -from Bcfg2.Compat import u_str - register = template.Library() # pylint: disable=E0611 @@ -33,9 +30,9 @@ def syntaxhilight(value, arg="diff", autoescape=None): if colorize: try: - output = u_str('') + output = smart_str('') lexer = get_lexer_by_name(arg) output += highlight(value, lexer, HtmlFormatter()) @@ -43,6 +40,7 @@ def syntaxhilight(value, arg="diff", autoescape=None): except: return value else: - return mark_safe(u_str('
    Tip: Install pygments ' - 'for highlighting
    %s
    ') % value) + return mark_safe(smart_str( + '
    Tip: Install pygments ' + 'for highlighting
    %s
    ') % value) syntaxhilight.needs_autoescape = True diff --git a/src/lib/Bcfg2/settings.py b/src/lib/Bcfg2/settings.py index 9393830a8..b736eb9a5 100644 --- a/src/lib/Bcfg2/settings.py +++ b/src/lib/Bcfg2/settings.py @@ -32,6 +32,8 @@ TIME_ZONE = None DEBUG = False TEMPLATE_DEBUG = DEBUG +ALLOWED_HOSTS = ['*'] + MEDIA_URL = '/site_media/' @@ -130,6 +132,7 @@ INSTALLED_APPS = ( 'django.contrib.sites', 'django.contrib.admin', 'Bcfg2.Server', + 'Bcfg2.Reporting', ) if HAS_SOUTH: INSTALLED_APPS = INSTALLED_APPS + ( -- cgit v1.2.3-1-g7c22 From b380b0d1b9c135069d91a19a618f617b75d7f80c Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Wed, 1 May 2013 15:28:52 -0500 Subject: Remove extra import Signed-off-by: Sol Jerome --- src/lib/Bcfg2/settings.py | 1 - 1 file changed, 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/settings.py b/src/lib/Bcfg2/settings.py index b736eb9a5..9adfd66bf 100644 --- a/src/lib/Bcfg2/settings.py +++ b/src/lib/Bcfg2/settings.py @@ -132,7 +132,6 @@ INSTALLED_APPS = ( 'django.contrib.sites', 'django.contrib.admin', 'Bcfg2.Server', - 'Bcfg2.Reporting', ) if HAS_SOUTH: INSTALLED_APPS = INSTALLED_APPS + ( -- cgit v1.2.3-1-g7c22 From fd993228d36c166593285a8ebbd2e6fb45c36d4d Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Mon, 6 May 2013 15:16:34 -0500 Subject: Add url loads for all templates Signed-off-by: Sol Jerome --- src/lib/Bcfg2/Reporting/templates/clients/detail.html | 4 ++++ src/lib/Bcfg2/Reporting/templates/clients/detailed-list.html | 4 ++++ src/lib/Bcfg2/Reporting/templates/clients/index.html | 4 ++++ src/lib/Bcfg2/Reporting/templates/clients/manage.html | 4 ++++ src/lib/Bcfg2/Reporting/templates/config_items/common.html | 1 + src/lib/Bcfg2/Reporting/templates/config_items/item.html | 4 ++++ src/lib/Bcfg2/Reporting/templates/config_items/listing.html | 4 ++++ src/lib/Bcfg2/Reporting/templates/displays/summary.html | 4 ++++ src/lib/Bcfg2/Reporting/templates/displays/timing.html | 4 ++++ 9 files changed, 33 insertions(+) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Reporting/templates/clients/detail.html b/src/lib/Bcfg2/Reporting/templates/clients/detail.html index 9c0299121..e890589a7 100644 --- a/src/lib/Bcfg2/Reporting/templates/clients/detail.html +++ b/src/lib/Bcfg2/Reporting/templates/clients/detail.html @@ -1,5 +1,9 @@ {% extends "base.html" %} {% load bcfg2_tags %} +{% comment %} +This is needed for Django versions less than 1.5 +{% endcomment %} +{% load url from future %} {% block title %}Bcfg2 - Client {{client.name}}{% endblock %} diff --git a/src/lib/Bcfg2/Reporting/templates/clients/detailed-list.html b/src/lib/Bcfg2/Reporting/templates/clients/detailed-list.html index 2a03eede1..33c78a5f0 100644 --- a/src/lib/Bcfg2/Reporting/templates/clients/detailed-list.html +++ b/src/lib/Bcfg2/Reporting/templates/clients/detailed-list.html @@ -1,5 +1,9 @@ {% extends "base-timeview.html" %} {% load bcfg2_tags %} +{% comment %} +This is needed for Django versions less than 1.5 +{% endcomment %} +{% load url from future %} {% block title %}Bcfg2 - Detailed Client Listing{% endblock %} {% block pagebanner %}Clients - Detailed View{% endblock %} diff --git a/src/lib/Bcfg2/Reporting/templates/clients/index.html b/src/lib/Bcfg2/Reporting/templates/clients/index.html index 957cbffd2..eba83670b 100644 --- a/src/lib/Bcfg2/Reporting/templates/clients/index.html +++ b/src/lib/Bcfg2/Reporting/templates/clients/index.html @@ -1,5 +1,9 @@ {% extends "base-timeview.html" %} {% load bcfg2_tags %} +{% comment %} +This is needed for Django versions less than 1.5 +{% endcomment %} +{% load url from future %} {% block extra_header_info %} {% endblock%} diff --git a/src/lib/Bcfg2/Reporting/templates/clients/manage.html b/src/lib/Bcfg2/Reporting/templates/clients/manage.html index 5ba3393b2..03918aad7 100644 --- a/src/lib/Bcfg2/Reporting/templates/clients/manage.html +++ b/src/lib/Bcfg2/Reporting/templates/clients/manage.html @@ -1,4 +1,8 @@ {% extends "base.html" %} +{% comment %} +This is needed for Django versions less than 1.5 +{% endcomment %} +{% load url from future %} {% block extra_header_info %} {% endblock%} diff --git a/src/lib/Bcfg2/Reporting/templates/config_items/common.html b/src/lib/Bcfg2/Reporting/templates/config_items/common.html index 0dbd52156..91f37d7dc 100644 --- a/src/lib/Bcfg2/Reporting/templates/config_items/common.html +++ b/src/lib/Bcfg2/Reporting/templates/config_items/common.html @@ -1,5 +1,6 @@ {% extends "base-timeview.html" %} {% load bcfg2_tags %} +{% load url from future %} {% block title %}Bcfg2 - Common Problems{% endblock %} diff --git a/src/lib/Bcfg2/Reporting/templates/config_items/item.html b/src/lib/Bcfg2/Reporting/templates/config_items/item.html index c15a85e0a..b03d48045 100644 --- a/src/lib/Bcfg2/Reporting/templates/config_items/item.html +++ b/src/lib/Bcfg2/Reporting/templates/config_items/item.html @@ -1,6 +1,10 @@ {% extends "base.html" %} {% load split %} {% load syntax_coloring %} +{% comment %} +This is needed for Django versions less than 1.5 +{% endcomment %} +{% load url from future %} {% block title %}Bcfg2 - Element Details{% endblock %} diff --git a/src/lib/Bcfg2/Reporting/templates/config_items/listing.html b/src/lib/Bcfg2/Reporting/templates/config_items/listing.html index fb10bb020..0e4812e85 100644 --- a/src/lib/Bcfg2/Reporting/templates/config_items/listing.html +++ b/src/lib/Bcfg2/Reporting/templates/config_items/listing.html @@ -1,5 +1,9 @@ {% extends "base-timeview.html" %} {% load bcfg2_tags %} +{% comment %} +This is needed for Django versions less than 1.5 +{% endcomment %} +{% load url from future %} {% block title %}Bcfg2 - Element Listing{% endblock %} diff --git a/src/lib/Bcfg2/Reporting/templates/displays/summary.html b/src/lib/Bcfg2/Reporting/templates/displays/summary.html index c432da95d..ffafd52e0 100644 --- a/src/lib/Bcfg2/Reporting/templates/displays/summary.html +++ b/src/lib/Bcfg2/Reporting/templates/displays/summary.html @@ -1,5 +1,9 @@ {% extends "base-timeview.html" %} {% load bcfg2_tags %} +{% comment %} +This is needed for Django versions less than 1.5 +{% endcomment %} +{% load url from future %} {% block title %}Bcfg2 - Client Summary{% endblock %} {% block pagebanner %}Clients - Summary{% endblock %} diff --git a/src/lib/Bcfg2/Reporting/templates/displays/timing.html b/src/lib/Bcfg2/Reporting/templates/displays/timing.html index 57806b63a..8ac5e49bb 100644 --- a/src/lib/Bcfg2/Reporting/templates/displays/timing.html +++ b/src/lib/Bcfg2/Reporting/templates/displays/timing.html @@ -1,5 +1,9 @@ {% extends "base-timeview.html" %} {% load bcfg2_tags %} +{% comment %} +This is needed for Django versions less than 1.5 +{% endcomment %} +{% load url from future %} {% block title %}Bcfg2 - Performance Metrics{% endblock %} {% block pagebanner %}Performance Metrics{% endblock %} -- cgit v1.2.3-1-g7c22 From 8a909207d3bbac898b1cdef21946cf6b70a70f51 Mon Sep 17 00:00:00 2001 From: Jason Kincl Date: Wed, 29 May 2013 00:03:23 -0400 Subject: Comments: Fix lint check so that it only runs if using clients.xml --- src/lib/Bcfg2/Server/Lint/Comments.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Lint/Comments.py b/src/lib/Bcfg2/Server/Lint/Comments.py index 7c3b2d9cc..080d0b821 100644 --- a/src/lib/Bcfg2/Server/Lint/Comments.py +++ b/src/lib/Bcfg2/Server/Lint/Comments.py @@ -144,9 +144,10 @@ class Comments(Bcfg2.Server.Lint.ServerPlugin): self.metadata.groups_xml.data, "metadata") if self.has_all_xincludes("clients.xml"): - self.check_xml(os.path.join(self.metadata.data, "clients.xml"), - self.metadata.clients_xml.data, - "metadata") + if hasattr(self.metadata, "clients_xml"): + self.check_xml(os.path.join(self.metadata.data, "clients.xml"), + self.metadata.clients_xml.data, + "metadata") def check_cfg(self): """ Check Cfg files and ``info.xml`` files for required -- cgit v1.2.3-1-g7c22 From 51d781db3ee335bc15581c62ee90fd71ab2bdd53 Mon Sep 17 00:00:00 2001 From: Jason Kincl Date: Wed, 29 May 2013 07:17:51 -0400 Subject: Changing order of logic --- src/lib/Bcfg2/Server/Lint/Comments.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Lint/Comments.py b/src/lib/Bcfg2/Server/Lint/Comments.py index 080d0b821..f028e225e 100644 --- a/src/lib/Bcfg2/Server/Lint/Comments.py +++ b/src/lib/Bcfg2/Server/Lint/Comments.py @@ -143,8 +143,8 @@ class Comments(Bcfg2.Server.Lint.ServerPlugin): self.check_xml(os.path.join(self.metadata.data, "groups.xml"), self.metadata.groups_xml.data, "metadata") - if self.has_all_xincludes("clients.xml"): - if hasattr(self.metadata, "clients_xml"): + if hasattr(self.metadata, "clients_xml"): + if self.has_all_xincludes("clients.xml"): self.check_xml(os.path.join(self.metadata.data, "clients.xml"), self.metadata.clients_xml.data, "metadata") -- cgit v1.2.3-1-g7c22 From 8682a0642ce953077779370307e9dc3d6aec64ff Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Mon, 3 Jun 2013 09:43:56 -0400 Subject: lint: catch unexpected Genshi errors --- src/lib/Bcfg2/Server/Lint/Genshi.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Lint/Genshi.py b/src/lib/Bcfg2/Server/Lint/Genshi.py index 7edeb8a49..1ecb6da42 100755 --- a/src/lib/Bcfg2/Server/Lint/Genshi.py +++ b/src/lib/Bcfg2/Server/Lint/Genshi.py @@ -37,6 +37,12 @@ class Genshi(Bcfg2.Server.Lint.ServerPlugin): err = sys.exc_info()[1] self.LintError("genshi-syntax-error", "Genshi syntax error: %s" % err) + except: + etype, err = sys.exc_info()[:2] + self.LintError( + "genshi-syntax-error", + "Unexpected Genshi error on %s: %s: %s" % + (entry.name, etype.__name__, err)) def check_tgenshi(self): """ Check templates in TGenshi for syntax errors. """ -- cgit v1.2.3-1-g7c22 From 0e8816f29635786a0fbade95aef1ab8de416f858 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Mon, 3 Jun 2013 09:45:26 -0400 Subject: lint: check for files in Cfg/ that aren't handled by Cfg --- src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py | 83 +++++++++++++++++++++------- 1 file changed, 62 insertions(+), 21 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py b/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py index c6ac9d8dc..842202a9c 100644 --- a/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py +++ b/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py @@ -10,6 +10,7 @@ import lxml.etree import Bcfg2.Options import Bcfg2.Server.Plugin import Bcfg2.Server.Lint +from itertools import chain from Bcfg2.Server.Plugin import PluginExecutionError # pylint: disable=W0622 from Bcfg2.Compat import u_str, unicode, b64encode, walk_packages, \ @@ -35,6 +36,24 @@ SETUP = None #: facility for passing it otherwise. CFG = None +_HANDLERS = [] + + +def handlers(): + """ A list of Cfg handler classes. Loading the handlers must + be done at run-time, not at compile-time, or it causes a + circular import and Bad Things Happen.""" + if not _HANDLERS: + for submodule in walk_packages(path=__path__, prefix=__name__ + "."): + mname = submodule[1].rsplit('.', 1)[-1] + module = getattr(__import__(submodule[1]).Server.Plugins.Cfg, + mname) + hdlr = getattr(module, mname) + if issubclass(hdlr, CfgBaseFileMatcher): + _HANDLERS.append(hdlr) + _HANDLERS.sort(key=operator.attrgetter("__priority__")) + return _HANDLERS + class CfgBaseFileMatcher(Bcfg2.Server.Plugin.SpecificData, Bcfg2.Server.Plugin.Debuggable): @@ -459,7 +478,6 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet, entry_type, encoding) Bcfg2.Server.Plugin.Debuggable.__init__(self) self.specific = None - self._handlers = None __init__.__doc__ = Bcfg2.Server.Plugin.EntrySet.__doc__ def set_debug(self, debug): @@ -468,24 +486,6 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet, entry.set_debug(debug) return rv - @property - def handlers(self): - """ A list of Cfg handler classes. Loading the handlers must - be done at run-time, not at compile-time, or it causes a - circular import and Bad Things Happen.""" - if self._handlers is None: - self._handlers = [] - for submodule in walk_packages(path=__path__, - prefix=__name__ + "."): - mname = submodule[1].rsplit('.', 1)[-1] - module = getattr(__import__(submodule[1]).Server.Plugins.Cfg, - mname) - hdlr = getattr(module, mname) - if CfgBaseFileMatcher in hdlr.__mro__: - self._handlers.append(hdlr) - self._handlers.sort(key=operator.attrgetter("__priority__")) - return self._handlers - def handle_event(self, event): """ Dispatch a FAM event to :func:`entry_init` or the appropriate child handler object. @@ -502,7 +502,7 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet, # process a bogus changed event like a created return - for hdlr in self.handlers: + for hdlr in handlers(): if hdlr.handles(event, basename=self.path): if action == 'changed': # warn about a bogus 'changed' event, but @@ -888,12 +888,15 @@ class CfgLint(Bcfg2.Server.Lint.ServerPlugin): for basename, entry in list(self.core.plugins['Cfg'].entries.items()): self.check_delta(basename, entry) self.check_pubkey(basename, entry) + self.check_missing_files() @classmethod def Errors(cls): return {"cat-file-used": "warning", "diff-file-used": "warning", - "no-pubkey-xml": "warning"} + "no-pubkey-xml": "warning", + "unknown-cfg-files": "error", + "extra-cfg-files": "error"} def check_delta(self, basename, entry): """ check that no .cat or .diff files are in use """ @@ -927,3 +930,41 @@ class CfgLint(Bcfg2.Server.Lint.ServerPlugin): self.LintError("no-pubkey-xml", "%s has no corresponding pubkey.xml at %s" % (basename, pubkey)) + + def check_missing_files(self): + """ check that all files on the filesystem are known to Cfg """ + cfg = self.core.plugins['Cfg'] + + # first, collect ignore patterns from handlers + ignore = [] + for hdlr in handlers(): + ignore.extend(hdlr.__ignore__) + + # next, get a list of all non-ignored files on the filesystem + all_files = set() + for root, _, files in os.walk(cfg.data): + all_files.update(os.path.join(root, fname) + for fname in files + if not any(fname.endswith("." + i) + for i in ignore)) + + # next, get a list of all files known to Cfg + cfg_files = set() + for root, eset in cfg.entries.items(): + cfg_files.update(os.path.join(cfg.data, root.lstrip("/"), fname) + for fname in eset.entries.keys()) + + # finally, compare the two + unknown_files = all_files - cfg_files + extra_files = cfg_files - all_files + if unknown_files: + self.LintError( + "unknown-cfg-files", + "Files on the filesystem could not be understood by Cfg: %s" % + "; ".join(unknown_files)) + if extra_files: + self.LintError( + "extra-cfg-files", + "Cfg has entries for files that do not exist on the " + "filesystem: %s\nThis is probably a bug." % + "; ".join(extra_files)) -- cgit v1.2.3-1-g7c22 From 01e785422bdf3fd1457045dcd2e9d8c4aa7304a1 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Mon, 3 Jun 2013 10:12:30 -0400 Subject: Packages: handle bcfg2-yum-helper failures more gracefully --- src/lib/Bcfg2/Server/Plugins/Packages/Yum.py | 32 +++++++++++++++++++--------- 1 file changed, 22 insertions(+), 10 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py index bb7caab0d..20b2c9500 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py @@ -675,7 +675,10 @@ class YumCollection(Collection): gdicts.append(dict(group=group, type=ptype)) if self.use_yum: - return self.call_helper("get_groups", inputdata=gdicts) + try: + return self.call_helper("get_groups", inputdata=gdicts) + except ValueError: + return dict() else: pkgs = dict() for gdict in gdicts: @@ -838,12 +841,13 @@ class YumCollection(Collection): return Collection.complete(self, packagelist) if packagelist: - result = \ - self.call_helper("complete", - dict(packages=list(packagelist), - groups=list(self.get_relevant_groups()))) - if not result: - # some sort of error, reported by call_helper() + try: + result = self.call_helper( + "complete", + dict(packages=list(packagelist), + groups=list(self.get_relevant_groups()))) + except ValueError: + # error reported by call_helper() return set(), packagelist # json doesn't understand sets or tuples, so we get back a # lists of lists (packages) and a list of unicode strings @@ -905,7 +909,7 @@ class YumCollection(Collection): err = sys.exc_info()[1] self.logger.error("Packages: error reading bcfg2-yum-helper " "output: %s" % err) - return None + raise def setup_data(self, force_update=False): """ Do any collection-level data setup tasks. This is called @@ -931,13 +935,21 @@ class YumCollection(Collection): if force_update: # we call this twice: one to clean up data from the old # config, and once to clean up data from the new config - self.call_helper("clean") + try: + self.call_helper("clean") + except ValueError: + # error reported by call_helper + pass os.unlink(self.cfgfile) self.write_config() if force_update: - self.call_helper("clean") + try: + self.call_helper("clean") + except ValueError: + # error reported by call_helper + pass class YumSource(Source): -- cgit v1.2.3-1-g7c22 From dae8f399151052fd2a0ce43ac61a56f399a28252 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Mon, 3 Jun 2013 10:54:54 -0400 Subject: bcfg2-admin: set appropriate return values on error --- src/lib/Bcfg2/Server/Admin/Client.py | 12 ++++-------- src/lib/Bcfg2/Server/Admin/Compare.py | 3 +-- src/lib/Bcfg2/Server/Admin/Minestruct.py | 11 ++++------- src/lib/Bcfg2/Server/Admin/Pull.py | 3 +-- src/lib/Bcfg2/Server/Admin/Reports.py | 23 ++++++++--------------- src/lib/Bcfg2/Server/Admin/Syncdb.py | 9 +++------ src/lib/Bcfg2/Server/Admin/Xcmd.py | 16 ++-------------- 7 files changed, 23 insertions(+), 54 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Admin/Client.py b/src/lib/Bcfg2/Server/Admin/Client.py index 570e993ed..187ccfd71 100644 --- a/src/lib/Bcfg2/Server/Admin/Client.py +++ b/src/lib/Bcfg2/Server/Admin/Client.py @@ -18,19 +18,15 @@ class Client(Bcfg2.Server.Admin.MetadataCore): try: self.metadata.add_client(args[1]) except MetadataConsistencyError: - err = sys.exc_info()[1] - print("Error in adding client: %s" % err) - raise SystemExit(1) + self.errExit("Error in adding client: %s" % sys.exc_info()[1]) elif args[0] in ['delete', 'remove', 'del', 'rm']: try: self.metadata.remove_client(args[1]) except MetadataConsistencyError: - err = sys.exc_info()[1] - print("Error in deleting client: %s" % err) - raise SystemExit(1) + self.errExit("Error in deleting client: %s" % + sys.exc_info()[1]) elif args[0] in ['list', 'ls']: for client in self.metadata.list_clients(): print(client) else: - print("No command specified") - raise SystemExit(1) + self.errExit("No command specified") diff --git a/src/lib/Bcfg2/Server/Admin/Compare.py b/src/lib/Bcfg2/Server/Admin/Compare.py index c56dd0a8f..e3648a6d0 100644 --- a/src/lib/Bcfg2/Server/Admin/Compare.py +++ b/src/lib/Bcfg2/Server/Admin/Compare.py @@ -145,5 +145,4 @@ class Compare(Bcfg2.Server.Admin.Mode): (old, new) = args return self.compareSpecifications(new, old) except IndexError: - print(self.__call__.__doc__) - raise SystemExit(1) + self.errExit(self.__call__.__doc__) diff --git a/src/lib/Bcfg2/Server/Admin/Minestruct.py b/src/lib/Bcfg2/Server/Admin/Minestruct.py index 93e42305c..21a56de23 100644 --- a/src/lib/Bcfg2/Server/Admin/Minestruct.py +++ b/src/lib/Bcfg2/Server/Admin/Minestruct.py @@ -21,8 +21,7 @@ class Minestruct(Bcfg2.Server.Admin.StructureMode): try: (opts, args) = getopt.getopt(args, 'f:g:h') except: - self.log.error(self.__doc__) - raise SystemExit(1) + self.errExit(self.__doc__) client = args[0] output = sys.stdout @@ -33,8 +32,7 @@ class Minestruct(Bcfg2.Server.Admin.StructureMode): try: output = open(optarg, 'w') except IOError: - self.log.error("Failed to open file: %s" % (optarg)) - raise SystemExit(1) + self.errExit("Failed to open file: %s" % (optarg)) elif opt == '-g': groups = optarg.split(':') @@ -44,9 +42,8 @@ class Minestruct(Bcfg2.Server.Admin.StructureMode): for item in source.GetExtra(client): extra.add(item) except: - self.log.error("Failed to find extra entry info for client %s" % - client) - raise SystemExit(1) + self.errExit("Failed to find extra entry info for client %s" % + client) root = lxml.etree.Element("Base") self.log.info("Found %d extra entries" % (len(extra))) add_point = root diff --git a/src/lib/Bcfg2/Server/Admin/Pull.py b/src/lib/Bcfg2/Server/Admin/Pull.py index 8001425df..cc0dced82 100644 --- a/src/lib/Bcfg2/Server/Admin/Pull.py +++ b/src/lib/Bcfg2/Server/Admin/Pull.py @@ -33,8 +33,7 @@ class Pull(Bcfg2.Server.Admin.MetadataCore): try: opts, gargs = getopt.getopt(args, 'vfIs') except: - print(self.__doc__) - raise SystemExit(1) + self.errExit(self.__doc__) for opt in opts: if opt[0] == '-v': self.log = True diff --git a/src/lib/Bcfg2/Server/Admin/Reports.py b/src/lib/Bcfg2/Server/Admin/Reports.py index 6e313e84b..849df8025 100644 --- a/src/lib/Bcfg2/Server/Admin/Reports.py +++ b/src/lib/Bcfg2/Server/Admin/Reports.py @@ -79,8 +79,7 @@ class Reports(Bcfg2.Server.Admin.Mode): def __call__(self, args): if len(args) == 0 or args[0] == '-h': - print(self.__usage__) - raise SystemExit(0) + self.errExit(self.__usage__) # FIXME - dry run @@ -101,9 +100,7 @@ class Reports(Bcfg2.Server.Admin.Mode): management.call_command("syncdb", verbosity=vrb) management.call_command("migrate", verbosity=vrb) except: - print("Update failed: %s" % - traceback.format_exc().splitlines()[-1]) - raise SystemExit(1) + self.errExit("Update failed: %s" % sys.exc_info()[1]) elif args[0] == 'purge': expired = False client = None @@ -124,22 +121,20 @@ class Reports(Bcfg2.Server.Admin.Mode): maxdate = datetime.datetime.now() - \ datetime.timedelta(days=int(args[i + 1])) except: - self.log.error("Invalid number of days: %s" % - args[i + 1]) - raise SystemExit(-1) + self.errExit("Invalid number of days: %s" % + args[i + 1]) i = i + 1 elif args[i] == '--expired': expired = True i = i + 1 if expired: if state: - self.log.error("--state is not valid with --expired") - raise SystemExit(-1) + self.errExit("--state is not valid with --expired") self.purge_expired(maxdate) else: self.purge(client, maxdate, state) else: - print("Unknown command: %s" % args[0]) + self.errExit("Unknown command: %s" % args[0]) @transaction.commit_on_success def scrub(self): @@ -155,8 +150,7 @@ class Reports(Bcfg2.Server.Admin.Mode): (start_count - cls.objects.count(), cls.__class__.__name__)) except: print("Failed to prune %s: %s" % - (cls.__class__.__name__, - traceback.format_exc().splitlines()[-1])) + (cls.__class__.__name__, sys.exc_info()[1])) def django_command_proxy(self, command): '''Call a django command''' @@ -180,8 +174,7 @@ class Reports(Bcfg2.Server.Admin.Mode): cobj = Client.objects.get(name=client) ipurge = ipurge.filter(client=cobj) except Client.DoesNotExist: - self.log.error("Client %s not in database" % client) - raise SystemExit(-1) + self.errExit("Client %s not in database" % client) self.log.debug("Filtering by client: %s" % client) if maxdate: diff --git a/src/lib/Bcfg2/Server/Admin/Syncdb.py b/src/lib/Bcfg2/Server/Admin/Syncdb.py index 4ba840b86..53cfd1bec 100644 --- a/src/lib/Bcfg2/Server/Admin/Syncdb.py +++ b/src/lib/Bcfg2/Server/Admin/Syncdb.py @@ -22,10 +22,7 @@ class Syncdb(Bcfg2.Server.Admin.Mode): call_command("syncdb", interactive=False, verbosity=0) self._database_available = True except ImproperlyConfigured: - err = sys.exc_info()[1] - self.log.error("Django configuration problem: %s" % err) - raise SystemExit(1) + self.errExit("Django configuration problem: %s" % + sys.exc_info()[1]) except: - err = sys.exc_info()[1] - self.log.error("Database update failed: %s" % err) - raise SystemExit(1) + self.errExit("Database update failed: %s" % sys.exc_info()[1]) diff --git a/src/lib/Bcfg2/Server/Admin/Xcmd.py b/src/lib/Bcfg2/Server/Admin/Xcmd.py index be556bed4..e3173e20a 100644 --- a/src/lib/Bcfg2/Server/Admin/Xcmd.py +++ b/src/lib/Bcfg2/Server/Admin/Xcmd.py @@ -31,27 +31,15 @@ class Xcmd(Bcfg2.Server.Admin.Mode): ca=setup['ca'], timeout=setup['timeout']) if len(setup['args']) == 0: - print("Usage: xcmd ") - return + self.errExit("Usage: xcmd ") cmd = setup['args'][0] args = () if len(setup['args']) > 1: args = tuple(setup['args'][1:]) try: data = getattr(proxy, cmd)(*args) - except xmlrpclib.Fault: - flt = sys.exc_info()[1] - if flt.faultCode == 7: - print("Unknown method %s" % cmd) - return - elif flt.faultCode == 20: - return - else: - raise except Bcfg2.Proxy.ProxyError: - err = sys.exc_info()[1] - print("Proxy Error: %s" % err) - return + self.errExit("Proxy Error: %s" % sys.exc_info()[1]) if data is not None: print(data) -- cgit v1.2.3-1-g7c22 From 06dae2a73ae03ea72feed4e7d6e56d25cfa24195 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Mon, 3 Jun 2013 10:56:26 -0400 Subject: Revert "bcfg2-admin: set appropriate return values on error" This reverts commit dae8f399151052fd2a0ce43ac61a56f399a28252. Splitting this into two commits. --- src/lib/Bcfg2/Server/Admin/Client.py | 12 ++++++++---- src/lib/Bcfg2/Server/Admin/Compare.py | 3 ++- src/lib/Bcfg2/Server/Admin/Minestruct.py | 11 +++++++---- src/lib/Bcfg2/Server/Admin/Pull.py | 3 ++- src/lib/Bcfg2/Server/Admin/Reports.py | 23 +++++++++++++++-------- src/lib/Bcfg2/Server/Admin/Syncdb.py | 9 ++++++--- src/lib/Bcfg2/Server/Admin/Xcmd.py | 16 ++++++++++++++-- 7 files changed, 54 insertions(+), 23 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Admin/Client.py b/src/lib/Bcfg2/Server/Admin/Client.py index 187ccfd71..570e993ed 100644 --- a/src/lib/Bcfg2/Server/Admin/Client.py +++ b/src/lib/Bcfg2/Server/Admin/Client.py @@ -18,15 +18,19 @@ class Client(Bcfg2.Server.Admin.MetadataCore): try: self.metadata.add_client(args[1]) except MetadataConsistencyError: - self.errExit("Error in adding client: %s" % sys.exc_info()[1]) + err = sys.exc_info()[1] + print("Error in adding client: %s" % err) + raise SystemExit(1) elif args[0] in ['delete', 'remove', 'del', 'rm']: try: self.metadata.remove_client(args[1]) except MetadataConsistencyError: - self.errExit("Error in deleting client: %s" % - sys.exc_info()[1]) + err = sys.exc_info()[1] + print("Error in deleting client: %s" % err) + raise SystemExit(1) elif args[0] in ['list', 'ls']: for client in self.metadata.list_clients(): print(client) else: - self.errExit("No command specified") + print("No command specified") + raise SystemExit(1) diff --git a/src/lib/Bcfg2/Server/Admin/Compare.py b/src/lib/Bcfg2/Server/Admin/Compare.py index e3648a6d0..c56dd0a8f 100644 --- a/src/lib/Bcfg2/Server/Admin/Compare.py +++ b/src/lib/Bcfg2/Server/Admin/Compare.py @@ -145,4 +145,5 @@ class Compare(Bcfg2.Server.Admin.Mode): (old, new) = args return self.compareSpecifications(new, old) except IndexError: - self.errExit(self.__call__.__doc__) + print(self.__call__.__doc__) + raise SystemExit(1) diff --git a/src/lib/Bcfg2/Server/Admin/Minestruct.py b/src/lib/Bcfg2/Server/Admin/Minestruct.py index 21a56de23..93e42305c 100644 --- a/src/lib/Bcfg2/Server/Admin/Minestruct.py +++ b/src/lib/Bcfg2/Server/Admin/Minestruct.py @@ -21,7 +21,8 @@ class Minestruct(Bcfg2.Server.Admin.StructureMode): try: (opts, args) = getopt.getopt(args, 'f:g:h') except: - self.errExit(self.__doc__) + self.log.error(self.__doc__) + raise SystemExit(1) client = args[0] output = sys.stdout @@ -32,7 +33,8 @@ class Minestruct(Bcfg2.Server.Admin.StructureMode): try: output = open(optarg, 'w') except IOError: - self.errExit("Failed to open file: %s" % (optarg)) + self.log.error("Failed to open file: %s" % (optarg)) + raise SystemExit(1) elif opt == '-g': groups = optarg.split(':') @@ -42,8 +44,9 @@ class Minestruct(Bcfg2.Server.Admin.StructureMode): for item in source.GetExtra(client): extra.add(item) except: - self.errExit("Failed to find extra entry info for client %s" % - client) + self.log.error("Failed to find extra entry info for client %s" % + client) + raise SystemExit(1) root = lxml.etree.Element("Base") self.log.info("Found %d extra entries" % (len(extra))) add_point = root diff --git a/src/lib/Bcfg2/Server/Admin/Pull.py b/src/lib/Bcfg2/Server/Admin/Pull.py index cc0dced82..8001425df 100644 --- a/src/lib/Bcfg2/Server/Admin/Pull.py +++ b/src/lib/Bcfg2/Server/Admin/Pull.py @@ -33,7 +33,8 @@ class Pull(Bcfg2.Server.Admin.MetadataCore): try: opts, gargs = getopt.getopt(args, 'vfIs') except: - self.errExit(self.__doc__) + print(self.__doc__) + raise SystemExit(1) for opt in opts: if opt[0] == '-v': self.log = True diff --git a/src/lib/Bcfg2/Server/Admin/Reports.py b/src/lib/Bcfg2/Server/Admin/Reports.py index 849df8025..6e313e84b 100644 --- a/src/lib/Bcfg2/Server/Admin/Reports.py +++ b/src/lib/Bcfg2/Server/Admin/Reports.py @@ -79,7 +79,8 @@ class Reports(Bcfg2.Server.Admin.Mode): def __call__(self, args): if len(args) == 0 or args[0] == '-h': - self.errExit(self.__usage__) + print(self.__usage__) + raise SystemExit(0) # FIXME - dry run @@ -100,7 +101,9 @@ class Reports(Bcfg2.Server.Admin.Mode): management.call_command("syncdb", verbosity=vrb) management.call_command("migrate", verbosity=vrb) except: - self.errExit("Update failed: %s" % sys.exc_info()[1]) + print("Update failed: %s" % + traceback.format_exc().splitlines()[-1]) + raise SystemExit(1) elif args[0] == 'purge': expired = False client = None @@ -121,20 +124,22 @@ class Reports(Bcfg2.Server.Admin.Mode): maxdate = datetime.datetime.now() - \ datetime.timedelta(days=int(args[i + 1])) except: - self.errExit("Invalid number of days: %s" % - args[i + 1]) + self.log.error("Invalid number of days: %s" % + args[i + 1]) + raise SystemExit(-1) i = i + 1 elif args[i] == '--expired': expired = True i = i + 1 if expired: if state: - self.errExit("--state is not valid with --expired") + self.log.error("--state is not valid with --expired") + raise SystemExit(-1) self.purge_expired(maxdate) else: self.purge(client, maxdate, state) else: - self.errExit("Unknown command: %s" % args[0]) + print("Unknown command: %s" % args[0]) @transaction.commit_on_success def scrub(self): @@ -150,7 +155,8 @@ class Reports(Bcfg2.Server.Admin.Mode): (start_count - cls.objects.count(), cls.__class__.__name__)) except: print("Failed to prune %s: %s" % - (cls.__class__.__name__, sys.exc_info()[1])) + (cls.__class__.__name__, + traceback.format_exc().splitlines()[-1])) def django_command_proxy(self, command): '''Call a django command''' @@ -174,7 +180,8 @@ class Reports(Bcfg2.Server.Admin.Mode): cobj = Client.objects.get(name=client) ipurge = ipurge.filter(client=cobj) except Client.DoesNotExist: - self.errExit("Client %s not in database" % client) + self.log.error("Client %s not in database" % client) + raise SystemExit(-1) self.log.debug("Filtering by client: %s" % client) if maxdate: diff --git a/src/lib/Bcfg2/Server/Admin/Syncdb.py b/src/lib/Bcfg2/Server/Admin/Syncdb.py index 53cfd1bec..4ba840b86 100644 --- a/src/lib/Bcfg2/Server/Admin/Syncdb.py +++ b/src/lib/Bcfg2/Server/Admin/Syncdb.py @@ -22,7 +22,10 @@ class Syncdb(Bcfg2.Server.Admin.Mode): call_command("syncdb", interactive=False, verbosity=0) self._database_available = True except ImproperlyConfigured: - self.errExit("Django configuration problem: %s" % - sys.exc_info()[1]) + err = sys.exc_info()[1] + self.log.error("Django configuration problem: %s" % err) + raise SystemExit(1) except: - self.errExit("Database update failed: %s" % sys.exc_info()[1]) + err = sys.exc_info()[1] + self.log.error("Database update failed: %s" % err) + raise SystemExit(1) diff --git a/src/lib/Bcfg2/Server/Admin/Xcmd.py b/src/lib/Bcfg2/Server/Admin/Xcmd.py index e3173e20a..be556bed4 100644 --- a/src/lib/Bcfg2/Server/Admin/Xcmd.py +++ b/src/lib/Bcfg2/Server/Admin/Xcmd.py @@ -31,15 +31,27 @@ class Xcmd(Bcfg2.Server.Admin.Mode): ca=setup['ca'], timeout=setup['timeout']) if len(setup['args']) == 0: - self.errExit("Usage: xcmd ") + print("Usage: xcmd ") + return cmd = setup['args'][0] args = () if len(setup['args']) > 1: args = tuple(setup['args'][1:]) try: data = getattr(proxy, cmd)(*args) + except xmlrpclib.Fault: + flt = sys.exc_info()[1] + if flt.faultCode == 7: + print("Unknown method %s" % cmd) + return + elif flt.faultCode == 20: + return + else: + raise except Bcfg2.Proxy.ProxyError: - self.errExit("Proxy Error: %s" % sys.exc_info()[1]) + err = sys.exc_info()[1] + print("Proxy Error: %s" % err) + return if data is not None: print(data) -- cgit v1.2.3-1-g7c22 From 7175d64e3b4c150340bb71363e5a25faac80e21e Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Mon, 3 Jun 2013 10:57:00 -0400 Subject: bcfg2-admin: set appropriate return values on error --- src/lib/Bcfg2/Server/Admin/Client.py | 12 ++++-------- src/lib/Bcfg2/Server/Admin/Compare.py | 3 +-- src/lib/Bcfg2/Server/Admin/Minestruct.py | 11 ++++------- src/lib/Bcfg2/Server/Admin/Pull.py | 3 +-- src/lib/Bcfg2/Server/Admin/Reports.py | 23 ++++++++--------------- src/lib/Bcfg2/Server/Admin/Syncdb.py | 9 +++------ src/lib/Bcfg2/Server/Admin/Xcmd.py | 16 ++-------------- 7 files changed, 23 insertions(+), 54 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Admin/Client.py b/src/lib/Bcfg2/Server/Admin/Client.py index 570e993ed..187ccfd71 100644 --- a/src/lib/Bcfg2/Server/Admin/Client.py +++ b/src/lib/Bcfg2/Server/Admin/Client.py @@ -18,19 +18,15 @@ class Client(Bcfg2.Server.Admin.MetadataCore): try: self.metadata.add_client(args[1]) except MetadataConsistencyError: - err = sys.exc_info()[1] - print("Error in adding client: %s" % err) - raise SystemExit(1) + self.errExit("Error in adding client: %s" % sys.exc_info()[1]) elif args[0] in ['delete', 'remove', 'del', 'rm']: try: self.metadata.remove_client(args[1]) except MetadataConsistencyError: - err = sys.exc_info()[1] - print("Error in deleting client: %s" % err) - raise SystemExit(1) + self.errExit("Error in deleting client: %s" % + sys.exc_info()[1]) elif args[0] in ['list', 'ls']: for client in self.metadata.list_clients(): print(client) else: - print("No command specified") - raise SystemExit(1) + self.errExit("No command specified") diff --git a/src/lib/Bcfg2/Server/Admin/Compare.py b/src/lib/Bcfg2/Server/Admin/Compare.py index c56dd0a8f..e3648a6d0 100644 --- a/src/lib/Bcfg2/Server/Admin/Compare.py +++ b/src/lib/Bcfg2/Server/Admin/Compare.py @@ -145,5 +145,4 @@ class Compare(Bcfg2.Server.Admin.Mode): (old, new) = args return self.compareSpecifications(new, old) except IndexError: - print(self.__call__.__doc__) - raise SystemExit(1) + self.errExit(self.__call__.__doc__) diff --git a/src/lib/Bcfg2/Server/Admin/Minestruct.py b/src/lib/Bcfg2/Server/Admin/Minestruct.py index 93e42305c..21a56de23 100644 --- a/src/lib/Bcfg2/Server/Admin/Minestruct.py +++ b/src/lib/Bcfg2/Server/Admin/Minestruct.py @@ -21,8 +21,7 @@ class Minestruct(Bcfg2.Server.Admin.StructureMode): try: (opts, args) = getopt.getopt(args, 'f:g:h') except: - self.log.error(self.__doc__) - raise SystemExit(1) + self.errExit(self.__doc__) client = args[0] output = sys.stdout @@ -33,8 +32,7 @@ class Minestruct(Bcfg2.Server.Admin.StructureMode): try: output = open(optarg, 'w') except IOError: - self.log.error("Failed to open file: %s" % (optarg)) - raise SystemExit(1) + self.errExit("Failed to open file: %s" % (optarg)) elif opt == '-g': groups = optarg.split(':') @@ -44,9 +42,8 @@ class Minestruct(Bcfg2.Server.Admin.StructureMode): for item in source.GetExtra(client): extra.add(item) except: - self.log.error("Failed to find extra entry info for client %s" % - client) - raise SystemExit(1) + self.errExit("Failed to find extra entry info for client %s" % + client) root = lxml.etree.Element("Base") self.log.info("Found %d extra entries" % (len(extra))) add_point = root diff --git a/src/lib/Bcfg2/Server/Admin/Pull.py b/src/lib/Bcfg2/Server/Admin/Pull.py index 8001425df..cc0dced82 100644 --- a/src/lib/Bcfg2/Server/Admin/Pull.py +++ b/src/lib/Bcfg2/Server/Admin/Pull.py @@ -33,8 +33,7 @@ class Pull(Bcfg2.Server.Admin.MetadataCore): try: opts, gargs = getopt.getopt(args, 'vfIs') except: - print(self.__doc__) - raise SystemExit(1) + self.errExit(self.__doc__) for opt in opts: if opt[0] == '-v': self.log = True diff --git a/src/lib/Bcfg2/Server/Admin/Reports.py b/src/lib/Bcfg2/Server/Admin/Reports.py index 6e313e84b..849df8025 100644 --- a/src/lib/Bcfg2/Server/Admin/Reports.py +++ b/src/lib/Bcfg2/Server/Admin/Reports.py @@ -79,8 +79,7 @@ class Reports(Bcfg2.Server.Admin.Mode): def __call__(self, args): if len(args) == 0 or args[0] == '-h': - print(self.__usage__) - raise SystemExit(0) + self.errExit(self.__usage__) # FIXME - dry run @@ -101,9 +100,7 @@ class Reports(Bcfg2.Server.Admin.Mode): management.call_command("syncdb", verbosity=vrb) management.call_command("migrate", verbosity=vrb) except: - print("Update failed: %s" % - traceback.format_exc().splitlines()[-1]) - raise SystemExit(1) + self.errExit("Update failed: %s" % sys.exc_info()[1]) elif args[0] == 'purge': expired = False client = None @@ -124,22 +121,20 @@ class Reports(Bcfg2.Server.Admin.Mode): maxdate = datetime.datetime.now() - \ datetime.timedelta(days=int(args[i + 1])) except: - self.log.error("Invalid number of days: %s" % - args[i + 1]) - raise SystemExit(-1) + self.errExit("Invalid number of days: %s" % + args[i + 1]) i = i + 1 elif args[i] == '--expired': expired = True i = i + 1 if expired: if state: - self.log.error("--state is not valid with --expired") - raise SystemExit(-1) + self.errExit("--state is not valid with --expired") self.purge_expired(maxdate) else: self.purge(client, maxdate, state) else: - print("Unknown command: %s" % args[0]) + self.errExit("Unknown command: %s" % args[0]) @transaction.commit_on_success def scrub(self): @@ -155,8 +150,7 @@ class Reports(Bcfg2.Server.Admin.Mode): (start_count - cls.objects.count(), cls.__class__.__name__)) except: print("Failed to prune %s: %s" % - (cls.__class__.__name__, - traceback.format_exc().splitlines()[-1])) + (cls.__class__.__name__, sys.exc_info()[1])) def django_command_proxy(self, command): '''Call a django command''' @@ -180,8 +174,7 @@ class Reports(Bcfg2.Server.Admin.Mode): cobj = Client.objects.get(name=client) ipurge = ipurge.filter(client=cobj) except Client.DoesNotExist: - self.log.error("Client %s not in database" % client) - raise SystemExit(-1) + self.errExit("Client %s not in database" % client) self.log.debug("Filtering by client: %s" % client) if maxdate: diff --git a/src/lib/Bcfg2/Server/Admin/Syncdb.py b/src/lib/Bcfg2/Server/Admin/Syncdb.py index 4ba840b86..53cfd1bec 100644 --- a/src/lib/Bcfg2/Server/Admin/Syncdb.py +++ b/src/lib/Bcfg2/Server/Admin/Syncdb.py @@ -22,10 +22,7 @@ class Syncdb(Bcfg2.Server.Admin.Mode): call_command("syncdb", interactive=False, verbosity=0) self._database_available = True except ImproperlyConfigured: - err = sys.exc_info()[1] - self.log.error("Django configuration problem: %s" % err) - raise SystemExit(1) + self.errExit("Django configuration problem: %s" % + sys.exc_info()[1]) except: - err = sys.exc_info()[1] - self.log.error("Database update failed: %s" % err) - raise SystemExit(1) + self.errExit("Database update failed: %s" % sys.exc_info()[1]) diff --git a/src/lib/Bcfg2/Server/Admin/Xcmd.py b/src/lib/Bcfg2/Server/Admin/Xcmd.py index be556bed4..e3173e20a 100644 --- a/src/lib/Bcfg2/Server/Admin/Xcmd.py +++ b/src/lib/Bcfg2/Server/Admin/Xcmd.py @@ -31,27 +31,15 @@ class Xcmd(Bcfg2.Server.Admin.Mode): ca=setup['ca'], timeout=setup['timeout']) if len(setup['args']) == 0: - print("Usage: xcmd ") - return + self.errExit("Usage: xcmd ") cmd = setup['args'][0] args = () if len(setup['args']) > 1: args = tuple(setup['args'][1:]) try: data = getattr(proxy, cmd)(*args) - except xmlrpclib.Fault: - flt = sys.exc_info()[1] - if flt.faultCode == 7: - print("Unknown method %s" % cmd) - return - elif flt.faultCode == 20: - return - else: - raise except Bcfg2.Proxy.ProxyError: - err = sys.exc_info()[1] - print("Proxy Error: %s" % err) - return + self.errExit("Proxy Error: %s" % sys.exc_info()[1]) if data is not None: print(data) -- cgit v1.2.3-1-g7c22 From b026f9b9a407a359b4d5615b1fb469f84b260218 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Mon, 3 Jun 2013 10:47:02 -0500 Subject: Services: Don't check status when set to 'ignore' Checking the status for services that don't support it leads to ugly output in the interactive client on some platforms. Signed-off-by: Sol Jerome --- src/lib/Bcfg2/Client/Tools/Chkconfig.py | 29 +++++++++++++------------- src/lib/Bcfg2/Client/Tools/DebInit.py | 36 +++++++++++++++++---------------- src/lib/Bcfg2/Client/Tools/RcUpdate.py | 30 ++++++++++++++------------- 3 files changed, 50 insertions(+), 45 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Client/Tools/Chkconfig.py b/src/lib/Bcfg2/Client/Tools/Chkconfig.py index 0f5f32302..256c28255 100644 --- a/src/lib/Bcfg2/Client/Tools/Chkconfig.py +++ b/src/lib/Bcfg2/Client/Tools/Chkconfig.py @@ -57,27 +57,28 @@ class Chkconfig(Bcfg2.Client.Tools.SvcTool): return True current_bootstatus = self.verify_bootstatus(entry, bootstatus) - svcstatus = self.check_service(entry) - if entry.get('status') == 'on': - if svcstatus: - current_srvstatus = True - else: - current_srvstatus = False - elif entry.get('status') == 'off': - if svcstatus: - current_srvstatus = False - else: - current_srvstatus = True - else: + if entry.get('status') == 'ignore': # 'ignore' should verify - current_srvstatus = True + current_svcstatus = True + else: + svcstatus = self.check_service(entry) + if entry.get('status') == 'on': + if svcstatus: + current_svcstatus = True + else: + current_svcstatus = False + elif entry.get('status') == 'off': + if svcstatus: + current_svcstatus = False + else: + current_svcstatus = True if svcstatus: entry.set('current_status', 'on') else: entry.set('current_status', 'off') - return current_bootstatus and current_srvstatus + return current_bootstatus and current_svcstatus def InstallService(self, entry): """Install Service entry.""" diff --git a/src/lib/Bcfg2/Client/Tools/DebInit.py b/src/lib/Bcfg2/Client/Tools/DebInit.py index 116d4f8b0..761c51db7 100644 --- a/src/lib/Bcfg2/Client/Tools/DebInit.py +++ b/src/lib/Bcfg2/Client/Tools/DebInit.py @@ -18,6 +18,9 @@ class DebInit(Bcfg2.Client.Tools.SvcTool): svcre = \ re.compile(r'/etc/.*/(?P[SK])(?P\d+)(?P\S+)') + def get_svc_command(self, service, action): + return '/usr/sbin/invoke-rc.d %s %s' % (service.get('name'), action) + def verify_bootstatus(self, entry, bootstatus): """Verify bootstatus for entry.""" rawfiles = glob.glob("/etc/rc*.d/[SK]*%s" % (entry.get('name'))) @@ -78,27 +81,29 @@ class DebInit(Bcfg2.Client.Tools.SvcTool): return True current_bootstatus = self.verify_bootstatus(entry, bootstatus) - svcstatus = self.check_service(entry) - if entry.get('status') == 'on': - if svcstatus: - current_srvstatus = True - else: - current_srvstatus = False - elif entry.get('status') == 'off': - if svcstatus: - current_srvstatus = False - else: - current_srvstatus = True - else: + if entry.get('status') == 'ignore': # 'ignore' should verify - current_srvstatus = True + current_svcstatus = True + svcstatus = True + else: + svcstatus = self.check_service(entry) + if entry.get('status') == 'on': + if svcstatus: + current_svcstatus = True + else: + current_svcstatus = False + elif entry.get('status') == 'off': + if svcstatus: + current_svcstatus = False + else: + current_svcstatus = True if svcstatus: entry.set('current_status', 'on') else: entry.set('current_status', 'off') - return current_bootstatus and current_srvstatus + return current_bootstatus and current_svcstatus def InstallService(self, entry): """Install Service entry.""" @@ -165,6 +170,3 @@ class DebInit(Bcfg2.Client.Tools.SvcTool): # Extra service removal is nonsensical # Extra services need to be reflected in the config return - - def get_svc_command(self, service, action): - return '/usr/sbin/invoke-rc.d %s %s' % (service.get('name'), action) diff --git a/src/lib/Bcfg2/Client/Tools/RcUpdate.py b/src/lib/Bcfg2/Client/Tools/RcUpdate.py index d6329256e..8e9626521 100644 --- a/src/lib/Bcfg2/Client/Tools/RcUpdate.py +++ b/src/lib/Bcfg2/Client/Tools/RcUpdate.py @@ -62,27 +62,29 @@ class RcUpdate(Bcfg2.Client.Tools.SvcTool): entry.get('name')) return False - svcstatus = self.check_service(entry) - if entry.get('status') == 'on': - if svcstatus: - current_srvstatus = True - else: - current_srvstatus = False - elif entry.get('status') == 'off': - if svcstatus: - current_srvstatus = False - else: - current_srvstatus = True - else: + if entry.get('status') == 'ignore': # 'ignore' should verify - current_srvstatus = True + current_svcstatus = True + svcstatus = True + else: + svcstatus = self.check_service(entry) + if entry.get('status') == 'on': + if svcstatus: + current_svcstatus = True + else: + current_svcstatus = False + elif entry.get('status') == 'off': + if svcstatus: + current_svcstatus = False + else: + current_svcstatus = True if svcstatus: entry.set('current_status', 'on') else: entry.set('current_status', 'off') - return current_bootstatus and current_srvstatus + return current_bootstatus and current_svcstatus def InstallService(self, entry): """Install Service entry.""" -- cgit v1.2.3-1-g7c22 From 3ed8637d59fcfe7b38aaa3f8717b0269d2c4650c Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Mon, 3 Jun 2013 13:16:21 -0400 Subject: fixed unit tests --- src/lib/Bcfg2/Server/Admin/Minestruct.py | 4 ++-- src/lib/Bcfg2/Server/Admin/Pull.py | 2 +- src/lib/Bcfg2/Server/Admin/Xcmd.py | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Admin/Minestruct.py b/src/lib/Bcfg2/Server/Admin/Minestruct.py index 21a56de23..37ca74894 100644 --- a/src/lib/Bcfg2/Server/Admin/Minestruct.py +++ b/src/lib/Bcfg2/Server/Admin/Minestruct.py @@ -20,7 +20,7 @@ class Minestruct(Bcfg2.Server.Admin.StructureMode): "Please see bcfg2-admin minestruct help for usage.") try: (opts, args) = getopt.getopt(args, 'f:g:h') - except: + except getopt.GetoptError: self.errExit(self.__doc__) client = args[0] @@ -41,7 +41,7 @@ class Minestruct(Bcfg2.Server.Admin.StructureMode): for source in self.bcore.plugins_by_type(PullSource): for item in source.GetExtra(client): extra.add(item) - except: + except: # pylint: disable=W0702 self.errExit("Failed to find extra entry info for client %s" % client) root = lxml.etree.Element("Base") diff --git a/src/lib/Bcfg2/Server/Admin/Pull.py b/src/lib/Bcfg2/Server/Admin/Pull.py index cc0dced82..459fcec65 100644 --- a/src/lib/Bcfg2/Server/Admin/Pull.py +++ b/src/lib/Bcfg2/Server/Admin/Pull.py @@ -32,7 +32,7 @@ class Pull(Bcfg2.Server.Admin.MetadataCore): use_stdin = False try: opts, gargs = getopt.getopt(args, 'vfIs') - except: + except getopt.GetoptError: self.errExit(self.__doc__) for opt in opts: if opt[0] == '-v': diff --git a/src/lib/Bcfg2/Server/Admin/Xcmd.py b/src/lib/Bcfg2/Server/Admin/Xcmd.py index e3173e20a..036129a1b 100644 --- a/src/lib/Bcfg2/Server/Admin/Xcmd.py +++ b/src/lib/Bcfg2/Server/Admin/Xcmd.py @@ -4,7 +4,6 @@ import sys import Bcfg2.Options import Bcfg2.Proxy import Bcfg2.Server.Admin -from Bcfg2.Compat import xmlrpclib class Xcmd(Bcfg2.Server.Admin.Mode): -- cgit v1.2.3-1-g7c22 From c9d2dba282f8fe97c06646d89facbf5ae7b24b58 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Mon, 3 Jun 2013 16:31:14 -0400 Subject: Frame: quiet down about experimental plugins --- src/lib/Bcfg2/Client/Frame.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Client/Frame.py b/src/lib/Bcfg2/Client/Frame.py index d30708e83..6bef77081 100644 --- a/src/lib/Bcfg2/Client/Frame.py +++ b/src/lib/Bcfg2/Client/Frame.py @@ -97,8 +97,8 @@ class Frame(object): self.logger.warning(deprecated) experimental = [tool.name for tool in self.tools if tool.experimental] if experimental: - self.logger.warning("Loaded experimental tool drivers:") - self.logger.warning(experimental) + self.logger.info("Loaded experimental tool drivers:") + self.logger.info(experimental) # find entries not handled by any tools self.unhandled = [entry for struct in config -- cgit v1.2.3-1-g7c22 From d071bc08bfdaf154f1691999e5f413c7a3b634af Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Mon, 3 Jun 2013 16:31:37 -0400 Subject: Core: don't unnecessarily set debug to False on server startup --- src/lib/Bcfg2/Server/Core.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Core.py b/src/lib/Bcfg2/Server/Core.py index c246860c1..6e0d38418 100644 --- a/src/lib/Bcfg2/Server/Core.py +++ b/src/lib/Bcfg2/Server/Core.py @@ -785,7 +785,8 @@ class BaseCore(object): while self.fam.pending() != 0: time.sleep(1) - self.set_debug(None, self.debug_flag) + if self.debug_flag: + self.set_debug(None, self.debug_flag) self._block() def _daemonize(self): -- cgit v1.2.3-1-g7c22 From 03950f97157d270cbc452d239b2e124d10e84f8e Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Wed, 5 Jun 2013 13:20:07 -0500 Subject: Reporting: exclude failures type from detail view Signed-off-by: Sol Jerome --- src/lib/Bcfg2/Reporting/views.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Reporting/views.py b/src/lib/Bcfg2/Reporting/views.py index 6cba7bf8c..c7c2a503f 100644 --- a/src/lib/Bcfg2/Reporting/views.py +++ b/src/lib/Bcfg2/Reporting/views.py @@ -338,6 +338,8 @@ def client_detail(request, hostname=None, pk=None): for label in etypes.values(): edict[label] = [] for ekind in inter.entry_types: + if ekind == 'failures': + continue for ent in getattr(inter, ekind).all(): edict[etypes[ent.state]].append(ent) context['entry_types'] = edict -- cgit v1.2.3-1-g7c22 From 844b02afe60de45310fd88be75686dffc21c37aa Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Sat, 8 Jun 2013 19:48:20 -0500 Subject: POSIX: Fix support for unicode files Signed-off-by: Sol Jerome --- src/lib/Bcfg2/Client/Tools/POSIX/File.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/File.py b/src/lib/Bcfg2/Client/Tools/POSIX/File.py index 168c35c98..6525b02e0 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/File.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/File.py @@ -163,6 +163,8 @@ class POSIXFile(POSIXTool): # prompts for -I and the reports try: content = open(entry.get('name')).read() + except UnicodeDecodeError: + content = open(entry.get('name'), encoding='utf-8').read() except IOError: self.logger.error("POSIX: Failed to read %s: %s" % (entry.get("name"), sys.exc_info()[1])) -- cgit v1.2.3-1-g7c22 From 895ee050b26bef8c17b06679036f6a0e44096c71 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Wed, 12 Jun 2013 09:52:42 -0500 Subject: Client: Exit when ^C is pressed interactively Signed-off-by: Sol Jerome --- src/lib/Bcfg2/Client/__init__.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Client/__init__.py b/src/lib/Bcfg2/Client/__init__.py index 3bc261f2f..25603186e 100644 --- a/src/lib/Bcfg2/Client/__init__.py +++ b/src/lib/Bcfg2/Client/__init__.py @@ -22,8 +22,5 @@ def prompt(msg): ans = input(msg) return ans in ['y', 'Y'] except EOFError: - # python 2.4.3 on CentOS doesn't like ^C for some reason - return False - except: - print("Error while reading input: %s" % sys.exc_info()[1]) - return False + # handle ^C on rhel-based platforms + raise SystemExit(1) -- cgit v1.2.3-1-g7c22 From 9173c94a53a4c4d9fd853ab9d25ad5e5a3c230c1 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Wed, 12 Jun 2013 16:17:00 -0400 Subject: fixed unit tests --- src/lib/Bcfg2/Client/Tools/POSIX/File.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/File.py b/src/lib/Bcfg2/Client/Tools/POSIX/File.py index 6525b02e0..9f47fb53a 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/File.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/File.py @@ -146,8 +146,8 @@ class POSIXFile(POSIXTool): return POSIXTool.install(self, entry) and rv - def _get_diffs(self, entry, interactive=False, sensitive=False, - is_binary=False, content=None): + def _get_diffs(self, entry, interactive=False, # pylint: disable=R0912 + sensitive=False, is_binary=False, content=None): """ generate the necessary diffs for entry """ if not interactive and sensitive: return -- cgit v1.2.3-1-g7c22 From fbf6edf62b7b105abb467ef5cb9254eb8f5396c6 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Thu, 13 Jun 2013 12:44:55 -0400 Subject: Probes: reduce race condition that can result in multiple probe groups --- src/lib/Bcfg2/Server/Plugins/Probes.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Plugins/Probes.py b/src/lib/Bcfg2/Server/Plugins/Probes.py index f8baddb4b..1a199d056 100644 --- a/src/lib/Bcfg2/Server/Plugins/Probes.py +++ b/src/lib/Bcfg2/Server/Plugins/Probes.py @@ -252,12 +252,15 @@ class Probes(Bcfg2.Server.Plugin.Probing, for group in self.cgroups[client.hostname]: try: - ProbesGroupsModel.objects.get(hostname=client.hostname, - group=group) - except ProbesGroupsModel.DoesNotExist: - grp = ProbesGroupsModel(hostname=client.hostname, - group=group) - grp.save() + ProbesGroupsModel.objects.get_or_create( + hostname=client.hostname, + group=group).save() + except ProbesGroupsModel.MultipleObjectsReturned: + ProbesGroupsModel.objects.filter(hostname=client.hostname, + group=group).delete() + ProbesGroupsModel.objects.get_or_create( + hostname=client.hostname, + group=group).save() ProbesGroupsModel.objects.filter( hostname=client.hostname).exclude( group__in=self.cgroups[client.hostname]).delete() -- cgit v1.2.3-1-g7c22 From a03fde3ea32d3eb2cadb443454749111dda1797f Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Thu, 13 Jun 2013 14:58:05 -0400 Subject: do not create data directories for plugins that don't need them --- src/lib/Bcfg2/Server/Plugin/base.py | 6 +++++- src/lib/Bcfg2/Server/Plugin/interfaces.py | 4 ++++ src/lib/Bcfg2/Server/Plugins/Metadata.py | 2 ++ src/lib/Bcfg2/Server/Plugins/POSIXCompat.py | 2 ++ src/lib/Bcfg2/Server/Plugins/ServiceCompat.py | 4 +++- 5 files changed, 16 insertions(+), 2 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Plugin/base.py b/src/lib/Bcfg2/Server/Plugin/base.py index ecd970b54..c825a57b5 100644 --- a/src/lib/Bcfg2/Server/Plugin/base.py +++ b/src/lib/Bcfg2/Server/Plugin/base.py @@ -87,6 +87,10 @@ class Plugin(Debuggable): #: alphabetically by their name. sort_order = 500 + #: Whether or not to automatically create a data directory for + #: this plugin + create = True + #: List of names of methods to be exposed as XML-RPC functions __rmi__ = Debuggable.__rmi__ @@ -107,7 +111,7 @@ class Plugin(Debuggable): self.Entries = {} self.core = core self.data = os.path.join(datastore, self.name) - if not os.path.exists(self.data): + if self.create and not os.path.exists(self.data): self.logger.warning("%s: %s does not exist, creating" % (self.name, self.data)) os.makedirs(self.data) diff --git a/src/lib/Bcfg2/Server/Plugin/interfaces.py b/src/lib/Bcfg2/Server/Plugin/interfaces.py index 0fd711be9..222b94fe3 100644 --- a/src/lib/Bcfg2/Server/Plugin/interfaces.py +++ b/src/lib/Bcfg2/Server/Plugin/interfaces.py @@ -286,6 +286,8 @@ class Statistics(Plugin): you should avoid using Statistics and use :class:`ThreadedStatistics` instead.""" + create = False + def process_statistics(self, client, xdata): """ Process the given XML statistics data for the specified client. @@ -526,6 +528,8 @@ class GoalValidator(object): class Version(Plugin): """ Version plugins interact with various version control systems. """ + create = False + #: The path to the VCS metadata file or directory, relative to the #: base of the Bcfg2 repository. E.g., for Subversion this would #: be ".svn" diff --git a/src/lib/Bcfg2/Server/Plugins/Metadata.py b/src/lib/Bcfg2/Server/Plugins/Metadata.py index 3b8361c76..4ed3dede5 100644 --- a/src/lib/Bcfg2/Server/Plugins/Metadata.py +++ b/src/lib/Bcfg2/Server/Plugins/Metadata.py @@ -40,6 +40,8 @@ if HAS_DJANGO: """ dict-like object to make it easier to access client bcfg2 versions from the database """ + create = False + def __getitem__(self, key): try: return MetadataClientModel.objects.get(hostname=key).version diff --git a/src/lib/Bcfg2/Server/Plugins/POSIXCompat.py b/src/lib/Bcfg2/Server/Plugins/POSIXCompat.py index 1736becc7..71128d64c 100644 --- a/src/lib/Bcfg2/Server/Plugins/POSIXCompat.py +++ b/src/lib/Bcfg2/Server/Plugins/POSIXCompat.py @@ -9,6 +9,8 @@ class POSIXCompat(Bcfg2.Server.Plugin.Plugin, Bcfg2.Server.Plugin.GoalValidator): """POSIXCompat is a goal validator plugin for POSIX entries.""" + create = False + def __init__(self, core, datastore): Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) Bcfg2.Server.Plugin.GoalValidator.__init__(self) diff --git a/src/lib/Bcfg2/Server/Plugins/ServiceCompat.py b/src/lib/Bcfg2/Server/Plugins/ServiceCompat.py index c3a2221f6..41e6bf8b5 100644 --- a/src/lib/Bcfg2/Server/Plugins/ServiceCompat.py +++ b/src/lib/Bcfg2/Server/Plugins/ServiceCompat.py @@ -6,7 +6,9 @@ import Bcfg2.Server.Plugin class ServiceCompat(Bcfg2.Server.Plugin.Plugin, Bcfg2.Server.Plugin.GoalValidator): """ Use old-style service modes for older clients """ - name = 'ServiceCompat' + + create = False + __author__ = 'bcfg-dev@mcs.anl.gov' mode_map = {('true', 'true'): 'default', ('interactive', 'true'): 'interactive_only', -- cgit v1.2.3-1-g7c22 From d67baf714e6c6635846e57b9258e649a59430c55 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Thu, 13 Jun 2013 15:25:26 -0400 Subject: Yum: handle and log helper errors better --- src/lib/Bcfg2/Server/Plugins/Packages/Yum.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py index 20b2c9500..4c143e069 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py @@ -878,11 +878,16 @@ class YumCollection(Collection): ``bcfg2-yum-helper`` command. """ cmd = [self.helper, "-c", self.cfgfile] - verbose = self.debug_flag or self.setup['verbose'] - if verbose: + if self.setup['verbose']: + cmd.append("-v") + if self.debug_flag: + if not self.setup['verbose']: + # ensure that running in debug gets -vv, even if + # verbose is not enabled + cmd.append("-v") cmd.append("-v") cmd.append(command) - self.debug_log("Packages: running %s" % " ".join(cmd), flag=verbose) + self.debug_log("Packages: running %s" % " ".join(cmd)) try: helper = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) except OSError: @@ -897,12 +902,18 @@ class YumCollection(Collection): else: (stdout, stderr) = helper.communicate() rv = helper.wait() + errlines = stderr.splitlines() if rv: self.logger.error("Packages: error running bcfg2-yum-helper " - "(returned %d): %s" % (rv, stderr)) + "(returned %d): %s" % (rv, errlines[0])) + for line in errlines[1:]: + self.logger.error("Packages: %s" % line) else: self.debug_log("Packages: debug info from bcfg2-yum-helper: %s" % - stderr, flag=verbose) + lines[0], flag=verbose) + for line in errlines[1:]: + self.debug_log("Packages: %s" % line) + try: return json.loads(stdout) except ValueError: -- cgit v1.2.3-1-g7c22 From 0ee4d98652a4b46113f0d5ede5f721d98023daf7 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Thu, 13 Jun 2013 15:55:00 -0400 Subject: Yum: fixed verbose logging from bcfg2-yum-helper --- src/lib/Bcfg2/Server/Plugins/Packages/Yum.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py index 4c143e069..b7d7ba978 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py @@ -910,7 +910,7 @@ class YumCollection(Collection): self.logger.error("Packages: %s" % line) else: self.debug_log("Packages: debug info from bcfg2-yum-helper: %s" % - lines[0], flag=verbose) + lines[0]) for line in errlines[1:]: self.debug_log("Packages: %s" % line) -- cgit v1.2.3-1-g7c22 From f9ba388e9c9b00d2a3c070eb1b46f4c30c27e6a3 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Thu, 13 Jun 2013 15:57:05 -0400 Subject: Yum: fixed yum-helper logging for real this time, i totally swear --- src/lib/Bcfg2/Server/Plugins/Packages/Yum.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py index b7d7ba978..4330de971 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py @@ -910,7 +910,7 @@ class YumCollection(Collection): self.logger.error("Packages: %s" % line) else: self.debug_log("Packages: debug info from bcfg2-yum-helper: %s" % - lines[0]) + errlines[0]) for line in errlines[1:]: self.debug_log("Packages: %s" % line) -- cgit v1.2.3-1-g7c22 From 5db7ab284f4b83c0b25e68edf258bae912a5b418 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Fri, 14 Jun 2013 10:58:13 -0400 Subject: Cfg: Fixed and documented .cat and .diff file behavior with host-specific base file --- src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py b/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py index 842202a9c..154cd5e63 100644 --- a/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py +++ b/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py @@ -10,7 +10,6 @@ import lxml.etree import Bcfg2.Options import Bcfg2.Server.Plugin import Bcfg2.Server.Lint -from itertools import chain from Bcfg2.Server.Plugin import PluginExecutionError # pylint: disable=W0622 from Bcfg2.Compat import u_str, unicode, b64encode, walk_packages, \ @@ -582,10 +581,18 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet, def bind_entry(self, entry, metadata): self.bind_info_to_entry(entry, metadata) - data = self._generate_data(entry, metadata) - - for fltr in self.get_handlers(metadata, CfgFilter): - data = fltr.modify_data(entry, metadata, data) + data, generator = self._generate_data(entry, metadata) + + if generator is not None: + # apply no filters if the data was created by a CfgCreator + for fltr in self.get_handlers(metadata, CfgFilter): + if fltr.specific <= generator.specific: + # only apply filters that are as specific or more + # specific than the generator used for this entry. + # Note that specificity comparison is backwards in + # this sense, since it's designed to sort from + # most specific to least specific. + data = fltr.modify_data(entry, metadata, data) if SETUP['validate']: try: @@ -694,7 +701,9 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet, :type entry: lxml.etree._Element :param metadata: The client metadata to generate data for :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata - :returns: string - the data for the entry + :returns: tuple of (string, generator) - the data for the + entry and the generator used to generate it (or + None, if data was created) """ try: generator = self.best_matching(metadata, @@ -703,7 +712,7 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet, except PluginExecutionError: # if no creators or generators exist, _create_data() # raises an appropriate exception - return self._create_data(entry, metadata) + return (self._create_data(entry, metadata), None) if entry.get('mode').lower() == 'inherit': # use on-disk permissions @@ -713,7 +722,7 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet, entry.set('mode', oct_mode(stat.S_IMODE(os.stat(fname).st_mode))) try: - return generator.get_data(entry, metadata) + return (generator.get_data(entry, metadata), generator) except: msg = "Cfg: Error rendering %s: %s" % (entry.get("name"), sys.exc_info()[1]) -- cgit v1.2.3-1-g7c22 From fcde897e8bf1ba97838677c6f5c4db43bbaf6aeb Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Fri, 14 Jun 2013 10:58:43 -0400 Subject: Probes: no need to .save() after .get_or_create() --- src/lib/Bcfg2/Server/Plugins/Probes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Plugins/Probes.py b/src/lib/Bcfg2/Server/Plugins/Probes.py index 1a199d056..20e366523 100644 --- a/src/lib/Bcfg2/Server/Plugins/Probes.py +++ b/src/lib/Bcfg2/Server/Plugins/Probes.py @@ -254,7 +254,7 @@ class Probes(Bcfg2.Server.Plugin.Probing, try: ProbesGroupsModel.objects.get_or_create( hostname=client.hostname, - group=group).save() + group=group) except ProbesGroupsModel.MultipleObjectsReturned: ProbesGroupsModel.objects.filter(hostname=client.hostname, group=group).delete() -- cgit v1.2.3-1-g7c22 From de0af523ce59bd1e4c53e10a873fcd961f8f2b30 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Fri, 14 Jun 2013 20:28:42 +0200 Subject: Client/Tools/Action: add shell attribute Add an option to specify whether a command should be executed within a shell to enable flow control and other shell-specific syntax. --- src/lib/Bcfg2/Client/Tools/Action.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Client/Tools/Action.py b/src/lib/Bcfg2/Client/Tools/Action.py index da4412b1d..0166e4c00 100644 --- a/src/lib/Bcfg2/Client/Tools/Action.py +++ b/src/lib/Bcfg2/Client/Tools/Action.py @@ -32,10 +32,17 @@ class Action(Bcfg2.Client.Tools.Tool): def RunAction(self, entry): """This method handles command execution and status return.""" + shell = False + shell_string = '' + if entry.get('shell', 'false') == 'true': + shell = True + shell_string = '(in shell) ' + if not self.setup['dryrun']: if self.setup['interactive']: - prompt = ('Run Action %s, %s: (y/N): ' % - (entry.get('name'), entry.get('command'))) + prompt = ('Run Action %s%s, %s: (y/N): ' % + (shell_string, entry.get('name'), + entry.get('command'))) # flush input buffer while len(select.select([sys.stdin.fileno()], [], [], 0.0)[0]) > 0: @@ -48,8 +55,9 @@ class Action(Bcfg2.Client.Tools.Tool): self.logger.debug("Action: Deferring execution of %s due " "to build mode" % entry.get('command')) return False - self.logger.debug("Running Action %s" % (entry.get('name'))) - rv = self.cmd.run(entry.get('command')) + self.logger.debug("Running Action %s %s" % + (shell_string, entry.get('name'))) + rv = self.cmd.run(entry.get('command'), shell=shell) self.logger.debug("Action: %s got return code %s" % (entry.get('command'), rv.retval)) entry.set('rc', str(rv.retval)) -- cgit v1.2.3-1-g7c22 From ef261545acbcc9ab0872383c5b66efaf53bdd329 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Sun, 16 Jun 2013 10:04:37 -0500 Subject: Compat: Fix u_str for PY3K Signed-off-by: Sol Jerome --- src/lib/Bcfg2/Compat.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Compat.py b/src/lib/Bcfg2/Compat.py index d034c0777..049236e03 100644 --- a/src/lib/Bcfg2/Compat.py +++ b/src/lib/Bcfg2/Compat.py @@ -79,10 +79,7 @@ except NameError: def u_str(string, encoding=None): """ print to file compatibility """ if sys.hexversion >= 0x03000000: - if encoding is not None: - return string.encode(encoding) - else: - return string + return string else: if encoding is not None: return unicode(string, encoding) -- cgit v1.2.3-1-g7c22 From ba133d1e5289a71ba1f312e582a62ca83f9085f9 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Mon, 17 Jun 2013 08:49:50 -0400 Subject: Probes: no need to .save() after .get_or_create() --- src/lib/Bcfg2/Server/Plugins/Probes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Plugins/Probes.py b/src/lib/Bcfg2/Server/Plugins/Probes.py index 20e366523..8937e4740 100644 --- a/src/lib/Bcfg2/Server/Plugins/Probes.py +++ b/src/lib/Bcfg2/Server/Plugins/Probes.py @@ -260,7 +260,7 @@ class Probes(Bcfg2.Server.Plugin.Probing, group=group).delete() ProbesGroupsModel.objects.get_or_create( hostname=client.hostname, - group=group).save() + group=group) ProbesGroupsModel.objects.filter( hostname=client.hostname).exclude( group__in=self.cgroups[client.hostname]).delete() -- cgit v1.2.3-1-g7c22 From 3182474429ae251603e46f6ac32e46cde87e92ac Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Mon, 17 Jun 2013 09:06:53 -0500 Subject: Reporting: Fix traceback when run interactively Signed-off-by: Sol Jerome --- src/lib/Bcfg2/Reporting/Collector.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Reporting/Collector.py b/src/lib/Bcfg2/Reporting/Collector.py index df82248d0..3d224432e 100644 --- a/src/lib/Bcfg2/Reporting/Collector.py +++ b/src/lib/Bcfg2/Reporting/Collector.py @@ -125,7 +125,9 @@ class ReportingCollector(object): # this wil be missing if called from bcfg2-admin self.terminate.set() if self.transport: - self.transport.shutdown() + try: + self.transport.shutdown() + except OSError: + pass if self.storage: self.storage.shutdown() - -- cgit v1.2.3-1-g7c22 From c058c61d3358b2def1bb67ec18bfe632b0543751 Mon Sep 17 00:00:00 2001 From: Jason Kincl Date: Thu, 13 Jun 2013 18:50:24 -0400 Subject: Svn: Adding config options for specifying a user and password for subversion and to trust server SSL certificates --- src/lib/Bcfg2/Server/Plugins/Svn.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Plugins/Svn.py b/src/lib/Bcfg2/Server/Plugins/Svn.py index 51f44c52d..b7f4fec57 100644 --- a/src/lib/Bcfg2/Server/Plugins/Svn.py +++ b/src/lib/Bcfg2/Server/Plugins/Svn.py @@ -59,9 +59,37 @@ class Svn(Bcfg2.Server.Plugin.Version): self.client.callback_conflict_resolver = \ self.get_conflict_resolver(choice) + try: + if self.core.setup.cfp.get( + "svn", + "always_trust").lower() == "true": + self.logger.info("Svn: Trust subversion SSL certificate") + self.client.callback_ssl_server_trust_prompt = \ + self.ssl_server_trust_prompt + except: + pass + + try: + if self.core.setup.cfp.get("svn", "user") and \ + self.core.setup.cfp.get("svn", "password"): + self.logger.info("Svn: Using user and password") + self.client.callback_get_login = \ + self.get_login + except: + pass + self.logger.debug("Svn: Initialized svn plugin with SVN directory %s" % self.vcs_path) + def get_login(self, realm, username, may_save): + return True, \ + self.core.setup.cfp.get("svn", "user"), \ + self.core.setup.cfp.get("svn", "password"), \ + False + + def ssl_server_trust_prompt(self, trust_dict): + return True, trust_dict['failures'], False + def get_conflict_resolver(self, choice): """ Get a PySvn conflict resolution callback """ def callback(conflict_description): -- cgit v1.2.3-1-g7c22 From 98bfb01afb27cd0de0dac5c7a6190ac22fa1d0f3 Mon Sep 17 00:00:00 2001 From: Jason Kincl Date: Fri, 14 Jun 2013 10:02:48 -0400 Subject: Svn: Tidying up code and logging of subversion trust and user/pass options --- src/lib/Bcfg2/Server/Plugins/Svn.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Plugins/Svn.py b/src/lib/Bcfg2/Server/Plugins/Svn.py index b7f4fec57..02656ffbe 100644 --- a/src/lib/Bcfg2/Server/Plugins/Svn.py +++ b/src/lib/Bcfg2/Server/Plugins/Svn.py @@ -63,31 +63,38 @@ class Svn(Bcfg2.Server.Plugin.Version): if self.core.setup.cfp.get( "svn", "always_trust").lower() == "true": - self.logger.info("Svn: Trust subversion SSL certificate") self.client.callback_ssl_server_trust_prompt = \ self.ssl_server_trust_prompt - except: - pass + except (ConfigParser.NoSectionError, ConfigParser.NoOptionError): + self.logger.debug("Svn: Using subversion cache for SSL " + "certificate trust") try: - if self.core.setup.cfp.get("svn", "user") and \ - self.core.setup.cfp.get("svn", "password"): - self.logger.info("Svn: Using user and password") + if (self.core.setup.cfp.get("svn", "user") and + self.core.setup.cfp.get("svn", "password")): self.client.callback_get_login = \ self.get_login - except: - pass + except (ConfigParser.NoSectionError, ConfigParser.NoOptionError): + self.logger.info("Svn: Using subversion cache for " + "password-based authetication") self.logger.debug("Svn: Initialized svn plugin with SVN directory %s" % self.vcs_path) def get_login(self, realm, username, may_save): + self.logger.debug("Svn: Logging in with username: %s" % + self.core.setup.cfp.get("svn", "user")) return True, \ self.core.setup.cfp.get("svn", "user"), \ self.core.setup.cfp.get("svn", "password"), \ False def ssl_server_trust_prompt(self, trust_dict): + self.logger.debug("Svn: Trusting SSL certificate from %s, " + "issued by %s for realm %s" % + (trust_dict['hostname'], + trust_dict['issuer_dname'], + trust_dict['realm'])) return True, trust_dict['failures'], False def get_conflict_resolver(self, choice): -- cgit v1.2.3-1-g7c22 From 06b398542a5bf4a073f407a0fe96b5fed8d8a90a Mon Sep 17 00:00:00 2001 From: Jason Kincl Date: Fri, 14 Jun 2013 14:02:18 -0400 Subject: Svn: Fixing pep8 and pylint checks --- src/lib/Bcfg2/Server/Plugins/Svn.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Plugins/Svn.py b/src/lib/Bcfg2/Server/Plugins/Svn.py index 02656ffbe..04395e144 100644 --- a/src/lib/Bcfg2/Server/Plugins/Svn.py +++ b/src/lib/Bcfg2/Server/Plugins/Svn.py @@ -61,7 +61,7 @@ class Svn(Bcfg2.Server.Plugin.Version): try: if self.core.setup.cfp.get( - "svn", + "svn", "always_trust").lower() == "true": self.client.callback_ssl_server_trust_prompt = \ self.ssl_server_trust_prompt @@ -70,29 +70,32 @@ class Svn(Bcfg2.Server.Plugin.Version): "certificate trust") try: - if (self.core.setup.cfp.get("svn", "user") and + if (self.core.setup.cfp.get("svn", "user") and self.core.setup.cfp.get("svn", "password")): self.client.callback_get_login = \ self.get_login except (ConfigParser.NoSectionError, ConfigParser.NoOptionError): - self.logger.info("Svn: Using subversion cache for " + self.logger.info("Svn: Using subversion cache for " "password-based authetication") self.logger.debug("Svn: Initialized svn plugin with SVN directory %s" % self.vcs_path) - + # pylint: disable=W0613 def get_login(self, realm, username, may_save): - self.logger.debug("Svn: Logging in with username: %s" % + """ PySvn callback to get credentials for HTTP basic authentication """ + self.logger.debug("Svn: Logging in with username: %s" % self.core.setup.cfp.get("svn", "user")) return True, \ - self.core.setup.cfp.get("svn", "user"), \ - self.core.setup.cfp.get("svn", "password"), \ - False + self.core.setup.cfp.get("svn", "user"), \ + self.core.setup.cfp.get("svn", "password"), \ + False + # pylint: enable=W0613 def ssl_server_trust_prompt(self, trust_dict): - self.logger.debug("Svn: Trusting SSL certificate from %s, " + """ PySvn callback to always trust SSL certificates from SVN server """ + self.logger.debug("Svn: Trusting SSL certificate from %s, " "issued by %s for realm %s" % - (trust_dict['hostname'], + (trust_dict['hostname'], trust_dict['issuer_dname'], trust_dict['realm'])) return True, trust_dict['failures'], False -- cgit v1.2.3-1-g7c22 From 9b7317bb94dec3235207598f85f34b1c01cae4f4 Mon Sep 17 00:00:00 2001 From: Jason Kincl Date: Fri, 14 Jun 2013 14:02:48 -0400 Subject: Probes: Fixing Django exception import --- src/lib/Bcfg2/Server/Plugins/Probes.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Plugins/Probes.py b/src/lib/Bcfg2/Server/Plugins/Probes.py index 8937e4740..0974184b4 100644 --- a/src/lib/Bcfg2/Server/Plugins/Probes.py +++ b/src/lib/Bcfg2/Server/Plugins/Probes.py @@ -12,6 +12,7 @@ import Bcfg2.Server.Plugin try: from django.db import models + from django.core.exceptions import MultipleObjectsReturned HAS_DJANGO = True class ProbesDataModel(models.Model, @@ -255,7 +256,7 @@ class Probes(Bcfg2.Server.Plugin.Probing, ProbesGroupsModel.objects.get_or_create( hostname=client.hostname, group=group) - except ProbesGroupsModel.MultipleObjectsReturned: + except MultipleObjectsReturned: ProbesGroupsModel.objects.filter(hostname=client.hostname, group=group).delete() ProbesGroupsModel.objects.get_or_create( -- cgit v1.2.3-1-g7c22 From 6ce11c9e50cba0303aea06672388d3af452fa468 Mon Sep 17 00:00:00 2001 From: Jason Kincl Date: Mon, 17 Jun 2013 10:38:42 -0400 Subject: Svn: Fixing pep8 check --- src/lib/Bcfg2/Server/Plugins/Svn.py | 1 + 1 file changed, 1 insertion(+) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Plugins/Svn.py b/src/lib/Bcfg2/Server/Plugins/Svn.py index 04395e144..240fd7f89 100644 --- a/src/lib/Bcfg2/Server/Plugins/Svn.py +++ b/src/lib/Bcfg2/Server/Plugins/Svn.py @@ -80,6 +80,7 @@ class Svn(Bcfg2.Server.Plugin.Version): self.logger.debug("Svn: Initialized svn plugin with SVN directory %s" % self.vcs_path) + # pylint: disable=W0613 def get_login(self, realm, username, may_save): """ PySvn callback to get credentials for HTTP basic authentication """ -- cgit v1.2.3-1-g7c22 From d543984b06796fd5c65def5e67d1dfd6cb068b6c Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Fri, 7 Jun 2013 04:24:30 +0200 Subject: Client/Tools/VCS: create directory for repository Older version of dulwich will not create the directory (even with mkdir=True) for the repository. So we cannot rely on it. Because we clean existing folders before, we have to create the directory in every case. --- src/lib/Bcfg2/Client/Tools/VCS.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Client/Tools/VCS.py b/src/lib/Bcfg2/Client/Tools/VCS.py index 1ab867215..23f04b5e3 100644 --- a/src/lib/Bcfg2/Client/Tools/VCS.py +++ b/src/lib/Bcfg2/Client/Tools/VCS.py @@ -71,7 +71,8 @@ class VCS(Bcfg2.Client.Tools.Tool): destname) return False - destr = dulwich.repo.Repo.init(destname, mkdir=True) + dulwich.file.ensure_dir_exists(destname) + destr = dulwich.repo.Repo.init(destname) cl, host_path = dulwich.client.get_transport_and_path(entry.get('sourceurl')) remote_refs = cl.fetch(host_path, destr, -- cgit v1.2.3-1-g7c22 From 3005879f1cbbfef2ec438a82a69f2fa0907d2dcf Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Fri, 7 Jun 2013 04:44:40 +0200 Subject: Client/Tools/VCS: add always on top feature You can specify a refname (like refs/heads/master) as revision and you will always get the current tree of this refname. During verify it is checked if the ref had changed in the remote repo and if an "update" is necessary. --- src/lib/Bcfg2/Client/Tools/VCS.py | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Client/Tools/VCS.py b/src/lib/Bcfg2/Client/Tools/VCS.py index 23f04b5e3..1f96ad5b4 100644 --- a/src/lib/Bcfg2/Client/Tools/VCS.py +++ b/src/lib/Bcfg2/Client/Tools/VCS.py @@ -47,11 +47,24 @@ class VCS(Bcfg2.Client.Tools.Tool): self.logger.info("Repository %s does not exist" % entry.get('name')) return False - cur_rev = repo.head() - if cur_rev != entry.get('revision'): + try: + expected_rev = entry.get('revision') + cur_rev = repo.head() + except: + return False + + try: + client, path = dulwich.client.get_transport_and_path(entry.get('sourceurl')) + remote_refs = client.fetch_pack(path, (lambda x: None), None, None, None) + if expected_rev in remote_refs: + expected_rev = remote_refs[expected_rev] + except: + pass + + if cur_rev != expected_rev: self.logger.info("At revision %s need to go to revision %s" % - (cur_rev, entry.get('revision'))) + (cur_rev.strip(), expected_rev.strip())) return False return True @@ -78,8 +91,13 @@ class VCS(Bcfg2.Client.Tools.Tool): destr, determine_wants=destr.object_store.determine_wants_all, progress=sys.stdout.write) - destr.refs['refs/heads/master'] = entry.get('revision') - dtree = destr[entry.get('revision')].tree + + if entry.get('revision') in remote_refs: + destr.refs['HEAD'] = remote_refs[entry.get('revision')] + else: + destr.refs['HEAD'] = entry.get('revision') + + dtree = destr['HEAD'].tree obj_store = destr.object_store for fname, mode, sha in obj_store.iter_tree_contents(dtree): fullpath = os.path.join(destname, fname) @@ -92,6 +110,7 @@ class VCS(Bcfg2.Client.Tools.Tool): f.write(destr[sha].data) f.close() os.chmod(os.path.join(destname, fname), mode) + return True # FIXME: figure out how to write the git index properly #iname = "%s/.git/index" % entry.get('name') -- cgit v1.2.3-1-g7c22 From a0612263ec30e7cb81dfd4bbd9bc73798630474d Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Fri, 7 Jun 2013 13:42:31 +0200 Subject: Client/Tools/VCS: some simplyfications using dulwich api --- src/lib/Bcfg2/Client/Tools/VCS.py | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Client/Tools/VCS.py b/src/lib/Bcfg2/Client/Tools/VCS.py index 1f96ad5b4..4a30d9d90 100644 --- a/src/lib/Bcfg2/Client/Tools/VCS.py +++ b/src/lib/Bcfg2/Client/Tools/VCS.py @@ -98,18 +98,14 @@ class VCS(Bcfg2.Client.Tools.Tool): destr.refs['HEAD'] = entry.get('revision') dtree = destr['HEAD'].tree - obj_store = destr.object_store - for fname, mode, sha in obj_store.iter_tree_contents(dtree): - fullpath = os.path.join(destname, fname) - try: - f = open(os.path.join(destname, fname), 'wb') - except IOError: - dir = os.path.split(fullpath)[0] - os.makedirs(dir) - f = open(os.path.join(destname, fname), 'wb') - f.write(destr[sha].data) - f.close() - os.chmod(os.path.join(destname, fname), mode) + for fname, mode, sha in destr.object_store.iter_tree_contents(dtree): + full_path = os.path.join(destname, fname) + dulwich.file.ensure_dir_exists(os.path.dirname(full_path)) + + file = open(full_path, 'wb') + file.write(destr[sha].as_raw_string()) + file.close() + os.chmod(full_path, mode) return True # FIXME: figure out how to write the git index properly -- cgit v1.2.3-1-g7c22 From 72e7bff7123e3639bf7da0866c633bdc123d1af4 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Fri, 7 Jun 2013 13:43:09 +0200 Subject: Client/Tools/VCS: add support for symlinks --- src/lib/Bcfg2/Client/Tools/VCS.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Client/Tools/VCS.py b/src/lib/Bcfg2/Client/Tools/VCS.py index 4a30d9d90..947cff11f 100644 --- a/src/lib/Bcfg2/Client/Tools/VCS.py +++ b/src/lib/Bcfg2/Client/Tools/VCS.py @@ -6,6 +6,7 @@ # * integrate properly with reports missing = [] +import errno import os import shutil import sys @@ -102,10 +103,22 @@ class VCS(Bcfg2.Client.Tools.Tool): full_path = os.path.join(destname, fname) dulwich.file.ensure_dir_exists(os.path.dirname(full_path)) - file = open(full_path, 'wb') - file.write(destr[sha].as_raw_string()) - file.close() - os.chmod(full_path, mode) + if dulwich.objects.S_ISGITLINK(mode): + src_path = destr[sha].as_raw_string() + try: + os.symlink(src_path, full_path) + except OSError: + e = sys.exc_info()[1] + if e.errno == errno.EEXIST: + os.unlink(full_path) + os.symlink(src_path, full_path) + else: + raise + else: + file = open(full_path, 'wb') + file.write(destr[sha].as_raw_string()) + file.close() + os.chmod(full_path, mode) return True # FIXME: figure out how to write the git index properly -- cgit v1.2.3-1-g7c22 From 0bc1fa1608b59c1f2a8b07ce71d70b158b63cb27 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Tue, 18 Jun 2013 20:03:12 +0200 Subject: Server/Admin/Syncdb: add missing import --- src/lib/Bcfg2/Server/Admin/Syncdb.py | 1 + 1 file changed, 1 insertion(+) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Admin/Syncdb.py b/src/lib/Bcfg2/Server/Admin/Syncdb.py index 53cfd1bec..eb417966d 100644 --- a/src/lib/Bcfg2/Server/Admin/Syncdb.py +++ b/src/lib/Bcfg2/Server/Admin/Syncdb.py @@ -3,6 +3,7 @@ import Bcfg2.settings import Bcfg2.Options import Bcfg2.Server.Admin import Bcfg2.Server.models +from django.core.exceptions import ImproperlyConfigured from django.core.management import setup_environ, call_command -- cgit v1.2.3-1-g7c22 From b78d3a3d2761a71ab0bc12ac2e53c13555e8ea16 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Fri, 7 Jun 2013 13:38:32 +0200 Subject: Client/Tools/VCS: build index after checkout --- src/lib/Bcfg2/Client/Tools/VCS.py | 47 +++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 9 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Client/Tools/VCS.py b/src/lib/Bcfg2/Client/Tools/VCS.py index 947cff11f..26e404cfa 100644 --- a/src/lib/Bcfg2/Client/Tools/VCS.py +++ b/src/lib/Bcfg2/Client/Tools/VCS.py @@ -1,7 +1,6 @@ """VCS support.""" # TODO: -# * git_write_index # * add svn support # * integrate properly with reports missing = [] @@ -10,6 +9,7 @@ import errno import os import shutil import sys +import stat # python-dulwich git imports try: @@ -27,6 +27,38 @@ except ImportError: import Bcfg2.Client.Tools +def cleanup_mode(mode): + """Cleanup a mode value. + + This will return a mode that can be stored in a tree object. + + :param mode: Mode to clean up. + """ + if stat.S_ISLNK(mode): + return stat.S_IFLNK + elif stat.S_ISDIR(mode): + return stat.S_IFDIR + elif dulwich.index.S_ISGITLINK(mode): + return dulwich.index.S_IFGITLINK + ret = stat.S_IFREG | int('644', 8) + ret |= (mode & int('111', 8)) + return ret + + +def index_entry_from_stat(stat_val, hex_sha, flags, mode=None): + """Create a new index entry from a stat value. + + :param stat_val: POSIX stat_result instance + :param hex_sha: Hex sha of the object + :param flags: Index flags + """ + if mode is None: + mode = cleanup_mode(stat_val.st_mode) + return (stat_val.st_ctime, stat_val.st_mtime, stat_val.st_dev, + stat_val.st_ino, mode, stat_val.st_uid, + stat_val.st_gid, stat_val.st_size, hex_sha, flags) + + class VCS(Bcfg2.Client.Tools.Tool): """VCS support.""" __handles__ = [('Path', 'vcs')] @@ -99,6 +131,7 @@ class VCS(Bcfg2.Client.Tools.Tool): destr.refs['HEAD'] = entry.get('revision') dtree = destr['HEAD'].tree + index = dulwich.index.Index(destr.index_path()) for fname, mode, sha in destr.object_store.iter_tree_contents(dtree): full_path = os.path.join(destname, fname) dulwich.file.ensure_dir_exists(os.path.dirname(full_path)) @@ -120,15 +153,11 @@ class VCS(Bcfg2.Client.Tools.Tool): file.close() os.chmod(full_path, mode) + st = os.lstat(full_path) + index[fname] = index_entry_from_stat(st, sha, 0) + + index.write() return True - # FIXME: figure out how to write the git index properly - #iname = "%s/.git/index" % entry.get('name') - #f = open(iname, 'w+') - #entries = obj_store[sha].iteritems() - #try: - # dulwich.index.write_index(f, entries) - #finally: - # f.close() def Verifysvn(self, entry, _): """Verify svn repositories""" -- cgit v1.2.3-1-g7c22 From c9fc434248ff3f8c1b800ced559385b17d4690de Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Wed, 19 Jun 2013 00:02:39 +0200 Subject: Client/Tools/VCS: fix symlink handling --- src/lib/Bcfg2/Client/Tools/VCS.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Client/Tools/VCS.py b/src/lib/Bcfg2/Client/Tools/VCS.py index 26e404cfa..3d19f5f1a 100644 --- a/src/lib/Bcfg2/Client/Tools/VCS.py +++ b/src/lib/Bcfg2/Client/Tools/VCS.py @@ -136,7 +136,7 @@ class VCS(Bcfg2.Client.Tools.Tool): full_path = os.path.join(destname, fname) dulwich.file.ensure_dir_exists(os.path.dirname(full_path)) - if dulwich.objects.S_ISGITLINK(mode): + if stat.S_ISLNK(mode): src_path = destr[sha].as_raw_string() try: os.symlink(src_path, full_path) -- cgit v1.2.3-1-g7c22 From ead3723f443f37d97cb45d26fddaaaa013f5edfa Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Wed, 19 Jun 2013 10:04:06 -0400 Subject: Yum: fixed logging bcfg2-yum-helper error output --- src/lib/Bcfg2/Server/Plugins/Packages/Yum.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py index 4330de971..4608bcca5 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py @@ -904,11 +904,13 @@ class YumCollection(Collection): rv = helper.wait() errlines = stderr.splitlines() if rv: + if not errlines: + errlines.append("No error output") self.logger.error("Packages: error running bcfg2-yum-helper " "(returned %d): %s" % (rv, errlines[0])) for line in errlines[1:]: self.logger.error("Packages: %s" % line) - else: + elif errlines: self.debug_log("Packages: debug info from bcfg2-yum-helper: %s" % errlines[0]) for line in errlines[1:]: -- cgit v1.2.3-1-g7c22 From 7d53dd1afe826fc6537d3a747fb3737cd011dec6 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Wed, 19 Jun 2013 14:59:50 -0400 Subject: Core: rewrite $HOME after dropping privs --- src/lib/Bcfg2/Server/Core.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Core.py b/src/lib/Bcfg2/Server/Core.py index 6e0d38418..f44634d35 100644 --- a/src/lib/Bcfg2/Server/Core.py +++ b/src/lib/Bcfg2/Server/Core.py @@ -3,6 +3,7 @@ implementations inherit from. """ import os import sys +import pwd import time import atexit import select @@ -758,6 +759,11 @@ class BaseCore(object): os.chmod(piddir, 493) # 0775 if not self._daemonize(): return False + + # rewrite $HOME. pulp stores its auth creds in ~/.pulp, so + # this is necessary to make that work when privileges are + # dropped + os.environ['HOME'] = pwd.getpwuid(self.setup['daemon_uid'])[5] else: os.umask(int(self.setup['umask'], 8)) -- cgit v1.2.3-1-g7c22 From 161603cd3dce7f4e0e5f50c9435e69b500085e1a Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Wed, 19 Jun 2013 15:00:46 -0400 Subject: Utils: PackedDigitRange __len__() breaks with open-ended ranges --- src/lib/Bcfg2/Utils.py | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Utils.py b/src/lib/Bcfg2/Utils.py index 1c2dceed2..9f46582c4 100644 --- a/src/lib/Bcfg2/Utils.py +++ b/src/lib/Bcfg2/Utils.py @@ -81,9 +81,6 @@ class PackedDigitRange(object): # pylint: disable=E0012,R0924 def __str__(self): return "[%s]" % self.str - def __len__(self): - return sum(r[1] - r[0] + 1 for r in self.ranges) + len(self.ints) - def locked(fd): """ Acquire a lock on a file. -- cgit v1.2.3-1-g7c22 From e353b9d0aadf6093407e2fc32c3baebc74586dad Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Tue, 25 Jun 2013 12:06:13 -0500 Subject: Chkconfig: Set svcstatus When status='ignore', set svcstatus to True so that the entry verifies properly. Signed-off-by: Sol Jerome --- src/lib/Bcfg2/Client/Tools/Chkconfig.py | 1 + 1 file changed, 1 insertion(+) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Client/Tools/Chkconfig.py b/src/lib/Bcfg2/Client/Tools/Chkconfig.py index 256c28255..156f76159 100644 --- a/src/lib/Bcfg2/Client/Tools/Chkconfig.py +++ b/src/lib/Bcfg2/Client/Tools/Chkconfig.py @@ -60,6 +60,7 @@ class Chkconfig(Bcfg2.Client.Tools.SvcTool): if entry.get('status') == 'ignore': # 'ignore' should verify current_svcstatus = True + svcstatus = True else: svcstatus = self.check_service(entry) if entry.get('status') == 'on': -- cgit v1.2.3-1-g7c22 From 8b49d8b198564d0dae3e40b99b6f9d76188dcda7 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Wed, 26 Jun 2013 09:15:40 -0500 Subject: Revert "Core: properly handle Ctrl-C" This reverts commit 4568c44372c99ba809826e016680da9b881bd8e8. Trying to handle ^c in the core is difficult and can break STDOUT for interactive programs that invoke the core. Signed-off-by: Sol Jerome Conflicts: src/lib/Bcfg2/Server/Core.py src/sbin/bcfg2-test tools/bcfg2-profile-templates.py --- src/lib/Bcfg2/Server/Core.py | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Core.py b/src/lib/Bcfg2/Server/Core.py index f44634d35..ecd68e1e4 100644 --- a/src/lib/Bcfg2/Server/Core.py +++ b/src/lib/Bcfg2/Server/Core.py @@ -2,15 +2,14 @@ implementations inherit from. """ import os -import sys import pwd -import time import atexit -import select -import signal import logging -import inspect +import select +import sys import threading +import time +import inspect import lxml.etree import Bcfg2.settings import Bcfg2.Server @@ -244,14 +243,6 @@ class BaseCore(object): #: The CA that signed the server cert self.ca = setup['ca'] - def hdlr(sig, frame): # pylint: disable=W0613 - """ Handle SIGINT/Ctrl-C by shutting down the core and exiting - properly. """ - self.shutdown() - os._exit(1) # pylint: disable=W0212 - - signal.signal(signal.SIGINT, hdlr) - #: The FAM :class:`threading.Thread`, #: :func:`_file_monitor_thread` self.fam_thread = \ -- cgit v1.2.3-1-g7c22 From 5565178f48063504c460de358bd1f3938fdceac5 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Wed, 26 Jun 2013 15:22:11 -0500 Subject: Lint: Fix Path type='vcs' schema checks Signed-off-by: Sol Jerome --- src/lib/Bcfg2/Server/Lint/RequiredAttrs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Lint/RequiredAttrs.py b/src/lib/Bcfg2/Server/Lint/RequiredAttrs.py index 6ffdd33a0..e49779a10 100644 --- a/src/lib/Bcfg2/Server/Lint/RequiredAttrs.py +++ b/src/lib/Bcfg2/Server/Lint/RequiredAttrs.py @@ -76,7 +76,7 @@ class RequiredAttrs(Bcfg2.Server.Lint.ServerPlugin): permissions=dict(name=is_filename, owner=is_username, group=is_username, mode=is_octal_mode), vcs=dict(vcstype=lambda v: (v != 'Path' and - hasattr(Bcfg2.Client.Tools.VCS, + hasattr(Bcfg2.Client.Tools.VCS.VCS, "Install%s" % v)), revision=None, sourceurl=None)), Service={"__any__": dict(name=None), -- cgit v1.2.3-1-g7c22 From 8daee5c5e0434bfc8caf8fac90bea4faf0605651 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Wed, 26 Jun 2013 16:32:59 -0400 Subject: TemplateHelper: fix traceback with TemplateHelper modules in place and --stdin argument to bcfg2-lint --- src/lib/Bcfg2/Server/Plugins/TemplateHelper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Server/Plugins/TemplateHelper.py b/src/lib/Bcfg2/Server/Plugins/TemplateHelper.py index fcd73bae2..db7370f01 100644 --- a/src/lib/Bcfg2/Server/Plugins/TemplateHelper.py +++ b/src/lib/Bcfg2/Server/Plugins/TemplateHelper.py @@ -115,7 +115,7 @@ class TemplateHelperLint(Bcfg2.Server.Lint.ServerPlugin): def Run(self): for helper in self.core.plugins['TemplateHelper'].entries.values(): - if self.HandlesFile(helper): + if self.HandlesFile(helper.name): self.check_helper(helper.name) def check_helper(self, helper): -- cgit v1.2.3-1-g7c22