commit | author | age
|
404117
|
1 |
#!/usr/bin/python2.7 |
AŠ |
2 |
|
|
3 |
# |
|
4 |
# This file and its contents are supplied under the terms of the |
|
5 |
# Common Development and Distribution License ("CDDL"), version 1.0. |
|
6 |
# You may only use this file in accordance with the terms of version |
|
7 |
# 1.0 of the CDDL. |
|
8 |
# |
|
9 |
# A full copy of the text of the CDDL should have accompanied this |
|
10 |
# source. A copy of the CDDL is also available via the Internet at |
|
11 |
# http://www.illumos.org/license/CDDL. |
|
12 |
# |
|
13 |
|
|
14 |
# |
|
15 |
# Copyright 2018 Adam Stevko |
|
16 |
# |
|
17 |
|
|
18 |
# |
|
19 |
# mapping.py - generate mapping between component FMRI and component package names, to be used for different purposes, |
|
20 |
# e.g. checking for outdated pacakges, vulnerable packages etc. |
|
21 |
# |
|
22 |
|
|
23 |
from __future__ import print_function, absolute_import |
|
24 |
|
|
25 |
import argparse |
|
26 |
import json |
|
27 |
import os |
|
28 |
import re |
|
29 |
import logging |
|
30 |
import subprocess |
|
31 |
import multiprocessing |
|
32 |
import sys |
|
33 |
|
|
34 |
try: |
|
35 |
from scandir import walk |
|
36 |
except ImportError: |
|
37 |
from os import walk |
|
38 |
|
|
39 |
logger = logging.getLogger('userland-mapping') |
|
40 |
|
|
41 |
COMONENT_MAPPING_FILENAME = 'mapping.json' |
|
42 |
|
|
43 |
|
|
44 |
def find_component_paths(path, subdir='components', debug=False): |
|
45 |
expression = re.compile(r'.+\.p5m$', re.IGNORECASE) |
|
46 |
|
|
47 |
paths = [] |
|
48 |
workspace_path = os.path.join(path, subdir) |
|
49 |
|
|
50 |
for dirpath, dirnames, filenames in walk(workspace_path): |
|
51 |
for name in filenames: |
|
52 |
if expression.match(name): |
|
53 |
paths.append(dirpath) |
|
54 |
del dirnames[:] |
|
55 |
break |
|
56 |
|
|
57 |
return paths |
|
58 |
|
|
59 |
|
|
60 |
def generate_component_data(component_path): |
|
61 |
result = [] |
|
62 |
|
|
63 |
proc = subprocess.Popen(['gmake', 'print-value-COMPONENT_NAME', 'print-package-names'], |
|
64 |
stdout=subprocess.PIPE, |
|
65 |
stderr=subprocess.PIPE, |
|
66 |
cwd=component_path) |
|
67 |
|
|
68 |
for out in proc.stdout: |
|
69 |
result.append(out.rstrip()) |
|
70 |
|
|
71 |
component_name = result[0] |
|
72 |
component_fmris = result[1:] |
|
73 |
component_relative_path = component_path.split(os.environ['WS_TOP'])[-1].replace('/', '', 1) |
|
74 |
|
|
75 |
return component_fmris, component_name, component_relative_path |
|
76 |
|
|
77 |
|
|
78 |
def generate_userland_mapping(workspace_path, subdir='components'): |
|
79 |
mapping = [] |
|
80 |
|
|
81 |
paths = find_component_paths(path=workspace_path, subdir=subdir) |
|
82 |
pool = multiprocessing.Pool(processes=multiprocessing.cpu_count()) |
|
83 |
results = pool.map(generate_component_data, paths) |
|
84 |
|
|
85 |
for component_fmris, component_name, component_relative_path in results: |
|
86 |
for component_fmri in component_fmris: |
|
87 |
mapping.append({'component_name': component_name, |
|
88 |
'component_fmri': component_fmri, |
|
89 |
'component_path': component_relative_path}) |
|
90 |
|
|
91 |
component_mapping_file = os.path.join(workspace_path, subdir, COMONENT_MAPPING_FILENAME) |
|
92 |
with open(component_mapping_file, 'w') as f: |
|
93 |
f.write(json.dumps(mapping, sort_keys=True, indent=4)) |
|
94 |
|
|
95 |
|
|
96 |
def main(): |
|
97 |
parser = argparse.ArgumentParser() |
|
98 |
|
|
99 |
parser.add_argument('-w', '--workspace', default=os.getenv('WS_TOP'), help='Path to workspace') |
|
100 |
parser.add_argument('--subdir', default='components', help='Directory holding components') |
|
101 |
|
|
102 |
args = parser.parse_args() |
|
103 |
|
|
104 |
workspace = args.workspace |
|
105 |
subdir = args.subdir |
|
106 |
|
|
107 |
generate_userland_mapping(workspace_path=workspace, subdir=subdir) |
|
108 |
|
|
109 |
|
|
110 |
if __name__ == '__main__': |
|
111 |
main() |