def Run(self, args): client = appengine_api_client.GetApiClientForTrack(self.ReleaseTrack()) services = client.ListServices() all_versions = client.ListVersions(services) # Sort versions to make behavior deterministic enough for unit testing. versions = sorted(version_util.GetMatchingVersions(all_versions, args.versions, args.service)) services_to_delete = [] for service in sorted(services): service_versions = len( [v for v in all_versions if v.service == service.id]) versions_to_delete = len([v for v in versions if v.service == service.id]) if service_versions == versions_to_delete and service_versions > 0: if service.id == 'default': raise VersionsDeleteError( 'The default service (module) may not be deleted, and must ' 'comprise at least one version.' ) else: services_to_delete.append(service) for version in copy.copy(versions): if version.service == service.id: versions.remove(version) for version in versions: if version.traffic_split: # TODO(b/32869800): collect info on all versions before raising. raise VersionsDeleteError( 'Version [{version}] is currently serving {allocation:.2f}% of ' 'traffic for service [{service}].\n\n' 'Please move all traffic away via one of the following methods:\n' ' - deploying a new version with the `--promote` argument\n' ' - running `gcloud app services set-traffic`\n' ' - running `gcloud app versions migrate`'.format( version=version.id, allocation=version.traffic_split * 100, service=version.service)) if services_to_delete: word = text.Pluralize(len(services_to_delete), 'service') log.warning( 'Requested deletion of all existing versions for the following {0}:' .format(word)) resource_printer.Print(services_to_delete, 'list', out=log.status) console_io.PromptContinue(prompt_string=( '\nYou cannot delete all versions of a service. Would you like to ' 'delete the entire {0} instead?').format(word), cancel_on_no=True) service_util.DeleteServices(client, services_to_delete) if versions: fmt = 'list[title="Deleting the following versions:"]' resource_printer.Print(versions, fmt, out=log.status) console_io.PromptContinue(cancel_on_no=True) else: if not services_to_delete: log.warning('No matching versions found.') version_util.DeleteVersions(client, versions)
def Run(self, args): # TODO(user): This fails with "module/version does not exist" even # when it exists if the scaling mode is set to auto. It would be good # to improve that error message. api_client = appengine_api_client.GetApiClient() services = api_client.ListServices() versions = version_util.GetMatchingVersions( api_client.ListVersions(services), args.versions, args.service) if versions: printer = console_io.ListPrinter( 'Stopping the following versions:') printer.Print(versions, output_stream=log.status) console_io.PromptContinue(cancel_on_no=True) else: log.warn('No matching versions found.') errors = [] for version in sorted(versions): try: with console_io.ProgressTracker( 'Stopping [{0}]'.format(version)): api_client.StopVersion(version.service, version.id) except (calliope_exceptions.HttpException, operations.OperationError, operations.OperationTimeoutError) as err: errors.append(str(err)) if errors: raise VersionsStopError('\n\n'.join(errors))
def Run(self, args): # TODO(b/36057452): This fails with "module/version does not exist" even # when it exists if the scaling mode is set to auto. It would be good # to improve that error message. api_client = appengine_api_client.GetApiClientForTrack( self.ReleaseTrack()) services = api_client.ListServices() versions = version_util.GetMatchingVersions( api_client.ListVersions(services), args.versions, args.service) if versions: fmt = 'list[title="Stopping the following versions:"]' resource_printer.Print(versions, fmt, out=log.status) console_io.PromptContinue(cancel_on_no=True) else: log.warn('No matching versions found.') errors = [] for version in sorted(versions): try: with progress_tracker.ProgressTracker( 'Stopping [{0}]'.format(version)): operations_util.CallAndCollectOpErrors( api_client.StopVersion, version.service, version.id, block=True) except operations_util.MiscOperationError as err: errors.append(str(err)) if errors: raise VersionsStopError('\n\n'.join(errors))
def Run(self, args): # TODO(user): This fails with "module/version does not exist" even # when it exists if the scaling mode is set to auto. It would be good # to improve that error message. api_client = appengine_api_client.GetApiClient() services = api_client.ListServices() versions = version_util.GetMatchingVersions( api_client.ListVersions(services), args.versions, args.service) if not versions: log.warn('No matching versions found.') return fmt = 'list[title="Starting the following versions:"]' resource_printer.Print(versions, fmt, out=log.status) console_io.PromptContinue(cancel_on_no=True) errors = {} for version in versions: try: with console_io.ProgressTracker('Starting [{0}]'.format(version)): api_client.StartVersion(version.service, version.id) except (calliope_exceptions.HttpException, operations.OperationError, operations.OperationTimeoutError) as err: errors[version] = str(err) if errors: printable_errors = {} for version, error_msg in errors.items(): short_name = '[{0}/{1}]'.format(version.service, version.id) printable_errors[short_name] = '{0}: {1}'.format(short_name, error_msg) raise VersionsStartError( 'Issues starting version(s): {0}\n\n'.format( ', '.join(printable_errors.keys())) + '\n\n'.join(printable_errors.values()))
def Run(self, args): # TODO(markpell): This fails with "module/version does not exist" even # when it exists if the scaling mode is set to auto. It would be good # to improve that error message. client = appengine_client.AppengineClient() versions = version_util.GetMatchingVersions(client.ListVersions(), args.versions, args.service, client.project) if not versions: log.warn('No matching versions found.') return printer = console_io.ListPrinter('Starting the following versions:') printer.Print(versions, output_stream=log.status) console_io.PromptContinue(cancel_on_no=True) errors = {} for version in versions: try: with console_io.ProgressTracker('Starting [{0}]'.format(version)): client.StartModule(module=version.service, version=version.version) except util.RPCError as err: errors[version] = str(err) if errors: printable_errors = {} for version, error_msg in errors.items(): short_name = '[{0}/{1}]'.format(version.service, version.version) printable_errors[short_name] = '{0}: {1}'.format(short_name, error_msg) raise VersionsStartError( 'Issues starting version(s): {0}\n\n'.format( ', '.join(printable_errors.keys())) + '\n\n'.join(printable_errors.values()))
def Run(self, args): # TODO(markpell): This fails with "module/version does not exist" even # when it exists if the scaling mode is set to auto. It would be good # to improve that error message. client = appengine_client.AppengineClient() versions = version_util.GetMatchingVersions(client.ListVersions(), args.versions, args.service, client.project) if versions: printer = console_io.ListPrinter( 'Stopping the following versions:') printer.Print(versions, output_stream=log.status) console_io.PromptContinue(cancel_on_no=True) else: log.warn('No matching versions found.') errors = [] for version in sorted(versions): try: with console_io.ProgressTracker( 'Stopping [{0}]'.format(version)): client.StopModule(module=version.service, version=version.version) except util.RPCError as err: errors.append(str(err)) if errors: raise VersionsStopError('\n\n'.join(errors))
def Run(self, args): if ':' in properties.VALUES.core.project.Get(required=True): raise UnsupportedAppIdError( '`browse` command is currently unsupported for app IDs with custom ' 'domains.') client = appengine_client.AppengineClient() versions = version_util.GetMatchingVersions(client.ListVersions(), args.versions, args.service, client.project) if not args.service and not any('/' in v for v in args.versions): # If no resource paths were provided and the service was not specified, # assume the default service. versions = [v for v in versions if v.service == 'default'] if not versions: log.warn('No matching versions found.') for version in versions: # Assume HTTPS. There's not enough information to determine based on the # results of ListVersions, but HTTPS is always more secure (though HTTP # will work in all cases, since it will redirect to HTTPS). url = deploy_command_util.GetAppHostname( version.project, version.service, version.version, use_ssl=appinfo.SECURE_HTTPS) log.status.Print( 'Opening [{0}] in a new tab in your default browser.'.format( url)) OpenInBrowser(url)
def Run(self, args): client = appengine_api_client.GetApiClient(self.Http(timeout=None)) services = client.ListServices() all_versions = client.ListVersions(services) versions = version_util.GetMatchingVersions(all_versions, args.versions, args.service, client.project) services_to_delete = [] for service in services: if (len([v for v in all_versions if v.service == service.id]) == len( [v for v in versions if v.service == service.id])): services_to_delete.append(service) for version in copy.copy(versions): if version.service == service.id: versions.remove(version) for version in versions: if version.traffic_split: # TODO(user): mention `migrate` once it's implemented. raise VersionsDeleteError( 'Version [{version}] is currently serving {allocation:.2f}% of ' 'traffic for service [{service}].\n\n' 'Please move all traffic away by deploying a new version with the' '`--promote` argument or running `gcloud preview app services ' 'set-traffic`.'.format(version=version.id, allocation=version.traffic_split * 100, service=version.service)) if services_to_delete: word = text.Pluralize(len(services_to_delete), 'service') log.warn( 'Requested deletion of all existing versions for the following ' '{0}:'.format(word)) printer = console_io.ListPrinter('') printer.Print(services_to_delete, output_stream=log.status) console_io.PromptContinue(prompt_string=( '\nYou cannot delete all versions of a service. Would you like to ' 'delete the entire {0} instead?').format(word), cancel_on_no=True) service_util.DeleteServices(client, services_to_delete) if versions: printer = console_io.ListPrinter( 'Deleting the following versions:') printer.Print(versions, output_stream=log.status) console_io.PromptContinue(cancel_on_no=True) else: if not services_to_delete: log.warn('No matching versions found.') version_util.DeleteVersions(client, versions)
def Run(self, args): client = appengine_client.AppengineClient() versions = version_util.GetMatchingVersions(client.ListVersions(), args.versions, args.service, client.project) for version in versions: if version.traffic_allocation: # TODO(zjn): mention `set-traffic` after b/24008284 is fixed. # TODO(zjn): mention `migrate` it's implemented. # TODO(zjn): mention `services delete` after it's implemented. raise VersionsDeleteError( 'Version [{version}] is currently serving {allocation}% of traffic ' 'for service [{service}].\n\n' 'Please move all traffic away by using the by deploying a new ' 'version with the `--promote` argument.'.format( version=version.version, allocation=version.traffic_allocation, service=version.service)) if versions: printer = console_io.ListPrinter( 'Deleting the following versions:') printer.Print(versions, output_stream=log.status) console_io.PromptContinue(cancel_on_no=True) else: log.warn('No matching versions found.') api_client = appengine_api_client.GetApiClient(self.Http(timeout=None)) errors = {} for version in sorted(versions): try: with console_io.ProgressTracker( 'Deleting [{0}]'.format(version)): api_client.DeleteVersion(version.service, version.version) except (calliope_exceptions.HttpException, operations.OperationError, operations.OperationTimeoutError) as err: errors[version] = str(err) if errors: printable_errors = {} for version, error_msg in errors.items(): short_name = '[{0}/{1}]'.format(version.service, version.version) printable_errors[short_name] = '{0}: {1}'.format( short_name, error_msg) raise VersionsDeleteError( 'Issues deleting version(s): {0}\n\n'.format(', '.join( printable_errors.keys())) + '\n\n'.join(printable_errors.values()))
def GetAllInstances(self, service=None, version=None): """List all instances, optionally filtering by service or version. Args: service: str, the ID of the service to filter by. version: str, the ID of the service to filter by. Returns: list of instance_util.Instance """ services = self.ListServices() log.debug('All services: {0}'.format(services)) services = service_util.GetMatchingServices( services, [service] if service else None) versions = self.ListVersions(services) log.debug('Versions: {0}'.format(map(str, versions))) versions = version_util.GetMatchingVersions( versions, [version] if version else None, service) return self.ListInstances(versions)
def Run(self, args): # TODO(b/36052475): This fails with "module/version does not exist" even # when it exists if the scaling mode is set to auto. It would be good # to improve that error message. api_client = appengine_api_client.GetApiClientForTrack( self.ReleaseTrack()) services = api_client.ListServices() versions = version_util.GetMatchingVersions( api_client.ListVersions(services), args.versions, args.service) if not versions: log.warning('No matching versions found.') return fmt = 'list[title="Starting the following versions:"]' resource_printer.Print(versions, fmt, out=log.status) console_io.PromptContinue(cancel_on_no=True) errors = {} # Sort versions to make behavior deterministic enough for unit testing. for version in sorted(versions): try: with progress_tracker.ProgressTracker( 'Starting [{0}]'.format(version)): operations_util.CallAndCollectOpErrors( api_client.StartVersion, version.service, version.id) except operations_util.MiscOperationError as err: errors[version] = str(err) if errors: printable_errors = {} for version, error_msg in errors.items(): short_name = '[{0}/{1}]'.format(version.service, version.id) printable_errors[short_name] = '{0}: {1}'.format( short_name, error_msg) raise VersionsStartError( 'Issues starting version(s): {0}\n\n'.format(', '.join( printable_errors.keys())) + '\n\n'.join(printable_errors.values()))
def GetAllInstances(self, service=None, version=None, version_filter=None): """Generator of all instances, optionally filtering by service or version. Args: service: str, the ID of the service to filter by. version: str, the ID of the version to filter by. version_filter: filter function accepting version_util.Version Returns: generator of instance_util.Instance """ services = self.ListServices() log.debug('All services: {0}'.format(services)) services = service_util.GetMatchingServices( services, [service] if service else None) versions = self.ListVersions(services) log.debug('Versions: {0}'.format(list(map(str, versions)))) versions = version_util.GetMatchingVersions( versions, [version] if version else None, service) versions = list(filter(version_filter, versions)) return self.ListInstances(versions)