1# Copyright 2020 Google Inc. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14# 15################################################################################ 16"""Cloud function to build base images on Google Cloud Builder.""" 17 18import logging 19 20import google.auth 21from googleapiclient.discovery import build 22 23BASE_IMAGES = [ 24 'base-image', 25 'base-clang', 26 'base-builder', 27 'base-builder-go', 28 'base-builder-jvm', 29 'base-builder-python', 30 'base-builder-rust', 31 'base-builder-swift', 32 'base-runner', 33 'base-runner-debug', 34] 35BASE_PROJECT = 'oss-fuzz-base' 36TAG_PREFIX = f'gcr.io/{BASE_PROJECT}/' 37MAJOR_VERSION = 'v1' 38 39 40def _get_base_image_steps(images, tag_prefix=TAG_PREFIX): 41 """Returns build steps for given images.""" 42 steps = [{ 43 'args': [ 44 'clone', 45 'https://github.com/google/oss-fuzz.git', 46 ], 47 'name': 'gcr.io/cloud-builders/git', 48 }] 49 50 for base_image in images: 51 image = tag_prefix + base_image 52 steps.append({ 53 'args': [ 54 'build', 55 '-t', 56 image, 57 '-t', 58 f'{image}:{MAJOR_VERSION}', 59 '.', 60 ], 61 'dir': 'oss-fuzz/infra/base-images/' + base_image, 62 'name': 'gcr.io/cloud-builders/docker', 63 }) 64 65 return steps 66 67 68def get_logs_url(build_id, project_id='oss-fuzz-base'): 69 """Returns url that displays the build logs.""" 70 return ('https://console.developers.google.com/logs/viewer?' 71 f'resource=build%2Fbuild_id%2F{build_id}&project={project_id}') 72 73 74# pylint: disable=no-member 75def run_build(steps, images): 76 """Execute the retrieved build steps in gcp.""" 77 credentials, _ = google.auth.default() 78 build_body = { 79 'steps': steps, 80 'timeout': str(6 * 3600) + 's', 81 'options': { 82 'machineType': 'N1_HIGHCPU_32' 83 }, 84 'images': images + [f'{image}:{MAJOR_VERSION}' for image in images] 85 } 86 cloudbuild = build('cloudbuild', 87 'v1', 88 credentials=credentials, 89 cache_discovery=False) 90 build_info = cloudbuild.projects().builds().create(projectId=BASE_PROJECT, 91 body=build_body).execute() 92 build_id = build_info['metadata']['build']['id'] 93 logging.info('Build ID: %s', build_id) 94 logging.info('Logs: %s', get_logs_url(build_id, BASE_PROJECT)) 95 96 97def base_builder(event, context): 98 """Cloud function to build base images.""" 99 del event, context 100 101 tag_prefix = f'gcr.io/{BASE_PROJECT}/' 102 steps = _get_base_image_steps(BASE_IMAGES, tag_prefix) 103 images = [tag_prefix + base_image for base_image in BASE_IMAGES] 104 105 run_build(steps, images) 106