示例#1
0
    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(service_name=service_name,
                                     version_id=version_id),
            version=self.messages.Version(servingStatus=serving_status),
            updateMask='servingStatus')
        operation = self.client.apps_services_versions.Patch(patch_request)
        if block:
            return operations_util.WaitForOperation(
                self.client.apps_operations, operation)
        else:
            return operation
示例#2
0
    def CreateDomainMapping(self, domain, certificate_id,
                            no_managed_certificate):
        """Creates a domain mapping for the given application.

    Args:
      domain: str, the custom domain string.
      certificate_id: str, a certificate id for the new domain.
      no_managed_certificate: bool, don't automatically provision a certificate.

    Returns:
      The created DomainMapping object.
    """
        ssl = self.messages.SslSettings(certificateId=certificate_id)

        domain_mapping = self.messages.DomainMapping(id=domain,
                                                     sslSettings=ssl)

        request = self.messages.AppengineAppsDomainMappingsCreateRequest(
            parent=self._FormatApp(),
            domainMapping=domain_mapping,
            noManagedCertificate=no_managed_certificate)

        operation = requests.MakeRequest(
            self.client.apps_domainMappings.Create, request)

        return operations_util.WaitForOperation(self.client.apps_operations,
                                                operation).response
示例#3
0
    def UpdateDispatchRules(self, dispatch_rules):
        """Updates an application's dispatch rules.

    Args:
      dispatch_rules: [{'service': str, 'domain': str, 'path': str}], dispatch-
          rules to set-and-replace.

    Returns:
      Long running operation.
    """

        # Create a configuration update request.
        update_mask = 'dispatchRules,'

        application_update = self.messages.Application()
        application_update.dispatchRules = [
            self.messages.UrlDispatchRule(**r) for r in dispatch_rules
        ]
        update_request = self.messages.AppengineAppsPatchRequest(
            name=self._FormatApp(),
            application=application_update,
            updateMask=update_mask)

        operation = self.client.apps.Patch(update_request)

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

        return operations_util.WaitForOperation(self.client.apps_operations,
                                                operation)
示例#4
0
    def UpdateDatabaseType(self, database_type):
        """Updates an application's database_type.

    Args:
      database_type: New database type to switch to

    Returns:
      Long running operation.
    """

        # Create a configuration update request.
        update_mask = 'databaseType'
        application_update = self.messages.Application()
        application_update.databaseType = database_type
        update_request = self.messages.AppengineAppsPatchRequest(
            name=self._FormatApp(),
            application=application_update,
            updateMask=update_mask)

        operation = self.client.apps.Patch(update_request)

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

        return operations_util.WaitForOperation(self.client.apps_operations,
                                                operation)
示例#5
0
    def SetTrafficSplit(self,
                        service_name,
                        allocations,
                        shard_by='UNSPECIFIED',
                        migrate=False):
        """Sets the traffic split of the given services.

    Args:
      service_name: str, The service 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_service_request = self.messages.AppengineAppsServicesPatchRequest(
            name=self._GetServiceRelativeName(service_name=service_name),
            service=self.messages.Service(split=traffic_split),
            migrateTraffic=migrate,
            updateMask='split')

        message = 'Setting traffic split for service [{service}]'.format(
            service=service_name)
        operation = self.client.apps_services.Patch(update_service_request)
        return operations_util.WaitForOperation(self.client.apps_operations,
                                                operation,
                                                message=message)
示例#6
0
    def CreateDomainMapping(self, domain, certificate_id, management_type):
        """Creates a domain mapping for the given application.

    Args:
      domain: str, the custom domain string.
      certificate_id: str, a certificate id for the new domain.
      management_type: SslSettings.SslManagementTypeValueValuesEnum,
                       AUTOMATIC or MANUAL certificate provisioning.

    Returns:
      The created DomainMapping object.
    """
        ssl = self.messages.SslSettings(certificateId=certificate_id,
                                        sslManagementType=management_type)

        domain_mapping = self.messages.DomainMapping(id=domain,
                                                     sslSettings=ssl)

        request = self.messages.AppengineAppsDomainMappingsCreateRequest(
            parent=self._FormatApp(), domainMapping=domain_mapping)

        operation = self.client.apps_domainMappings.Create(request)

        return operations_util.WaitForOperation(self.client.apps_operations,
                                                operation).response
  def UpdateDomainMapping(self, domain, certificate_id, no_certificate_id):
    """Updates a domain mapping for the given application.

    Args:
      domain: str, the custom domain string.
      certificate_id: str, a certificate id for the domain.
      no_certificate_id: boolean, remove the certificate id from the domain.

    Returns:
      The updated DomainMapping object.
    """
    mask_fields = []
    if certificate_id or no_certificate_id:
      mask_fields.append('sslSettings.certificateId')

    ssl = self.messages.SslSettings(certificateId=certificate_id)

    domain_mapping = self.messages.DomainMapping(id=domain, sslSettings=ssl)

    if not mask_fields:
      raise exceptions.MinimumArgumentException(
          'Please specify at least one attribute to the domain-mapping update.')

    request = self.messages.AppengineAppsDomainMappingsPatchRequest(
        name=self._FormatDomainMapping(domain),
        domainMapping=domain_mapping,
        updateMask=','.join(mask_fields))

    operation = requests.MakeRequest(self.client.apps_domainMappings.Patch,
                                     request)

    return operations_util.WaitForOperation(self.client.apps_operations,
                                            operation).response
  def PatchApplication(self,
                       split_health_checks=None):
    """Updates an application.

    Args:
      split_health_checks: Boolean, whether to enable split health checks by
      default.

    Returns:
      Long running operation.
    """

    # Create a configuration update request.
    update_mask = ''
    if split_health_checks is not None:
      update_mask += 'featureSettings.splitHealthChecks,'

    application_update = self.messages.Application()
    application_update.featureSettings = self.messages.FeatureSettings(
        splitHealthChecks=split_health_checks)
    update_request = self.messages.AppengineAppsPatchRequest(
        name=self._FormatApp(),
        application=application_update,
        updateMask=update_mask)

    operation = self.client.apps.Patch(update_request)

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

    return operations_util.WaitForOperation(self.client.apps_operations,
                                            operation)
示例#9
0
    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:
      apitools_exceptions.HttpConflictError if app already exists

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

        operation = self.client.apps.Create(create_request)

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

        message = (
            'Creating App Engine application in project [{project}] and '
            'region [{region}].'.format(project=self.project, region=location))
        return operations_util.WaitForOperation(self.client.apps_operations,
                                                operation,
                                                message=message)
    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.Application(id=self.project,
                                                   locationId=location)

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

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

        return operations_util.WaitForOperation(self.client.apps_operations,
                                                operation)
    def DeployService(self,
                      service_name,
                      version_id,
                      service_config,
                      manifest,
                      build,
                      endpoints_info=None,
                      extra_config_settings=None):
        """Updates and deploys new app versions based on given config.

    If the build operation has not yet completed, streams the Google Cloud
    Builder logs as well.

    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.
      build: BuildArtifact, a wrapper which contains either the build
        ID for an in-progress parallel build, or the name of the container image
        for a serial build.
      endpoints_info: EndpointsServiceInfo, Endpoints service info to be added
        to the AppInfoExternal configuration. Only provided when Endpoints API
        Management feature is enabled.
      extra_config_settings: dict, client config settings to pass to the server
        as beta settings.
    Returns:
      A Version resource representing the deployed version.
    """
        version_resource = self._CreateVersionResource(service_config,
                                                       manifest, version_id,
                                                       build, endpoints_info,
                                                       extra_config_settings)
        create_request = self.messages.AppengineAppsServicesVersionsCreateRequest(
            parent=self._GetServiceRelativeName(service_name=service_name),
            version=version_resource)

        operation = self.client.apps_services_versions.Create(create_request)

        # If build operation is still in progress, stream build logs and wait for
        # completion before polling the service deployment operation for completion.
        # Service deployment can never complete before the build has finished, as it
        # is dependent on the built image.
        if build and build.IsBuildId() and build.build_op:
            cloud_build.CloudBuildClient().WaitAndStreamLogs(build.build_op)
            metrics.CustomTimedEvent(metric_names.CLOUDBUILD_EXECUTE_ASYNC)

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

        message = 'Updating service [{service}]'.format(service=service_name)

        return operations_util.WaitForOperation(self.client.apps_operations,
                                                operation,
                                                message=message)
示例#12
0
  def DeleteDomainMapping(self, domain):
    """Deletes a domain mapping for the given application.

    Args:
      domain: str, the domain to delete.
    """
    request = self.messages.AppengineAppsDomainMappingsDeleteRequest(
        name=self._FormatDomainMapping(domain))

    operation = self.client.apps_domainMappings.Delete(request)

    operations_util.WaitForOperation(self.client.apps_operations, operation)
示例#13
0
 def Run(self, args):
     api_client = appengine_api_client.GetApiClient()
     operation = api_client.GetOperation(args.operation)
     if operation.done:
         log.status.Print('Operation [{0}] is already done.'.format(
             args.operation))
         return operation
     else:
         with progress_tracker.ProgressTracker(
                 'Waiting for operation [{0}] to complete.'.format(
                     args.operation)):
             return operations_util.WaitForOperation(
                 api_client.client.apps_operations, operation)
示例#14
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_util.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_util.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)
  def DeleteInstance(self, res):
    """Delete a Flexible instance.

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

    Returns:
      The completed Operation.
    """
    request = self.messages.AppengineAppsServicesVersionsInstancesDeleteRequest(
        name=res.RelativeName())
    operation = self.client.apps_services_versions_instances.Delete(request)
    return operations_util.WaitForOperation(self.client.apps_operations,
                                            operation)
    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_util.WaitForOperation(self.client.apps_operations,
                                                operation)
示例#17
0
    def DeployService(self,
                      service_name,
                      version_id,
                      service_config,
                      manifest,
                      build,
                      endpoints_info=None,
                      extra_config_settings=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.
      build: BuildArtifact, a wrapper which contains either the build
        ID for an in-progress parallel build, or the name of the container image
        for a serial build.
      endpoints_info: EndpointsServiceInfo, Endpoints service info to be added
        to the AppInfoExternal configuration. Only provided when Endpoints API
        Management feature is enabled.
      extra_config_settings: dict, client config settings to pass to the server
        as beta settings.
    Returns:
      A Version resource representing the deployed version.
    """
        version_resource = self._CreateVersionResource(service_config,
                                                       manifest, version_id,
                                                       build, endpoints_info,
                                                       extra_config_settings)
        create_request = self.messages.AppengineAppsServicesVersionsCreateRequest(
            parent=self._GetServiceRelativeName(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))

        message = 'Updating service [{service}]'.format(service=service_name)

        return operations_util.WaitForOperation(self.client.apps_operations,
                                                operation,
                                                message=message)
    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_util.WaitForOperation(self.client.apps_operations,
                                                operation)
    def RepairApplication(self):
        """Creates missing app resources.

    In particular, the Application.code_bucket GCS reference.

    Returns:
      A long running operation.
    """
        request = self.messages.AppengineAppsRepairRequest(
            name=self._FormatApp(),
            repairApplicationRequest=self.messages.RepairApplicationRequest())

        operation = requests.MakeRequest(self.client.apps.Repair, request)

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

        return operations_util.WaitForOperation(self.client.apps_operations,
                                                operation)
示例#20
0
  def UpdateDomainMapping(self,
                          domain,
                          certificate_id,
                          no_certificate_id,
                          management_type):
    """Updates a domain mapping for the given application.

    Args:
      domain: str, the custom domain string.
      certificate_id: str, a certificate id for the domain.
      no_certificate_id: bool, remove the certificate id from the domain.
      management_type: SslSettings.SslManagementTypeValueValuesEnum,
                       AUTOMATIC or MANUAL certificate provisioning.

    Returns:
      The updated DomainMapping object.
    """
    mask_fields = []
    if certificate_id or no_certificate_id:
      mask_fields.append('sslSettings.certificateId')
    if management_type:
      mask_fields.append('sslSettings.sslManagementType')

    ssl = self.messages.SslSettings(
        certificateId=certificate_id, sslManagementType=management_type)

    domain_mapping = self.messages.DomainMapping(id=domain, sslSettings=ssl)

    if not mask_fields:
      raise exceptions.MinimumArgumentException(
          ['--[no-]certificate-id', '--no_managed_certificate'],
          'Please specify at least one attribute to the domain-mapping update.')

    request = self.messages.AppengineAppsDomainMappingsPatchRequest(
        name=self._FormatDomainMapping(domain),
        domainMapping=domain_mapping,
        updateMask=','.join(mask_fields))

    operation = self.client.apps_domainMappings.Patch(request)

    return operations_util.WaitForOperation(self.client.apps_operations,
                                            operation).response
示例#21
0
  def _SetAppEngineApplicationIap(self, enabled, oauth2_client_id=None,
                                  oauth2_client_secret=None):
    application = _GetApplication(self.project)

    api_client = appengine_api_client.AppengineApiClient.GetApiClient()

    iap_kwargs = _MakeIAPKwargs(False, application.iap, enabled,
                                oauth2_client_id, oauth2_client_secret)
    application_update = api_client.messages.Application(
        iap=api_client.messages.IdentityAwareProxy(**iap_kwargs))

    application = resources.REGISTRY.Parse(
        self.project, collection=APPENGINE_APPS_COLLECTION)

    update_request = api_client.messages.AppengineAppsPatchRequest(
        name=application.RelativeName(),
        application=application_update,
        updateMask='iap,')
    operation = api_client.client.apps.Patch(update_request)
    return operations_util.WaitForOperation(api_client.client.apps_operations,
                                            operation)
  def DebugInstance(self, res, ssh_key=None):
    """Enable debugging of a Flexible instance.

    Args:
      res: A googleclousdk.core.Resource object.
      ssh_key: str, Public SSH key to add to the instance. Examples:
        `[USERNAME]:ssh-rsa [KEY_VALUE] [USERNAME]` ,
        `[USERNAME]:ssh-rsa [KEY_VALUE] google-ssh {"userName":"******",`
        `"expireOn":"[EXPIRE_TIME]"}`
        For more information, see Adding and Removing SSH Keys
        (https://cloud.google.com/compute/docs/instances/adding-removing-ssh-
        keys).

    Returns:
      The completed Operation.
    """
    request = self.messages.AppengineAppsServicesVersionsInstancesDebugRequest(
        name=res.RelativeName(),
        debugInstanceRequest=self.messages.DebugInstanceRequest(sshKey=ssh_key))
    operation = self.client.apps_services_versions_instances.Debug(request)
    return operations_util.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(
            parent=self._GetServiceRelativeName(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_util.WaitForOperation(self.client.apps_operations,
                                                operation)
  def RepairApplication(self, progress_message=None):
    """Creates missing app resources.

    In particular, the Application.code_bucket GCS reference.

    Args:
      progress_message: str, the message to use while the operation is polled,
        if not the default.

    Returns:
      A long running operation.
    """
    request = self.messages.AppengineAppsRepairRequest(
        name=self._FormatApp(),
        repairApplicationRequest=self.messages.RepairApplicationRequest())

    operation = requests.MakeRequest(self.client.apps.Repair, request)

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

    return operations_util.WaitForOperation(
        self.client.apps_operations, operation, message=progress_message)
示例#25
0
    def SetIngressTrafficAllowed(self, service_name, ingress_traffic_allowed):
        """Sets the ingress traffic allowed for a service.

    Args:
      service_name: str, The service name
      ingress_traffic_allowed: An IngressTrafficAllowed enum.

    Returns:
      The completed Operation. The Operation will contain a Service resource.
    """
        network_settings = self.messages.NetworkSettings(
            ingressTrafficAllowed=ingress_traffic_allowed)
        update_service_request = self.messages.AppengineAppsServicesPatchRequest(
            name=self._GetServiceRelativeName(service_name=service_name),
            service=self.messages.Service(networkSettings=network_settings),
            updateMask='networkSettings')

        message = 'Setting ingress settings for service [{service}]'.format(
            service=service_name)
        operation = self.client.apps_services.Patch(update_service_request)
        return operations_util.WaitForOperation(self.client.apps_operations,
                                                operation,
                                                message=message)
示例#26
0
    def DeployService(self,
                      service_name,
                      version_id,
                      service_config,
                      manifest,
                      build,
                      extra_config_settings=None):
        """Updates and deploys new app versions.

    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.
      build: BuildArtifact, a wrapper which contains either the build
        ID for an in-progress parallel build, the name of the container image
        for a serial build, or the options for creating a build elsewhere. Not
        present during standard deploys.
      extra_config_settings: dict, client config settings to pass to the server
        as beta settings.
    Returns:
      The Admin API Operation, unfinished.
    """
        operation = self._CreateVersion(service_name, version_id,
                                        service_config, manifest, build,
                                        extra_config_settings)

        message = 'Updating service [{service}]'.format(service=service_name)
        if util.Environment.IsFlexible(service_config.env):
            message += ' (this may take several minutes)'

        operation_metadata_type = self._ResolveMetadataType()
        # This indicates that a server-side build should be created.
        if build and build.IsBuildOptions():
            if not operation_metadata_type:
                log.warning(
                    'Unable to determine build from Operation metadata. '
                    'Skipping log streaming')
            else:
                # Poll the operation until the build is present.
                poller = operations_util.AppEngineOperationBuildPoller(
                    self.client.apps_operations, operation_metadata_type)
                operation = operations_util.WaitForOperation(
                    self.client.apps_operations,
                    operation,
                    message=message,
                    poller=poller)
                build_id = operations_util.GetBuildFromOperation(
                    operation, operation_metadata_type)
                if build_id:
                    build = app_cloud_build.BuildArtifact.MakeBuildIdArtifact(
                        build_id)
        if build and build.IsBuildId():
            build_ref = resources.REGISTRY.Parse(
                build.identifier,
                params={'projectId': properties.VALUES.core.project.GetOrFail},
                collection='cloudbuild.projects.builds')
            cloudbuild_logs.CloudBuildClient().Stream(build_ref)

        done_poller = operations_util.AppEngineOperationPoller(
            self.client.apps_operations, operation_metadata_type)
        return operations_util.WaitForOperation(self.client.apps_operations,
                                                operation,
                                                message=message,
                                                poller=done_poller)
示例#27
0
    def DeployService(self,
                      service_name,
                      version_id,
                      service_config,
                      manifest,
                      build,
                      extra_config_settings=None,
                      service_account_email=None):
        """Updates and deploys new app versions.

    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.
      build: BuildArtifact, a wrapper which contains either the build
        ID for an in-progress parallel build, the name of the container image
        for a serial build, or the options for creating a build elsewhere. Not
        present during standard deploys.
      extra_config_settings: dict, client config settings to pass to the server
        as beta settings.
      service_account_email: Identity of this deployed version. If not set, the
        Admin API will fall back to use the App Engine default appspot service
        account.

    Returns:
      The Admin API Operation, unfinished.

    Raises:
      apitools_exceptions.HttpNotFoundError if build ID doesn't exist
    """
        operation = self._CreateVersion(service_name, version_id,
                                        service_config, manifest, build,
                                        extra_config_settings,
                                        service_account_email)

        message = 'Updating service [{service}]'.format(service=service_name)
        if service_config.env in [env.FLEX, env.MANAGED_VMS]:
            message += ' (this may take several minutes)'

        operation_metadata_type = self._ResolveMetadataType()
        # This indicates that a server-side build should be created.
        if build and build.IsBuildOptions():
            if not operation_metadata_type:
                log.warning(
                    'Unable to determine build from Operation metadata. '
                    'Skipping log streaming')
            else:
                # Poll the operation until the build is present.
                poller = operations_util.AppEngineOperationBuildPoller(
                    self.client.apps_operations, operation_metadata_type)
                operation = operations_util.WaitForOperation(
                    self.client.apps_operations,
                    operation,
                    message=message,
                    poller=poller)
                build_id = operations_util.GetBuildFromOperation(
                    operation, operation_metadata_type)
                if build_id:
                    build = app_cloud_build.BuildArtifact.MakeBuildIdArtifact(
                        build_id)

        if build and build.IsBuildId():
            try:
                build_ref = resources.REGISTRY.Parse(
                    build.identifier,
                    params={
                        'projectId': properties.VALUES.core.project.GetOrFail
                    },
                    collection='cloudbuild.projects.builds')
                cloudbuild_logs.CloudBuildClient().Stream(build_ref,
                                                          out=log.status)
            except apitools_exceptions.HttpNotFoundError:
                region = util.ConvertToCloudRegion(
                    self.GetApplication().locationId)
                build_ref = resources.REGISTRY.Create(
                    collection='cloudbuild.projects.locations.builds',
                    projectsId=properties.VALUES.core.project.GetOrFail,
                    locationsId=region,
                    buildsId=build.identifier)
                cloudbuild_logs.CloudBuildClient().Stream(build_ref,
                                                          out=log.status)

        done_poller = operations_util.AppEngineOperationPoller(
            self.client.apps_operations, operation_metadata_type)
        return operations_util.WaitForOperation(self.client.apps_operations,
                                                operation,
                                                message=message,
                                                poller=done_poller)