def RunDeploy( args, api_client, use_beta_stager=False, runtime_builder_strategy=runtime_builders.RuntimeBuilderStrategy.NEVER, parallel_build=True, flex_image_build_option=FlexImageBuildOptions.ON_CLIENT, disable_build_cache=False): """Perform a deployment based on the given args. Args: args: argparse.Namespace, An object that contains the values for the arguments specified in the ArgsDeploy() function. api_client: api_lib.app.appengine_api_client.AppengineClient, App Engine Admin API client. use_beta_stager: Use the stager registry defined for the beta track rather than the default stager registry. runtime_builder_strategy: runtime_builders.RuntimeBuilderStrategy, when to use the new CloudBuild-based runtime builders (alternative is old externalized runtimes). parallel_build: bool, whether to use parallel build and deployment path. Only supported in v1beta and v1alpha App Engine Admin API. flex_image_build_option: FlexImageBuildOptions, whether a flex deployment should upload files so that the server can build the image or build the image on client. disable_build_cache: bool, disable the build cache. Returns: A dict on the form `{'versions': new_versions, 'configs': updated_configs}` where new_versions is a list of version_util.Version, and updated_configs is a list of config file identifiers, see yaml_parsing.ConfigYamlInfo. """ project = properties.VALUES.core.project.Get(required=True) deploy_options = DeployOptions.FromProperties( runtime_builder_strategy=runtime_builder_strategy, parallel_build=parallel_build, flex_image_build_option=flex_image_build_option) with files.TemporaryDirectory() as staging_area: stager = _MakeStager(args.skip_staging, use_beta_stager, args.staging_command, staging_area) services, configs = deployables.GetDeployables( args.deployables, stager, deployables.GetPathMatchers()) service_infos = [d.service_info for d in services] flags.ValidateImageUrl(args.image_url, service_infos) # pylint: disable=protected-access log.debug( 'API endpoint: [{endpoint}], API version: [{version}]'.format( endpoint=api_client.client.url, version=api_client.client._VERSION)) # The legacy admin console API client. # The Admin Console API existed long before the App Engine Admin API, and # isn't being improved. We're in the process of migrating all of the calls # over to the Admin API, but a few things (notably config deployments) # haven't been ported over yet. ac_client = appengine_client.AppengineClient(args.server, args.ignore_bad_certs) app = _PossiblyCreateApp(api_client, project) _RaiseIfStopped(api_client, app) app = _PossiblyRepairApp(api_client, app) # Tell the user what is going to happen, and ask them to confirm. version_id = args.version or util.GenerateVersionId() deployed_urls = output_helpers.DisplayProposedDeployment( app, project, services, configs, version_id, deploy_options.promote) console_io.PromptContinue(cancel_on_no=True) if service_infos: # Do generic app setup if deploying any services. # All deployment paths for a service involve uploading source to GCS. metrics.CustomTimedEvent(metric_names.GET_CODE_BUCKET_START) code_bucket_ref = args.bucket or flags.GetCodeBucket(app, project) metrics.CustomTimedEvent(metric_names.GET_CODE_BUCKET) log.debug( 'Using bucket [{b}].'.format(b=code_bucket_ref.ToBucketUrl())) # Prepare Flex if any service is going to deploy an image. if any([s.RequiresImage() for s in service_infos]): if deploy_options.use_service_management: deploy_command_util.PossiblyEnableFlex(project) else: deploy_command_util.DoPrepareManagedVms(ac_client) all_services = dict([(s.id, s) for s in api_client.ListServices()]) else: code_bucket_ref = None all_services = {} new_versions = [] deployer = ServiceDeployer(api_client, deploy_options) # Track whether a service has been deployed yet, for metrics. service_deployed = False for service in services: if not service_deployed: metrics.CustomTimedEvent( metric_names.FIRST_SERVICE_DEPLOY_START) new_version = version_util.Version(project, service.service_id, version_id) deployer.Deploy(service, new_version, code_bucket_ref, args.image_url, all_services, app.gcrDomain, disable_build_cache=disable_build_cache, flex_image_build_option=flex_image_build_option) new_versions.append(new_version) log.status.Print('Deployed service [{0}] to [{1}]'.format( service.service_id, deployed_urls[service.service_id])) if not service_deployed: metrics.CustomTimedEvent(metric_names.FIRST_SERVICE_DEPLOY) service_deployed = True # Deploy config files. if configs: metrics.CustomTimedEvent(metric_names.UPDATE_CONFIG_START) for config in configs: message = 'Updating config [{config}]'.format(config=config.name) with progress_tracker.ProgressTracker(message): ac_client.UpdateConfig(config.name, config.parsed) metrics.CustomTimedEvent(metric_names.UPDATE_CONFIG) updated_configs = [c.name for c in configs] PrintPostDeployHints(new_versions, updated_configs) # Return all the things that were deployed. return {'versions': new_versions, 'configs': updated_configs}
def RunDeploy(args, enable_endpoints=False, app_create=False, use_beta_stager=False): """Perform a deployment based on the given args. Args: args: argparse.Namespace, An object that contains the values for the arguments specified in the ArgsDeploy() function. enable_endpoints: Enable Cloud Endpoints for the deployed app. app_create: Offer to create an app if current GCP project is appless. use_beta_stager: Use the stager registry defined for the beta track rather than the default stager registry. Returns: A dict on the form `{'versions': new_versions, 'configs': updated_configs}` where new_versions is a list of version_util.Version, and updated_configs is a list of config file identifiers, see yaml_parsing.ConfigYamlInfo. """ version_id = args.version or util.GenerateVersionId() flags.ValidateVersion(version_id) project = properties.VALUES.core.project.Get(required=True) deploy_options = DeployOptions.FromProperties(enable_endpoints, app_create) # Parse existing app.yamls or try to generate a new one if the directory is # empty. if not args.deployables: yaml_path = deploy_command_util.DEFAULT_DEPLOYABLE if not os.path.exists(deploy_command_util.DEFAULT_DEPLOYABLE): log.warning('Automatic app detection is currently in Beta') yaml_path = deploy_command_util.CreateAppYamlForAppDirectory( os.getcwd()) app_config = yaml_parsing.AppConfigSet([yaml_path]) else: app_config = yaml_parsing.AppConfigSet(args.deployables) # If applicable, sort services by order they were passed to the command. services = app_config.Services() if not args.skip_image_url_validation: flags.ValidateImageUrl(args.image_url, services) # The new API client. api_client = appengine_api_client.GetApiClient() # pylint: disable=protected-access log.debug('API endpoint: [{endpoint}], API version: [{version}]'.format( endpoint=api_client.client.url, version=api_client.client._VERSION)) # The legacy admin console API client. # The Admin Console API existed long before the App Engine Admin API, and # isn't being improved. We're in the process of migrating all of the calls # over to the Admin API, but a few things (notably config deployments) haven't # been ported over yet. ac_client = appengine_client.AppengineClient(args.server, args.ignore_bad_certs) app = _PossiblyCreateApp(api_client, project, deploy_options.app_create) if properties.VALUES.app.use_gsutil.GetBool(): log.warning( 'Your gcloud installation has a deprecated config property ' 'enabled: [app/use_gsutil], which will be removed in a ' 'future version. Run `gcloud config unset app/use_gsutil` to ' 'switch to the recommended approach. If you encounter any ' 'issues, please report using `gcloud feedback`. To revert ' 'temporarily, run `gcloud config set app/use_gsutil True`.\n') # Tell the user what is going to happen, and ask them to confirm. deployed_urls = output_helpers.DisplayProposedDeployment( app, project, app_config, version_id, deploy_options.promote) console_io.PromptContinue(cancel_on_no=True) if services: # Do generic app setup if deploying any services. # All deployment paths for a service involve uploading source to GCS. code_bucket_ref = args.bucket or flags.GetCodeBucket(app, project) metrics.CustomTimedEvent(metric_names.GET_CODE_BUCKET) log.debug( 'Using bucket [{b}].'.format(b=code_bucket_ref.ToBucketUrl())) # Prepare Flex if any service is going to deploy an image. if any([m.RequiresImage() for m in services.values()]): deploy_command_util.DoPrepareManagedVms(ac_client) all_services = dict([(s.id, s) for s in api_client.ListServices()]) else: code_bucket_ref = None all_services = {} new_versions = [] if args.skip_staging: stager = staging.GetNoopStager() elif use_beta_stager: stager = staging.GetBetaStager() else: stager = staging.GetStager() deployer = ServiceDeployer(api_client, stager, deploy_options) for name, service in services.iteritems(): new_version = version_util.Version(project, name, version_id) deployer.Deploy(service, new_version, code_bucket_ref, args.image_url, all_services) new_versions.append(new_version) log.status.Print('Deployed service [{0}] to [{1}]'.format( name, deployed_urls[name])) # Deploy config files. for (name, config) in app_config.Configs().iteritems(): message = 'Updating config [{config}]'.format(config=name) with progress_tracker.ProgressTracker(message): ac_client.UpdateConfig(name, config.parsed) updated_configs = app_config.Configs().keys() PrintPostDeployHints(new_versions, updated_configs) # Return all the things that were deployed. return {'versions': new_versions, 'configs': updated_configs}
def RunDeploy(unused_self, args, enable_endpoints=False, app_create=False): """Perform a deployment based on the given args.""" version_id = args.version or util.GenerateVersionId() flags.ValidateVersion(version_id) project = properties.VALUES.core.project.Get(required=True) deploy_options = DeployOptions.FromProperties(enable_endpoints, app_create) # Parse existing app.yamls or try to generate a new one if the directory is # empty. if not args.deployables: yaml_path = deploy_command_util.DEFAULT_DEPLOYABLE if not os.path.exists(deploy_command_util.DEFAULT_DEPLOYABLE): log.warning('Automatic app detection is currently in Beta') yaml_path = deploy_command_util.CreateAppYamlForAppDirectory( os.getcwd()) app_config = yaml_parsing.AppConfigSet([yaml_path]) else: app_config = yaml_parsing.AppConfigSet(args.deployables) services = app_config.Services() if not args.skip_image_url_validation: flags.ValidateImageUrl(args.image_url, services) # The new API client. api_client = appengine_api_client.GetApiClient() # pylint: disable=protected-access log.debug('API endpoint: [{endpoint}], API version: [{version}]'.format( endpoint=api_client.client.url, version=api_client.client._VERSION)) # The legacy admin console API client. # The Admin Console API existed long before the App Engine Admin API, and # isn't being improved. We're in the process of migrating all of the calls # over to the Admin API, but a few things (notably config deployments) haven't # been ported over yet. ac_client = appengine_client.AppengineClient(args.server, args.ignore_bad_certs) app = _PossiblyCreateApp(api_client, project, deploy_options.app_create) # Tell the user what is going to happen, and ask them to confirm. deployed_urls = output_helpers.DisplayProposedDeployment( app, project, app_config, version_id, deploy_options.promote) console_io.PromptContinue(cancel_on_no=True) if services: # Do generic app setup if deploying any services. # All deployment paths for a service involve uploading source to GCS. code_bucket_ref = args.bucket or flags.GetCodeBucket(app, project) metrics.CustomTimedEvent(metric_names.GET_CODE_BUCKET) log.debug( 'Using bucket [{b}].'.format(b=code_bucket_ref.ToBucketUrl())) # Prepare Flex if any service is going to deploy an image. if any([m.RequiresImage() for m in services.values()]): deploy_command_util.DoPrepareManagedVms(ac_client) all_services = dict([(s.id, s) for s in api_client.ListServices()]) else: code_bucket_ref = None all_services = {} new_versions = [] stager = staging.GetNoopStager( ) if args.skip_staging else staging.GetStager() deployer = ServiceDeployer(api_client, stager, deploy_options) for (name, service) in services.iteritems(): new_version = version_util.Version(project, name, version_id) deployer.Deploy(service, new_version, code_bucket_ref, args.image_url, all_services) new_versions.append(new_version) log.status.Print('Deployed service [{0}] to [{1}]'.format( name, deployed_urls[name])) # Deploy config files. for (name, config) in app_config.Configs().iteritems(): message = 'Updating config [{config}]'.format(config=name) with progress_tracker.ProgressTracker(message): ac_client.UpdateConfig(name, config.parsed) updated_configs = app_config.Configs().keys() PrintPostDeployHints(new_versions, updated_configs) # Return all the things that were deployed. return {'versions': new_versions, 'configs': updated_configs}
def RunDeploy( args, enable_endpoints=False, use_beta_stager=False, runtime_builder_strategy=runtime_builders.RuntimeBuilderStrategy.NEVER, use_service_management=False, check_for_stopped=False): """Perform a deployment based on the given args. Args: args: argparse.Namespace, An object that contains the values for the arguments specified in the ArgsDeploy() function. enable_endpoints: Enable Cloud Endpoints for the deployed app. use_beta_stager: Use the stager registry defined for the beta track rather than the default stager registry. runtime_builder_strategy: runtime_builders.RuntimeBuilderStrategy, when to use the new CloudBuild-based runtime builders (alternative is old externalized runtimes). use_service_management: bool, whether to use servicemanagement API to enable the Appengine Flexible API for a Flexible deployment. check_for_stopped: bool, whether to check if the app is stopped before deploying. Returns: A dict on the form `{'versions': new_versions, 'configs': updated_configs}` where new_versions is a list of version_util.Version, and updated_configs is a list of config file identifiers, see yaml_parsing.ConfigYamlInfo. """ project = properties.VALUES.core.project.Get(required=True) deploy_options = DeployOptions.FromProperties( enable_endpoints, runtime_builder_strategy=runtime_builder_strategy) # Parse existing app.yamls or try to generate a new one if the directory is # empty. if not args.deployables: yaml_path = deploy_command_util.DEFAULT_DEPLOYABLE if not os.path.exists(deploy_command_util.DEFAULT_DEPLOYABLE): log.warning('Automatic app detection is currently in Beta') yaml_path = deploy_command_util.CreateAppYamlForAppDirectory( os.getcwd()) app_config = yaml_parsing.AppConfigSet([yaml_path]) else: app_config = yaml_parsing.AppConfigSet(args.deployables) # If applicable, sort services by order they were passed to the command. services = app_config.Services() if not args.skip_image_url_validation: flags.ValidateImageUrl(args.image_url, services) # The new API client. api_client = appengine_api_client.GetApiClient() # pylint: disable=protected-access log.debug('API endpoint: [{endpoint}], API version: [{version}]'.format( endpoint=api_client.client.url, version=api_client.client._VERSION)) # The legacy admin console API client. # The Admin Console API existed long before the App Engine Admin API, and # isn't being improved. We're in the process of migrating all of the calls # over to the Admin API, but a few things (notably config deployments) haven't # been ported over yet. ac_client = appengine_client.AppengineClient(args.server, args.ignore_bad_certs) app = _PossiblyCreateApp(api_client, project) if check_for_stopped: _RaiseIfStopped(api_client, app) app = _PossiblyRepairApp(api_client, app) # Tell the user what is going to happen, and ask them to confirm. version_id = args.version or util.GenerateVersionId() deployed_urls = output_helpers.DisplayProposedDeployment( app, project, app_config, version_id, deploy_options.promote) console_io.PromptContinue(cancel_on_no=True) if services: # Do generic app setup if deploying any services. # All deployment paths for a service involve uploading source to GCS. metrics.CustomTimedEvent(metric_names.GET_CODE_BUCKET_START) code_bucket_ref = args.bucket or flags.GetCodeBucket(app, project) metrics.CustomTimedEvent(metric_names.GET_CODE_BUCKET) log.debug( 'Using bucket [{b}].'.format(b=code_bucket_ref.ToBucketUrl())) # Prepare Flex if any service is going to deploy an image. if any([m.RequiresImage() for m in services.values()]): if use_service_management: deploy_command_util.PossiblyEnableFlex(project) else: deploy_command_util.DoPrepareManagedVms(ac_client) all_services = dict([(s.id, s) for s in api_client.ListServices()]) else: code_bucket_ref = None all_services = {} new_versions = [] if args.skip_staging: stager = staging.GetNoopStager() elif use_beta_stager: stager = staging.GetBetaStager() else: stager = staging.GetStager() deployer = ServiceDeployer(api_client, stager, deploy_options) # Track whether a service has been deployed yet, for metrics. service_deployed = False for name, service in services.iteritems(): if not service_deployed: metrics.CustomTimedEvent(metric_names.FIRST_SERVICE_DEPLOY_START) new_version = version_util.Version(project, name, version_id) deployer.Deploy(service, new_version, code_bucket_ref, args.image_url, all_services, app.gcrDomain) new_versions.append(new_version) log.status.Print('Deployed service [{0}] to [{1}]'.format( name, deployed_urls[name])) if not service_deployed: metrics.CustomTimedEvent(metric_names.FIRST_SERVICE_DEPLOY) service_deployed = True # Deploy config files. if app_config.Configs(): metrics.CustomTimedEvent(metric_names.UPDATE_CONFIG_START) for (name, config) in app_config.Configs().iteritems(): message = 'Updating config [{config}]'.format(config=name) with progress_tracker.ProgressTracker(message): ac_client.UpdateConfig(name, config.parsed) if app_config.Configs(): metrics.CustomTimedEvent(metric_names.UPDATE_CONFIG) updated_configs = app_config.Configs().keys() PrintPostDeployHints(new_versions, updated_configs) # Return all the things that were deployed. return {'versions': new_versions, 'configs': updated_configs}