lib/command/run.rb in cpl-0.5.1 vs lib/command/run.rb in cpl-0.6.0
- old
+ new
@@ -6,11 +6,13 @@
USAGE = "run COMMAND"
REQUIRES_ARGS = true
DEFAULT_ARGS = ["bash"].freeze
OPTIONS = [
app_option(required: true),
- image_option
+ image_option,
+ workload_option,
+ use_local_token_option
].freeze
DESCRIPTION = "Runs one-off **_interactive_** replicas (analog of `heroku run`)"
LONG_DESCRIPTION = <<~DESC
- Runs one-off **_interactive_** replicas (analog of `heroku run`)
- Uses `Standard` workload type and `cpln exec` as the execution method, with CLI streaming
@@ -32,23 +34,29 @@
cpl run rails c -a $APP_NAME
# Uses a different image (which may not be promoted yet).
cpl run rails db:migrate -a $APP_NAME --image appimage:123 # Exact image name
cpl run rails db:migrate -a $APP_NAME --image latest # Latest sequential image
+
+ # Uses a different workload
+ cpl run bash -a $APP_NAME -w other-workload
+
+ # Overrides remote CPLN_TOKEN env variable with local token.
+ # Useful when need superuser rights in remote container
+ cpl run bash -a $APP_NAME --use-local-token
```
EX
- attr_reader :location, :workload, :one_off
+ attr_reader :location, :workload, :one_off, :container
def call
@location = config[:default_location]
- @workload = config[:one_off_workload]
+ @workload = config.options["workload"] || config[:one_off_workload]
@one_off = "#{workload}-run-#{rand(1000..9999)}"
clone_workload
wait_for_workload(one_off)
- sleep 2 # sometimes replica query lags workload creation, despite ok by prev query
wait_for_replica(one_off, location)
run_in_replica
ensure
ensure_workload_deleted(one_off)
end
@@ -58,19 +66,20 @@
def clone_workload # rubocop:disable Metrics/MethodLength
progress.puts "- Cloning workload '#{workload}' on '#{config.options[:app]}' to '#{one_off}'"
# Create a base copy of workload props
spec = cp.fetch_workload!(workload).fetch("spec")
- container = spec["containers"].detect { _1["name"] == workload } || spec["containers"].first
+ container_spec = spec["containers"].detect { _1["name"] == workload } || spec["containers"].first
+ @container = container_spec["name"]
# remove other containers if any
- spec["containers"] = [container]
+ spec["containers"] = [container_spec]
# Stub workload command with dummy server that just responds to port
# Needed to avoid execution of ENTRYPOINT and CMD of Dockerfile
- container["command"] = "ruby"
- container["args"] = ["-e", Scripts.http_dummy_server_ruby]
+ container_spec["command"] = "ruby"
+ container_spec["args"] = ["-e", Scripts.http_dummy_server_ruby]
# Ensure one-off workload will be running
spec["defaultOptions"]["suspend"] = false
# Ensure no scaling
@@ -79,28 +88,40 @@
spec["defaultOptions"]["capacityAI"] = false
# Override image if specified
image = config.options[:image]
image = "/org/#{config.org}/image/#{latest_image}" if image == "latest"
- container["image"] = image if image
+ container_spec["image"] = image if image
# Set runner
- container["env"] ||= []
- container["env"] << { "name" => "CONTROLPLANE_RUNNER", "value" => runner_script }
+ container_spec["env"] ||= []
+ container_spec["env"] << { "name" => "CONTROLPLANE_RUNNER", "value" => runner_script }
+ if config.options["use_local_token"]
+ container_spec["env"] << { "name" => "CONTROLPLANE_TOKEN", "value" => ControlplaneApiDirect.new.api_token }
+ end
+
# Create workload clone
cp.apply("kind" => "workload", "name" => one_off, "spec" => spec)
end
def runner_script
script = Scripts.helpers_cleanup
+
+ if config.options["use_local_token"]
+ script += <<~SHELL
+ CPLN_TOKEN=$CONTROLPLANE_TOKEN
+ unset CONTROLPLANE_TOKEN
+ SHELL
+ end
+
script += args_join(config.args)
script
end
def run_in_replica
progress.puts "- Connecting"
command = %(bash -c 'eval "$CONTROLPLANE_RUNNER"')
- cp.workload_exec(one_off, location: location, container: workload, command: command)
+ cp.workload_exec(one_off, location: location, container: container, command: command)
end
end
end