1#! /usr/bin/env python3 2# Copyright 2021 Google LLC 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15# 16################################################################################ 17"""Script for building and pushing base-images to gcr.io/oss-fuzz-base/ with 18"-test" suffix. This is useful for reusing the build infra to test image 19changes.""" 20import logging 21import multiprocessing 22import os 23import subprocess 24import sys 25 26TAG_PREFIX = 'gcr.io/oss-fuzz-base/' 27INFRA_DIR = os.path.dirname(__file__) 28IMAGES_DIR = os.path.join(INFRA_DIR, 'base-images') 29 30 31def push_image(tag): 32 """Pushes image with |tag| to docker registry.""" 33 logging.info('Pushing: %s', tag) 34 command = ['docker', 'push', tag] 35 subprocess.run(command, check=True) 36 logging.info('Pushed: %s', tag) 37 38 39def build_and_push_image(image, test_image_suffix): 40 """Builds and pushes |image| to docker registry with "-testing" suffix.""" 41 main_tag = TAG_PREFIX + image 42 testing_tag = main_tag + '-' + test_image_suffix 43 tags = [main_tag, testing_tag] 44 build_image(image, tags) 45 push_image(testing_tag) 46 47 48def build_image(image, tags): 49 """Builds |image| and tags it with |tags|.""" 50 logging.info('Building: %s', image) 51 command = ['docker', 'build'] 52 for tag in tags: 53 command.extend(['--tag', tag]) 54 path = os.path.join(IMAGES_DIR, image) 55 command.append(path) 56 subprocess.run(command, check=True) 57 logging.info('Built: %s', image) 58 59 60def build_and_push_images(test_image_suffix): 61 """Builds and pushes base-images.""" 62 images = [ 63 ['base-image'], 64 ['base-clang'], 65 # base-runner is also dependent on base-clang. 66 ['base-builder', 'base-runner'], 67 [ 68 'base-runner-debug', 'base-builder-go', 'base-builder-jvm', 69 'base-builder-python', 'base-builder-rust', 'base-builder-swift' 70 ], 71 ] 72 max_parallelization = max([len(image_list) for image_list in images]) 73 proc_count = min(multiprocessing.cpu_count(), max_parallelization) 74 logging.info('Using %d parallel processes.', proc_count) 75 pool = multiprocessing.Pool(proc_count) 76 for image_list in images: 77 args_list = [(image, test_image_suffix) for image in image_list] 78 pool.starmap(build_and_push_image, args_list) 79 80 81def main(): 82 """"Builds base-images tags them with "-testing" suffix (in addition to normal 83 tag) and pushes testing suffixed images to docker registry.""" 84 test_image_suffix = sys.argv[1] 85 logging.basicConfig(level=logging.DEBUG) 86 logging.info('Doing simple gcloud command to ensure 2FA passes.') 87 subprocess.run(['gcloud', 'projects', 'list', '--limit=1'], check=True) 88 build_and_push_images(test_image_suffix) 89 90 91if __name__ == '__main__': 92 main() 93