From ff0fb8416fec14108b37e76f3fb38983bca05798 Mon Sep 17 00:00:00 2001 From: Igor Alexandrov Date: Tue, 1 Oct 2024 14:02:19 +0400 Subject: [PATCH 1/4] Added network configuration option to application, proxy and accessory sections --- lib/kamal/commands/accessory.rb | 6 +++--- lib/kamal/commands/app.rb | 2 +- lib/kamal/commands/app/execution.rb | 2 +- lib/kamal/configuration.rb | 9 +++++++++ lib/kamal/configuration/accessory.rb | 10 ++++++++++ 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/lib/kamal/commands/accessory.rb b/lib/kamal/commands/accessory.rb index 0c1b9009..9abb6dfc 100644 --- a/lib/kamal/commands/accessory.rb +++ b/lib/kamal/commands/accessory.rb @@ -1,7 +1,7 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base attr_reader :accessory_config delegate :service_name, :image, :hosts, :port, :files, :directories, :cmd, - :publish_args, :env_args, :volume_args, :label_args, :option_args, + :network_args, :publish_args, :env_args, :volume_args, :label_args, :option_args, :secrets_io, :secrets_path, :env_directory, to: :accessory_config @@ -15,7 +15,7 @@ def run "--name", service_name, "--detach", "--restart", "unless-stopped", - "--network", "kamal", + *network_args, *config.logging_args, *publish_args, *env_args, @@ -64,7 +64,7 @@ def execute_in_new_container(*command, interactive: false) docker :run, ("-it" if interactive), "--rm", - "--network", "kamal", + *network_args, *env_args, *volume_args, image, diff --git a/lib/kamal/commands/app.rb b/lib/kamal/commands/app.rb index 6d8f44c6..56a5656b 100644 --- a/lib/kamal/commands/app.rb +++ b/lib/kamal/commands/app.rb @@ -18,7 +18,7 @@ def run(hostname: nil) "--detach", "--restart unless-stopped", "--name", container_name, - "--network", "kamal", + *config.network_args, *([ "--hostname", hostname ] if hostname), "-e", "KAMAL_CONTAINER_NAME=\"#{container_name}\"", "-e", "KAMAL_VERSION=\"#{config.version}\"", diff --git a/lib/kamal/commands/app/execution.rb b/lib/kamal/commands/app/execution.rb index 4434c26a..5770f7aa 100644 --- a/lib/kamal/commands/app/execution.rb +++ b/lib/kamal/commands/app/execution.rb @@ -11,7 +11,7 @@ def execute_in_new_container(*command, interactive: false, env:) docker :run, ("-it" if interactive), "--rm", - "--network", "kamal", + *config.network_args, *role&.env_args(host), *argumentize("--env", env), *config.volume_args, diff --git a/lib/kamal/configuration.rb b/lib/kamal/configuration.rb index fb997949..97db7e49 100644 --- a/lib/kamal/configuration.rb +++ b/lib/kamal/configuration.rb @@ -17,6 +17,7 @@ class Kamal::Configuration PROXY_MINIMUM_VERSION = "v0.7.0" PROXY_HTTP_PORT = 80 PROXY_HTTPS_PORT = 443 + NETWORK = "kamal" class << self def create_from(config_file:, destination: nil, version: nil) @@ -190,6 +191,10 @@ def logging_args logging.args end + def network_args + argumentize "--network", network + end + def readiness_delay raw_config.readiness_delay || 7 @@ -290,6 +295,10 @@ def to_h end private + def network + raw_config["network"] || NETWORK + end + # Will raise ArgumentError if any required config keys are missing def ensure_destination_if_required if require_destination? && destination.nil? diff --git a/lib/kamal/configuration/accessory.rb b/lib/kamal/configuration/accessory.rb index 804a1502..7aed80ea 100644 --- a/lib/kamal/configuration/accessory.rb +++ b/lib/kamal/configuration/accessory.rb @@ -1,6 +1,8 @@ class Kamal::Configuration::Accessory include Kamal::Configuration::Validation + NETWORK = "kamal" + delegate :argumentize, :optionize, to: Kamal::Utils attr_reader :name, :accessory_config, :env @@ -38,6 +40,10 @@ def port end end + def network_args + argumentize "--network", network + end + def publish_args argumentize "--publish", port if port end @@ -173,4 +179,8 @@ def hosts_from_roles accessory_config["roles"].flat_map { |role| config.role(role).hosts } end end + + def network + accessory_config["network"] || NETWORK + end end From 40ad22e8f359af1ab272f1ee466a57c8c4385b26 Mon Sep 17 00:00:00 2001 From: Igor Alexandrov Date: Tue, 1 Oct 2024 14:40:34 +0400 Subject: [PATCH 2/4] Added network_args to proxy configuration --- lib/kamal/commands/proxy.rb | 2 +- lib/kamal/configuration/proxy.rb | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/kamal/commands/proxy.rb b/lib/kamal/commands/proxy.rb index acff3dbd..3399531f 100644 --- a/lib/kamal/commands/proxy.rb +++ b/lib/kamal/commands/proxy.rb @@ -4,7 +4,7 @@ class Kamal::Commands::Proxy < Kamal::Commands::Base def run docker :run, "--name", container_name, - "--network", "kamal", + *config.network_args, "--detach", "--restart", "unless-stopped", "--volume", "kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy", diff --git a/lib/kamal/configuration/proxy.rb b/lib/kamal/configuration/proxy.rb index ad8c6e5e..d8e5d70b 100644 --- a/lib/kamal/configuration/proxy.rb +++ b/lib/kamal/configuration/proxy.rb @@ -3,6 +3,7 @@ class Kamal::Configuration::Proxy DEFAULT_LOG_REQUEST_HEADERS = [ "Cache-Control", "Last-Modified", "User-Agent" ] CONTAINER_NAME = "kamal-proxy" + NETWORK = "kamal" delegate :argumentize, :optionize, to: Kamal::Utils @@ -51,6 +52,10 @@ def deploy_command_args(target:) optionize ({ target: "#{target}:#{app_port}" }).merge(deploy_options) end + def network_args + argumentize "--network", network + end + def merge(other) self.class.new config: config, proxy_config: proxy_config.deep_merge(other.proxy_config) end @@ -59,4 +64,8 @@ def merge(other) def seconds_duration(value) value ? "#{value}s" : nil end + + def network + proxy_config["network"] || NETWORK + end end From 95f82d13ed319673d32dd82c0d4b19c2768f266e Mon Sep 17 00:00:00 2001 From: Igor Alexandrov Date: Tue, 1 Oct 2024 20:24:28 +0400 Subject: [PATCH 3/4] Added tests for network configuration option --- lib/kamal/configuration/docs/accessory.yml | 8 ++++++++ lib/kamal/configuration/docs/configuration.yml | 7 +++++++ lib/kamal/configuration/docs/proxy.yml | 7 +++++++ test/configuration/accessory_test.rb | 9 +++++++++ test/configuration/proxy_test.rb | 9 +++++++++ test/configuration_test.rb | 9 +++++++++ 6 files changed, 49 insertions(+) diff --git a/lib/kamal/configuration/docs/accessory.yml b/lib/kamal/configuration/docs/accessory.yml index 86d49b77..e77bf754 100644 --- a/lib/kamal/configuration/docs/accessory.yml +++ b/lib/kamal/configuration/docs/accessory.yml @@ -90,3 +90,11 @@ accessories: # They are not created or copied before mounting: volumes: - /path/to/mysql-logs:/var/log/mysql + + # Network + # + # The network the accessory will be attached to. + # + # Defaults to kamal: + network: custom + diff --git a/lib/kamal/configuration/docs/configuration.yml b/lib/kamal/configuration/docs/configuration.yml index 6b059346..b59394a3 100644 --- a/lib/kamal/configuration/docs/configuration.yml +++ b/lib/kamal/configuration/docs/configuration.yml @@ -176,3 +176,10 @@ logging: # Alias configuration, see kamal docs alias: aliases: ... + +# Network +# +# The network the application will be attached to. +# +# Defaults to kamal: +network: custom diff --git a/lib/kamal/configuration/docs/proxy.yml b/lib/kamal/configuration/docs/proxy.yml index 76ec3e41..0af14826 100644 --- a/lib/kamal/configuration/docs/proxy.yml +++ b/lib/kamal/configuration/docs/proxy.yml @@ -103,3 +103,10 @@ proxy: # By default, kamal-proxy will not forward the headers if the `ssl` option is set to `true`, and # will forward them if it is set to `false`. forward_headers: true + + # Network + # + # The network the proxy container will be attached to. + # + # Defaults to kamal: + network: custom diff --git a/test/configuration/accessory_test.rb b/test/configuration/accessory_test.rb index 2615dab6..f5220902 100644 --- a/test/configuration/accessory_test.rb +++ b/test/configuration/accessory_test.rb @@ -152,4 +152,13 @@ class ConfigurationAccessoryTest < ActiveSupport::TestCase test "options" do assert_equal [ "--cpus", "\"4\"", "--memory", "\"2GB\"" ], @config.accessory(:redis).option_args end + + test "network_args default" do + assert_equal [ "--network", "kamal" ], @config.accessory(:mysql).network_args + end + + test "network_args with configured options" do + @deploy[:accessories]["mysql"]["network"] = "database" + assert_equal [ "--network", "database" ], @config.accessory(:mysql).network_args + end end diff --git a/test/configuration/proxy_test.rb b/test/configuration/proxy_test.rb index 1bdfaeab..d1796b4d 100644 --- a/test/configuration/proxy_test.rb +++ b/test/configuration/proxy_test.rb @@ -39,6 +39,15 @@ class ConfigurationProxyTest < ActiveSupport::TestCase assert_not config.proxy.deploy_options.has_key?(:tls) end + test "network_args defaults" do + assert_equal [ "--network", "kamal" ], config.proxy.network_args + end + + test "network_args with configured options" do + @deploy[:proxy] = { "network" => "example" } + assert_equal [ "--network", "example" ], config.proxy.network_args + end + private def config Kamal::Configuration.new(@deploy) diff --git a/test/configuration_test.rb b/test/configuration_test.rb index 21709180..63bd37da 100644 --- a/test/configuration_test.rb +++ b/test/configuration_test.rb @@ -217,6 +217,15 @@ class ConfigurationTest < ActiveSupport::TestCase assert_equal [ "--log-driver", "\"local\"", "--log-opt", "max-size=\"100m\"", "--log-opt", "max-file=\"5\"" ], config.logging_args end + test "network_args default" do + assert_equal [ "--network", "kamal" ], @config.network_args + end + + test "network_args with configured options" do + config = Kamal::Configuration.new(@deploy.tap { |c| c.merge!(network: "custom") }) + assert_equal [ "--network", "custom" ], config.network_args + end + test "erb evaluation of yml config" do config = Kamal::Configuration.create_from config_file: Pathname.new(File.expand_path("fixtures/deploy.erb.yml", __dir__)) assert_equal "my-user", config.registry.username From c186b43d127e3388cf2a3f5b7122a6f0decf7032 Mon Sep 17 00:00:00 2001 From: Igor Alexandrov Date: Tue, 1 Oct 2024 20:41:36 +0400 Subject: [PATCH 4/4] Added command tests --- test/commands/accessory_test.rb | 8 ++++++++ test/commands/app_test.rb | 8 ++++++++ test/commands/proxy_test.rb | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/test/commands/accessory_test.rb b/test/commands/accessory_test.rb index f3d71ffd..1befd9e6 100644 --- a/test/commands/accessory_test.rb +++ b/test/commands/accessory_test.rb @@ -71,6 +71,14 @@ class CommandsAccessoryTest < ActiveSupport::TestCase new_command(:busybox).run.join(" ") end + test "run in custom network" do + @config[:accessories]["mysql"]["network"] = "custom" + + assert_equal \ + "docker run --name app-mysql --detach --restart unless-stopped --network custom --log-opt max-size=\"10m\" --publish 3306:3306 --env MYSQL_ROOT_HOST=\"%\" --env-file .kamal/apps/app/env/accessories/mysql.env --label service=\"app-mysql\" private.registry/mysql:8.0", + new_command(:mysql).run.join(" ") + end + test "start" do assert_equal \ "docker container start app-mysql", diff --git a/test/commands/app_test.rb b/test/commands/app_test.rb index aabe39c1..561bae3a 100644 --- a/test/commands/app_test.rb +++ b/test/commands/app_test.rb @@ -64,6 +64,14 @@ class CommandsAppTest < ActiveSupport::TestCase new_command.run.join(" ") end + test "run in custom network" do + @config[:network] = "custom" + + assert_equal \ + "docker run --detach --restart unless-stopped --name app-web-999 --network custom -e KAMAL_CONTAINER_NAME=\"app-web-999\" -e KAMAL_VERSION=\"999\" --env-file .kamal/apps/app/env/roles/web.env --log-opt max-size=\"10m\" --label service=\"app\" --label role=\"web\" --label destination dhh/app:999", + new_command.run.join(" ") + end + test "start" do assert_equal \ "docker start app-web-999", diff --git a/test/commands/proxy_test.rb b/test/commands/proxy_test.rb index 4af78533..ddf14f66 100644 --- a/test/commands/proxy_test.rb +++ b/test/commands/proxy_test.rb @@ -27,6 +27,14 @@ class CommandsProxyTest < ActiveSupport::TestCase new_command.run.join(" ") end + test "run in custom network" do + @config[:network] = "custom" + + assert_equal \ + "docker run --name kamal-proxy --network custom --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy $(cat .kamal/proxy/options || echo \"--publish 80:80 --publish 443:443\") basecamp/kamal-proxy:#{Kamal::Configuration::PROXY_MINIMUM_VERSION}", + new_command.run.join(" ") + end + test "proxy start" do assert_equal \ "docker container start kamal-proxy",