-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathconvert2rhel.py
executable file
·199 lines (154 loc) · 6.73 KB
/
convert2rhel.py
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#!/usr/bin/python2
import json
import os
import subprocess
import sys
import time
import argparse
# Based on the existence of the following files do a certain thing
MOCK_DUMP_ENV_VARS = "/tmp/c2r_mock_dump_env_vars" # Dump env vars
MOCK_INFINITE_LOOP = "/tmp/c2r_mock_infinite_loop" # Infinitely loop
MOCK_KMOD_INHIBITOR = "/tmp/c2r_mock_kmod_inhibitor" # Report an inhibitor about unsupported kernel modules
MOCK_EXECUTE_SCRIPT = "/tmp/c2r_mock_execute_script" # Do whatever is inside this script file
MOCK_DO_NOTHING = "/tmp/c2r_mock_do_nothing" # Do nothing, just create a report and end immediately
# The output of a mock to check the test result
MOCK_OUTPUT_FILE = "/tmp/c2r_mock_test.json"
# Script mode as defined in the script
# (https://github.com/oamg/convert2rhel-insights-tasks/blob/main/scripts/c2r_script.py#L15)
SCRIPT_MODE = os.environ.get("SCRIPT_MODE", None)
# Report json files as expected by script
BASE_REPORT_DATA_FOLDER = "/usr/share/convert2rhel/data/"
ANALYZE_NO_ISSUE_FILE = BASE_REPORT_DATA_FOLDER + "analyze/convert2rhel-pre-conversion.json"
ANALYZE_KMOD_INHIBITOR_FILE = BASE_REPORT_DATA_FOLDER + "kmod/convert2rhel-pre-conversion.json"
CONVERT_NO_ISSUE_FILE = BASE_REPORT_DATA_FOLDER + "convert/convert2rhel-post-conversion.json"
C2R_LOG_FOLDER = "/var/log/convert2rhel"
C2R_ANALYZE_JSON_LOG_LOCATION = C2R_LOG_FOLDER + "/convert2rhel-pre-conversion.json"
C2R_CONVERT_JSON_LOG_LOCATION = C2R_LOG_FOLDER + "/convert2rhel-post-conversion.json"
REPORT_STATUS_ORDER = ["SUCCESS", "INFO", "SKIP", "OVERRIDABLE", "WARNING", "ERROR"]
def parse_arguments(args):
parser = argparse.ArgumentParser()
# Add allowed options
parser.add_argument(
"-y",
action='store_true'
)
parser.add_argument(
"--els",
action='store_true'
)
parser.add_argument(
"--enablerepo",
action="append",
)
# Parse arguments
return parser.parse_args(args)
def create_log_folder():
"""Create a c2r log folder if does not exists"""
if not os.path.exists(C2R_LOG_FOLDER):
os.makedirs(C2R_LOG_FOLDER)
def put_reportfile_to_expected_location(reportfile, log_destination_location):
"""
Download and put the c2r report file in the log directory
where the rhc-worker-script parse the result of the c2r run
"""
create_log_folder()
try:
with open(log_destination_location, "w") as f:
f.write(json.dumps(reportfile))
except:
raise RuntimeError("Mock failed to create a report")
'''
Crafts a report adding all entries from :path_issues to the
base reportfile located in :reportfile_path
:param reportfile_path: Path to the base reportfile
:param report_issues: Array with the report filename to be added
'''
def craft_report(reportfile_path, report_issues):
BASE_REPORT_CRAFT_FOLDER = BASE_REPORT_DATA_FOLDER + "craft/"
reportfile = {}
# Get the base reportfile
with open(reportfile_path, mode="r") as f:
reportfile = json.load(f)
# Push all report_issues into base reportfile
for report_issue in report_issues:
REPORT_CRAFT_FOLDER = BASE_REPORT_CRAFT_FOLDER + report_issue
with open(REPORT_CRAFT_FOLDER, mode="r") as f:
json_issue = json.load(f)
# The report need a summary status. The summary status is the most critical status between all
# the reported issues. The status importance order is given by REPORT_STATUS_ORDER,
# ordered from less to most important.
if REPORT_STATUS_ORDER.index(json_issue["status"]) > REPORT_STATUS_ORDER.index(reportfile["status"]):
# If this issue status is more critical than the saved one, save this one.
reportfile["status"] = json_issue["status"]
for action_key in json_issue["actions"].keys():
reportfile["actions"][action_key] = json_issue["actions"][action_key]
return reportfile
def main():
"""Main script logic"""
script_es = 0
reportfile_path = ""
log_destination_location = ""
report_issues = []
if SCRIPT_MODE not in ("ANALYSIS", "CONVERSION"):
print("SCRIPT_MODE envar is not one of the expected, got: {}".format(SCRIPT_MODE))
sys.exit(10)
# Set defaults
if SCRIPT_MODE == "ANALYSIS":
reportfile_path = ANALYZE_NO_ISSUE_FILE
log_destination_location = C2R_ANALYZE_JSON_LOG_LOCATION
else:
reportfile_path = CONVERT_NO_ISSUE_FILE
log_destination_location = C2R_CONVERT_JSON_LOG_LOCATION
# Parse arguments
ARGUMENTS_START = 2 if SCRIPT_MODE == "ANALYSIS" else 1
parsed_opts = parse_arguments(sys.argv[ARGUMENTS_START:])
if not parsed_opts.els and SCRIPT_MODE == "ANALYSIS":
report_issues.append("els.json")
if not parsed_opts.y:
print("Missing parameter: \"-y\".")
sys.exit(10)
# Decide what to do based on existence of a specific file.
# This serves as a communication with a running test.
if os.path.isfile(MOCK_DUMP_ENV_VARS):
parsed_arguments_dict = vars(parsed_opts)
for key, value in parsed_arguments_dict.items():
os.environ[key] = str(value)
with open(MOCK_OUTPUT_FILE, mode="w") as f:
json.dump(dict(os.environ), f)
elif os.path.isfile(MOCK_INFINITE_LOOP):
while True:
# Infinitely sleep and write every 5 seconds actual time.
time.sleep(5)
with open(C2R_LOG_FOLDER + "/convert2rhel.log", mode="a") as f:
f.write(time.ctime() + "\n")
elif os.path.isfile(MOCK_KMOD_INHIBITOR):
report_issues.append("kmod.json")
if SCRIPT_MODE == "CONVERSION":
script_es = 1
elif os.path.isfile(MOCK_EXECUTE_SCRIPT):
# Check if file is executable
cmd = ["[", "-x", MOCK_EXECUTE_SCRIPT, "]"]
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1)
process.wait()
if process.returncode != 0:
print("The script is not executable, make it executable to run!")
sys.exit(10)
# Execute the MOCK_EXECUTE_SCRIPT file path
process = subprocess.Popen(MOCK_EXECUTE_SCRIPT, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1)
# Wait for the process to end
process.wait()
# Exit with the executed script return code
script_es = process.returncode
elif os.path.isfile(MOCK_DO_NOTHING):
pass
else:
print(
"Script do now know what to do.. :(\n \
create one of the specific files to tell it what to do."
)
sys.exit(10)
reportfile = craft_report(reportfile_path, report_issues)
put_reportfile_to_expected_location(reportfile, log_destination_location)
sys.exit(script_es)
if __name__ == "__main__":
main()