diff --git a/lib/kamal/commands/app.rb b/lib/kamal/commands/app.rb index 5f0744cc..e544ca94 100644 --- a/lib/kamal/commands/app.rb +++ b/lib/kamal/commands/app.rb @@ -1,4 +1,6 @@ class Kamal::Commands::App < Kamal::Commands::Base + include Assets, Cord, Execution + ACTIVE_DOCKER_STATUSES = [ :running, :restarting ] attr_reader :role, :role_config @@ -64,33 +66,6 @@ class Kamal::Commands::App < Kamal::Commands::Base end - def execute_in_existing_container(*command, interactive: false) - docker :exec, - ("-it" if interactive), - container_name, - *command - end - - def execute_in_new_container(*command, interactive: false) - docker :run, - ("-it" if interactive), - "--rm", - *role_config&.env_args, - *config.volume_args, - *role_config&.option_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), host: host - end - - def execute_in_new_container_over_ssh(*command, host:) - run_over_ssh execute_in_new_container(*command, interactive: true), host: host - end - - def current_running_container_id docker :ps, "--quiet", *filter_args(statuses: ACTIVE_DOCKER_STATUSES), "--latest" end @@ -151,53 +126,6 @@ class Kamal::Commands::App < Kamal::Commands::Base [:rm, "-f", role_config.host_env_file_path] end - def cord(version:) - pipe \ - docker(:inspect, "-f '{{ range .Mounts }}{{printf \"%s %s\\n\" .Source .Destination}}{{ end }}'", container_name(version)), - [:awk, "'$2 == \"#{role_config.cord_volume.container_path}\" {print $1}'"] - end - - def tie_cord(cord) - create_empty_file(cord) - end - - def cut_cord(cord) - remove_directory(cord) - end - - def extract_assets - asset_container = "#{role_config.container_prefix}-assets" - - combine \ - make_directory(role_config.asset_extracted_path), - [*docker(:stop, "-t 1", asset_container, "2> /dev/null"), "|| true"], - docker(:run, "--name", asset_container, "--detach", "--rm", config.latest_image, "sleep 1000000"), - docker(:cp, "-L", "#{asset_container}:#{role_config.asset_path}/.", role_config.asset_extracted_path), - docker(:stop, "-t 1", asset_container), - by: "&&" - end - - def sync_asset_volumes(old_version: nil) - new_extracted_path, new_volume_path = role_config.asset_extracted_path(config.version), role_config.asset_volume.host_path - if old_version.present? - old_extracted_path, old_volume_path = role_config.asset_extracted_path(old_version), role_config.asset_volume(old_version).host_path - end - - commands = [make_directory(new_volume_path), copy_contents(new_extracted_path, new_volume_path)] - - if old_version.present? - commands << copy_contents(new_extracted_path, old_volume_path, continue_on_error: true) - commands << copy_contents(old_extracted_path, new_volume_path, continue_on_error: true) - end - - chain *commands - end - - def clean_up_assets - chain \ - find_and_remove_older_siblings(role_config.asset_extracted_path), - find_and_remove_older_siblings(role_config.asset_volume_path) - end private def container_name(version = nil) @@ -221,19 +149,4 @@ class Kamal::Commands::App < Kamal::Commands::Base end end end - - def find_and_remove_older_siblings(path) - [ - :find, - Pathname.new(path).dirname.to_s, - "-maxdepth 1", - "-name", "'#{role_config.container_prefix}-*'", - "!", "-name", Pathname.new(path).basename.to_s, - "-exec rm -rf \"{}\" +" - ] - end - - def copy_contents(source, destination, continue_on_error: false) - [ :cp, "-rnT", "#{source}", destination, *("|| true" if continue_on_error)] - end end diff --git a/lib/kamal/commands/app/assets.rb b/lib/kamal/commands/app/assets.rb new file mode 100644 index 00000000..cc65627a --- /dev/null +++ b/lib/kamal/commands/app/assets.rb @@ -0,0 +1,51 @@ +module Kamal::Commands::App::Assets + def extract_assets + asset_container = "#{role_config.container_prefix}-assets" + + combine \ + make_directory(role_config.asset_extracted_path), + [*docker(:stop, "-t 1", asset_container, "2> /dev/null"), "|| true"], + docker(:run, "--name", asset_container, "--detach", "--rm", config.latest_image, "sleep 1000000"), + docker(:cp, "-L", "#{asset_container}:#{role_config.asset_path}/.", role_config.asset_extracted_path), + docker(:stop, "-t 1", asset_container), + by: "&&" + end + + def sync_asset_volumes(old_version: nil) + new_extracted_path, new_volume_path = role_config.asset_extracted_path(config.version), role_config.asset_volume.host_path + if old_version.present? + old_extracted_path, old_volume_path = role_config.asset_extracted_path(old_version), role_config.asset_volume(old_version).host_path + end + + commands = [make_directory(new_volume_path), copy_contents(new_extracted_path, new_volume_path)] + + if old_version.present? + commands << copy_contents(new_extracted_path, old_volume_path, continue_on_error: true) + commands << copy_contents(old_extracted_path, new_volume_path, continue_on_error: true) + end + + chain *commands + end + + def clean_up_assets + chain \ + find_and_remove_older_siblings(role_config.asset_extracted_path), + find_and_remove_older_siblings(role_config.asset_volume_path) + end + + private + def find_and_remove_older_siblings(path) + [ + :find, + Pathname.new(path).dirname.to_s, + "-maxdepth 1", + "-name", "'#{role_config.container_prefix}-*'", + "!", "-name", Pathname.new(path).basename.to_s, + "-exec rm -rf \"{}\" +" + ] + end + + def copy_contents(source, destination, continue_on_error: false) + [ :cp, "-rnT", "#{source}", destination, *("|| true" if continue_on_error)] + end +end diff --git a/lib/kamal/commands/app/cord.rb b/lib/kamal/commands/app/cord.rb new file mode 100644 index 00000000..ef722d66 --- /dev/null +++ b/lib/kamal/commands/app/cord.rb @@ -0,0 +1,22 @@ +module Kamal::Commands::App::Cord + def cord(version:) + pipe \ + docker(:inspect, "-f '{{ range .Mounts }}{{printf \"%s %s\\n\" .Source .Destination}}{{ end }}'", container_name(version)), + [:awk, "'$2 == \"#{role_config.cord_volume.container_path}\" {print $1}'"] + end + + def tie_cord(cord) + create_empty_file(cord) + end + + def cut_cord(cord) + remove_directory(cord) + end + + private + def create_empty_file(file) + chain \ + make_directory_for(file), + [:touch, file] + end +end diff --git a/lib/kamal/commands/app/execution.rb b/lib/kamal/commands/app/execution.rb new file mode 100644 index 00000000..ff387726 --- /dev/null +++ b/lib/kamal/commands/app/execution.rb @@ -0,0 +1,27 @@ +module Kamal::Commands::App::Execution + def execute_in_existing_container(*command, interactive: false) + docker :exec, + ("-it" if interactive), + container_name, + *command + end + + def execute_in_new_container(*command, interactive: false) + docker :run, + ("-it" if interactive), + "--rm", + *role_config&.env_args, + *config.volume_args, + *role_config&.option_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), host: host + end + + def execute_in_new_container_over_ssh(*command, host:) + run_over_ssh execute_in_new_container(*command, interactive: true), host: host + end +end diff --git a/lib/kamal/commands/base.rb b/lib/kamal/commands/base.rb index ff31c747..7552a92d 100644 --- a/lib/kamal/commands/base.rb +++ b/lib/kamal/commands/base.rb @@ -73,11 +73,5 @@ module Kamal::Commands def tags(**details) Kamal::Tags.from_config(config, **details) end - - def create_empty_file(file) - chain \ - make_directory_for(file), - [:touch, file] - end end end