Пример #1
0
    def DeployModule(self, module_name, version_id, module_config, manifest,
                     image):
        """Updates and deploys new app versions based on given config.

    Args:
      module_name: str, The module to deploy.
      version_id: str, The version of the module to deploy.
      module_config: AppInfoExternal, Module info parsed from a module yaml
        file.
      manifest: Dictionary mapping source files to Google Cloud Storage
        locations.
      image: The name of the container image.
    Returns:
      A Version resource representing the deployed version.
    """
        version_resource = self._CreateVersionResource(module_config, manifest,
                                                       version_id, image)
        create_request = self.messages.AppengineAppsModulesVersionsCreateRequest(
            name=self._FormatModule(app_id=self.project,
                                    module_name=module_name),
            version=version_resource)

        operation = requests.MakeRequest(
            self.client.apps_modules_versions.Create, create_request)

        log.debug('Received operation: [{operation}]'.format(
            operation=operation.name))

        return operations.WaitForOperation(self.client.apps_operations,
                                           operation)
Пример #2
0
    def SetTrafficSplit(self,
                        module_name,
                        allocations,
                        shard_by='UNSPECIFIED',
                        migrate=False):
        """Sets the traffic split of the given modules.

    Args:
      module_name: str, The module name
      allocations: A dict mapping version ID to traffic split.
      shard_by: A ShardByValuesEnum value specifying how to shard the traffic.
      migrate: Whether or not to migrate traffic.
    Returns:
      Long running operation.
    """
        # Create a traffic split where 100% of traffic goes to the specified
        # version.
        traffic_split = encoding.PyValueToMessage(self.messages.TrafficSplit, {
            'allocations': allocations,
            'shardBy': shard_by
        })
        update_module_request = self.messages.AppengineAppsModulesPatchRequest(
            name=self._FormatModule(app_id=self.project,
                                    module_name=module_name),
            module=self.messages.Module(split=traffic_split),
            migrateTraffic=migrate,
            mask='split')

        operation = requests.MakeRequest(self.client.apps_modules.Patch,
                                         update_module_request)
        return operations.WaitForOperation(self.client.apps_operations,
                                           operation)
    def CreateApp(self, location):
        """Creates an App Engine app within the current cloud project.

    Creates a new singleton app within the currently selected Cloud Project.
    The action is one-time and irreversible.

    Args:
      location: str, The location (region) of the app, i.e. "us-central"

    Raises:
      googlecloudsdk.api_lib.app.exceptions.ConflictError if app already exists

    Returns:
      A long running operation.
    """
        create_request = self.messages.AppengineAppsCreateRequest(
            application=self.messages.Application(id=self.project,
                                                  location=location))

        operation = requests.MakeRequest(self.client.apps.Create,
                                         create_request)

        log.debug('Received operation: [{operation}]'.format(
            operation=operation.name))

        return operations.WaitForOperation(self.client.apps_operations,
                                           operation)
    def SetServingStatus(self,
                         service_name,
                         version_id,
                         serving_status,
                         block=True):
        """Sets the serving status of the specified version.

    Args:
      service_name: str, The service name
      version_id: str, The version to delete.
      serving_status: The serving status to set.
      block: bool, whether to block on the completion of the operation

    Returns:
      The completed Operation if block is True, or the Operation to wait on
      otherwise.
    """
        patch_request = self.messages.AppengineAppsServicesVersionsPatchRequest(
            name=self._FormatVersion(app_id=self.project,
                                     service_name=service_name,
                                     version_id=version_id),
            version=self.messages.Version(servingStatus=serving_status),
            mask='servingStatus')
        operation = requests.MakeRequest(
            self.client.apps_services_versions.Patch, patch_request)
        if block:
            return operations.WaitForOperation(self.client.apps_operations,
                                               operation)
        else:
            return operation
Пример #5
0
    def _WaitAndStreamLogs(self, build_op, logs_bucket, build_id, logs_uri):
        """Wait for a Cloud Build to finish, optionally streaming logs."""
        log.status.Print(
            'Started cloud build [{build_id}].'.format(build_id=build_id))
        if logs_bucket:
            log_object = self.CLOUDBUILD_LOGFILE_FMT_STRING.format(
                build_id=build_id)
            log_tailer = cloudbuild_logs.LogTailer(bucket=logs_bucket,
                                                   obj=log_object)
            log_loc = None
            if logs_uri:
                log.status.Print('To see logs in the Cloud Console: ' +
                                 logs_uri)
                log_loc = 'at ' + logs_uri
            else:
                log.status.Print('Logs can be found in the Cloud Console.')
                log_loc = 'in the Cloud Console.'
            op = operations.WaitForOperation(
                operation_service=self.client.operations,
                operation=build_op,
                retry_interval=self._RETRY_INTERVAL,
                max_retries=self._MAX_RETRIES,
                retry_callback=log_tailer.Poll)
            # Poll the logs one final time to ensure we have everything. We know this
            # final poll will get the full log contents because GCS is strongly
            # consistent and Container Builder waits for logs to finish pushing before
            # marking the build complete.
            log_tailer.Poll(is_last=True)
        else:
            op = operations.WaitForOperation(
                operation_service=self.client.operations,
                operation=build_op,
                retry_interval=self._RETRY_INTERVAL,
                max_retries=self._MAX_RETRIES)

        final_status = _GetStatusFromOp(op)
        if final_status != self.CLOUDBUILD_SUCCESS:
            raise BuildFailedError('Cloud build failed with status ' +
                                   final_status + '. Check logs ' + log_loc)
Пример #6
0
def ExecuteCloudBuild(project, source_uri, output_image, cloudbuild_client):
    """Execute a call to Argo CloudBuild service and wait for it to finish.

  Args:
    project: the cloud project ID.
    source_uri: GCS object containing source to build;
                eg, gs://my-bucket/v1/foo/some.version.stuff.
    output_image: GCR location for the output docker image;
                  eg, gcr.io/test-argo/hardcoded-output-tag.
    cloudbuild_client: client to the Argo Cloud Build service.

  Raises:
    BuildFailedError: when the build fails.
  """
    (source_bucket, source_object) = cloud_storage.ParseGcsUri(source_uri)
    # TODO(user): Consider building multiple output images in a single call
    # to Argo Cloud Builder.
    build_op = cloudbuild_client.projects_builds.Create(
        cloudbuild_v1.CloudbuildProjectsBuildsCreateRequest(
            projectId=project,
            build=cloudbuild_v1.Build(
                source=cloudbuild_v1.Source(
                    storageSource=cloudbuild_v1.StorageSource(
                        bucket=source_bucket,
                        object=source_object,
                    ), ),
                steps=[
                    cloudbuild_v1.BuildStep(name=CLOUDBUILD_BUILDER,
                                            args=[output_image])
                ],
                images=[output_image],
            ),
        ))
    # Build ops are named "operation/build/{project_id}/{build_id}".
    build_id = build_op.name.split('/')[-1]
    log.status.Print(
        'Started cloud build [{build_id}].'.format(build_id=build_id))
    logs_uri = CLOUDBUILD_LOGS_URI_TEMPLATE.format(project_id=project,
                                                   build_id=build_id)
    # TODO(user): wait for job to be scheduled before printing logs uri.
    # Alternatively, it would be nice if we wrote a single line to the logs prior
    # to returning from the Create call.
    log.status.Print('Logs at: ' + logs_uri)
    message = 'Waiting for cloud build [{build_id}]'.format(build_id=build_id)
    with console_io.ProgressTracker(message):
        op = operations.WaitForOperation(cloudbuild_client.operations,
                                         build_op)
    final_status = _GetStatusFromOp(op)
    if final_status != CLOUDBUILD_SUCCESS:
        raise BuildFailedError('Cloud build failed with status ' +
                               final_status + '. Check logs at ' + logs_uri)
Пример #7
0
    def DeleteService(self, service_name):
        """Deletes the specified service.

    Args:
      service_name: str, Name of the service to delete.

    Returns:
      The completed Operation.
    """
        delete_request = self.messages.AppengineAppsServicesDeleteRequest(
            name=self._GetServiceRelativeName(service_name=service_name))
        operation = requests.MakeRequest(self.client.apps_services.Delete,
                                         delete_request)
        return operations.WaitForOperation(self.client.apps_operations,
                                           operation)
Пример #8
0
    def DeleteInstance(self, res):
        """Delete a Flexible instance.

    Args:
      res: A googleclousdk.core.Resource object.

    Returns:
      The completed Operation.
    """
        request = self.messages.AppengineAppsServicesVersionsInstancesDeleteRequest(
            name=res.RelativeName())
        operation = requests.MakeRequest(
            self.client.apps_services_versions_instances.Delete, request)
        return operations.WaitForOperation(self.client.apps_operations,
                                           operation)
Пример #9
0
    def DeleteService(self, service_name):
        """Deletes the specified service.

    Args:
      service_name: str, Name of the service to delete.

    Returns:
      The completed Operation.
    """
        delete_request = self.messages.AppengineAppsModulesDeleteRequest(
            name=self._FormatModule(app_id=self.project,
                                    module_name=service_name))
        operation = requests.MakeRequest(self.client.apps_modules.Delete,
                                         delete_request)
        return operations.WaitForOperation(self.client.apps_operations,
                                           operation)
Пример #10
0
    def DeleteVersion(self, service_name, version_id):
        """Deletes the specified version of the given service.

    Args:
      service_name: str, The service name
      version_id: str, The version to delete.

    Returns:
      The completed Operation.
    """
        delete_request = self.messages.AppengineAppsServicesVersionsDeleteRequest(
            name=self._FormatVersion(service_name=service_name,
                                     version_id=version_id))
        operation = requests.MakeRequest(
            self.client.apps_services_versions.Delete, delete_request)
        return operations.WaitForOperation(self.client.apps_operations,
                                           operation)
Пример #11
0
    def DeleteVersion(self, module_name, version_id):
        """Deletes the specified version of the given module.

    Args:
      module_name: str, The module name
      version_id: str, The version to set as default.

    Returns:
      A Version resource representing the deleted version.
    """
        delete_request = self.messages.AppengineAppsModulesVersionsDeleteRequest(
            name=self._FormatVersion(app_id=self.project,
                                     module_name=module_name,
                                     version_id=version_id))
        operation = requests.MakeRequest(
            self.client.apps_modules_versions.Delete, delete_request)
        return operations.WaitForOperation(self.client.apps_operations,
                                           operation)
    def DeleteInstance(self, service, version, instance):
        """Delete a Flexible instance.

    Args:
      service: str, The service id
      version: str, The version id
      instance: str, The instance id

    Returns:
      The completed Operation.
    """
        request = self.messages.AppengineAppsServicesVersionsInstancesDeleteRequest(
            name=self._FormatInstance(app_id=self.project,
                                      service_name=service,
                                      version_id=version,
                                      instance_id=instance))
        operation = requests.MakeRequest(
            self.client.apps_services_versions_instances.Delete, request)
        return operations.WaitForOperation(self.client.apps_operations,
                                           operation)
Пример #13
0
    def SetServingStatus(self, service_name, version_id, serving_status):
        """Sets the serving status of the specified version.

    Args:
      service_name: str, The service name
      version_id: str, The version to delete.
      serving_status: The serving status to set.

    Returns:
      The completed Operation.
    """
        patch_request = self.messages.AppengineAppsServicesVersionsPatchRequest(
            name=self._FormatVersion(app_id=self.project,
                                     service_name=service_name,
                                     version_id=version_id),
            version=self.messages.Version(servingStatus=serving_status),
            mask='servingStatus')
        operation = requests.MakeRequest(
            self.client.apps_services_versions.Patch, patch_request)
        return operations.WaitForOperation(self.client.apps_operations,
                                           operation)
    def DeployService(self,
                      service_name,
                      version_id,
                      service_config,
                      manifest,
                      image,
                      endpoints_info=None):
        """Updates and deploys new app versions based on given config.

    Args:
      service_name: str, The service to deploy.
      version_id: str, The version of the service to deploy.
      service_config: AppInfoExternal, Service info parsed from a service yaml
        file.
      manifest: Dictionary mapping source files to Google Cloud Storage
        locations.
      image: The name of the container image.
      endpoints_info: EndpointsServiceInfo, Endpoints service info to be added
        to the AppInfoExternal configuration. Only provided when Endpoints API
        Management feature is enabled.
    Returns:
      A Version resource representing the deployed version.
    """
        version_resource = self._CreateVersionResource(service_config,
                                                       manifest, version_id,
                                                       image, endpoints_info)
        create_request = self.messages.AppengineAppsServicesVersionsCreateRequest(
            name=self._FormatService(app_id=self.project,
                                     service_name=service_name),
            version=version_resource)

        operation = requests.MakeRequest(
            self.client.apps_services_versions.Create, create_request)

        log.debug('Received operation: [{operation}]'.format(
            operation=operation.name))

        return operations.WaitForOperation(self.client.apps_operations,
                                           operation)
def ExecuteCloudBuild(project, bucket_ref, object_name, output_image,
                      cloudbuild_client, http):
    """Execute a call to CloudBuild service and wait for it to finish.

  Args:
    project: the cloud project ID.
    bucket_ref: Reference to GCS bucket containing source to build.
    object_name: GCS object name containing source to build.
    output_image: GCR location for the output docker image;
                  eg, gcr.io/test-gae/hardcoded-output-tag.
    cloudbuild_client: client to the Cloud Build service.
    http: an http provider that can be used to create api clients.

  Raises:
    BuildFailedError: when the build fails.
  """
    builder = properties.VALUES.app.container_builder_image.Get()
    log.debug('Using builder image: [{0}]'.format(builder))
    logs_bucket = bucket_ref.bucket
    build_op = cloudbuild_client.projects_builds.Create(
        cloudbuild_v1.CloudbuildProjectsBuildsCreateRequest(
            projectId=project,
            build=cloudbuild_v1.Build(
                source=cloudbuild_v1.Source(
                    storageSource=cloudbuild_v1.StorageSource(
                        bucket=bucket_ref.bucket,
                        object=object_name,
                    ), ),
                steps=[
                    cloudbuild_v1.BuildStep(name=builder, args=[output_image])
                ],
                images=[output_image],
                logsBucket=logs_bucket,
            ),
        ))
    # Find build ID from operation metadata and print the logs URL.
    build_id = None
    if build_op.metadata is not None:
        for prop in build_op.metadata.additionalProperties:
            if prop.key == 'build':
                for build_prop in prop.value.object_value.properties:
                    if build_prop.key == 'id':
                        build_id = build_prop.value.string_value
                        break
                break

    if build_id is None:
        raise BuildFailedError('Could not determine build ID')
    log.status.Print(
        'Started cloud build [{build_id}].'.format(build_id=build_id))
    log_object = CLOUDBUILD_LOGFILE_FMT_STRING.format(build_id=build_id)
    log_tailer = cloud_storage.LogTailer(http=http,
                                         bucket=logs_bucket,
                                         obj=log_object)
    logs_uri = CLOUDBUILD_LOGS_URI_TEMPLATE.format(project_id=project,
                                                   build_id=build_id)
    log.status.Print('To see logs in the Cloud Console: ' + logs_uri)
    op = operations.WaitForOperation(
        operation_service=cloudbuild_client.operations,
        operation=build_op,
        retry_interval=1,
        max_retries=60 * 60,
        retry_callback=log_tailer.Poll)
    # Poll the logs one final time to ensure we have everything. We know this
    # final poll will get the full log contents because GCS is strongly consistent
    # and Container Builder waits for logs to finish pushing before marking the
    # build complete.
    log_tailer.Poll(is_last=True)
    final_status = _GetStatusFromOp(op)
    if final_status != CLOUDBUILD_SUCCESS:
        raise BuildFailedError('Cloud build failed with status ' +
                               final_status + '. Check logs at ' + logs_uri)