module Google::Serverless::Exec::Tasks

# Serverless Rake Tasks.

To make these tasks available, add the line `require “google/serverless/exec/tasks”` to your Rakefile. If your app uses Ruby on Rails, then the serverless gem provides a railtie that adds its tasks automatically, so you don't have to do anything beyond adding the gem to your Gemfile.

The following tasks are defined:

## Rake serverless:exec

Executes a given command in the context of a serverless application. See {Google::Serverless::Exec} for more information on this capability.

The command to be run may either be provided as a rake argument, or as command line arguments, delimited by two dashes `–`. (The dashes are needed to separate your command from rake arguments and flags.) For example, to run a production database migration, you can run either of the following equivalent commands:

bundle exec rake "serverless:exec[bundle exec bin/rails db:migrate]"
bundle exec rake serverless:exec -- bundle exec bin/rails db:migrate

To display usage instructions, provide two dashes but no command:

bundle exec rake serverless:exec --

### Parameters

You may customize the behavior of the serverless execution through a few enviroment variable parameters. These are set via the normal mechanism at the end of a rake command line. For example, to set GAE_CONFIG:

bundle exec rake serverless:exec GAE_CONFIG=myservice.yaml -- bundle exec bin/rails db:migrate

Be sure to set these parameters before the double dash. Any arguments following the double dash are interpreted as part of the command itself.

The following environment variable parameters are supported:

#### GAE_TIMEOUT

Amount of time to wait before serverless:exec terminates the command. Expressed as a string formatted like: “2h15m10s”. Default is “10m”.

#### GAE_PROJECT

The ID of your Google Cloud project. If not specified, uses the current project from gcloud.

#### GAE_CONFIG

Path to the App Engine config file, used when your app has multiple services, or the config file is otherwise not called `./app.yaml`. The config file is used to determine the name of the App Engine service.

#### GAE_SERVICE

Name of the service to be used. Overrides any service name specified in your config file.

#### GAE_EXEC_STRATEGY

The execution strategy to use. Valid values are “deployment” (which is the default for App Engine Standard apps) and “cloud_build” (which is the default for App Engine Flexible and Cloud Run apps).

Normally you should leave the strategy set to the default. The main reason to change it is if your app runs on the Flexible Environment and talks to a database over a VPC (using a private IP address). The “cloud_build” strategy used by default for Flexible apps cannot connect to a VPC, so you should use “deployment” in this case. (But note that, otherwise, the “deployment” strategy is significantly slower for apps on the Flexible environment.)

#### GAE_VERSION

The version of the service, used to identify which application image to use to run your command. If not specified, uses the most recently created version, regardless of whether that version is actually serving traffic. Applies only to the “cloud_build” strategy. (The “deployment” strategy deploys its own temporary version of your app.)

#### GAE_EXEC_WRAPPER_IMAGE

The fully-qualified name of the wrapper image to use. (This is a Docker image that emulates the App Engine environment in Google Cloud Build for the “cloud_build” strategy, and applies only to that strategy.) Normally, you should not override this unless you are testing a new wrapper.

#### CLOUD_BUILD_GCS_LOG_DIR

GCS bucket name of the cloud build log when GAE_STRATEGY is “cloud_build”. (ex. “gs://BUCKET-NAME/FOLDER-NAME”)

Constants

CONFIG_ENV

@private

GCS_LOG_DIR

@private

PRODUCT_ENV

@private

PROJECT_ENV

@private

SERVICE_ENV

@private

STRATEGY_ENV

@private

TIMEOUT_ENV

@private

VERSION_ENV

@private

WRAPPER_IMAGE_ENV

@private

Public Class Methods

define() click to toggle source

@private Define rake tasks.

# File lib/google/serverless/exec/tasks.rb, line 148
def define
  if @defined
    puts "Serverless rake tasks already defined."
    return
  end
  @defined = true
    
  setup_exec_task
end

Private Class Methods

extract_command(cmd, argv) click to toggle source
# File lib/google/serverless/exec/tasks.rb, line 182
          def extract_command cmd, argv
            if cmd
              ::Shellwords.split cmd
            else
              i = (argv.index { |a| a.to_s == "--" } || -1) + 1
              if i.zero?
                report_error <<~MESSAGE
                  No command provided for serverless:exec.
                  Did you remember to delimit it with two dashes? e.g.
                  bundle exec rake serverless:exec -- bundle exec ruby myscript.rb
                  For detailed usage instructions, provide two dashes but no command:
                  bundle exec rake serverless:exec --
                MESSAGE
              end
              command = ::ARGV[i..-1]
              if command.empty?
                show_usage
                exit
              end
              command
            end
          end
extract_product(product) click to toggle source
# File lib/google/serverless/exec/tasks.rb, line 205
def extract_product product
  if product
    product = product.dup
    product.downcase!
    
    case product
    when "app_engine"
      APP_ENGINE
    when "cloud_run"
      CLOUD_RUN
    end
  else
    nil
  end
end
report_error(str) click to toggle source
# File lib/google/serverless/exec/tasks.rb, line 371
def report_error str
  ::STDERR.puts str
  exit 1
end
setup_exec_task() click to toggle source
# File lib/google/serverless/exec/tasks.rb, line 160
def setup_exec_task
  ::Rake.application.last_description =
    "Execute the given command in a Google serverless application."
  ::Rake::Task.define_task "serverless:exec", [:cmd] do |_t, args|
    verify_gcloud_and_report_errors
    command = extract_command args[:cmd], ::ARGV
    selected_product = extract_product ::ENV[PRODUCT_ENV]
    app_exec = Exec.new command,
                        project:       ::ENV[PROJECT_ENV],
                        service:       ::ENV[SERVICE_ENV],
                        config_path:   ::ENV[CONFIG_ENV],
                        version:       ::ENV[VERSION_ENV],
                        timeout:       ::ENV[TIMEOUT_ENV],
                        wrapper_image: ::ENV[WRAPPER_IMAGE_ENV],
                        strategy:      ::ENV[STRATEGY_ENV],
                        gcs_log_dir:   ::ENV[GCS_LOG_DIR],
                        product:       selected_product
    start_and_report_errors app_exec
    exit
  end
end
show_usage() click to toggle source
# File lib/google/serverless/exec/tasks.rb, line 221
          def show_usage
            puts <<~USAGE
              rake serverless:exec
              This Rake task executes a given command in the context of a serverless
              application. For more information,
              on this capability, see the Google::Serverless::Exec documentation at
              http://www.rubydoc.info/gems/appengine/AppEngine/Exec
              The command to be run may either be provided as a rake argument, or as
              command line arguments delimited by two dashes `--`. (The dashes are
              needed to separate your command from rake arguments and flags.)
              For example, to run a production database migration, you can run either
              of the following equivalent commands:
                  bundle exec rake "serverless:exec[bundle exec bin/rails db:migrate]"
                  bundle exec rake serverless:exec -- bundle exec bin/rails db:migrate
              To display these usage instructions, provide two dashes but no command:
                  bundle exec rake serverless:exec --
              You may customize the behavior of the serverless execution through a few
              enviroment variable parameters. These are set via the normal mechanism at
              the end of a rake command line but before the double dash. For example, to
              set GAE_CONFIG:
                  bundle exec rake serverless:exec GAE_CONFIG=myservice.yaml -- bundle exec bin/rails db:migrate
              Be sure to set these parameters before the double dash. Any arguments
              following the double dash are interpreted as part of the command itself.
              The following environment variable parameters are supported:
              GAE_TIMEOUT
                Amount of time to wait before serverless:exec terminates the command.
                Expressed as a string formatted like: "2h15m10s". Default is "10m".
              GAE_PROJECT
                The ID of your Google Cloud project. If not specified, uses the current
                project from gcloud.
              GAE_CONFIG
                Path to the App Engine config file, used when your app has multiple
                services, or the config file is otherwise not called `./app.yaml`. The
                config file is used to determine the name of the App Engine service.
              GAE_SERVICE
                Name of the service to be used. Overrides any service name specified in
                your config file.
              GAE_EXEC_STRATEGY
                The execution strategy to use. Valid values are "deployment" (which is the
                default for App Engine Standard apps) and "cloud_build" (which is the
                default for App Engine Flexible and Cloud Run apps).
                Normally you should leave the strategy set to the default. The main reason
                to change it is if your app runs on the Flexible Environment and talks to
                a database over a VPC (using a private IP address). The "cloud_build"
                strategy used by default for Flexible apps cannot connect to a VPC, so you
                should use "deployment" in this case. (But note that, otherwise, the
                "deployment" strategy is significantly slower for apps on the Flexible
                environment.)
              GAE_VERSION
                The version of the service, used to identify which application image to
                use to run your command. If not specified, uses the most recently created
                version, regardless of whether that version is actually serving traffic.
                Applies only to the "cloud_build" strategy. (The "deployment" strategy
                deploys its own temporary version of your app.)
              GAE_EXEC_WRAPPER_IMAGE
                The fully-qualified name of the wrapper image to use. (This is a Docker
                image that emulates the App Engine environment in Google Cloud Build for
                the "cloud_build" strategy, and applies only to that strategy.) Normally,
                you should not override this unless you are testing a new wrapper.
              CLOUD_BUILD_GCS_LOG_DIR
                GCS bucket name of the cloud build log when GAE_STRATEGY is "cloud_build".
                (ex. "gs://BUCKET-NAME/FOLDER-NAME")
              PRODUCT
                The serverless product to use. Valid values are "app_engine" and "cloud_run".
                If not specified, autodetects the serverless product to use.
              This rake task is provided by the "serverless" gem. To make these tasks
              available, add the following line to your Rakefile:
                  require "google/serverless/exec/tasks"
              If your app uses Ruby on Rails, the gem provides a railtie that adds its
              tasks automatically, so you don't have to do anything beyond adding the
              gem to your Gemfile.
              For more information or to report issues, visit the Github page:
              https://github.com/GoogleCloudPlatform/google-serverless-exec
            USAGE
          end
start_and_report_errors(app_exec) click to toggle source
# File lib/google/serverless/exec/tasks.rb, line 322
          def start_and_report_errors app_exec
            app_exec.start
          rescue Exec::ConfigFileNotFound => e
            report_error <<~MESSAGE
              Could not determine which service should run this command because the App
              Engine config file "#{e.config_path}" was not found.
              Specify the config file using the GAE_CONFIG argument. e.g.
                bundle exec rake serverless:exec GAE_CONFIG=myapp.yaml -- myscript.sh
              Alternately, you may specify a service name directly with GAE_SERVICE. e.g.
                bundle exec rake serverless:exec GAE_SERVICE=myservice -- myscript.sh
            MESSAGE
          rescue Exec::BadConfigFileFormat => e
            report_error <<~MESSAGE
              Could not determine which service should run this command because the App
              Engine config file "#{e.config_path}" was malformed.
              It must be a valid YAML file.
              Specify the config file using the GAE_CONFIG argument. e.g.
                bundle exec rake serverless:exec GAE_CONFIG=myapp.yaml -- myscript.sh
              Alternately, you may specify a service name directly with GAE_SERVICE. e.g.
                bundle exec rake serverless:exec GAE_SERVICE=myservice -- myscript.sh
            MESSAGE
          rescue Exec::NoSuchVersion => e
            if e.version
              report_error <<~MESSAGE
                Could not find version "#{e.version}" of service "#{e.service}".
                Please double-check the version exists. To use the most recent version by
                default, omit the GAE_VERSION argument.
              MESSAGE
            else
              report_error <<~MESSAGE
                Could not find any versions of service "#{e.service}".
                Please double-check that you have deployed this service. If you want to run
                a command against a different service, you may provide a GAE_CONFIG argument
                pointing to your App Engine config file, or a GAE_SERVICE argument to specify
                a service directly.
              MESSAGE
            end
          rescue Exec::NoDefaultProject
            report_error <<~MESSAGE
              Could not get the default project from gcloud.
              Please either set the current project using
                gcloud config set project my-project-id
              or specify the project by setting the GAE_PROJECT argument. e.g.
                bundle exec rake serverless:exec GAE_PROJECT=my-project-id -- myscript.sh
            MESSAGE
          rescue Exec::UsageError => e
            report_error e.message
          end
verify_gcloud_and_report_errors() click to toggle source
# File lib/google/serverless/exec/tasks.rb, line 297
          def verify_gcloud_and_report_errors
            Exec::Gcloud.verify!
          rescue Exec::Gcloud::BinaryNotFound
            report_error <<~MESSAGE
              Could not find the `gcloud` binary in your system path.
              This tool requires the Google Cloud SDK. To download and install it,
              visit https://cloud.google.com/sdk/downloads
            MESSAGE
          rescue Exec::Gcloud::GcloudNotAuthenticated
            report_error <<~MESSAGE
              The gcloud authorization has not been completed. If you have not yet
              initialized the Google Cloud SDK, we recommend running the `gcloud init`
              command as described at https://cloud.google.com/sdk/docs/initializing
              Alternately, you may log in directly by running `gcloud auth login`.
            MESSAGE
          rescue Exec::Gcloud::ProjectNotSet
            report_error <<~MESSAGE
              The gcloud project configuration has not been set. If you have not yet
              initialized the Google Cloud SDK, we recommend running the `gcloud init`
              command as described at https://cloud.google.com/sdk/docs/initializing
              Alternately, you may set the default project configuration directly by
              running `gcloud config set project <project-name>`.
            MESSAGE
          end