Clarify exec modes and drop tailored versions
This commit is contained in:
22
README.md
22
README.md
@@ -302,9 +302,9 @@ Now run `mrsk accessory start mysql` to start the MySQL server on 1.1.1.3. See `
|
|||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
|
|
||||||
### Running remote execution and runners
|
### Running commands on servers
|
||||||
|
|
||||||
If you need to execute commands inside the Rails containers, you can use `mrsk app exec` and `mrsk app runner`. Examples:
|
You can execute one-off commands on the servers:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Runs command on all servers
|
# Runs command on all servers
|
||||||
@@ -347,13 +347,25 @@ Database adapter sqlite3
|
|||||||
Database schema version 20221231233303
|
Database schema version 20221231233303
|
||||||
|
|
||||||
# Run Rails runner on primary server
|
# Run Rails runner on primary server
|
||||||
mrsk app runner -p 'puts Rails.application.config.time_zone'
|
mrsk app exec -p 'bin/rails runner "puts Rails.application.config.time_zone"'
|
||||||
UTC
|
UTC
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running a Rails console
|
### Running interactive commands over SSH
|
||||||
|
|
||||||
|
You can run interactive commands, like a Rails console or a bash session, on a server (default is primary, use `--hosts` to connect to another):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Starts a bash session in a new container made from the most recent app image
|
||||||
|
mrsk app exec -i bash
|
||||||
|
|
||||||
|
# Starts a bash session in the currently running container for the app
|
||||||
|
mrsk app exec -i --reuse bash
|
||||||
|
|
||||||
|
# Starts a Rails console in a new container made from the most recent app image
|
||||||
|
mrsk app exec -i 'bin/rails console'
|
||||||
|
```
|
||||||
|
|
||||||
If you need to interact with the production console for the app, you can use `mrsk app console`, which will start a Rails console session on the primary host. You can start the console on a different host using `mrsk app console --host 192.168.0.2`. Be mindful that this is a live wire! Any changes made to the production database will take effect immeditately.
|
|
||||||
|
|
||||||
### Running details to see state of containers
|
### Running details to see state of containers
|
||||||
|
|
||||||
|
|||||||
@@ -47,49 +47,40 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
desc "exec [CMD]", "Execute a custom command on servers"
|
desc "exec [CMD]", "Execute a custom command on servers"
|
||||||
option :method, aliases: "-m", default: "exec", desc: "Execution method: [exec] perform inside app container / [run] perform in new container / [ssh] perform over ssh"
|
option :interactive, aliases: "-i", type: :boolean, default: false, desc: "Execute command over ssh for an interactive shell (use for console/bash)"
|
||||||
|
option :reuse, type: :boolean, default: false, desc: "Reuse currently running container instead of starting a new one"
|
||||||
def exec(cmd)
|
def exec(cmd)
|
||||||
runner = \
|
case
|
||||||
case options[:method]
|
when options[:interactive] && options[:reuse]
|
||||||
when "exec" then "exec"
|
say "Get current version of running container...", :magenta unless options[:version]
|
||||||
when "run" then "run_exec"
|
using_version(options[:version] || current_running_version) do |version|
|
||||||
when "ssh" then "exec_over_ssh"
|
say "Launching interactive command with version #{version} via SSH from existing container on #{MRSK.primary_host}...", :magenta
|
||||||
else raise "Unknown method: #{options[:method]}"
|
run_locally { exec MRSK.app.execute_in_existing_container_over_ssh(cmd, host: MRSK.primary_host) }
|
||||||
end.inquiry
|
|
||||||
|
|
||||||
if runner.exec_over_ssh?
|
|
||||||
run_locally do
|
|
||||||
info "Launching command on #{MRSK.primary_host}"
|
|
||||||
exec MRSK.app.exec_over_ssh(cmd, host: MRSK.primary_host)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
when options[:interactive]
|
||||||
|
say "Get most recent version available as an image...", :magenta unless options[:version]
|
||||||
|
using_version(options[:version] || most_recent_version_available) do |version|
|
||||||
|
say "Launching interactive command with version #{version} via SSH from new container on #{MRSK.primary_host}...", :magenta
|
||||||
|
run_locally { exec MRSK.app.execute_in_new_container_over_ssh(cmd, host: MRSK.primary_host) }
|
||||||
|
end
|
||||||
|
|
||||||
|
when options[:reuse]
|
||||||
|
say "Get current version of running container...", :magenta unless options[:version]
|
||||||
|
using_version(options[:version] || current_running_version) do |version|
|
||||||
|
say "Launching command with version #{version} from existing container on #{MRSK.primary_host}", :magenta
|
||||||
|
on(MRSK.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.execute_in_existing_container(cmd)) }
|
||||||
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
on(MRSK.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.send(runner, cmd)) }
|
say "Get most recent version available as an image...", :magenta unless options[:version]
|
||||||
|
using_version(options[:version] || most_recent_version_available) do |version|
|
||||||
|
say "Launching command with version #{version} from new container on #{MRSK.primary_host}", :magenta
|
||||||
|
on(MRSK.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.execute_in_new_container(cmd)) }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "console", "Start Rails Console on primary host (or specific host set by --hosts)"
|
|
||||||
def console
|
|
||||||
say "Get most recent version available as an image...", :magenta unless options[:version]
|
|
||||||
using_version(options[:version] || most_recent_version_available) do |version|
|
|
||||||
say "Launching Rails console of version #{version} on #{MRSK.primary_host}...", :magenta
|
|
||||||
run_locally { exec MRSK.app.console(host: MRSK.primary_host) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
desc "bash", "Start a bash session on primary host (or specific host set by --hosts)"
|
|
||||||
def bash
|
|
||||||
say "Get most recent version available as an image...", :magenta unless options[:version]
|
|
||||||
using_version(options[:version] || most_recent_version_available) do |version|
|
|
||||||
say "Launching bash session of version #{version} on #{MRSK.primary_host}...", :magenta
|
|
||||||
run_locally { exec MRSK.app.bash(host: MRSK.primary_host) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
desc "runner [EXPRESSION]", "Execute Rails runner with given expression"
|
|
||||||
def runner(expression)
|
|
||||||
on(MRSK.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.exec("bin/rails", "runner", "'#{expression}'")) }
|
|
||||||
end
|
|
||||||
|
|
||||||
desc "containers", "List all the app containers currently on servers"
|
desc "containers", "List all the app containers currently on servers"
|
||||||
def containers
|
def containers
|
||||||
on(MRSK.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.list_containers) }
|
on(MRSK.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.list_containers) }
|
||||||
|
|||||||
@@ -42,14 +42,14 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
|
|||||||
("grep '#{grep}'" if grep)
|
("grep '#{grep}'" if grep)
|
||||||
end
|
end
|
||||||
|
|
||||||
def exec(*command, interactive: false)
|
def execute_in_existing_container(*command, interactive: false)
|
||||||
docker :exec,
|
docker :exec,
|
||||||
("-it" if interactive),
|
("-it" if interactive),
|
||||||
config.service_with_version,
|
config.service_with_version,
|
||||||
*command
|
*command
|
||||||
end
|
end
|
||||||
|
|
||||||
def run_exec(*command, interactive: false)
|
def execute_in_new_container(*command, interactive: false)
|
||||||
docker :run,
|
docker :run,
|
||||||
("-it" if interactive),
|
("-it" if interactive),
|
||||||
"--rm",
|
"--rm",
|
||||||
@@ -60,8 +60,12 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
|
|||||||
*command
|
*command
|
||||||
end
|
end
|
||||||
|
|
||||||
def exec_over_ssh(*command, host:)
|
def execute_in_existing_container_over_ssh(*command, host:)
|
||||||
run_over_ssh run_exec(*command, interactive: true).join(" "), host: host
|
run_over_ssh execute_in_existing_container(*command, interactive: true).join(" "), host: host
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute_in_new_container_over_ssh(*command, host:)
|
||||||
|
run_over_ssh execute_in_new_container(*command, interactive: true).join(" "), host: host
|
||||||
end
|
end
|
||||||
|
|
||||||
def follow_logs(host:, grep: nil)
|
def follow_logs(host:, grep: nil)
|
||||||
@@ -72,14 +76,6 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
|
|||||||
).join(" "), host: host
|
).join(" "), host: host
|
||||||
end
|
end
|
||||||
|
|
||||||
def console(host:)
|
|
||||||
exec_over_ssh "bin/rails", "c", host: host
|
|
||||||
end
|
|
||||||
|
|
||||||
def bash(host:)
|
|
||||||
exec_over_ssh "bash", host: host
|
|
||||||
end
|
|
||||||
|
|
||||||
def list_containers
|
def list_containers
|
||||||
docker :container, :ls, "-a", *service_filter
|
docker :container, :ls, "-a", *service_filter
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -26,10 +26,10 @@ class CommandsAppTest < ActiveSupport::TestCase
|
|||||||
[:docker, :run, "-d", "--restart unless-stopped", "--name", "app-missing", "-e", "RAILS_MASTER_KEY=456", "--volume", "/local/path:/container/path", "--label", "service=app", "--label", "role=web", "--label", "traefik.http.routers.app.rule='PathPrefix(`/`)'", "--label", "traefik.http.services.app.loadbalancer.healthcheck.path=/up", "--label", "traefik.http.services.app.loadbalancer.healthcheck.interval=1s", "--label", "traefik.http.middlewares.app.retry.attempts=3", "--label", "traefik.http.middlewares.app.retry.initialinterval=500ms", "dhh/app:missing"], @app.run
|
[:docker, :run, "-d", "--restart unless-stopped", "--name", "app-missing", "-e", "RAILS_MASTER_KEY=456", "--volume", "/local/path:/container/path", "--label", "service=app", "--label", "role=web", "--label", "traefik.http.routers.app.rule='PathPrefix(`/`)'", "--label", "traefik.http.services.app.loadbalancer.healthcheck.path=/up", "--label", "traefik.http.services.app.loadbalancer.healthcheck.interval=1s", "--label", "traefik.http.middlewares.app.retry.attempts=3", "--label", "traefik.http.middlewares.app.retry.initialinterval=500ms", "dhh/app:missing"], @app.run
|
||||||
end
|
end
|
||||||
|
|
||||||
test "run with" do
|
test "execute in new container" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
[ :docker, :run, "--rm", "-e", "RAILS_MASTER_KEY=456", "dhh/app:missing", "bin/rails", "db:setup" ],
|
[ :docker, :run, "--rm", "-e", "RAILS_MASTER_KEY=456", "dhh/app:missing", "bin/rails", "db:setup" ],
|
||||||
@app.run_exec("bin/rails", "db:setup")
|
@app.execute_in_new_container("bin/rails", "db:setup")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "run without master key" do
|
test "run without master key" do
|
||||||
|
|||||||
Reference in New Issue
Block a user