diff --git a/lib/kamal/cli/accessory.rb b/lib/kamal/cli/accessory.rb index 468487fa..e6bce05f 100644 --- a/lib/kamal/cli/accessory.rb +++ b/lib/kamal/cli/accessory.rb @@ -177,7 +177,7 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base if name == "all" KAMAL.accessory_names.each { |accessory_name| remove(accessory_name) } else - if options[:confirmed] || ask("This will remove all containers, images and data directories for #{name}. Are you sure?", limited_to: %w[ y N ], default: "N") == "y" + confirming "This will remove all containers, images and data directories for #{name}. Are you sure?" do with_accessory(name) do stop(name) remove_container(name) diff --git a/lib/kamal/cli/base.rb b/lib/kamal/cli/base.rb index 514c3ae6..12a72e66 100644 --- a/lib/kamal/cli/base.rb +++ b/lib/kamal/cli/base.rb @@ -103,6 +103,16 @@ module Kamal::Cli release_lock end + def confirming(question) + return yield if options[:confirmed] + + if ask(question, limited_to: %w[ y N ], default: "N") == "y" + yield + else + say "Aborted", :red + end + end + def acquire_lock raise_if_locked do say "Acquiring the deploy lock...", :magenta diff --git a/lib/kamal/cli/main.rb b/lib/kamal/cli/main.rb index 409d11e8..00ffbfe3 100644 --- a/lib/kamal/cli/main.rb +++ b/lib/kamal/cli/main.rb @@ -197,7 +197,7 @@ class Kamal::Cli::Main < Kamal::Cli::Base option :confirmed, aliases: "-y", type: :boolean, default: false, desc: "Proceed without confirmation question" def remove mutating do - if options[:confirmed] || ask("This will remove all containers and images. Are you sure?", limited_to: %w[ y N ], default: "N") == "y" + confirming "This will remove all containers and images. Are you sure?" do invoke "kamal:cli:traefik:remove", [], options.without(:confirmed) invoke "kamal:cli:app:remove", [], options.without(:confirmed) invoke "kamal:cli:accessory:remove", [ "all" ], options diff --git a/lib/kamal/cli/traefik.rb b/lib/kamal/cli/traefik.rb index 3cbf51b0..c13e2d80 100644 --- a/lib/kamal/cli/traefik.rb +++ b/lib/kamal/cli/traefik.rb @@ -11,20 +11,23 @@ class Kamal::Cli::Traefik < Kamal::Cli::Base desc "reboot", "Reboot Traefik on servers (stop container, remove container, start new container)" option :rolling, type: :boolean, default: false, desc: "Reboot traefik on hosts in sequence, rather than in parallel" + option :confirmed, aliases: "-y", type: :boolean, default: false, desc: "Proceed without confirmation question" def reboot - mutating do - host_groups = options[:rolling] ? KAMAL.traefik_hosts : [ KAMAL.traefik_hosts ] - host_groups.each do |hosts| - host_list = Array(hosts).join(",") - run_hook "pre-traefik-reboot", hosts: host_list - on(hosts) do - execute *KAMAL.auditor.record("Rebooted traefik"), verbosity: :debug - execute *KAMAL.registry.login - execute *KAMAL.traefik.stop, raise_on_non_zero_exit: false - execute *KAMAL.traefik.remove_container - execute *KAMAL.traefik.run + confirming "This will cause a brief outage on each host. Are you sure?" do + mutating do + host_groups = options[:rolling] ? KAMAL.traefik_hosts : [ KAMAL.traefik_hosts ] + host_groups.each do |hosts| + host_list = Array(hosts).join(",") + run_hook "pre-traefik-reboot", hosts: host_list + on(hosts) do + execute *KAMAL.auditor.record("Rebooted traefik"), verbosity: :debug + execute *KAMAL.registry.login + execute *KAMAL.traefik.stop, raise_on_non_zero_exit: false + execute *KAMAL.traefik.remove_container + execute *KAMAL.traefik.run + end + run_hook "post-traefik-reboot", hosts: host_list end - run_hook "post-traefik-reboot", hosts: host_list end end end diff --git a/test/cli/traefik_test.rb b/test/cli/traefik_test.rb index e8b4702a..d83529cd 100644 --- a/test/cli/traefik_test.rb +++ b/test/cli/traefik_test.rb @@ -11,7 +11,7 @@ class CliTraefikTest < CliTestCase test "reboot" do Kamal::Commands::Registry.any_instance.expects(:login).twice - run_command("reboot").tap do |output| + run_command("reboot", "-y").tap do |output| assert_match "docker container stop traefik", output assert_match "docker container prune --force --filter label=org.opencontainers.image.title=Traefik", output assert_match "docker run --name traefik --detach --restart unless-stopped --publish 80:80 --volume /var/run/docker.sock:/var/run/docker.sock --env-file .kamal/env/traefik/traefik.env --log-opt max-size=\"10m\" --label traefik.http.routers.catchall.entryPoints=\"http\" --label traefik.http.routers.catchall.rule=\"PathPrefix(\\`/\\`)\" --label traefik.http.routers.catchall.service=\"unavailable\" --label traefik.http.routers.catchall.priority=\"1\" --label traefik.http.services.unavailable.loadbalancer.server.port=\"0\" #{Kamal::Commands::Traefik::DEFAULT_IMAGE} --providers.docker --log.level=\"DEBUG\"", output @@ -21,7 +21,7 @@ class CliTraefikTest < CliTestCase test "reboot --rolling" do Object.any_instance.stubs(:sleep) - run_command("reboot", "--rolling").tap do |output| + run_command("reboot", "--rolling", "-y").tap do |output| assert_match "Running docker container prune --force --filter label=org.opencontainers.image.title=Traefik on 1.1.1.1", output end end diff --git a/test/integration/traefik_test.rb b/test/integration/traefik_test.rb index 3b5735ab..dcbdbfcb 100644 --- a/test/integration/traefik_test.rb +++ b/test/integration/traefik_test.rb @@ -7,13 +7,13 @@ class TraefikTest < IntegrationTest kamal :traefik, :boot assert_traefik_running - output = kamal :traefik, :reboot, capture: true + output = kamal :traefik, :reboot, "-y", capture: true assert_traefik_running assert_hooks_ran "pre-traefik-reboot", "post-traefik-reboot" assert_match /Rebooting Traefik on vm1,vm2.../, output assert_match /Rebooted Traefik on vm1,vm2/, output - output = kamal :traefik, :reboot, :"--rolling", capture: true + output = kamal :traefik, :reboot, :"--rolling", "-y", capture: true assert_traefik_running assert_hooks_ran "pre-traefik-reboot", "post-traefik-reboot" assert_match /Rebooting Traefik on vm1.../, output