def ReleaseService(self, service_ref, config_changes, tracker=None, asyn=False, allow_unauthenticated=None): """Change the given service in prod using the given config_changes. Ensures a new revision is always created, even if the spec of the revision has not changed. Arguments: service_ref: Resource, the service to release config_changes: list, objects that implement Adjust(). tracker: StagedProgressTracker, to report on the progress of releasing. asyn: bool, if True, release asyncronously allow_unauthenticated: bool, True if creating a hosted Cloud Run service which should also have its IAM policy set to allow unauthenticated access. False if removing the IAM policy to allow unauthenticated access from a service. """ if tracker is None: tracker = progress_tracker.NoOpStagedProgressTracker( stages.ServiceStages(allow_unauthenticated is not None), interruptable=True, aborted_message='aborted') with_image = any( isinstance(c, config_changes_mod.ImageChange) for c in config_changes) self._UpdateOrCreateService(service_ref, config_changes, with_image) if allow_unauthenticated is not None: try: tracker.StartStage(stages.SERVICE_IAM_POLICY_SET) tracker.UpdateStage(stages.SERVICE_IAM_POLICY_SET, '') self.AddOrRemoveIamPolicyBinding( service_ref, allow_unauthenticated, ALLOW_UNAUTH_POLICY_BINDING_MEMBERS, ALLOW_UNAUTH_POLICY_BINDING_ROLE) tracker.CompleteStage(stages.SERVICE_IAM_POLICY_SET) except api_exceptions.HttpError: warning_message = ( 'Setting IAM policy failed, try "gcloud beta run services ' '{}-iam-policy-binding --region={region} --member=allUsers ' '--role=roles/run.invoker {service}"'.format( 'add' if allow_unauthenticated else 'remove', region=self._region, service=service_ref.servicesId)) tracker.CompleteStageWithWarning( stages.SERVICE_IAM_POLICY_SET, warning_message=warning_message) if not asyn: getter = functools.partial(self.GetService, service_ref) poller = ServiceConditionPoller(getter, tracker) self.WaitForCondition(poller) for msg in run_condition.GetNonTerminalMessages( poller.GetConditions()): tracker.AddWarning(msg)
def ReleaseService(self, service_ref, config_changes, tracker=None, asyn=False, allow_unauthenticated=None, for_replace=False, prefetch=False, build_op_ref=None, build_log_url=None): """Change the given service in prod using the given config_changes. Ensures a new revision is always created, even if the spec of the revision has not changed. Arguments: service_ref: Resource, the service to release. config_changes: list, objects that implement Adjust(). tracker: StagedProgressTracker, to report on the progress of releasing. asyn: bool, if True, return without waiting for the service to be updated. allow_unauthenticated: bool, True if creating a hosted Cloud Run service which should also have its IAM policy set to allow unauthenticated access. False if removing the IAM policy to allow unauthenticated access from a service. for_replace: bool, If the change is for a replacing the service from a YAML specification. prefetch: the service, pre-fetched for ReleaseService. `False` indicates the caller did not perform a prefetch; `None` indicates a nonexistant service. build_op_ref: The reference to the build. build_log_url: The log url of the build result. """ if tracker is None: tracker = progress_tracker.NoOpStagedProgressTracker( stages.ServiceStages(allow_unauthenticated is not None), interruptable=True, aborted_message='aborted') if build_op_ref is not None: tracker.StartStage(stages.BUILD_READY) tracker.UpdateHeaderMessage('Building Container.') tracker.UpdateStage( stages.BUILD_READY, 'Logs are available at [{build_log_url}].'.format( build_log_url=build_log_url)) client = cloudbuild_util.GetClientInstance() poller = waiter.CloudOperationPoller(client.projects_builds, client.operations) operation = waiter.PollUntilDone(poller, build_op_ref) response_dict = encoding.MessageToPyValue(operation.response) if response_dict and response_dict['status'] != 'SUCCESS': tracker.FailStage( stages.BUILD_READY, None, message='Container build failed and ' 'logs are available at [{build_log_url}].'.format( build_log_url=build_log_url)) return else: tracker.CompleteStage(stages.BUILD_READY) if prefetch is None: serv = None else: serv = prefetch or self.GetService(service_ref) if for_replace: with_image = True else: with_image = any( isinstance(c, config_changes_mod.ImageChange) for c in config_changes) self._AddRevisionForcingChange(serv, config_changes) if serv and not with_image: # Avoid changing the running code by making the new revision by digest self._EnsureImageDigest(serv, config_changes) config_changes = [_SetClientNameAndVersion()] + config_changes self._UpdateOrCreateService( service_ref, config_changes, with_image, serv) if allow_unauthenticated is not None: try: tracker.StartStage(stages.SERVICE_IAM_POLICY_SET) tracker.UpdateStage(stages.SERVICE_IAM_POLICY_SET, '') self.AddOrRemoveIamPolicyBinding(service_ref, allow_unauthenticated, ALLOW_UNAUTH_POLICY_BINDING_MEMBER, ALLOW_UNAUTH_POLICY_BINDING_ROLE) tracker.CompleteStage(stages.SERVICE_IAM_POLICY_SET) except api_exceptions.HttpError: warning_message = ( 'Setting IAM policy failed, try "gcloud beta run services ' '{}-iam-policy-binding --region={region} --member=allUsers ' '--role=roles/run.invoker {service}"'.format( 'add' if allow_unauthenticated else 'remove', region=self._region, service=service_ref.servicesId)) tracker.CompleteStageWithWarning( stages.SERVICE_IAM_POLICY_SET, warning_message=warning_message) if not asyn: getter = functools.partial(self.GetService, service_ref) poller = ServiceConditionPoller( getter, tracker, dependencies=stages.ServiceDependencies(), serv=serv) self.WaitForCondition(poller) for msg in run_condition.GetNonTerminalMessages(poller.GetConditions()): tracker.AddWarning(msg)