| # Copyright 2021 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| from recipe_engine import recipe_api |
| |
| GCEM_CLIENT_CIPD_PATH = "fuchsia/gce_mediator/client/gcem_client" |
| GCEM_CLIENT_CIPD_REVISION = "g3-revision:gce-mediator-client_20210405_RC00" |
| |
| |
| class GCEApi(recipe_api.RecipeApi): |
| """API to create GCE Images and Instances via the GCE Mediator""" |
| |
| def _swarming_host(self): |
| """Returns the swarming host this task is running on""" |
| swarming_url_elems = self.m.buildbucket.build.infra.swarming.hostname.split(".") |
| swarming_host = "" |
| if swarming_url_elems: |
| swarming_host = swarming_url_elems[0] |
| return swarming_host |
| |
| def create_botanist_config( |
| self, |
| gcem_host, |
| gcem_cloud_project, |
| gcem_machine_shape, |
| swarming_task_id, |
| output_path, |
| ): |
| """Creates the config used by GCE targets in botanist. |
| |
| See https://cs.opensource.google/fuchsia/fuchsia/+/main:tools/botanist/target/gce.go;l=146 |
| for the schema used. |
| |
| Args: |
| gcem_host (string): the GCE Mediator endpoint to use. |
| gcem_cloud_project (string): the cloud project to create the image in. |
| gcem_machine_shape (string): the machine shape of the VM to create. |
| swarming_task_id (string): the orchestrator's swarming task. |
| output_path (path): the file to output the config to. |
| """ |
| config = [ |
| { |
| "type": "gce", |
| "mediator_url": gcem_host, |
| "build_id": swarming_task_id, |
| "cloud_project": gcem_cloud_project, |
| "swarming_server": self._swarming_host(), |
| "machine_shape": gcem_machine_shape, |
| }, |
| ] |
| self.m.file.write_json( |
| "write gce config", |
| output_path, |
| config, |
| indent=2, |
| ) |
| |
| def create_image( |
| self, |
| gcem_host, |
| gcem_cloud_project, |
| image_manifest, |
| swarming_task_id, |
| gcs_bucket, |
| namespace, |
| timeout_secs=5 * 60, |
| ): |
| """Uses a build's UEFI disk artifact to create a fuchsia image on google compute. |
| |
| Args: |
| gcem_host (string): the GCE Mediator endpoint to use. |
| gcem_cloud_project (string): the cloud project to create the image in. |
| image_manifest (dict): Manifest of images in the GN graph. |
| swarming_task_id (string): the orchestrator's swarming task. |
| timeout_secs (int): the number of seconds to wait for GCE image creation. |
| gcs_bucket (string): A GCS bucket containing a GCE disk image. |
| namespace (string): The build ID or led run ID of the build that |
| created the disk image. |
| """ |
| gcem_cli_path = self.m.cipd.ensure_tool( |
| GCEM_CLIENT_CIPD_PATH, |
| GCEM_CLIENT_CIPD_REVISION, |
| ) |
| |
| # The GCS path is initialized as an empty string. If it is not found, the |
| # gcem_client tool below will catch the error, so we don't need another |
| # check here. |
| gcs_path = "" |
| for image in image_manifest: |
| if image["name"] == "uefi-disk": |
| # The filename here must match the canonical GCE image name used |
| # in artifactory here: |
| # https://cs.opensource.google/fuchsia/fuchsia/+/main:tools/artifactory/images.go;l=22 |
| gcs_path = f"https://storage.googleapis.com/{gcs_bucket}/builds/{namespace}/images/{self.m.path.dirname(image['path'])}/disk.tar.gz" |
| break |
| |
| cmd = [ |
| gcem_cli_path, |
| "create-image", |
| "-host", |
| gcem_host, |
| "-project", |
| gcem_cloud_project, |
| "-swarming-host", |
| self._swarming_host(), |
| "-build-id", |
| swarming_task_id, |
| "-gcs-path", |
| gcs_path, |
| ] |
| |
| self.m.step("create GCE image", cmd, timeout=timeout_secs) |