aboutsummaryrefslogtreecommitdiffhomepage
path: root/infra/build/functions/request_build.py
diff options
context:
space:
mode:
Diffstat (limited to 'infra/build/functions/request_build.py')
-rw-r--r--infra/build/functions/request_build.py87
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))