blob: ab9ed82323ae691c9485ec9939d8bd3b9e6a8f52 [file] [log] [blame]
Inseob Kim29e357e2022-01-17 16:37:51 +09001#!/usr/bin/env python3
2
3# Copyright 2022 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17import argparse
18import glob
19import logging
20import os
21import shutil
22import subprocess
23import tempfile
24import zipfile
25"""This tool generates a mapping file for {ver} core sepolicy."""
26
27
28def check_run(cmd):
29 logging.debug('Running cmd: %s' % cmd)
30 subprocess.run(cmd, check=True)
31
32
33def check_output(cmd):
34 logging.debug('Running cmd: %s' % cmd)
35 return subprocess.run(cmd, check=True, stdout=subprocess.PIPE)
36
37
38def fetch_artifact(branch, build, pattern, destination='.'):
39 """Fetches build artifacts from Android Build server.
40
41 Args:
42 branch: string, branch to pull build artifacts from
43 build: string, build ID or "latest"
44 pattern: string, pattern of build artifact file name
45 destination: string, destination to pull build artifact to
46 """
47 fetch_artifact_path = '/google/data/ro/projects/android/fetch_artifact'
48 cmd = [
49 fetch_artifact_path, '--branch', branch, '--target',
50 'aosp_arm64-userdebug'
51 ]
52 if build == 'latest':
53 cmd.append('--latest')
54 else:
55 cmd.extend(['--bid', build])
56 cmd.extend([pattern, destination])
57 check_run(cmd)
58
59
60def extract_mapping_file_from_img(img_path, ver, destination='.'):
61 """ Extracts system/etc/selinux/mapping/{ver}.cil from system.img file.
62
63 Args:
64 img_path: string, path to system.img file
65 ver: string, version of designated mapping file
66 destination: string, destination to pull the mapping file to
67 """
68
69 cmd = [
70 'debugfs', '-R',
71 'cat system/etc/selinux/mapping/%s.cil' % ver, img_path
72 ]
73 with open(os.path.join(destination, '%s.cil' % ver), 'wb') as f:
74 logging.debug('Extracting %s.cil to %s' % (ver, destination))
75 f.write(check_output(cmd).stdout)
76
77
78def download_mapping_file(branch, build, ver, destination='.'):
79 """ Downloads system/etc/selinux/mapping/{ver}.cil from Android Build server.
80
81 Args:
82 branch: string, branch to pull build artifacts from (e.g. "sc-v2-dev")
83 build: string, build ID or "latest"
84 ver: string, version of designated mapping file (e.g. "32.0")
85 destination: string, destination to pull build artifact to
86 """
87 temp_dir = tempfile.mkdtemp()
88
89 try:
90 artifact_pattern = 'aosp_arm64-img-*.zip'
91 fetch_artifact(branch, build, artifact_pattern, temp_dir)
92
93 # glob must succeed
94 zip_path = glob.glob(os.path.join(temp_dir, artifact_pattern))[0]
95 with zipfile.ZipFile(zip_path) as zip_file:
96 logging.debug('Extracting system.img to %s' % temp_dir)
97 zip_file.extract('system.img', temp_dir)
98
99 system_img_path = os.path.join(temp_dir, 'system.img')
100 extract_mapping_file_from_img(system_img_path, ver, destination)
101 finally:
102 logging.info('Deleting temporary dir: {}'.format(temp_dir))
103 shutil.rmtree(temp_dir)
104
105
106def get_args():
107 parser = argparse.ArgumentParser()
108 parser.add_argument(
109 '--branch',
110 required=True,
111 help='Branch to pull build from. e.g. "sc-v2-dev"')
112 parser.add_argument('--build', required=True, help='Build ID, or "latest"')
113 parser.add_argument(
114 '--version',
115 required=True,
116 help='Version of designated mapping file. e.g. "32.0"')
117 parser.add_argument(
118 '-v',
119 '--verbose',
120 action='count',
121 default=0,
122 help='Increase output verbosity, e.g. "-v", "-vv".')
123 return parser.parse_args()
124
125
126def main():
127 args = get_args()
128
129 verbosity = min(args.verbose, 2)
130 logging.basicConfig(
131 format='%(levelname)-8s [%(filename)s:%(lineno)d] %(message)s',
132 level=(logging.WARNING, logging.INFO, logging.DEBUG)[verbosity])
133
134 download_mapping_file(args.branch, args.build, args.version)
135
136
137if __name__ == '__main__':
138 main()