diff options
Diffstat (limited to 'infra/build/functions/request_build.py')
-rw-r--r-- | infra/build/functions/request_build.py | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/infra/build/functions/request_build.py b/infra/build/functions/request_build.py new file mode 100644 index 00000000..2a76d69e --- /dev/null +++ b/infra/build/functions/request_build.py @@ -0,0 +1,87 @@ +# Copyright 2020 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +################################################################################ +"""Cloud function to request builds.""" +import base64 +import logging +import sys + +import google.auth +from googleapiclient.discovery import build +from google.cloud import ndb + +import build_lib +import build_project +from datastore_entities import Project + +BASE_PROJECT = 'oss-fuzz-base' + + +def get_project_data(project_name): + """Retrieve project metadata from datastore.""" + with ndb.Client().context(): + query = Project.query(Project.name == project_name) + project = query.get() + if project is None: + raise RuntimeError( + 'Project {0} not available in cloud datastore'.format(project_name)) + project_yaml_contents = project.project_yaml_contents + dockerfile_lines = project.dockerfile_contents.split('\n') + + return (project_yaml_contents, dockerfile_lines) + + +def get_build_steps(project_name, image_project, base_images_project): + """Retrieve build steps.""" + project_yaml_contents, dockerfile_lines = get_project_data(project_name) + build_steps = build_project.get_build_steps(project_name, + project_yaml_contents, + dockerfile_lines, image_project, + base_images_project) + return build_steps + + +# pylint: disable=no-member +def request_build(event, context): + """Entry point for cloud function to request builds.""" + del context #unused + if 'data' in event: + project_name = base64.b64decode(event['data']).decode('utf-8') + else: + logging.error('Project name missing from payload') + sys.exit(1) + + credentials, image_project = google.auth.default() + build_steps = get_build_steps(project_name, image_project, BASE_PROJECT) + + build_body = { + 'steps': build_steps, + 'timeout': str(build_lib.BUILD_TIMEOUT) + 's', + 'options': { + 'machineType': 'N1_HIGHCPU_32' + }, + 'tags': [project_name + '-fuzzing',], + } + + cloudbuild = build('cloudbuild', + 'v1', + credentials=credentials, + cache_discovery=False) + build_info = cloudbuild.projects().builds().create(projectId=image_project, + body=build_body).execute() + build_id = build_info['metadata']['build']['id'] + + logging.info('Build ID: %s', build_id) + logging.info('Logs: %s', build_project.get_logs_url(build_id, image_project)) |