forked from redhat-openstack/packstack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathospluginutils.py
More file actions
162 lines (128 loc) · 5.03 KB
/
Copy pathospluginutils.py
File metadata and controls
162 lines (128 loc) · 5.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import logging
import os
import re
from packstack.installer import basedefs
from packstack.installer.setup_controller import Controller
from packstack.installer.exceptions import PackStackError
controller = Controller()
PUPPET_DIR = os.path.join(basedefs.DIR_PROJECT_DIR, "puppet")
PUPPET_TEMPLATE_DIR = os.path.join(PUPPET_DIR, "templates")
class NovaConfig(object):
"""
Helper class to create puppet manifest entries for nova_config
"""
def __init__(self):
self.options = {}
def addOption(self, n, v):
self.options[n] = v
def getManifestEntry(self):
entry = ""
if not self.options:
return entry
entry += "nova_config{\n"
for k, v in self.options.items():
entry += ' "%s": value => "%s";\n' % (k, v)
entry += "}"
return entry
class ManifestFiles(object):
def __init__(self):
self.filelist = []
self.data = {}
# continuous manifest file that have the same marker can be
# installed in parallel, if on different servers
def addFile(self, filename, marker, data=''):
self.data[filename] = self.data.get(filename, '') + '\n' + data
for f, p in self.filelist:
if f == filename:
return
self.filelist.append((filename, marker))
def getFiles(self):
return [f for f in self.filelist]
def writeManifests(self):
"""
Write out the manifest data to disk, this should only be called once
write before the puppet manifests are copied to the various servers
"""
os.mkdir(basedefs.PUPPET_MANIFEST_DIR, 0700)
for fname, data in self.data.items():
path = os.path.join(basedefs.PUPPET_MANIFEST_DIR, fname)
fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0600)
with os.fdopen(fd, 'w') as fp:
fp.write(data)
manifestfiles = ManifestFiles()
def getManifestTemplate(template_name):
with open(os.path.join(PUPPET_TEMPLATE_DIR, template_name)) as fp:
return fp.read() % controller.CONF
def appendManifestFile(manifest_name, data, marker=''):
manifestfiles.addFile(manifest_name, marker, data)
def gethostlist(CONF):
hosts = []
for key, value in CONF.items():
if key.endswith("_HOST"):
value = value.split('/')[0]
if value and value not in hosts:
hosts.append(value)
if key.endswith("_HOSTS"):
for host in value.split(","):
host = host.strip()
host = host.split('/')[0]
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