Remove proxy only if no apps are installed
This commit is contained in:
@@ -207,12 +207,12 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "remove_service_directory [NAME]", "Remove accessory directory used for uploaded files and data directories from host", hide: true
|
desc "remove_app_directory [NAME]", "Remove accessory directory used for uploaded files and data directories from host", hide: true
|
||||||
def remove_service_directory(name)
|
def remove_app_directory(name)
|
||||||
with_lock do
|
with_lock do
|
||||||
with_accessory(name) do |accessory, hosts|
|
with_accessory(name) do |accessory, hosts|
|
||||||
on(hosts) do
|
on(hosts) do
|
||||||
execute *accessory.remove_service_directory
|
execute *accessory.remove_app_directory
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -248,7 +248,7 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
|||||||
stop(name)
|
stop(name)
|
||||||
remove_container(name)
|
remove_container(name)
|
||||||
remove_image(name)
|
remove_image(name)
|
||||||
remove_service_directory(name)
|
remove_app_directory(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
def prepare(name)
|
def prepare(name)
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ class Kamal::Cli::App < Kamal::Cli::Base
|
|||||||
stop
|
stop
|
||||||
remove_containers
|
remove_containers
|
||||||
remove_images
|
remove_images
|
||||||
remove_service_directory
|
remove_app_directory
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -273,15 +273,15 @@ class Kamal::Cli::App < Kamal::Cli::Base
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "remove_service_directory", "Remove the service directory from servers", hide: true
|
desc "remove_app_directory", "Remove the service directory from servers", hide: true
|
||||||
def remove_service_directory
|
def remove_app_directory
|
||||||
with_lock do
|
with_lock do
|
||||||
on(KAMAL.hosts) do |host|
|
on(KAMAL.hosts) do |host|
|
||||||
roles = KAMAL.roles_on(host)
|
roles = KAMAL.roles_on(host)
|
||||||
|
|
||||||
roles.each do |role|
|
roles.each do |role|
|
||||||
execute *KAMAL.auditor.record("Removed #{KAMAL.config.service_directory} on all servers", role: role), verbosity: :debug
|
execute *KAMAL.auditor.record("Removed #{KAMAL.config.app_directory} on all servers", role: role), verbosity: :debug
|
||||||
execute *KAMAL.server.remove_service_directory
|
execute *KAMAL.server.remove_app_directory
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ module Kamal::Cli
|
|||||||
|
|
||||||
def ensure_service_and_locks_directory
|
def ensure_service_and_locks_directory
|
||||||
on(KAMAL.hosts) do
|
on(KAMAL.hosts) do
|
||||||
execute(*KAMAL.server.ensure_service_directory)
|
execute(*KAMAL.server.ensure_app_directory)
|
||||||
end
|
end
|
||||||
|
|
||||||
on(KAMAL.primary_host) do
|
on(KAMAL.primary_host) do
|
||||||
|
|||||||
@@ -150,11 +150,15 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
desc "remove", "Remove proxy container and image from servers"
|
desc "remove", "Remove proxy container and image from servers"
|
||||||
|
option :force, type: :boolean, default: false, desc: "Force removing proxy when apps are still installed"
|
||||||
def remove
|
def remove
|
||||||
with_lock do
|
with_lock do
|
||||||
stop
|
if removal_allowed?(options[:force])
|
||||||
remove_container
|
stop
|
||||||
remove_image
|
remove_container
|
||||||
|
remove_image
|
||||||
|
remove_host_directory
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -178,8 +182,37 @@ class Kamal::Cli::Proxy < Kamal::Cli::Base
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
desc "remove_host_directory", "Remove proxy directory from servers", hide: true
|
||||||
|
def remove_host_directory
|
||||||
|
with_lock do
|
||||||
|
on(KAMAL.proxy_hosts) do
|
||||||
|
execute *KAMAL.auditor.record("Removed #{KAMAL.config.proxy_directory}"), verbosity: :debug
|
||||||
|
execute *KAMAL.proxy.remove_host_directory
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def reset_invocation(cli_class)
|
def reset_invocation(cli_class)
|
||||||
instance_variable_get("@_invocations")[cli_class].pop
|
instance_variable_get("@_invocations")[cli_class].pop
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def removal_allowed?(force)
|
||||||
|
on(KAMAL.proxy_hosts) do |host|
|
||||||
|
app_count = capture_with_info(*KAMAL.server.app_directory_count).chomp.to_i
|
||||||
|
raise "The are other applications installed on #{host}" if app_count > 0
|
||||||
|
end
|
||||||
|
|
||||||
|
true
|
||||||
|
rescue SSHKit::Runner::ExecuteError => e
|
||||||
|
raise unless e.message.include?("The are other applications installed on")
|
||||||
|
|
||||||
|
if force
|
||||||
|
say "Forcing, so removing the proxy, even though other apps are installed", :magenta
|
||||||
|
else
|
||||||
|
say "Not removing the proxy, as other apps are installed, ignore this check with kamal proxy remove --force", :magenta
|
||||||
|
end
|
||||||
|
|
||||||
|
force
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_service_directory
|
def remove_app_directory
|
||||||
[ :rm, "-rf", service_name ]
|
[ :rm, "-rf", service_name ]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,10 @@ class Kamal::Commands::Proxy < Kamal::Commands::Base
|
|||||||
docker :image, :prune, "--all", "--force", "--filter", "label=org.opencontainers.image.title=kamal-proxy"
|
docker :image, :prune, "--all", "--force", "--filter", "label=org.opencontainers.image.title=kamal-proxy"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def remove_host_directory
|
||||||
|
remove_directory config.proxy_directory
|
||||||
|
end
|
||||||
|
|
||||||
def cleanup_traefik
|
def cleanup_traefik
|
||||||
chain \
|
chain \
|
||||||
docker(:container, :stop, "traefik"),
|
docker(:container, :stop, "traefik"),
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
class Kamal::Commands::Server < Kamal::Commands::Base
|
class Kamal::Commands::Server < Kamal::Commands::Base
|
||||||
def ensure_service_directory
|
def ensure_app_directory
|
||||||
make_directory config.service_directory
|
make_directory config.app_directory
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_service_directory
|
def remove_app_directory
|
||||||
remove_directory config.service_directory
|
remove_directory config.app_directory
|
||||||
|
end
|
||||||
|
|
||||||
|
def app_directory_count
|
||||||
|
pipe \
|
||||||
|
[ :ls, config.apps_directory ],
|
||||||
|
[ :wc, "-l" ]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -194,16 +194,24 @@ class Kamal::Configuration
|
|||||||
".kamal"
|
".kamal"
|
||||||
end
|
end
|
||||||
|
|
||||||
def service_directory
|
def apps_directory
|
||||||
File.join run_directory, "apps", [ service, destination ].compact.join("-")
|
File.join run_directory, "apps"
|
||||||
|
end
|
||||||
|
|
||||||
|
def app_directory
|
||||||
|
File.join apps_directory, [ service, destination ].compact.join("-")
|
||||||
|
end
|
||||||
|
|
||||||
|
def proxy_directory
|
||||||
|
File.join run_directory, "proxy"
|
||||||
end
|
end
|
||||||
|
|
||||||
def env_directory
|
def env_directory
|
||||||
File.join service_directory, "env"
|
File.join app_directory, "env"
|
||||||
end
|
end
|
||||||
|
|
||||||
def assets_directory
|
def assets_directory
|
||||||
File.join service_directory, "assets"
|
File.join app_directory, "assets"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ class Kamal::Configuration::Proxy
|
|||||||
|
|
||||||
def config_volume
|
def config_volume
|
||||||
Kamal::Configuration::Volume.new \
|
Kamal::Configuration::Volume.new \
|
||||||
host_path: File.join(config.run_directory, "proxy", "config"),
|
host_path: File.join(config.proxy_directory, "config"),
|
||||||
container_path: "/root/.config/kamal-proxy"
|
container_path: "/root/.config/kamal-proxy"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ class CliAccessoryTest < CliTestCase
|
|||||||
Kamal::Cli::Accessory.any_instance.expects(:stop).with("mysql")
|
Kamal::Cli::Accessory.any_instance.expects(:stop).with("mysql")
|
||||||
Kamal::Cli::Accessory.any_instance.expects(:remove_container).with("mysql")
|
Kamal::Cli::Accessory.any_instance.expects(:remove_container).with("mysql")
|
||||||
Kamal::Cli::Accessory.any_instance.expects(:remove_image).with("mysql")
|
Kamal::Cli::Accessory.any_instance.expects(:remove_image).with("mysql")
|
||||||
Kamal::Cli::Accessory.any_instance.expects(:remove_service_directory).with("mysql")
|
Kamal::Cli::Accessory.any_instance.expects(:remove_app_directory).with("mysql")
|
||||||
|
|
||||||
run_command("remove", "mysql", "-y")
|
run_command("remove", "mysql", "-y")
|
||||||
end
|
end
|
||||||
@@ -175,11 +175,11 @@ class CliAccessoryTest < CliTestCase
|
|||||||
Kamal::Cli::Accessory.any_instance.expects(:stop).with("mysql")
|
Kamal::Cli::Accessory.any_instance.expects(:stop).with("mysql")
|
||||||
Kamal::Cli::Accessory.any_instance.expects(:remove_container).with("mysql")
|
Kamal::Cli::Accessory.any_instance.expects(:remove_container).with("mysql")
|
||||||
Kamal::Cli::Accessory.any_instance.expects(:remove_image).with("mysql")
|
Kamal::Cli::Accessory.any_instance.expects(:remove_image).with("mysql")
|
||||||
Kamal::Cli::Accessory.any_instance.expects(:remove_service_directory).with("mysql")
|
Kamal::Cli::Accessory.any_instance.expects(:remove_app_directory).with("mysql")
|
||||||
Kamal::Cli::Accessory.any_instance.expects(:stop).with("redis")
|
Kamal::Cli::Accessory.any_instance.expects(:stop).with("redis")
|
||||||
Kamal::Cli::Accessory.any_instance.expects(:remove_container).with("redis")
|
Kamal::Cli::Accessory.any_instance.expects(:remove_container).with("redis")
|
||||||
Kamal::Cli::Accessory.any_instance.expects(:remove_image).with("redis")
|
Kamal::Cli::Accessory.any_instance.expects(:remove_image).with("redis")
|
||||||
Kamal::Cli::Accessory.any_instance.expects(:remove_service_directory).with("redis")
|
Kamal::Cli::Accessory.any_instance.expects(:remove_app_directory).with("redis")
|
||||||
|
|
||||||
run_command("remove", "all", "-y")
|
run_command("remove", "all", "-y")
|
||||||
end
|
end
|
||||||
@@ -192,8 +192,8 @@ class CliAccessoryTest < CliTestCase
|
|||||||
assert_match "docker image rm --force mysql", run_command("remove_image", "mysql")
|
assert_match "docker image rm --force mysql", run_command("remove_image", "mysql")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "remove_service_directory" do
|
test "remove_app_directory" do
|
||||||
assert_match "rm -rf app-mysql", run_command("remove_service_directory", "mysql")
|
assert_match "rm -rf app-mysql", run_command("remove_app_directory", "mysql")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "hosts param respected" do
|
test "hosts param respected" do
|
||||||
|
|||||||
@@ -98,11 +98,36 @@ class CliProxyTest < CliTestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "remove" do
|
test "remove" do
|
||||||
Kamal::Cli::Proxy.any_instance.expects(:stop)
|
run_command("remove").tap do |output|
|
||||||
Kamal::Cli::Proxy.any_instance.expects(:remove_container)
|
assert_match "/usr/bin/env ls .kamal/apps | wc -l", output
|
||||||
Kamal::Cli::Proxy.any_instance.expects(:remove_image)
|
assert_match "docker container prune --force --filter label=org.opencontainers.image.title=kamal-proxy", output
|
||||||
|
assert_match "docker image prune --all --force --filter label=org.opencontainers.image.title=kamal-proxy", output
|
||||||
|
assert_match "/usr/bin/env rm -r .kamal/proxy", output
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
run_command("remove")
|
test "remove with other apps" do
|
||||||
|
Thread.report_on_exception = false
|
||||||
|
|
||||||
|
SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info).with(:ls, ".kamal/apps", "|", :wc, "-l").returns("1\n").twice
|
||||||
|
|
||||||
|
run_command("remove").tap do |output|
|
||||||
|
assert_match "Not removing the proxy, as other apps are installed, ignore this check with kamal proxy remove --force", output
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
Thread.report_on_exception = true
|
||||||
|
end
|
||||||
|
|
||||||
|
test "force remove with other apps" do
|
||||||
|
Thread.report_on_exception = false
|
||||||
|
|
||||||
|
SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info).with(:ls, ".kamal/apps", "|", :wc, "-l").returns("1\n").twice
|
||||||
|
|
||||||
|
run_command("remove").tap do |output|
|
||||||
|
assert_match "Not removing the proxy, as other apps are installed, ignore this check with kamal proxy remove --force", output
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
Thread.report_on_exception = true
|
||||||
end
|
end
|
||||||
|
|
||||||
test "remove_container" do
|
test "remove_container" do
|
||||||
@@ -117,6 +142,12 @@ class CliProxyTest < CliTestCase
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "remove_host_directory" do
|
||||||
|
run_command("remove_host_directory").tap do |output|
|
||||||
|
assert_match "/usr/bin/env rm -r .kamal/proxy", output
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def run_command(*command, fixture: :with_proxy)
|
def run_command(*command, fixture: :with_proxy)
|
||||||
stdouted { Kamal::Cli::Proxy.start([ *command, "-c", "test/fixtures/deploy_#{fixture}.yml" ]) }
|
stdouted { Kamal::Cli::Proxy.start([ *command, "-c", "test/fixtures/deploy_#{fixture}.yml" ]) }
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ class CommandsServerTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "ensure service directory" do
|
test "ensure service directory" do
|
||||||
assert_equal "mkdir -p .kamal/apps/app", new_command.ensure_service_directory.join(" ")
|
assert_equal "mkdir -p .kamal/apps/app", new_command.ensure_app_directory.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|||||||
@@ -49,5 +49,6 @@ class AppTest < IntegrationTest
|
|||||||
kamal :app, :remove
|
kamal :app, :remove
|
||||||
|
|
||||||
assert_app_is_down
|
assert_app_is_down
|
||||||
|
assert_app_directory_removed
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -148,4 +148,16 @@ class IntegrationTest < ActiveSupport::TestCase
|
|||||||
def container_running?(host:, name:)
|
def container_running?(host:, name:)
|
||||||
docker_compose("exec #{host} docker ps --filter=name=#{name} | tail -n+2", capture: true).strip.present?
|
docker_compose("exec #{host} docker ps --filter=name=#{name} | tail -n+2", capture: true).strip.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def assert_app_directory_removed
|
||||||
|
assert_directory_removed("./kamal/apps/#{@app}")
|
||||||
|
end
|
||||||
|
|
||||||
|
def assert_proxy_directory_removed
|
||||||
|
assert_directory_removed("./kamal/proxy")
|
||||||
|
end
|
||||||
|
|
||||||
|
def assert_directory_removed(directory)
|
||||||
|
assert docker_compose("exec vm1 ls #{directory} | wc -l", capture: true).strip == "0"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -97,6 +97,8 @@ class MainTest < IntegrationTest
|
|||||||
|
|
||||||
kamal :remove, "-y"
|
kamal :remove, "-y"
|
||||||
assert_no_images_or_containers
|
assert_no_images_or_containers
|
||||||
|
assert_app_directory_removed
|
||||||
|
assert_proxy_directory_removed
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ class ProxyTest < IntegrationTest
|
|||||||
|
|
||||||
kamal :proxy, :remove
|
kamal :proxy, :remove
|
||||||
assert_proxy_not_running
|
assert_proxy_not_running
|
||||||
|
assert_proxy_directory_removed
|
||||||
|
|
||||||
kamal :env, :delete
|
kamal :env, :delete
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user