Extract executions into separate concern

This commit is contained in:
David Heinemeier Hansson
2023-02-03 16:39:26 +01:00
parent a3fe8856c9
commit 8848335fbc
5 changed files with 71 additions and 45 deletions

View File

@@ -1,8 +1,9 @@
require "mrsk/commands/base" require "mrsk/commands/base"
require "mrsk/commands/concerns/repository" require "mrsk/commands/concerns"
class Mrsk::Commands::App < Mrsk::Commands::Base class Mrsk::Commands::App < Mrsk::Commands::Base
include Mrsk::Commands::Concerns::Repository include Mrsk::Commands::Concerns::Executions,
Mrsk::Commands::Concerns::Repository
def run(role: :web) def run(role: :web)
role = config.role(role) role = config.role(role)
@@ -42,32 +43,6 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
("grep '#{grep}'" if grep) ("grep '#{grep}'" if grep)
end end
def execute_in_existing_container(*command, interactive: false)
docker :exec,
("-it" if interactive),
config.service_with_version,
*command
end
def execute_in_new_container(*command, interactive: false)
docker :run,
("-it" if interactive),
"--rm",
*rails_master_key_arg,
*config.env_args,
*config.volume_args,
config.absolute_image,
*command
end
def execute_in_existing_container_over_ssh(*command, 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
def follow_logs(host:, grep: nil) def follow_logs(host:, grep: nil)
run_over_ssh pipe( run_over_ssh pipe(
current_container_id, current_container_id,

View File

@@ -0,0 +1,5 @@
module Mrsk::Commands::Concerns
end
require "mrsk/commands/concerns/executions"
require "mrsk/commands/concerns/repository"

View File

@@ -0,0 +1,27 @@
module Mrsk::Commands::Concerns::Executions
def execute_in_existing_container(*command, interactive: false)
docker :exec,
("-it" if interactive),
config.service_with_version,
*command
end
def execute_in_new_container(*command, interactive: false)
docker :run,
("-it" if interactive),
"--rm",
*rails_master_key_arg,
*config.env_args,
*config.volume_args,
config.absolute_image,
*command
end
def execute_in_existing_container_over_ssh(*command, 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

View File

@@ -1,21 +1,19 @@
module Mrsk::Commands::Concerns module Mrsk::Commands::Concerns::Repository
module Repository def container_id_for(container_name:)
def container_id_for(container_name:) docker :container, :ls, "-a", "-f", "name=#{container_name}", "-q"
docker :container, :ls, "-a", "-f", "name=#{container_name}", "-q" end
end
def current_running_version def current_running_version
# FIXME: Find more graceful way to extract the version from "app-version" than using sed and tail! # FIXME: Find more graceful way to extract the version from "app-version" than using sed and tail!
pipe \ pipe \
docker(:ps, "--filter", "label=service=#{config.service}", "--format", '"{{.Names}}"'), docker(:ps, "--filter", "label=service=#{service_name}", "--format", '"{{.Names}}"'),
%(sed 's/-/\\n/g'), %(sed 's/-/\\n/g'),
"tail -n 1" "tail -n 1"
end end
def most_recent_version_from_available_images def most_recent_version_from_available_images
pipe \ pipe \
docker(:image, :ls, "--format", '"{{.Tag}}"', config.repository), docker(:image, :ls, "--format", '"{{.Tag}}"', config.repository),
"head -n 1" "head -n 1"
end
end end
end end

View File

@@ -1,6 +1,7 @@
require "test_helper" require "test_helper"
require "mrsk/configuration" require "mrsk/configuration"
require "mrsk/commands/app" require "mrsk/commands/app"
require "minitest/autorun" # using stubs that take args
class CommandsAppTest < ActiveSupport::TestCase class CommandsAppTest < ActiveSupport::TestCase
setup do setup do
@@ -32,6 +33,26 @@ class CommandsAppTest < ActiveSupport::TestCase
@app.execute_in_new_container("bin/rails", "db:setup") @app.execute_in_new_container("bin/rails", "db:setup")
end end
test "execute in existing container" do
assert_equal \
[ :docker, :exec, "app-missing", "bin/rails", "db:setup" ],
@app.execute_in_existing_container("bin/rails", "db:setup")
end
test "execute in new container over ssh" do
@app.stub(:run_over_ssh, ->(cmd, host:) { cmd }) do
assert_match %r|docker run -it --rm -e RAILS_MASTER_KEY=456 dhh/app:missing bin/rails c|,
@app.execute_in_new_container_over_ssh("bin/rails", "c", host: "app-1")
end
end
test "execute in existing container over ssh" do
@app.stub(:run_over_ssh, ->(cmd, host:) { cmd }) do
assert_match %r|docker exec -it app-missing bin/rails c|,
@app.execute_in_existing_container_over_ssh("bin/rails", "c", host: "app-1")
end
end
test "run without master key" do test "run without master key" do
ENV["RAILS_MASTER_KEY"] = nil ENV["RAILS_MASTER_KEY"] = nil
@app = Mrsk::Commands::App.new Mrsk::Configuration.new(@config.tap { |c| c[:skip_master_key] = true }) @app = Mrsk::Commands::App.new Mrsk::Configuration.new(@config.tap { |c| c[:skip_master_key] = true })