From 4bf77ccd1b1e7b36b9b928c5332d16b3c7ab92cc Mon Sep 17 00:00:00 2001 From: Samuel Sieg Date: Fri, 10 Mar 2023 11:26:35 +0100 Subject: [PATCH 1/8] Allow `deploy`/`deliver` without building and pushing the image --- lib/mrsk/cli/build.rb | 3 ++- lib/mrsk/cli/main.rb | 13 +++++++------ test/cli/build_test.rb | 25 +++++++++++++++++++++++-- test/test_helper.rb | 10 ++++++++++ 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/lib/mrsk/cli/build.rb b/lib/mrsk/cli/build.rb index 3e8912d7..ec39282e 100644 --- a/lib/mrsk/cli/build.rb +++ b/lib/mrsk/cli/build.rb @@ -1,7 +1,8 @@ class Mrsk::Cli::Build < Mrsk::Cli::Base desc "deliver", "Build app and push app image to registry then pull image on servers" + option :skip_push, aliases: "-P", type: :boolean, default: false, desc: "Skip image build and push" def deliver - push + push unless options[:skip_push] pull end diff --git a/lib/mrsk/cli/main.rb b/lib/mrsk/cli/main.rb index 73268f50..163c0327 100644 --- a/lib/mrsk/cli/main.rb +++ b/lib/mrsk/cli/main.rb @@ -9,27 +9,28 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base end desc "deploy", "Deploy app to servers" + option :skip_push, aliases: "-P", type: :boolean, default: false, desc: "Skip image build and push" def deploy runtime = print_runtime do say "Ensure curl and Docker are installed...", :magenta - invoke "mrsk:cli:server:bootstrap" + invoke "mrsk:cli:server:bootstrap", [], options.without(:skip_push) say "Log into image registry...", :magenta - invoke "mrsk:cli:registry:login" + invoke "mrsk:cli:registry:login", [], options.without(:skip_push) say "Build and push app image...", :magenta invoke "mrsk:cli:build:deliver" say "Ensure Traefik is running...", :magenta - invoke "mrsk:cli:traefik:boot" + invoke "mrsk:cli:traefik:boot", [], options.without(:skip_push) say "Ensure app can pass healthcheck...", :magenta - invoke "mrsk:cli:healthcheck:perform" + invoke "mrsk:cli:healthcheck:perform", [], options.without(:skip_push) - invoke "mrsk:cli:app:boot" + invoke "mrsk:cli:app:boot", [], options.without(:skip_push) say "Prune old containers and images...", :magenta - invoke "mrsk:cli:prune:all" + invoke "mrsk:cli:prune:all", [], options.without(:skip_push) end audit_broadcast "Deployed app in #{runtime.to_i} seconds" unless options[:skip_broadcast] diff --git a/test/cli/build_test.rb b/test/cli/build_test.rb index 3d5f4431..2ded0193 100644 --- a/test/cli/build_test.rb +++ b/test/cli/build_test.rb @@ -1,10 +1,31 @@ require_relative "cli_test_case" class CliBuildTest < CliTestCase + test "deliver" do + run_command("deliver").tap do |output| + assert_match /docker buildx build --push --platform linux\/amd64,linux\/arm64 --builder mrsk-app-multiarch -t dhh\/app:999 -t dhh\/app:latest --label service="app" --file Dockerfile \. as .*\@localhost/, output + assert_match /docker image rm --force dhh\/app:999 on 1\.1\.1\.2/, output + assert_match /docker pull dhh\/app:999 on 1\.1\.1\.1/, output + end + end + + test "deliver without push" do + run_command("deliver", "--skip-push").tap do |output| + assert_match /docker image rm --force dhh\/app:999 on 1\.1\.1\.2/, output + assert_match /docker pull dhh\/app:999 on 1\.1\.1\.1/, output + end + end + + test "push" do + run_command("push").tap do |output| + assert_match /docker buildx build --push --platform linux\/amd64,linux\/arm64 --builder mrsk-app-multiarch -t dhh\/app:999 -t dhh\/app:latest --label service="app" --file Dockerfile \. as .*\@localhost/, output + end + end + test "pull" do run_command("pull").tap do |output| - assert_match /docker image rm --force dhh\/app:999/, output - assert_match /docker pull dhh\/app:999/, output + assert_match /docker image rm --force dhh\/app:999 on 1\.1\.1\.2/, output + assert_match /docker pull dhh\/app:999 on 1\.1\.1\.1/, output end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 4c381df2..6f29420b 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -9,7 +9,17 @@ require "mrsk" ActiveSupport::LogSubscriber.logger = ActiveSupport::Logger.new(STDOUT) if ENV["VERBOSE"] +# Applies to remote commands only SSHKit.config.backend = SSHKit::Backend::Printer +# Ensure local commands use the printer backend too +module SSHKit + module DSL + def run_locally(&block) + SSHKit::Backend::Printer.new(SSHKit::Host.new(:local), &block).run + end + end +end + class ActiveSupport::TestCase end From 9b39f2f3ab85c5fc028ed765347954b466a1d529 Mon Sep 17 00:00:00 2001 From: Samuel Sieg Date: Sun, 12 Mar 2023 10:41:04 +0100 Subject: [PATCH 2/8] Keep it simple for the proposal --- lib/mrsk/cli/build.rb | 4 ++-- lib/mrsk/cli/main.rb | 35 ++++++++++++++++++++++++----------- test/cli/build_test.rb | 21 --------------------- test/test_helper.rb | 9 --------- 4 files changed, 26 insertions(+), 43 deletions(-) diff --git a/lib/mrsk/cli/build.rb b/lib/mrsk/cli/build.rb index ec39282e..cb106741 100644 --- a/lib/mrsk/cli/build.rb +++ b/lib/mrsk/cli/build.rb @@ -1,8 +1,8 @@ class Mrsk::Cli::Build < Mrsk::Cli::Base desc "deliver", "Build app and push app image to registry then pull image on servers" - option :skip_push, aliases: "-P", type: :boolean, default: false, desc: "Skip image build and push" + option :use_prebuilt_image, aliases: "-P", type: :boolean, default: false, desc: "Use prebuilt image, skip build" def deliver - push unless options[:skip_push] + push unless options[:use_prebuilt_image] pull end diff --git a/lib/mrsk/cli/main.rb b/lib/mrsk/cli/main.rb index 163c0327..b77e5256 100644 --- a/lib/mrsk/cli/main.rb +++ b/lib/mrsk/cli/main.rb @@ -9,38 +9,51 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base end desc "deploy", "Deploy app to servers" - option :skip_push, aliases: "-P", type: :boolean, default: false, desc: "Skip image build and push" + option :use_prebuilt_image, aliases: "-P", type: :boolean, default: false, desc: "Use prebuilt image, skip build" def deploy runtime = print_runtime do + options_without_prebuilt_image = options.without(:use_prebuilt_image) + say "Ensure curl and Docker are installed...", :magenta - invoke "mrsk:cli:server:bootstrap", [], options.without(:skip_push) + invoke "mrsk:cli:server:bootstrap", [], options_without_prebuilt_image say "Log into image registry...", :magenta - invoke "mrsk:cli:registry:login", [], options.without(:skip_push) + invoke "mrsk:cli:registry:login", [], options_without_prebuilt_image - say "Build and push app image...", :magenta - invoke "mrsk:cli:build:deliver" + unless options[:use_prebuilt_image] + say "Build and push app image...", :magenta + invoke "mrsk:cli:build:push" + end + + say "Pull image onto servers...", :magenta + invoke "mrsk:cli:build:pull", [], options_without_prebuilt_image say "Ensure Traefik is running...", :magenta - invoke "mrsk:cli:traefik:boot", [], options.without(:skip_push) + invoke "mrsk:cli:traefik:boot", [], options_without_prebuilt_image say "Ensure app can pass healthcheck...", :magenta - invoke "mrsk:cli:healthcheck:perform", [], options.without(:skip_push) + invoke "mrsk:cli:healthcheck:perform", [], options_without_prebuilt_image - invoke "mrsk:cli:app:boot", [], options.without(:skip_push) + invoke "mrsk:cli:app:boot", [], options_without_prebuilt_image say "Prune old containers and images...", :magenta - invoke "mrsk:cli:prune:all", [], options.without(:skip_push) + invoke "mrsk:cli:prune:all", [], options_without_prebuilt_image end audit_broadcast "Deployed app in #{runtime.to_i} seconds" unless options[:skip_broadcast] end desc "redeploy", "Deploy app to servers without bootstrapping servers, starting Traefik, pruning, and registry login" + option :use_prebuilt_image, aliases: "-P", type: :boolean, default: false, desc: "Use prebuilt image, skip build" def redeploy runtime = print_runtime do - say "Build and push app image...", :magenta - invoke "mrsk:cli:build:deliver" + unless options[:use_prebuilt_image] + say "Build and push app image...", :magenta + invoke "mrsk:cli:build:push" + end + + say "Pull image onto servers...", :magenta + invoke "mrsk:cli:build:pull" say "Ensure app can pass healthcheck...", :magenta invoke "mrsk:cli:healthcheck:perform" diff --git a/test/cli/build_test.rb b/test/cli/build_test.rb index 2ded0193..b2ce6fd4 100644 --- a/test/cli/build_test.rb +++ b/test/cli/build_test.rb @@ -1,27 +1,6 @@ require_relative "cli_test_case" class CliBuildTest < CliTestCase - test "deliver" do - run_command("deliver").tap do |output| - assert_match /docker buildx build --push --platform linux\/amd64,linux\/arm64 --builder mrsk-app-multiarch -t dhh\/app:999 -t dhh\/app:latest --label service="app" --file Dockerfile \. as .*\@localhost/, output - assert_match /docker image rm --force dhh\/app:999 on 1\.1\.1\.2/, output - assert_match /docker pull dhh\/app:999 on 1\.1\.1\.1/, output - end - end - - test "deliver without push" do - run_command("deliver", "--skip-push").tap do |output| - assert_match /docker image rm --force dhh\/app:999 on 1\.1\.1\.2/, output - assert_match /docker pull dhh\/app:999 on 1\.1\.1\.1/, output - end - end - - test "push" do - run_command("push").tap do |output| - assert_match /docker buildx build --push --platform linux\/amd64,linux\/arm64 --builder mrsk-app-multiarch -t dhh\/app:999 -t dhh\/app:latest --label service="app" --file Dockerfile \. as .*\@localhost/, output - end - end - test "pull" do run_command("pull").tap do |output| assert_match /docker image rm --force dhh\/app:999 on 1\.1\.1\.2/, output diff --git a/test/test_helper.rb b/test/test_helper.rb index 6f29420b..bf1f7b49 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -12,14 +12,5 @@ ActiveSupport::LogSubscriber.logger = ActiveSupport::Logger.new(STDOUT) if ENV[" # Applies to remote commands only SSHKit.config.backend = SSHKit::Backend::Printer -# Ensure local commands use the printer backend too -module SSHKit - module DSL - def run_locally(&block) - SSHKit::Backend::Printer.new(SSHKit::Host.new(:local), &block).run - end - end -end - class ActiveSupport::TestCase end From ff0170076e8c70e821869614ee46779567381a07 Mon Sep 17 00:00:00 2001 From: Samuel Sieg Date: Sun, 12 Mar 2023 10:44:33 +0100 Subject: [PATCH 3/8] Simplify --- lib/mrsk/cli/main.rb | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/lib/mrsk/cli/main.rb b/lib/mrsk/cli/main.rb index b77e5256..5d24c3f7 100644 --- a/lib/mrsk/cli/main.rb +++ b/lib/mrsk/cli/main.rb @@ -12,32 +12,25 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base option :use_prebuilt_image, aliases: "-P", type: :boolean, default: false, desc: "Use prebuilt image, skip build" def deploy runtime = print_runtime do - options_without_prebuilt_image = options.without(:use_prebuilt_image) - say "Ensure curl and Docker are installed...", :magenta - invoke "mrsk:cli:server:bootstrap", [], options_without_prebuilt_image + invoke "mrsk:cli:server:bootstrap", [], options.without(:use_prebuilt_image) say "Log into image registry...", :magenta - invoke "mrsk:cli:registry:login", [], options_without_prebuilt_image + invoke "mrsk:cli:registry:login", [], options.without(:use_prebuilt_image) - unless options[:use_prebuilt_image] - say "Build and push app image...", :magenta - invoke "mrsk:cli:build:push" - end - - say "Pull image onto servers...", :magenta - invoke "mrsk:cli:build:pull", [], options_without_prebuilt_image + say "Build and push app image...", :magenta + invoke "mrsk:cli:build:deliver" say "Ensure Traefik is running...", :magenta - invoke "mrsk:cli:traefik:boot", [], options_without_prebuilt_image + invoke "mrsk:cli:traefik:boot", [], options.without(:use_prebuilt_image) say "Ensure app can pass healthcheck...", :magenta - invoke "mrsk:cli:healthcheck:perform", [], options_without_prebuilt_image + invoke "mrsk:cli:healthcheck:perform", [], options.without(:use_prebuilt_image) - invoke "mrsk:cli:app:boot", [], options_without_prebuilt_image + invoke "mrsk:cli:app:boot", [], options.without(:use_prebuilt_image) say "Prune old containers and images...", :magenta - invoke "mrsk:cli:prune:all", [], options_without_prebuilt_image + invoke "mrsk:cli:prune:all", [], options.without(:use_prebuilt_image) end audit_broadcast "Deployed app in #{runtime.to_i} seconds" unless options[:skip_broadcast] From 47af6d94835087f3bd3e9b5e26fee2431835de05 Mon Sep 17 00:00:00 2001 From: Samuel Sieg Date: Sun, 12 Mar 2023 10:53:29 +0100 Subject: [PATCH 4/8] Is a global option better? --- lib/mrsk/cli/base.rb | 8 +++++--- lib/mrsk/cli/build.rb | 3 +-- lib/mrsk/cli/main.rb | 23 ++++++++--------------- lib/mrsk/commander.rb | 2 +- 4 files changed, 15 insertions(+), 21 deletions(-) diff --git a/lib/mrsk/cli/base.rb b/lib/mrsk/cli/base.rb index c7a87964..8fa3fc6b 100644 --- a/lib/mrsk/cli/base.rb +++ b/lib/mrsk/cli/base.rb @@ -12,6 +12,7 @@ module Mrsk::Cli class_option :quiet, type: :boolean, aliases: "-q", desc: "Minimal logging" class_option :version, desc: "Run commands against a specific app version" + class_option :use_prebuilt_image, type: :boolean, default: false, desc: "Use prebuilt image, skip building" class_option :primary, type: :boolean, aliases: "-p", desc: "Run commands only on primary host instead of all" class_option :hosts, aliases: "-h", desc: "Run commands on these hosts instead of all (separate by comma)" @@ -39,9 +40,10 @@ module Mrsk::Cli def initialize_commander(options) MRSK.tap do |commander| - commander.config_file = Pathname.new(File.expand_path(options[:config_file])) - commander.destination = options[:destination] - commander.version = options[:version] + commander.config_file = Pathname.new(File.expand_path(options[:config_file])) + commander.destination = options[:destination] + commander.version = options[:version] + commander.use_prebuilt_image = options[:use_prebuilt_image] commander.specific_hosts = options[:hosts]&.split(",") commander.specific_roles = options[:roles]&.split(",") diff --git a/lib/mrsk/cli/build.rb b/lib/mrsk/cli/build.rb index cb106741..dd721d6f 100644 --- a/lib/mrsk/cli/build.rb +++ b/lib/mrsk/cli/build.rb @@ -1,8 +1,7 @@ class Mrsk::Cli::Build < Mrsk::Cli::Base desc "deliver", "Build app and push app image to registry then pull image on servers" - option :use_prebuilt_image, aliases: "-P", type: :boolean, default: false, desc: "Use prebuilt image, skip build" def deliver - push unless options[:use_prebuilt_image] + push unless MRSK.use_prebuilt_image pull end diff --git a/lib/mrsk/cli/main.rb b/lib/mrsk/cli/main.rb index 5d24c3f7..73268f50 100644 --- a/lib/mrsk/cli/main.rb +++ b/lib/mrsk/cli/main.rb @@ -9,44 +9,37 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base end desc "deploy", "Deploy app to servers" - option :use_prebuilt_image, aliases: "-P", type: :boolean, default: false, desc: "Use prebuilt image, skip build" def deploy runtime = print_runtime do say "Ensure curl and Docker are installed...", :magenta - invoke "mrsk:cli:server:bootstrap", [], options.without(:use_prebuilt_image) + invoke "mrsk:cli:server:bootstrap" say "Log into image registry...", :magenta - invoke "mrsk:cli:registry:login", [], options.without(:use_prebuilt_image) + invoke "mrsk:cli:registry:login" say "Build and push app image...", :magenta invoke "mrsk:cli:build:deliver" say "Ensure Traefik is running...", :magenta - invoke "mrsk:cli:traefik:boot", [], options.without(:use_prebuilt_image) + invoke "mrsk:cli:traefik:boot" say "Ensure app can pass healthcheck...", :magenta - invoke "mrsk:cli:healthcheck:perform", [], options.without(:use_prebuilt_image) + invoke "mrsk:cli:healthcheck:perform" - invoke "mrsk:cli:app:boot", [], options.without(:use_prebuilt_image) + invoke "mrsk:cli:app:boot" say "Prune old containers and images...", :magenta - invoke "mrsk:cli:prune:all", [], options.without(:use_prebuilt_image) + invoke "mrsk:cli:prune:all" end audit_broadcast "Deployed app in #{runtime.to_i} seconds" unless options[:skip_broadcast] end desc "redeploy", "Deploy app to servers without bootstrapping servers, starting Traefik, pruning, and registry login" - option :use_prebuilt_image, aliases: "-P", type: :boolean, default: false, desc: "Use prebuilt image, skip build" def redeploy runtime = print_runtime do - unless options[:use_prebuilt_image] - say "Build and push app image...", :magenta - invoke "mrsk:cli:build:push" - end - - say "Pull image onto servers...", :magenta - invoke "mrsk:cli:build:pull" + say "Build and push app image...", :magenta + invoke "mrsk:cli:build:deliver" say "Ensure app can pass healthcheck...", :magenta invoke "mrsk:cli:healthcheck:perform" diff --git a/lib/mrsk/commander.rb b/lib/mrsk/commander.rb index be2fd2e3..d9fb5347 100644 --- a/lib/mrsk/commander.rb +++ b/lib/mrsk/commander.rb @@ -1,7 +1,7 @@ require "active_support/core_ext/enumerable" class Mrsk::Commander - attr_accessor :config_file, :destination, :verbosity, :version + attr_accessor :config_file, :destination, :verbosity, :version, :use_prebuilt_image def initialize(config_file: nil, destination: nil, verbosity: :info) @config_file, @destination, @verbosity = config_file, destination, verbosity From 6232175ef8f2c516140b40e9044a2c9b054592da Mon Sep 17 00:00:00 2001 From: Samuel Sieg Date: Sun, 12 Mar 2023 10:56:12 +0100 Subject: [PATCH 5/8] Undo changes from experimenting --- test/cli/build_test.rb | 4 ++-- test/test_helper.rb | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/test/cli/build_test.rb b/test/cli/build_test.rb index b2ce6fd4..3d5f4431 100644 --- a/test/cli/build_test.rb +++ b/test/cli/build_test.rb @@ -3,8 +3,8 @@ require_relative "cli_test_case" class CliBuildTest < CliTestCase test "pull" do run_command("pull").tap do |output| - assert_match /docker image rm --force dhh\/app:999 on 1\.1\.1\.2/, output - assert_match /docker pull dhh\/app:999 on 1\.1\.1\.1/, output + assert_match /docker image rm --force dhh\/app:999/, output + assert_match /docker pull dhh\/app:999/, output end end diff --git a/test/test_helper.rb b/test/test_helper.rb index bf1f7b49..4c381df2 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -9,7 +9,6 @@ require "mrsk" ActiveSupport::LogSubscriber.logger = ActiveSupport::Logger.new(STDOUT) if ENV["VERBOSE"] -# Applies to remote commands only SSHKit.config.backend = SSHKit::Backend::Printer class ActiveSupport::TestCase From cb15800d2529cd0cb29ab916bbac029a7edbc39c Mon Sep 17 00:00:00 2001 From: Samuel Sieg Date: Mon, 13 Mar 2023 16:02:24 +0100 Subject: [PATCH 6/8] Move option to `deploy`/`redeploy`, rename to `skip-push` --- lib/mrsk/cli/base.rb | 8 +++----- lib/mrsk/cli/build.rb | 2 +- lib/mrsk/cli/main.rb | 38 +++++++++++++++++++++++++++----------- lib/mrsk/commander.rb | 2 +- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/lib/mrsk/cli/base.rb b/lib/mrsk/cli/base.rb index 8fa3fc6b..c7a87964 100644 --- a/lib/mrsk/cli/base.rb +++ b/lib/mrsk/cli/base.rb @@ -12,7 +12,6 @@ module Mrsk::Cli class_option :quiet, type: :boolean, aliases: "-q", desc: "Minimal logging" class_option :version, desc: "Run commands against a specific app version" - class_option :use_prebuilt_image, type: :boolean, default: false, desc: "Use prebuilt image, skip building" class_option :primary, type: :boolean, aliases: "-p", desc: "Run commands only on primary host instead of all" class_option :hosts, aliases: "-h", desc: "Run commands on these hosts instead of all (separate by comma)" @@ -40,10 +39,9 @@ module Mrsk::Cli def initialize_commander(options) MRSK.tap do |commander| - commander.config_file = Pathname.new(File.expand_path(options[:config_file])) - commander.destination = options[:destination] - commander.version = options[:version] - commander.use_prebuilt_image = options[:use_prebuilt_image] + commander.config_file = Pathname.new(File.expand_path(options[:config_file])) + commander.destination = options[:destination] + commander.version = options[:version] commander.specific_hosts = options[:hosts]&.split(",") commander.specific_roles = options[:roles]&.split(",") diff --git a/lib/mrsk/cli/build.rb b/lib/mrsk/cli/build.rb index dd721d6f..3e8912d7 100644 --- a/lib/mrsk/cli/build.rb +++ b/lib/mrsk/cli/build.rb @@ -1,7 +1,7 @@ class Mrsk::Cli::Build < Mrsk::Cli::Base desc "deliver", "Build app and push app image to registry then pull image on servers" def deliver - push unless MRSK.use_prebuilt_image + push pull end diff --git a/lib/mrsk/cli/main.rb b/lib/mrsk/cli/main.rb index 73268f50..e34cdaf3 100644 --- a/lib/mrsk/cli/main.rb +++ b/lib/mrsk/cli/main.rb @@ -9,42 +9,58 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base end desc "deploy", "Deploy app to servers" + option :skip_push, aliases: "-P", type: :boolean, default: false, desc: "Skip image build and push" def deploy + invoke_options = options.without(:skip_push) + runtime = print_runtime do say "Ensure curl and Docker are installed...", :magenta - invoke "mrsk:cli:server:bootstrap" + invoke "mrsk:cli:server:bootstrap", [], invoke_options say "Log into image registry...", :magenta invoke "mrsk:cli:registry:login" - say "Build and push app image...", :magenta - invoke "mrsk:cli:build:deliver" + if options[:skip_push] + say "Pull app image...", :magenta + invoke "mrsk:cli:build:pull", [], invoke_options + else + say "Build and push app image...", :magenta + invoke "mrsk:cli:build:deliver", [], invoke_options + end say "Ensure Traefik is running...", :magenta - invoke "mrsk:cli:traefik:boot" + invoke "mrsk:cli:traefik:boot", [], invoke_options say "Ensure app can pass healthcheck...", :magenta - invoke "mrsk:cli:healthcheck:perform" + invoke "mrsk:cli:healthcheck:perform", [], invoke_options - invoke "mrsk:cli:app:boot" + invoke "mrsk:cli:app:boot", [], invoke_options say "Prune old containers and images...", :magenta - invoke "mrsk:cli:prune:all" + invoke "mrsk:cli:prune:all", [], invoke_options end audit_broadcast "Deployed app in #{runtime.to_i} seconds" unless options[:skip_broadcast] end desc "redeploy", "Deploy app to servers without bootstrapping servers, starting Traefik, pruning, and registry login" + option :skip_push, aliases: "-P", type: :boolean, default: false, desc: "Skip image build and push" def redeploy + invoke_options = options.without(:skip_push) + runtime = print_runtime do - say "Build and push app image...", :magenta - invoke "mrsk:cli:build:deliver" + if options[:skip_push] + say "Pull app image...", :magenta + invoke "mrsk:cli:build:pull", [], invoke_options + else + say "Build and push app image...", :magenta + invoke "mrsk:cli:build:deliver", [], invoke_options + end say "Ensure app can pass healthcheck...", :magenta - invoke "mrsk:cli:healthcheck:perform" + invoke "mrsk:cli:healthcheck:perform", [], invoke_options - invoke "mrsk:cli:app:boot" + invoke "mrsk:cli:app:boot", [], invoke_options end audit_broadcast "Redeployed app in #{runtime.to_i} seconds" unless options[:skip_broadcast] diff --git a/lib/mrsk/commander.rb b/lib/mrsk/commander.rb index d9fb5347..be2fd2e3 100644 --- a/lib/mrsk/commander.rb +++ b/lib/mrsk/commander.rb @@ -1,7 +1,7 @@ require "active_support/core_ext/enumerable" class Mrsk::Commander - attr_accessor :config_file, :destination, :verbosity, :version, :use_prebuilt_image + attr_accessor :config_file, :destination, :verbosity, :version def initialize(config_file: nil, destination: nil, verbosity: :info) @config_file, @destination, @verbosity = config_file, destination, verbosity From c29d1ddebad235df7978abbc0feb32b79c65619e Mon Sep 17 00:00:00 2001 From: Samuel Sieg Date: Mon, 13 Mar 2023 16:05:21 +0100 Subject: [PATCH 7/8] Fix --- lib/mrsk/cli/main.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mrsk/cli/main.rb b/lib/mrsk/cli/main.rb index e34cdaf3..c9d81115 100644 --- a/lib/mrsk/cli/main.rb +++ b/lib/mrsk/cli/main.rb @@ -18,7 +18,7 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base invoke "mrsk:cli:server:bootstrap", [], invoke_options say "Log into image registry...", :magenta - invoke "mrsk:cli:registry:login" + invoke "mrsk:cli:registry:login", [], invoke_options if options[:skip_push] say "Pull app image...", :magenta From 0ac2cd2a4bccd92421e1942fb8b55062f0a889e1 Mon Sep 17 00:00:00 2001 From: Samuel Sieg Date: Tue, 14 Mar 2023 11:49:31 +0100 Subject: [PATCH 8/8] Add tests for deploy/redeploy commands --- test/cli/main_test.rb | 68 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/test/cli/main_test.rb b/test/cli/main_test.rb index 9f5640e4..fe7d4d6a 100644 --- a/test/cli/main_test.rb +++ b/test/cli/main_test.rb @@ -6,6 +6,74 @@ class CliMainTest < CliTestCase assert_equal Mrsk::VERSION, version end + test "deploy" do + invoke_options = { "config_file" => "test/fixtures/deploy_with_accessories.yml", "skip_broadcast" => false, "skip_push" => false} + + Mrsk::Cli::Main.any_instance.expects(:invoke).with("mrsk:cli:server:bootstrap", [], invoke_options) + Mrsk::Cli::Main.any_instance.expects(:invoke).with("mrsk:cli:registry:login", [], invoke_options) + Mrsk::Cli::Main.any_instance.expects(:invoke).with("mrsk:cli:build:deliver", [], invoke_options) + Mrsk::Cli::Main.any_instance.expects(:invoke).with("mrsk:cli:traefik:boot", [], invoke_options) + Mrsk::Cli::Main.any_instance.expects(:invoke).with("mrsk:cli:healthcheck:perform", [], invoke_options) + Mrsk::Cli::Main.any_instance.expects(:invoke).with("mrsk:cli:app:boot", [], invoke_options) + Mrsk::Cli::Main.any_instance.expects(:invoke).with("mrsk:cli:prune:all", [], invoke_options) + + run_command("deploy").tap do |output| + assert_match /Ensure curl and Docker are installed/, output + assert_match /Log into image registry/, output + assert_match /Build and push app image/, output + assert_match /Ensure Traefik is running/, output + assert_match /Ensure app can pass healthcheck/, output + assert_match /Prune old containers and images/, output + end + end + + test "deploy with skip_push" do + invoke_options = { "config_file" => "test/fixtures/deploy_with_accessories.yml", "skip_broadcast" => false, "skip_push" => true } + + Mrsk::Cli::Main.any_instance.expects(:invoke).with("mrsk:cli:server:bootstrap", [], invoke_options) + Mrsk::Cli::Main.any_instance.expects(:invoke).with("mrsk:cli:registry:login", [], invoke_options) + Mrsk::Cli::Main.any_instance.expects(:invoke).with("mrsk:cli:build:pull", [], invoke_options) + Mrsk::Cli::Main.any_instance.expects(:invoke).with("mrsk:cli:traefik:boot", [], invoke_options) + Mrsk::Cli::Main.any_instance.expects(:invoke).with("mrsk:cli:healthcheck:perform", [], invoke_options) + Mrsk::Cli::Main.any_instance.expects(:invoke).with("mrsk:cli:app:boot", [], invoke_options) + Mrsk::Cli::Main.any_instance.expects(:invoke).with("mrsk:cli:prune:all", [], invoke_options) + + run_command("deploy", "--skip_push").tap do |output| + assert_match /Ensure curl and Docker are installed/, output + assert_match /Log into image registry/, output + assert_match /Pull app image/, output + assert_match /Ensure Traefik is running/, output + assert_match /Ensure app can pass healthcheck/, output + assert_match /Prune old containers and images/, output + end + end + + test "redeploy" do + invoke_options = { "config_file" => "test/fixtures/deploy_with_accessories.yml", "skip_broadcast" => false, "skip_push" => false} + + Mrsk::Cli::Main.any_instance.expects(:invoke).with("mrsk:cli:build:deliver", [], invoke_options) + Mrsk::Cli::Main.any_instance.expects(:invoke).with("mrsk:cli:healthcheck:perform", [], invoke_options) + Mrsk::Cli::Main.any_instance.expects(:invoke).with("mrsk:cli:app:boot", [], invoke_options) + + run_command("redeploy").tap do |output| + assert_match /Build and push app image/, output + assert_match /Ensure app can pass healthcheck/, output + end + end + + test "redeploy with skip_push" do + invoke_options = { "config_file" => "test/fixtures/deploy_with_accessories.yml", "skip_broadcast" => false, "skip_push" => true } + + Mrsk::Cli::Main.any_instance.expects(:invoke).with("mrsk:cli:build:pull", [], invoke_options) + Mrsk::Cli::Main.any_instance.expects(:invoke).with("mrsk:cli:healthcheck:perform", [], invoke_options) + Mrsk::Cli::Main.any_instance.expects(:invoke).with("mrsk:cli:app:boot", [], invoke_options) + + run_command("redeploy", "--skip_push").tap do |output| + assert_match /Pull app image/, output + assert_match /Ensure app can pass healthcheck/, output + end + end + test "rollback bad version" do run_command("details") # Preheat MRSK const