1# -*- coding: utf-8 -*- # 2# Copyright 2015 Google LLC. All Rights Reserved. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16"""The `app instances enable-debug` command.""" 17 18from __future__ import absolute_import 19from __future__ import division 20from __future__ import unicode_literals 21 22from googlecloudsdk.api_lib.app import appengine_api_client 23from googlecloudsdk.api_lib.app import env 24from googlecloudsdk.api_lib.app import instances_util 25from googlecloudsdk.calliope import base 26from googlecloudsdk.core import properties 27from googlecloudsdk.core import resources 28from googlecloudsdk.core.console import console_io 29from googlecloudsdk.core.console import progress_tracker 30 31 32class EnableDebug(base.Command): 33 """Enable debug mode for an instance (only works on the flexible environment). 34 35 When in debug mode, SSH will be enabled on the VMs, and you can use 36 `gcloud compute ssh` to login to them. They will be removed from the health 37 checking pools, but they still receive requests. 38 39 Note that any local changes to an instance will be *lost* if debug mode is 40 disabled on the instance. New instance(s) may spawn depending on the app's 41 scaling settings. 42 43 Additionally, debug mode doesn't work for applications using the 44 App Engine standard environment. 45 """ 46 47 detailed_help = { 48 'EXAMPLES': """\ 49 To enable debug mode for a particular instance, run: 50 51 $ {command} --service=s1 --version=v1 i1 52 53 To enable debug mode for an instance chosen interactively, run: 54 55 $ {command} 56 """, 57 } 58 59 @staticmethod 60 def Args(parser): 61 parser.add_argument( 62 'instance', nargs='?', 63 help="""\ 64 Instance ID to enable debug mode on. If not specified, 65 select instance interactively. Must uniquely specify (with other 66 flags) exactly one instance""") 67 68 parser.add_argument( 69 '--service', '-s', 70 help="""\ 71 If specified, only match instances belonging to the given service. 72 This affects both interactive and non-interactive selection.""") 73 74 parser.add_argument( 75 '--version', '-v', 76 help="""\ 77 If specified, only match instances belonging to the given version. 78 This affects both interactive and non-interactive selection.""") 79 80 def Run(self, args): 81 api_client = appengine_api_client.GetApiClientForTrack(self.ReleaseTrack()) 82 all_instances = list(api_client.GetAllInstances( 83 args.service, args.version, 84 version_filter=lambda v: v.environment in [env.FLEX, env.MANAGED_VMS])) 85 try: 86 res = resources.REGISTRY.Parse(args.instance) 87 except Exception: # pylint:disable=broad-except 88 # If parsing fails, use interactive selection or provided instance ID. 89 instance = instances_util.GetMatchingInstance( 90 all_instances, service=args.service, version=args.version, 91 instance=args.instance) 92 else: 93 instance = instances_util.GetMatchingInstance( 94 all_instances, service=res.servicesId, version=res.versionsId, 95 instance=res.instancesId) 96 97 console_io.PromptContinue( 98 'About to enable debug mode for instance [{0}].'.format(instance), 99 cancel_on_no=True) 100 message = 'Enabling debug mode for instance [{0}]'.format(instance) 101 res = resources.REGISTRY.Parse( 102 instance.id, 103 params={ 104 'appsId': properties.VALUES.core.project.GetOrFail, 105 'versionsId': instance.version, 106 'instancesId': instance.id, 107 'servicesId': instance.service, 108 }, 109 collection='appengine.apps.services.versions.instances') 110 with progress_tracker.ProgressTracker(message): 111 api_client.DebugInstance(res) 112