Ejemplo n.º 1
0
def _MakeStager(skip_staging, use_beta_stager, staging_command, staging_area):
    """Creates the appropriate stager for the given arguments/release track.

  The stager is responsible for invoking the right local staging depending on
  env and runtime.

  Args:
    skip_staging: bool, if True use a no-op Stager. Takes precedence over other
      arguments.
    use_beta_stager: bool, if True, use a stager that includes beta staging
      commands.
    staging_command: str, path to an executable on disk. If given, use this
      command explicitly for staging. Takes precedence over later arguments.
    staging_area: str, the path to the staging area

  Returns:
    staging.Stager, the appropriate stager for the command
  """
    if skip_staging:
        return staging.GetNoopStager(staging_area)
    elif staging_command:
        command = staging.ExecutableCommand.FromInput(staging_command)
        return staging.GetOverrideStager(command, staging_area)
    elif use_beta_stager:
        return staging.GetBetaStager(staging_area)
    else:
        return staging.GetStager(staging_area)
Ejemplo n.º 2
0
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)

    with files.TemporaryDirectory() as staging_area:
        if args.skip_staging:
            stager = staging.GetNoopStager(staging_area)
        elif use_beta_stager:
            stager = staging.GetBetaStager(staging_area)
        else:
            stager = staging.GetStager(staging_area)
        services, configs = deployables.GetDeployables(
            args.deployables, stager, deployables.GetPathMatchers())
        service_infos = [d.service_info for d in services]

        if not args.skip_image_url_validation:
            flags.ValidateImageUrl(args.image_url, service_infos)

        # 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, 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 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)
            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(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}
Ejemplo n.º 4
0
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}