Skip to content

Commit 58e23f9

Browse files
authored
Merge pull request #1459 from basecamp/xargs-proxy-options
Use xargs to handle spaces in proxy options
2 parents a028262 + 7fa27fa commit 58e23f9

File tree

5 files changed

+41
-20
lines changed

5 files changed

+41
-20
lines changed

lib/kamal/commands/proxy.rb

+9-9
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ class Kamal::Commands::Proxy < Kamal::Commands::Base
22
delegate :argumentize, :optionize, to: Kamal::Utils
33

44
def run
5-
docker :run,
6-
"--name", container_name,
7-
"--network", "kamal",
8-
"--detach",
9-
"--restart", "unless-stopped",
10-
"--volume", "kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy",
11-
"\$\(#{get_boot_options.join(" ")}\)",
12-
config.proxy_image
5+
pipe \
6+
[ :echo, "\$\(#{get_boot_options.join(" ")}\) #{config.proxy_image}" ],
7+
xargs(docker(:run,
8+
"--name", container_name,
9+
"--network", "kamal",
10+
"--detach",
11+
"--restart", "unless-stopped",
12+
"--volume", "kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy"))
1313
end
1414

1515
def start
@@ -73,7 +73,7 @@ def remove_proxy_directory
7373
end
7474

7575
def get_boot_options
76-
combine [ :cat, config.proxy_options_file ], [ :echo, "\"#{config.proxy_options_default.join(" ")}\"" ], by: "||"
76+
combine [ :cat, config.proxy_options_file, "2>", "/dev/null" ], [ :echo, "\"#{config.proxy_options_default.join(" ")}\"" ], by: "||"
7777
end
7878

7979
def reset_boot_options

test/cli/proxy_test.rb

+7-7
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ class CliProxyTest < CliTestCase
44
test "boot" do
55
run_command("boot").tap do |output|
66
assert_match "docker login", output
7-
assert_match "docker run --name kamal-proxy --network kamal --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 --log-opt max-size=10m\") #{KAMAL.config.proxy_image}", output
7+
assert_match "echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") basecamp/kamal-proxy:#{Kamal::Configuration::PROXY_MINIMUM_VERSION} | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy", output
88
end
99
end
1010

@@ -18,7 +18,7 @@ class CliProxyTest < CliTestCase
1818
exception = assert_raises do
1919
run_command("boot").tap do |output|
2020
assert_match "docker login", output
21-
assert_match "docker run --name kamal-proxy --network kamal --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 --log-opt max-size=10m\") #{KAMAL.config.proxy_image}", output
21+
assert_match "echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") basecamp/kamal-proxy:#{Kamal::Configuration::PROXY_MINIMUM_VERSION} | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy", output
2222
end
2323
end
2424

@@ -36,7 +36,7 @@ class CliProxyTest < CliTestCase
3636

3737
run_command("boot").tap do |output|
3838
assert_match "docker login", output
39-
assert_match "docker container start kamal-proxy || docker run --name kamal-proxy --network kamal --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 --log-opt max-size=10m\") #{KAMAL.config.proxy_image}", output
39+
assert_match "docker container start kamal-proxy || echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") basecamp/kamal-proxy:#{Kamal::Configuration::PROXY_MINIMUM_VERSION} | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy", output
4040
end
4141
ensure
4242
Thread.report_on_exception = false
@@ -56,12 +56,12 @@ class CliProxyTest < CliTestCase
5656
run_command("reboot", "-y").tap do |output|
5757
assert_match "docker container stop kamal-proxy on 1.1.1.1", output
5858
assert_match "docker container prune --force --filter label=org.opencontainers.image.title=kamal-proxy on 1.1.1.1", output
59-
assert_match "docker run --name kamal-proxy --network kamal --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 --log-opt max-size=10m\") #{KAMAL.config.proxy_image} on 1.1.1.1", output
59+
assert_match "echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") basecamp/kamal-proxy:#{Kamal::Configuration::PROXY_MINIMUM_VERSION} | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy on 1.1.1.1", output
6060
assert_match "docker exec kamal-proxy kamal-proxy deploy app-web --target=\"abcdefabcdef:80\" --deploy-timeout=\"6s\" --drain-timeout=\"30s\" --buffer-requests --buffer-responses --log-request-header=\"Cache-Control\" --log-request-header=\"Last-Modified\" --log-request-header=\"User-Agent\" on 1.1.1.1", output
6161

6262
assert_match "docker container stop kamal-proxy on 1.1.1.2", output
6363
assert_match "docker container prune --force --filter label=org.opencontainers.image.title=kamal-proxy on 1.1.1.2", output
64-
assert_match "docker run --name kamal-proxy --network kamal --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 --log-opt max-size=10m\") #{KAMAL.config.proxy_image} on 1.1.1.2", output
64+
assert_match "echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") basecamp/kamal-proxy:#{Kamal::Configuration::PROXY_MINIMUM_VERSION} | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy on 1.1.1.2", output
6565
assert_match "docker exec kamal-proxy kamal-proxy deploy app-web --target=\"abcdefabcdef:80\" --deploy-timeout=\"6s\" --drain-timeout=\"30s\" --buffer-requests --buffer-responses --log-request-header=\"Cache-Control\" --log-request-header=\"Last-Modified\" --log-request-header=\"User-Agent\" on 1.1.1.2", output
6666
end
6767
end
@@ -196,7 +196,7 @@ class CliProxyTest < CliTestCase
196196
assert_match "/usr/bin/env mkdir -p .kamal", output
197197
assert_match "docker network create kamal", output
198198
assert_match "docker login -u [REDACTED] -p [REDACTED]", output
199-
assert_match "docker container start kamal-proxy || docker run --name kamal-proxy --network kamal --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 --log-opt max-size=10m\") basecamp/kamal-proxy:#{Kamal::Configuration::PROXY_MINIMUM_VERSION}", output
199+
assert_match "docker container start kamal-proxy || echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") basecamp/kamal-proxy:#{Kamal::Configuration::PROXY_MINIMUM_VERSION} | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy", output
200200
assert_match "/usr/bin/env mkdir -p .kamal", output
201201
assert_match %r{docker rename app-web-latest app-web-latest_replaced_.*}, output
202202
assert_match "/usr/bin/env mkdir -p .kamal/apps/app/env/roles", output
@@ -316,7 +316,7 @@ class CliProxyTest < CliTestCase
316316

317317
test "boot_config get" do
318318
SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info)
319-
.with(:cat, ".kamal/proxy/options", "||", :echo, "\"--publish 80:80 --publish 443:443 --log-opt max-size=10m\"")
319+
.with(:cat, ".kamal/proxy/options", "2>", "/dev/null", "||", :echo, "\"--publish 80:80 --publish 443:443 --log-opt max-size=10m\"")
320320
.returns("--publish 80:80 --publish 8443:443 --label=foo=bar")
321321
.twice
322322

test/commands/proxy_test.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ class CommandsProxyTest < ActiveSupport::TestCase
1515

1616
test "run" do
1717
assert_equal \
18-
"docker run --name kamal-proxy --network kamal --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 --log-opt max-size=10m\") basecamp/kamal-proxy:#{Kamal::Configuration::PROXY_MINIMUM_VERSION}",
18+
"echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") basecamp/kamal-proxy:#{Kamal::Configuration::PROXY_MINIMUM_VERSION} | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy",
1919
new_command.run.join(" ")
2020
end
2121

2222
test "run without configuration" do
2323
@config.delete(:proxy)
2424

2525
assert_equal \
26-
"docker run --name kamal-proxy --network kamal --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 --log-opt max-size=10m\") basecamp/kamal-proxy:#{Kamal::Configuration::PROXY_MINIMUM_VERSION}",
26+
"echo $(cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\") basecamp/kamal-proxy:#{Kamal::Configuration::PROXY_MINIMUM_VERSION} | xargs docker run --name kamal-proxy --network kamal --detach --restart unless-stopped --volume kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy",
2727
new_command.run.join(" ")
2828
end
2929

@@ -113,7 +113,7 @@ class CommandsProxyTest < ActiveSupport::TestCase
113113

114114
test "get_boot_options" do
115115
assert_equal \
116-
"cat .kamal/proxy/options || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\"",
116+
"cat .kamal/proxy/options 2> /dev/null || echo \"--publish 80:80 --publish 443:443 --log-opt max-size=10m\"",
117117
new_command.get_boot_options.join(" ")
118118
end
119119

Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
kamal proxy boot_config set --publish false \
22
--docker_options label=traefik.http.services.kamal_proxy.loadbalancer.server.scheme=http \
3-
label=traefik.http.routers.kamal_proxy.rule=PathPrefix\(\`/\`\)
3+
label=traefik.http.routers.kamal_proxy.rule=PathPrefix\(\`/\`\) \
4+
sysctl=net.ipv4.ip_local_port_range=\"10000\ 60999\"

test/integration/proxy_test.rb

+20
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,27 @@ class ProxyTest < IntegrationTest
4646
logs = kamal :proxy, :logs, capture: true
4747
assert_match /No previous state to restore/, logs
4848

49+
kamal :proxy, :boot_config, :set, "--docker-options='sysctl net.ipv4.ip_local_port_range=\"10000 60999\"'"
50+
assert_docker_options_in_file
51+
52+
kamal :proxy, :reboot, "-y"
53+
assert_docker_options_in_container
54+
55+
kamal :proxy, :boot_config, :reset
56+
4957
kamal :proxy, :remove
5058
assert_proxy_not_running
5159
end
60+
61+
private
62+
def assert_docker_options_in_file
63+
boot_config = kamal :proxy, :boot_config, :get, capture: true
64+
assert_match "Host vm1: --publish 80:80 --publish 443:443 --log-opt max-size=10m --sysctl net.ipv4.ip_local_port_range=\"10000 60999\"", boot_config
65+
end
66+
67+
def assert_docker_options_in_container
68+
assert_equal \
69+
"{\"net.ipv4.ip_local_port_range\":\"10000 60999\"}",
70+
docker_compose("exec vm1 docker inspect --format '{{ json .HostConfig.Sysctls }}' kamal-proxy", capture: true).strip
71+
end
5272
end

0 commit comments

Comments
 (0)