Marcel Telka
2024-04-01 8b81466c5260d9945b49594e5cc088e75ee18d44
commit | author | age
de89cf 1 #!/usr/bin/python3.9
404117 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 import argparse
24 import json
25 import os
26 import re
27 import logging
28 import subprocess
29 import multiprocessing
30
7e9f71 31 from bass.component import Component
1e2fed 32
404117 33 try:
34     from scandir import walk
35 except ImportError:
36     from os import walk
37
38 logger = logging.getLogger('userland-mapping')
39
1e2fed 40 COMPONENT_MAPPING_FILENAME = 'mapping.json'
404117 41
42
43 def find_component_paths(path, subdir='components', debug=False):
44     expression = re.compile(r'.+\.p5m$', re.IGNORECASE)
45
46     paths = []
47     workspace_path = os.path.join(path, subdir)
48
49     for dirpath, dirnames, filenames in walk(workspace_path):
50         for name in filenames:
51             if expression.match(name):
9cb600 52                 if not os.path.isfile(os.path.join( dirpath, 'pkg5.ignore')):
AL 53                     paths.append(dirpath)
404117 54                 del dirnames[:]
55                 break
56
57     return paths
58
59
11232f 60 def generate_component_data(component_path, subdir='components'):
404117 61     result = []
7e9f71 62     component = Component(path=component_path)
AL 63     component_name = component.name
1e2fed 64     if not component_name:
AL 65         raise ValueError('Component name is empty for path ' + component_path + '.')
66     component_fmris = component.supplied_packages
404117 67
11232f 68     component_relative_path = component_path.split(os.path.join(os.environ['WS_TOP'], subdir))[-1].replace('/', '', 1)
404117 69
70     return component_fmris, component_name, component_relative_path
71
72
780de6 73 def generate_userland_mapping(workspace_path, subdir='components', repo='userland', repo_map=[]):
404117 74     mapping = []
75
76     paths = find_component_paths(path=workspace_path, subdir=subdir)
77     pool = multiprocessing.Pool(processes=multiprocessing.cpu_count())
78     results = pool.map(generate_component_data, paths)
79
80     for component_fmris, component_name, component_relative_path in results:
81         for component_fmri in component_fmris:
780de6 82             component_repo = repo
JMC 83             for rm in repo_map:
84                 if component_relative_path.startswith(rm['pfx']):
85                     component_repo = rm['repo']
86
1e2fed 87             mapping.append({'name': component_name,
AL 88                             'fmri': component_fmri,
780de6 89                             'path': component_relative_path,
JMC 90                             'repo': component_repo})
404117 91
1e2fed 92     component_mapping_file = os.path.join(workspace_path, subdir, COMPONENT_MAPPING_FILENAME)
404117 93     with open(component_mapping_file, 'w') as f:
94         f.write(json.dumps(mapping, sort_keys=True, indent=4))
95
96
97 def main():
98     parser = argparse.ArgumentParser()
99
100     parser.add_argument('-w', '--workspace', default=os.getenv('WS_TOP'), help='Path to workspace')
101     parser.add_argument('--subdir', default='components', help='Directory holding components')
780de6 102     parser.add_argument('--repo', default='userland', help='Default target repository')
JMC 103     parser.add_argument('--repo-map', help='Target repository for this directory; e.g., encumbered/=userland-encumbered', action='append')
404117 104
105     args = parser.parse_args()
106
107     workspace = args.workspace
108     subdir = args.subdir
109
780de6 110     repo = args.repo
JMC 111     repo_map = []
112     if args.repo_map:
113         for rm in args.repo_map:
114             l = rm.split("=")
115             if len(l) != 2:
116                 raise ValueError('invalid --repo-map: ' + rm)
117             repo_map.append({'pfx': l[0], 'repo': l[1]})
118
119     generate_userland_mapping(workspace_path=workspace, subdir=subdir, repo=repo, repo_map=repo_map)
404117 120
121 if __name__ == '__main__':
122     main()