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:
@@ -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
101
packstack/modules/puppet.py
Normal 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
|
||||
Reference in New Issue
Block a user