• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 datetime
19import logging
20
21import google.auth
22from googleapiclient.discovery import build
23
24BASE_IMAGES = [
25    'base-image',
26    'base-clang',
27    'base-builder',
28    'base-runner',
29    'base-runner-debug',
30]
31BASE_PROJECT = 'oss-fuzz-base'
32TAG_PREFIX = f'gcr.io/{BASE_PROJECT}/'
33
34BASE_SANITIZER_LIBS_IMAGE = TAG_PREFIX + 'base-sanitizer-libs-builder'
35MSAN_LIBS_IMAGE = TAG_PREFIX + 'msan-libs-builder'
36
37
38def _get_base_image_steps(images, tag_prefix=TAG_PREFIX):
39  """Returns build steps for given images."""
40  steps = [{
41      'args': [
42          'clone',
43          'https://github.com/google/oss-fuzz.git',
44      ],
45      'name': 'gcr.io/cloud-builders/git',
46  }]
47
48  for base_image in images:
49    steps.append({
50        'args': [
51            'build',
52            '-t',
53            tag_prefix + base_image,
54            '.',
55        ],
56        'dir': 'oss-fuzz/infra/base-images/' + base_image,
57        'name': 'gcr.io/cloud-builders/docker',
58    })
59
60  return steps
61
62
63def get_logs_url(build_id, project_id='oss-fuzz-base'):
64  """Returns url that displays the build logs."""
65  url_format = ('https://console.developers.google.com/logs/viewer?'
66                'resource=build%2Fbuild_id%2F{0}&project={1}')
67  return url_format.format(build_id, project_id)
68
69
70# pylint: disable=no-member
71def run_build(steps, images):
72  """Execute the retrieved build steps in gcp."""
73  credentials, _ = google.auth.default()
74  build_body = {
75      'steps': steps,
76      'timeout': str(6 * 3600) + 's',
77      'options': {
78          'machineType': 'N1_HIGHCPU_32'
79      },
80      'images': images
81  }
82  cloudbuild = build('cloudbuild',
83                     'v1',
84                     credentials=credentials,
85                     cache_discovery=False)
86  build_info = cloudbuild.projects().builds().create(projectId=BASE_PROJECT,
87                                                     body=build_body).execute()
88  build_id = build_info['metadata']['build']['id']
89  logging.info('Build ID: %s', build_id)
90  logging.info('Logs: %s', get_logs_url(build_id, BASE_PROJECT))
91
92
93def base_builder(event, context):
94  """Cloud function to build base images."""
95  del event, context
96
97  tag_prefix = f'gcr.io/{BASE_PROJECT}/'
98  steps = _get_base_image_steps(BASE_IMAGES, tag_prefix)
99  images = [tag_prefix + base_image for base_image in BASE_IMAGES]
100
101  run_build(steps, images)
102
103
104def _get_msan_steps(image):
105  """Get build steps for msan-libs-builder."""
106  timestamp = datetime.datetime.utcnow().strftime('%Y%m%d%H%M')
107  upload_name = 'msan-libs-' + timestamp + '.zip'
108
109  steps = _get_base_image_steps([
110      'base-sanitizer-libs-builder',
111      'msan-libs-builder',
112  ])
113  steps.extend([{
114      'name': image,
115      'args': [
116          'bash',
117          '-c',
118          'cd /msan && zip -r /workspace/libs.zip .',
119      ],
120  }, {
121      'name':
122          'gcr.io/cloud-builders/gsutil',
123      'args': [
124          'cp',
125          '/workspace/libs.zip',
126          'gs://oss-fuzz-msan-libs/' + upload_name,
127      ],
128  }])
129  return steps
130
131
132def base_msan_builder(event, context):
133  """Cloud function to build base images."""
134  del event, context
135  steps = _get_msan_steps(MSAN_LIBS_IMAGE)
136  images = [
137      BASE_SANITIZER_LIBS_IMAGE,
138      MSAN_LIBS_IMAGE,
139  ]
140
141  run_build(steps, images)
142