diff --git a/lib/kamal/cli/base.rb b/lib/kamal/cli/base.rb index 16a8c9157..a583ebad5 100644 --- a/lib/kamal/cli/base.rb +++ b/lib/kamal/cli/base.rb @@ -32,60 +32,18 @@ def initialize(args = [], local_options = {}, config = {}) super end @original_env = ENV.to_h.dup - load_env initialize_commander(options_with_subcommand_class_options) end private - def reload_env - reset_env - load_env - end - - def load_env + def load_secrets if destination = options[:destination] - if File.exist?(".kamal/env.#{destination}") || File.exist?(".kamal/env") - Dotenv.load(".kamal/env.#{destination}", ".kamal/env") - else - loading_files = [ (".env" if File.exist?(".env")), (".env.#{destination}" if File.exist?(".env.#{destination}")) ].compact - if loading_files.any? - warn "Loading #{loading_files.join(" and ")} from the project root, use .kamal/env* instead" - Dotenv.load(".env.#{destination}", ".env") - end - end + Dotenv.parse(".kamal/secrets.#{destination}", ".kamal/secrets") else - if File.exist?(".kamal/env") - Dotenv.load(".kamal/env") - elsif File.exist?(".env") - warn "Loading .env from the project root is deprecated, use .kamal/env instead" - Dotenv.load(".env") - end - end - end - - def reset_env - replace_env @original_env - end - - def replace_env(env) - ENV.clear - ENV.update(env) - end - - def with_original_env - keeping_current_env do - reset_env - yield + Dotenv.parse(".kamal/secrets") end end - def keeping_current_env - current_env = ENV.to_h.dup - yield - ensure - replace_env(current_env) - end - def options_with_subcommand_class_options options.merge(@_initializer.last[:class_options] || {}) end diff --git a/lib/kamal/cli/env.rb b/lib/kamal/cli/env.rb deleted file mode 100644 index f12174a7b..000000000 --- a/lib/kamal/cli/env.rb +++ /dev/null @@ -1,54 +0,0 @@ -require "tempfile" - -class Kamal::Cli::Env < Kamal::Cli::Base - desc "push", "Push the env file to the remote hosts" - def push - with_lock do - on(KAMAL.hosts) do - execute *KAMAL.auditor.record("Pushed env files"), verbosity: :debug - - KAMAL.roles_on(host).each do |role| - execute *KAMAL.app(role: role, host: host).make_env_directory - upload! role.env(host).secrets_io, role.env(host).secrets_file, mode: 400 - end - end - - on(KAMAL.traefik_hosts) do - execute *KAMAL.traefik.make_env_directory - upload! KAMAL.traefik.env.secrets_io, KAMAL.traefik.env.secrets_file, mode: 400 - end - - on(KAMAL.accessory_hosts) do - KAMAL.accessories_on(host).each do |accessory| - accessory_config = KAMAL.config.accessory(accessory) - execute *KAMAL.accessory(accessory).make_env_directory - upload! accessory_config.env.secrets_io, accessory_config.env.secrets_file, mode: 400 - end - end - end - end - - desc "delete", "Delete the env file from the remote hosts" - def delete - with_lock do - on(KAMAL.hosts) do - execute *KAMAL.auditor.record("Deleted env files"), verbosity: :debug - - KAMAL.roles_on(host).each do |role| - execute *KAMAL.app(role: role, host: host).remove_env_file - end - end - - on(KAMAL.traefik_hosts) do - execute *KAMAL.traefik.remove_env_file - end - - on(KAMAL.accessory_hosts) do - KAMAL.accessories_on(host).each do |accessory| - accessory_config = KAMAL.config.accessory(accessory) - execute *KAMAL.accessory(accessory).remove_env_file - end - end - end - end -end diff --git a/lib/kamal/cli/main.rb b/lib/kamal/cli/main.rb index 08c0e714a..b72c1c8f2 100644 --- a/lib/kamal/cli/main.rb +++ b/lib/kamal/cli/main.rb @@ -9,10 +9,6 @@ def setup say "Ensure Docker is installed...", :magenta invoke "kamal:cli:server:bootstrap", [], invoke_options - say "Evaluate and push env files...", :magenta - invoke "kamal:cli:main:envify", [], invoke_options - invoke "kamal:cli:env:push", [], invoke_options - invoke "kamal:cli:accessory:boot", [ "all" ], invoke_options deploy end @@ -179,45 +175,6 @@ def init end end - desc "envify", "Create .env by evaluating .env.erb (or .env.staging.erb -> .env.staging when using -d staging)" - option :skip_push, aliases: "-P", type: :boolean, default: false, desc: "Skip .env file push" - def envify - if destination = options[:destination] - env_template_path = ".kamal/env.#{destination}.erb" - env_path = ".kamal/env.#{destination}" - else - env_template_path = ".kamal/env.erb" - env_path = ".kamal/env" - end - - unless Pathname.new(File.expand_path(env_template_path)).exist? - if destination = options[:destination] - env_template_path = ".env.#{destination}.erb" - env_path = ".env.#{destination}" - else - env_template_path = ".env.erb" - env_path = ".env" - end - - if Pathname.new(File.expand_path(env_template_path)).exist? - warn "Loading #{env_template_path} from the project root is deprecated, use .kamal/env[.].erb instead" - end - end - - if Pathname.new(File.expand_path(env_template_path)).exist? - # Ensure existing env doesn't pollute template evaluation - content = with_original_env { ERB.new(File.read(env_template_path), trim_mode: "-").result } - File.write(env_path, content, perm: 0600) - - unless options[:skip_push] - reload_env - invoke "kamal:cli:env:push", options - end - else - puts "Skipping envify (no #{env_template_path} exist)" - end - end - desc "remove", "Remove Traefik, app, accessories, and registry session from servers" option :confirmed, aliases: "-y", type: :boolean, default: false, desc: "Proceed without confirmation question" def remove diff --git a/test/cli/main_test.rb b/test/cli/main_test.rb index a93320b38..8272f67bf 100644 --- a/test/cli/main_test.rb +++ b/test/cli/main_test.rb @@ -8,8 +8,6 @@ class CliMainTest < CliTestCase invoke_options = { "config_file" => "test/fixtures/deploy_simple.yml", "version" => "999", "skip_hooks" => false } Kamal::Cli::Main.any_instance.expects(:invoke).with("kamal:cli:server:bootstrap", [], invoke_options) - Kamal::Cli::Main.any_instance.expects(:invoke).with("kamal:cli:main:envify", [], invoke_options) - Kamal::Cli::Main.any_instance.expects(:invoke).with("kamal:cli:env:push", [], invoke_options) Kamal::Cli::Main.any_instance.expects(:invoke).with("kamal:cli:accessory:boot", [ "all" ], invoke_options) Kamal::Cli::Main.any_instance.expects(:deploy) @@ -24,7 +22,6 @@ class CliMainTest < CliTestCase Kamal::Cli::Main.any_instance.expects(:invoke).with("kamal:cli:server:bootstrap", [], invoke_options) Kamal::Cli::Main.any_instance.expects(:invoke).with("kamal:cli:env:push", [], invoke_options) - Kamal::Cli::Main.any_instance.expects(:invoke).with("kamal:cli:main:envify", [], invoke_options) Kamal::Cli::Main.any_instance.expects(:invoke).with("kamal:cli:accessory:boot", [ "all" ], invoke_options) # deploy Kamal::Cli::Main.any_instance.expects(:invoke).with("kamal:cli:registry:login", [], invoke_options.merge(skip_local: true)) @@ -438,50 +435,6 @@ class CliMainTest < CliTestCase end end - test "envify" do - with_test_env_files("env.erb": "HELLO=<%= 'world' %>") do - run_command("envify") - assert_equal("HELLO=world", File.read(".kamal/env")) - end - end - - test "envify with blank line trimming" do - file = <<~EOF - HELLO=<%= 'world' %> - <% if true -%> - KEY=value - <% end -%> - EOF - - with_test_env_files("env.erb": file) do - run_command("envify") - assert_equal("HELLO=world\nKEY=value\n", File.read(".kamal/env")) - end - end - - test "envify with destination" do - with_test_env_files("env.world.erb": "HELLO=<%= 'world' %>") do - run_command("envify", "-d", "world", config_file: "deploy_for_dest") - assert_equal "HELLO=world", File.read(".kamal/env.world") - end - end - - test "envify with skip_push" do - Pathname.any_instance.expects(:exist?).returns(true).times(2) - File.expects(:read).with(".kamal/env.erb").returns("HELLO=<%= 'world' %>") - File.expects(:write).with(".kamal/env", "HELLO=world", perm: 0600) - - Kamal::Cli::Main.any_instance.expects(:invoke).with("kamal:cli:env:push").never - run_command("envify", "--skip-push") - end - - test "envify with clean env" do - with_test_env_files("env": "HELLO=already", "env.erb": "HELLO=<%= ENV.fetch 'HELLO', 'never' %>") do - run_command("envify", "--skip-push") - assert_equal "HELLO=never", File.read(".kamal/env") - end - end - test "remove with confirmation" do run_command("remove", "-y", config_file: "deploy_with_accessories").tap do |output| assert_match /docker container stop traefik/, output diff --git a/test/integration/accessory_test.rb b/test/integration/accessory_test.rb index 8c23703b3..bc2fb3788 100644 --- a/test/integration/accessory_test.rb +++ b/test/integration/accessory_test.rb @@ -2,8 +2,6 @@ class AccessoryTest < IntegrationTest test "boot, stop, start, restart, logs, remove" do - kamal :envify - kamal :accessory, :boot, :busybox assert_accessory_running :busybox @@ -21,8 +19,6 @@ class AccessoryTest < IntegrationTest kamal :accessory, :remove, :busybox, "-y" assert_accessory_not_running :busybox - - kamal :env, :delete end private diff --git a/test/integration/app_test.rb b/test/integration/app_test.rb index 9824ce0d2..b7dcdc343 100644 --- a/test/integration/app_test.rb +++ b/test/integration/app_test.rb @@ -2,8 +2,6 @@ class AppTest < IntegrationTest test "stop, start, boot, logs, images, containers, exec, remove" do - kamal :envify - kamal :deploy assert_app_is_up diff --git a/test/integration/broken_deploy_test.rb b/test/integration/broken_deploy_test.rb index 5ab24f554..77f0ff96a 100644 --- a/test/integration/broken_deploy_test.rb +++ b/test/integration/broken_deploy_test.rb @@ -4,8 +4,6 @@ class BrokenDeployTest < IntegrationTest test "deploying a bad image" do @app = "app_with_roles" - kamal :envify - first_version = latest_app_version kamal :deploy diff --git a/test/integration/lock_test.rb b/test/integration/lock_test.rb index db086251c..4a53ba519 100644 --- a/test/integration/lock_test.rb +++ b/test/integration/lock_test.rb @@ -2,8 +2,6 @@ class LockTest < IntegrationTest test "acquire, release, status" do - kamal :envify - kamal :lock, :acquire, "-m 'Integration Tests'" status = kamal :lock, :status, capture: true diff --git a/test/integration/main_test.rb b/test/integration/main_test.rb index 5525faa59..79e39a6b9 100644 --- a/test/integration/main_test.rb +++ b/test/integration/main_test.rb @@ -1,8 +1,7 @@ require_relative "integration_test" class MainTest < IntegrationTest - test "envify, deploy, redeploy, rollback, details and audit" do - kamal :envify + test "deploy, redeploy, rollback, details and audit" do assert_env_files remove_local_env_file @@ -37,16 +36,11 @@ class MainTest < IntegrationTest audit = kamal :audit, capture: true assert_match /Booted app version #{first_version}.*Booted app version #{second_version}.*Booted app version #{first_version}.*/m, audit - - kamal :env, :delete - assert_no_remote_env_file end test "app with roles" do @app = "app_with_roles" - kamal :envify - version = latest_app_version assert_app_is_down @@ -103,7 +97,6 @@ class MainTest < IntegrationTest kamal :remove, "-y" assert_no_images_or_containers - kamal :envify kamal :setup assert_images_and_containers @@ -113,7 +106,7 @@ class MainTest < IntegrationTest private def assert_local_env_file(contents) - assert_equal contents, deployer_exec("cat .kamal/env", capture: true) + assert_equal contents, deployer_exec("cat .kamal/secrets", capture: true) end def assert_envs(version:) @@ -143,15 +136,15 @@ def assert_env_files end def remove_local_env_file - deployer_exec("rm .kamal/env") + deployer_exec("rm .kamal/secrets") end def assert_remote_env_file(contents, vm:) - assert_equal contents, docker_compose("exec #{vm} cat /root/.kamal/env/roles/app-web.env", capture: true) + assert_equal contents, docker_compose("exec #{vm} cat /root/.kamal/secrets/roles/app-web.env", capture: true) end def assert_no_remote_env_file - assert_equal "nofile", docker_compose("exec vm1 stat /root/.kamal/env/roles/app-web.env 2> /dev/null || echo nofile", capture: true) + assert_equal "nofile", docker_compose("exec vm1 stat /root/.kamal/secrets/roles/app-web.env 2> /dev/null || echo nofile", capture: true) end def assert_accumulated_assets(*versions) diff --git a/test/integration/traefik_test.rb b/test/integration/traefik_test.rb index d2aa2a97c..48f9ea024 100644 --- a/test/integration/traefik_test.rb +++ b/test/integration/traefik_test.rb @@ -2,8 +2,6 @@ class TraefikTest < IntegrationTest test "boot, reboot, stop, start, restart, logs, remove" do - kamal :envify - kamal :traefik, :boot assert_traefik_running @@ -46,8 +44,6 @@ class TraefikTest < IntegrationTest kamal :traefik, :remove assert_traefik_not_running - - kamal :env, :delete end private