From b964e04f935afd8f1cc2e4efe032cb1a915da372 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 3 Feb 2023 17:24:36 +0100 Subject: [PATCH] Bring accessory execution in line with app --- lib/mrsk/cli/accessory.rb | 48 ++++++++++++++------------------------ test/cli/accessory_test.rb | 14 +++++++++++ 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/lib/mrsk/cli/accessory.rb b/lib/mrsk/cli/accessory.rb index 2263fe48..918c3d0b 100644 --- a/lib/mrsk/cli/accessory.rb +++ b/lib/mrsk/cli/accessory.rb @@ -82,39 +82,27 @@ class Mrsk::Cli::Accessory < Mrsk::Cli::Base end end - desc "exec [NAME] [CMD]", "Execute a custom command on accessory host" - option :method, aliases: "-m", default: "exec", desc: "Execution method: [exec] perform inside container / [run] perform in new container / [ssh] perform over ssh" + desc "exec [NAME] [CMD]", "Execute a custom command on servers" + 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(name, cmd) - runner = \ - case options[:method] - when "exec" then "exec" - when "run" then "run_exec" - when "ssh_exec" then "exec_over_ssh" - when "ssh_run" then "run_over_ssh" - else raise "Unknown method: #{options[:method]}" - end.inquiry - with_accessory(name) do |accessory| - if runner.exec_over_ssh? || runner.run_over_ssh? - run_locally do - info "Launching command on #{accessory.host}" - exec accessory.send(runner, cmd) - end + case + when options[:interactive] && options[:reuse] + say "Launching interactive command with via SSH from existing container...", :magenta + run_locally { exec accessory.execute_in_existing_container_over_ssh(cmd) } + + when options[:interactive] + say "Launching interactive command via SSH from new container...", :magenta + run_locally { exec accessory.execute_in_new_container_over_ssh(cmd) } + + when options[:reuse] + say "Launching command from existing container...", :magenta + on(accessory.host) { capture_with_info(*accessory.execute_in_existing_container(cmd)) } + else - on(accessory.host) do - info "Launching command on #{accessory.host}" - execute *accessory.send(runner, cmd) - end - end - end - end - - desc "bash [NAME]", "Start a bash session on primary host (or specific host set by --hosts)" - def bash(name) - with_accessory(name) do |accessory| - run_locally do - info "Launching bash session on #{accessory.host}" - exec accessory.bash + say "Launching command from new container...", :magenta + on(accessory.host) { capture_with_info(*accessory.execute_in_new_container(cmd)) } end end end diff --git a/test/cli/accessory_test.rb b/test/cli/accessory_test.rb index f3373f84..dde44a61 100644 --- a/test/cli/accessory_test.rb +++ b/test/cli/accessory_test.rb @@ -17,6 +17,20 @@ class CliAccessoryTest < CliTestCase assert_match "Running docker run --name app-mysql -d --restart unless-stopped -p 3306:3306 -e [REDACTED] -e MYSQL_ROOT_HOST=% --volume $PWD/app-mysql/etc/mysql/my.cnf:/etc/mysql/my.cnf --volume $PWD/app-mysql/data:/var/lib/mysql --label service=app-mysql mysql:5.7 on 1.1.1.3", run_command("boot", "mysql") end + test "exec" do + run_command("exec", "mysql", "mysql -v").tap do |output| + assert_match /Launching command from new container/, output + assert_match /mysql -v/, output + end + end + + test "exec with reuse" do + run_command("exec", "mysql", "--reuse", "mysql -v").tap do |output| + assert_match /Launching command from existing container/, output + assert_match %r[docker exec app-mysql mysql -v], output + end + end + private def run_command(*command) stdouted { Mrsk::Cli::Accessory.start([*command, "-c", "test/fixtures/deploy_with_accessories.yml"]) }