fritzkink
2023-12-27 706019354bab81fc3f01995caf1ae1a2dfa346cf
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
67     if not component_fmris:
68         raise ValueError('Component FMRIs is empty for path ' + component_path + '.')
404117 69
11232f 70     component_relative_path = component_path.split(os.path.join(os.environ['WS_TOP'], subdir))[-1].replace('/', '', 1)
404117 71
72     return component_fmris, component_name, component_relative_path
73
74
780de6 75 def generate_userland_mapping(workspace_path, subdir='components', repo='userland', repo_map=[]):
404117 76     mapping = []
77
78     paths = find_component_paths(path=workspace_path, subdir=subdir)
79     pool = multiprocessing.Pool(processes=multiprocessing.cpu_count())
80     results = pool.map(generate_component_data, paths)
81
82     for component_fmris, component_name, component_relative_path in results:
83         for component_fmri in component_fmris:
780de6 84             component_repo = repo
JMC 85             for rm in repo_map:
86                 if component_relative_path.startswith(rm['pfx']):
87                     component_repo = rm['repo']
88
1e2fed 89             mapping.append({'name': component_name,
AL 90                             'fmri': component_fmri,
780de6 91                             'path': component_relative_path,
JMC 92                             'repo': component_repo})
404117 93
1e2fed 94     component_mapping_file = os.path.join(workspace_path, subdir, COMPONENT_MAPPING_FILENAME)
404117 95     with open(component_mapping_file, 'w') as f:
96         f.write(json.dumps(mapping, sort_keys=True, indent=4))
97
98
99 def main():
100     parser = argparse.ArgumentParser()
101
102     parser.add_argument('-w', '--workspace', default=os.getenv('WS_TOP'), help='Path to workspace')
103     parser.add_argument('--subdir', default='components', help='Directory holding components')
780de6 104     parser.add_argument('--repo', default='userland', help='Default target repository')
JMC 105     parser.add_argument('--repo-map', help='Target repository for this directory; e.g., encumbered/=userland-encumbered', action='append')
404117 106
107     args = parser.parse_args()
108
109     workspace = args.workspace
110     subdir = args.subdir
111
780de6 112     repo = args.repo
JMC 113     repo_map = []
114     if args.repo_map:
115         for rm in args.repo_map:
116             l = rm.split("=")
117             if len(l) != 2:
118                 raise ValueError('invalid --repo-map: ' + rm)
119             repo_map.append({'pfx': l[0], 'repo': l[1]})
120
121     generate_userland_mapping(workspace_path=workspace, subdir=subdir, repo=repo, repo_map=repo_map)
404117 122
123 if __name__ == '__main__':
124     main()