Change message in certain cases

In some cases Puppet error messages are useless.
This patch implements algorithm which makes certain error
messages more userfriendly.

Change-Id: Iac6f1c5382b3c3d605df3477477558858eca69ef
Fixes: rhbz#989334, rhbz#1006476, rhbz#1003959
This commit is contained in:
Martin Magr
2013-09-23 11:43:31 +02:00
parent 6b19e22919
commit 5859915898
10 changed files with 213 additions and 139 deletions

View File

@@ -90,73 +90,3 @@ def gethostlist(CONF):
if host and host not in hosts:
hosts.append(host)
return hosts
_error_exceptions = [
# puppet preloads a provider using the mysql command before it is installed
re.compile('Command mysql is missing'),
# puppet preloads a database_grant provider which fails if /root/.my.cnf
# this is ok because it will be retried later if needed
re.compile('Could not prefetch database_grant provider.*?\\.my\\.cnf'),
# swift puppet module tries to install swift-plugin-s3, there is no such
# pakage on RHEL, fixed in the upstream puppet module
re.compile('yum.*?install swift-plugin-s3'),
]
def isErrorException(line):
for ee in _error_exceptions:
if ee.search(line):
return True
return False
_re_color = re.compile('\x1b.*?\d\dm')
_re_errorline = re.compile('err: | Syntax error at|^Duplicate definition:|'
'^No matching value for selector param|'
'^Parameter name failed:|Error: |^Invalid tag |'
'^Invalid parameter |^Duplicate declaration: '
'^Could not find resource |^Could not parse for ')
def validate_puppet_logfile(logfile):
"""
Check a puppet log file for errors and raise an error if we find any
"""
fp = open(logfile)
data = fp.read()
fp.close()
manifestfile = os.path.splitext(logfile)[0]
for line in data.split('\n'):
line = line.strip()
if _re_errorline.search(line) is None:
continue
message = _re_color.sub('', line) # remove colors
if isErrorException(line):
logging.info("Ignoring expected error during puppet run %s : %s" %
(manifestfile, message))
continue
message = "Error during puppet run : " + message
logging.error("Error during remote puppet apply of " + manifestfile)
logging.error(data)
raise PackStackError(message)
def scan_puppet_logfile(logfile):
"""
Returns list of packstack_info/packstack_warn notices parsed from
given puppet log file.
"""
output = []
notice = re.compile(r"notice: .*Notify\[packstack_info\]"
"\/message: defined \'message\' as "
"\'(?P<message>.*)\'")
with open(logfile) as content:
for line in content:
match = notice.search(line)
if match:
output.append(match.group('message'))
return output

101
packstack/modules/puppet.py Normal file
View File

@@ -0,0 +1,101 @@
# -*- coding: utf-8 -*-
import logging
import os
import re
from packstack.installer.exceptions import PuppetError
# TODO: Fill logger name when logging system will be refactored
logger = logging.getLogger()
re_color = re.compile('\x1b.*?\d\dm')
re_error = re.compile(
'err:|Syntax error at|^Duplicate definition:|^Invalid tag|'
'^No matching value for selector param|^Parameter name failed:|Error:|'
'^Invalid parameter|^Duplicate declaration:|^Could not find resource|'
'^Could not parse for|^\/usr\/bin\/env\: jruby\: No such file or directory'
)
re_ignore = re.compile(
# Puppet preloads a provider using the mysql command before it is installed
'Command mysql is missing|'
# Puppet preloads a database_grant provider which fails if /root/.my.cnf
# is missing, this is ok because it will be retried later if needed
'Could not prefetch database_grant provider.*?\\.my\\.cnf|'
# Swift Puppet module tries to install swift-plugin-s3, there is no such
# package on RHEL, fixed in the upstream puppet module
'yum.*?install swift-plugin-s3'
)
re_notice = re.compile(r"notice: .*Notify\[packstack_info\]"
"\/message: defined \'message\' as "
"\'(?P<message>.*)\'")
surrogates = [
# Value in /etc/sysctl.conf cannot be changed
('Sysctl::Value\[.*\]\/Sysctl\[(?P<arg1>.*)\].*Field \'val\' is required',
'Cannot change value of %(arg1)s in /etc/sysctl.conf'),
# Package is not found in yum repos
('Package\[.*\]\/ensure.*yum.*install (?P<arg1>.*)\'.*Nothing to do',
'Package %(arg1)s has not been found in enabled Yum repos.'),
# Packstack does not cooperate with jruby
('jruby', 'Your Puppet installation uses jruby instead of ruby. Package '
'jruby does not cooperate with Packstack well. You will have to '
'fix this manually.'),
]
def validate_logfile(logpath):
"""
Check given Puppet log file for errors and raise PuppetError if there is
any error
"""
manifestpath = os.path.splitext(logpath)[0]
manifestfile = os.path.basename(manifestpath)
with open(logpath) as logfile:
for line in logfile:
line = line.strip()
if re_error.search(line) is None:
continue
error = re_color.sub('', line) # remove colors
if re_ignore.search(line):
msg = ('Ignoring expected error during Puppet run %s: %s' %
(manifestfile, error))
logger.debug(msg)
continue
for regex, surrogate in surrogates:
match = re.search(regex, error)
if match is None:
continue
args = {}
num = 1
while True:
try:
args['arg%d' % num] = match.group(num)
num += 1
except IndexError:
break
error = surrogate % args
message = ('Error appeared during Puppet run: %s\n%s\n'
'You will find full trace in log %s' %
(manifestfile, error, logpath))
raise PuppetError(message)
def scan_logfile(logpath):
"""
Returns list of packstack_info/packstack_warn notices parsed from
given puppet log file.
"""
output = []
with open(logpath) as logfile:
for line in logfile:
match = re_notice.search(line)
if match:
output.append(match.group('message'))
return output