build_all_guides   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 112
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
eloc 73
dl 0
loc 112
ccs 0
cts 56
cp 0
rs 10
c 0
b 0
f 0
wmc 11

2 Functions

Rating   Name   Duplication   Size   Complexity  
A parse_args() 0 23 1
C main() 0 59 10
1
#!/usr/bin/python3
2
3
from __future__ import print_function
4
5
"""
6
Takes given XCCDF or DataStream and for every profile in it it generates one
7
OpenSCAP HTML guide. Also generates an index file that lists all the profiles
8
and allows the user to navigate between them.
9
10
Author: Martin Preisler <[email protected]>
11
"""
12
13
import os.path
14
import argparse
15
import threading
16
import sys
17
18
import ssg.build_guides
19
import ssg.xccdf
20
import ssg.utils
21
import ssg.xml
22
23
24
def parse_args():
25
    p = argparse.ArgumentParser()
26
27
    sp = p.add_subparsers(help="actions")
28
29
    make_sp = sp.add_parser("build", help="Build all the HTML guides")
30
    make_sp.set_defaults(cmd="build")
31
32
    input_sp = sp.add_parser("list-inputs", help="Generate input list")
33
    input_sp.set_defaults(cmd="list_inputs")
34
35
    output_sp = sp.add_parser("list-outputs", help="Generate output list")
36
    output_sp.set_defaults(cmd="list_outputs")
37
38
    p.add_argument("-j", "--jobs", type=int, action="store",
39
                   default=ssg.utils.get_cpu_count(),
40
                   help="how many jobs should be processed in parallel")
41
    p.add_argument("-i", "--input", action="store", required=True,
42
                   help="input file, can be XCCDF or Source DataStream")
43
    p.add_argument("-o", "--output", action="store", required=True,
44
                   help="output directory")
45
46
    return p.parse_args()
47
48
49
def main():
50
    args = parse_args()
51
52
    input_path, input_basename, path_base, output_dir = \
53
        ssg.build_guides.get_path_args(args)
54
    index_path = os.path.join(output_dir, "%s-guide-index.html" % (path_base))
55
56
    if args.cmd == "list_inputs":
57
        print(input_path)
58
        sys.exit(0)
59
60
    input_tree = ssg.xml.ElementTree.parse(input_path)
61
    benchmarks = ssg.xccdf.get_benchmark_id_title_map(input_tree)
62
    if len(benchmarks) == 0:
63
        raise RuntimeError(
64
            "Expected input file '%s' to contain at least 1 xccdf:Benchmark. "
65
            "No Benchmarks were found!" %
66
            (input_path)
67
        )
68
69
    benchmark_profile_pairs = ssg.build_guides.get_benchmark_profile_pairs(
70
        input_tree, benchmarks)
71
72
    if args.cmd == "list_outputs":
73
        guide_paths = ssg.build_guides.get_output_guide_paths(benchmarks,
74
                                                              benchmark_profile_pairs,
75
                                                              path_base, output_dir)
76
77
        for guide_path in guide_paths:
78
            print(guide_path)
79
        print(index_path)
80
        sys.exit(0)
81
82
    index_links, index_options, index_initial_src, queue = \
83
        ssg.build_guides.fill_queue(benchmarks, benchmark_profile_pairs,
84
                                    input_path, path_base, output_dir)
85
86
    workers = []
87
    for worker_id in range(args.jobs):
88
        worker = threading.Thread(
89
            name="Guide generate worker #%i" % (worker_id),
90
            target=lambda queue=queue: ssg.build_guides.builder(queue)
91
        )
92
        workers.append(worker)
93
        worker.daemon = True
94
        worker.start()
95
96
    for worker in workers:
97
        worker.join()
98
99
    if queue.unfinished_tasks > 0:
100
        raise RuntimeError("Some of the guides were not exported successfully")
101
102
    index_source = ssg.build_guides.build_index(benchmarks, input_basename,
103
                                                index_links, index_options,
104
                                                index_initial_src)
105
106
    with open(index_path, "wb") as f:
107
        f.write(index_source.encode("utf-8"))
108
109
110
if __name__ == "__main__":
111
    main()
112