diff --git a/lib/mrsk/cli/app.rb b/lib/mrsk/cli/app.rb index f2116831..06fd552d 100644 --- a/lib/mrsk/cli/app.rb +++ b/lib/mrsk/cli/app.rb @@ -3,16 +3,18 @@ require "mrsk/cli/base" class Mrsk::Cli::App < Mrsk::Cli::Base desc "boot", "Boot app on servers (or start them if they've already been booted)" def boot - MRSK.config.roles.each do |role| - on(role.hosts) do |host| - begin - execute *MRSK.app.run(role: role.name) - rescue SSHKit::Command::Failed => e - if e.message =~ /already in use/ - error "Container with same version already deployed on #{host}, starting that instead" - execute *MRSK.app.start, host: host - else - raise + using_most_recent_version_available do + MRSK.config.roles.each do |role| + on(role.hosts) do |host| + begin + execute *MRSK.app.run(role: role.name) + rescue SSHKit::Command::Failed => e + if e.message =~ /already in use/ + error "Container with same version already deployed on #{host}, starting that instead" + execute *MRSK.app.start, host: host + else + raise + end end end end @@ -69,9 +71,15 @@ class Mrsk::Cli::App < Mrsk::Cli::Base desc "console", "Start Rails Console on primary host (or specific host set by --hosts)" def console - run_locally do - info "Launching Rails console on #{MRSK.primary_host}" - exec MRSK.app.console(host: MRSK.primary_host) + using_most_recent_version_available do |version| + run_locally do + if version + info "Launching Rails console on #{MRSK.primary_host} [Version: #{version}]" + exec MRSK.app.console(host: MRSK.primary_host) + else + error "No image available for #{MRSK.config.repository}" + end + end end end @@ -144,8 +152,41 @@ class Mrsk::Cli::App < Mrsk::Cli::Base on(MRSK.hosts) { execute *MRSK.app.remove_containers } end - desc "remove_images [NAME]", "Remove app images from servers" + desc "remove_images", "Remove app images from servers" def remove_images on(MRSK.hosts) { execute *MRSK.app.remove_images } end + + private + def using_most_recent_version_available(host: MRSK.primary_host) + using_version(most_recent_version_available(host: host)) do |version| + yield version + end + end + + def using_current_running_version(host: MRSK.primary_host) + using_version(current_running_version(host: host)) do |version| + yield version + end + end + + def using_version(new_version) + old_version = MRSK.config.version + MRSK.config.version = new_version + yield new_version + ensure + MRSK.config.version = old_version + end + + def most_recent_version_available(host:) + version = nil + on(host) { version = capture_with_info(*MRSK.app.most_recent_version_from_available_images).strip } + version + end + + def current_running_version(host:) + version = nil + on(host) { version = capture_with_info(*MRSK.app.current_running_version).strip } + version + end end diff --git a/lib/mrsk/commands/app.rb b/lib/mrsk/commands/app.rb index 7e17b0e9..237277fd 100644 --- a/lib/mrsk/commands/app.rb +++ b/lib/mrsk/commands/app.rb @@ -1,6 +1,9 @@ require "mrsk/commands/base" +require "mrsk/commands/concerns/repository" class Mrsk::Commands::App < Mrsk::Commands::Base + include Mrsk::Commands::Concerns::Repository + def run(role: :web) role = config.role(role) diff --git a/lib/mrsk/commands/concerns/repository.rb b/lib/mrsk/commands/concerns/repository.rb new file mode 100644 index 00000000..6e8a4f24 --- /dev/null +++ b/lib/mrsk/commands/concerns/repository.rb @@ -0,0 +1,17 @@ +module Mrsk::Commands::Concerns + module Repository + def current_running_version + # FIXME: Find more graceful way to extract the version from "app-version" than using sed and tail! + pipe \ + docker(:ps, "--filter", "label=service=hey", "--format", '"{{.Names}}"'), + "sed 's/-/\n/g'", + "tail -n 1" + end + + def most_recent_version_from_available_images + pipe \ + docker(:image, :ls, "--format", '"{{.Tag}}"', config.repository), + "head -n 1" + end + end +end diff --git a/lib/mrsk/configuration.rb b/lib/mrsk/configuration.rb index b4ef0582..23723214 100644 --- a/lib/mrsk/configuration.rb +++ b/lib/mrsk/configuration.rb @@ -9,6 +9,7 @@ class Mrsk::Configuration delegate :service, :image, :servers, :env, :labels, :registry, :builder, to: :raw_config, allow_nil: true delegate :argumentize, :argumentize_env_with_secrets, to: Mrsk::Utils + attr_accessor :version attr_accessor :raw_config class << self @@ -73,10 +74,6 @@ class Mrsk::Configuration end - def version - @version - end - def repository [ raw_config.registry["server"], image ].compact.join("/") end