dash 3.1.5 → 3.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +26 -6
- data/bin/dash +2 -2
- data/lib/{kamal → dash}/cli/accessory.rb +24 -24
- data/lib/dash/cli/alias/command.rb +10 -0
- data/lib/{kamal → dash}/cli/app/assets.rb +2 -2
- data/lib/{kamal → dash}/cli/app/boot.rb +15 -15
- data/lib/{kamal → dash}/cli/app/error_pages.rb +6 -6
- data/lib/{kamal → dash}/cli/app/rollout_boot.rb +6 -6
- data/lib/{kamal → dash}/cli/app/ssl_certificates.rb +3 -3
- data/lib/{kamal → dash}/cli/app.rb +87 -87
- data/lib/{kamal → dash}/cli/base.rb +73 -49
- data/lib/dash/cli/build/clone.rb +59 -0
- data/lib/{kamal → dash}/cli/build/port_forwarding.rb +1 -1
- data/lib/{kamal → dash}/cli/build.rb +45 -45
- data/lib/{kamal → dash}/cli/doctor/config_checks.rb +3 -3
- data/lib/{kamal → dash}/cli/doctor/endpoint_checks.rb +25 -7
- data/lib/{kamal → dash}/cli/doctor/host_checks.rb +23 -23
- data/lib/{kamal → dash}/cli/doctor.rb +9 -9
- data/lib/{kamal → dash}/cli/healthcheck/barrier.rb +2 -2
- data/lib/{kamal → dash}/cli/healthcheck/drift_error.rb +2 -2
- data/lib/dash/cli/healthcheck/error.rb +2 -0
- data/lib/{kamal → dash}/cli/healthcheck/poller.rb +7 -7
- data/lib/{kamal → dash}/cli/lock.rb +1 -1
- data/lib/dash/cli/main/migrate.rb +77 -0
- data/lib/{kamal → dash}/cli/main.rb +87 -76
- data/lib/{kamal → dash}/cli/proxy/drift.rb +4 -4
- data/lib/{kamal → dash}/cli/proxy/loadbalancer_claim.rb +6 -6
- data/lib/{kamal → dash}/cli/proxy/loadbalancer_reboot.rb +23 -23
- data/lib/{kamal → dash}/cli/proxy/reboot.rb +15 -15
- data/lib/{kamal → dash}/cli/proxy.rb +172 -160
- data/lib/{kamal → dash}/cli/prune.rb +10 -10
- data/lib/{kamal → dash}/cli/registry.rb +13 -13
- data/lib/{kamal → dash}/cli/secrets.rb +3 -3
- data/lib/{kamal → dash}/cli/server.rb +15 -15
- data/lib/{kamal → dash}/cli/templates/deploy.yml +6 -6
- data/lib/dash/cli/templates/sample_hooks/docker-setup.sample +3 -0
- data/lib/dash/cli/templates/sample_hooks/post-app-boot.sample +3 -0
- data/lib/dash/cli/templates/sample_hooks/post-app-stop.sample +9 -0
- data/lib/dash/cli/templates/sample_hooks/post-deploy.sample +14 -0
- data/lib/dash/cli/templates/sample_hooks/post-proxy-deploy.sample +3 -0
- data/lib/dash/cli/templates/sample_hooks/post-proxy-reboot.sample +3 -0
- data/lib/dash/cli/templates/sample_hooks/pre-app-boot.sample +3 -0
- data/lib/{kamal → dash}/cli/templates/sample_hooks/pre-app-stop.sample +2 -2
- data/lib/{kamal → dash}/cli/templates/sample_hooks/pre-build.sample +8 -8
- data/lib/{kamal → dash}/cli/templates/sample_hooks/pre-connect.sample +8 -8
- data/lib/{kamal → dash}/cli/templates/sample_hooks/pre-deploy.sample +9 -9
- data/lib/dash/cli/templates/sample_hooks/pre-proxy-deploy.sample +3 -0
- data/lib/dash/cli/templates/sample_hooks/pre-proxy-reboot.sample +3 -0
- data/lib/dash/cli/templates/secrets +22 -0
- data/lib/{kamal → dash}/cli.rb +2 -2
- data/lib/{kamal → dash}/commander/specifics.rb +2 -2
- data/lib/{kamal → dash}/commander.rb +31 -23
- data/lib/{kamal → dash}/commands/accessory/proxy.rb +1 -1
- data/lib/{kamal → dash}/commands/accessory.rb +2 -2
- data/lib/{kamal → dash}/commands/app/assets.rb +1 -1
- data/lib/{kamal → dash}/commands/app/containers.rb +1 -1
- data/lib/{kamal → dash}/commands/app/error_pages.rb +2 -2
- data/lib/{kamal → dash}/commands/app/execution.rb +1 -1
- data/lib/{kamal → dash}/commands/app/images.rb +1 -1
- data/lib/{kamal → dash}/commands/app/logging.rb +1 -1
- data/lib/{kamal → dash}/commands/app/proxy.rb +1 -1
- data/lib/{kamal → dash}/commands/app.rb +1 -1
- data/lib/{kamal → dash}/commands/auditor.rb +3 -7
- data/lib/{kamal → dash}/commands/base.rb +39 -3
- data/lib/{kamal → dash}/commands/builder/base.rb +2 -2
- data/lib/{kamal → dash}/commands/builder/clone.rb +3 -3
- data/lib/{kamal → dash}/commands/builder/cloud.rb +1 -1
- data/lib/{kamal → dash}/commands/builder/hybrid.rb +1 -1
- data/lib/{kamal → dash}/commands/builder/local.rb +1 -1
- data/lib/{kamal → dash}/commands/builder/pack.rb +1 -1
- data/lib/{kamal → dash}/commands/builder/remote.rb +1 -1
- data/lib/{kamal → dash}/commands/builder.rb +7 -7
- data/lib/{kamal → dash}/commands/docker.rb +1 -1
- data/lib/{kamal → dash}/commands/hook.rb +1 -1
- data/lib/{kamal → dash}/commands/loadbalancer.rb +9 -8
- data/lib/{kamal → dash}/commands/lock.rb +2 -2
- data/lib/{kamal → dash}/commands/proxy/cert_transfer.rb +3 -3
- data/lib/{kamal → dash}/commands/proxy.rb +20 -10
- data/lib/{kamal → dash}/commands/prune.rb +1 -1
- data/lib/dash/commands/registry.rb +44 -0
- data/lib/{kamal → dash}/commands/server.rb +1 -5
- data/lib/dash/commands.rb +2 -0
- data/lib/{kamal → dash}/configuration/accessory.rb +11 -11
- data/lib/{kamal → dash}/configuration/alias.rb +3 -3
- data/lib/{kamal → dash}/configuration/boot.rb +2 -2
- data/lib/{kamal → dash}/configuration/builder.rb +7 -7
- data/lib/{kamal → dash}/configuration/docs/accessory.yml +6 -6
- data/lib/{kamal → dash}/configuration/docs/alias.yml +2 -2
- data/lib/{kamal → dash}/configuration/docs/boot.yml +1 -1
- data/lib/{kamal → dash}/configuration/docs/builder.yml +3 -3
- data/lib/{kamal → dash}/configuration/docs/configuration.yml +25 -18
- data/lib/{kamal → dash}/configuration/docs/env.yml +17 -17
- data/lib/{kamal → dash}/configuration/docs/proxy.yml +53 -30
- data/lib/{kamal → dash}/configuration/docs/registry.yml +6 -6
- data/lib/{kamal → dash}/configuration/docs/role.yml +1 -1
- data/lib/{kamal → dash}/configuration/docs/servers.yml +2 -2
- data/lib/{kamal → dash}/configuration/env/tag.rb +2 -2
- data/lib/{kamal → dash}/configuration/env.rb +5 -5
- data/lib/{kamal → dash}/configuration/loadbalancer.rb +3 -3
- data/lib/{kamal → dash}/configuration/logging.rb +3 -3
- data/lib/{kamal → dash}/configuration/output.rb +4 -4
- data/lib/{kamal → dash}/configuration/proxy/acme.rb +4 -3
- data/lib/{kamal → dash}/configuration/proxy/boot.rb +10 -8
- data/lib/{kamal → dash}/configuration/proxy/run.rb +14 -14
- data/lib/{kamal → dash}/configuration/proxy.rb +16 -16
- data/lib/{kamal → dash}/configuration/registry.rb +3 -3
- data/lib/{kamal → dash}/configuration/role/healthcheck.rb +3 -3
- data/lib/{kamal → dash}/configuration/role.rb +13 -13
- data/lib/{kamal → dash}/configuration/servers.rb +4 -4
- data/lib/{kamal → dash}/configuration/ssh.rb +3 -3
- data/lib/{kamal → dash}/configuration/sshkit.rb +2 -2
- data/lib/{kamal → dash}/configuration/validation.rb +2 -2
- data/lib/{kamal → dash}/configuration/validator/accessory.rb +1 -1
- data/lib/{kamal → dash}/configuration/validator/alias.rb +2 -2
- data/lib/{kamal → dash}/configuration/validator/builder.rb +1 -1
- data/lib/dash/configuration/validator/configuration.rb +6 -0
- data/lib/{kamal → dash}/configuration/validator/env.rb +2 -2
- data/lib/{kamal → dash}/configuration/validator/proxy.rb +8 -8
- data/lib/{kamal → dash}/configuration/validator/registry.rb +1 -1
- data/lib/{kamal → dash}/configuration/validator/role.rb +1 -1
- data/lib/{kamal → dash}/configuration/validator/servers.rb +1 -1
- data/lib/{kamal → dash}/configuration/validator.rb +4 -4
- data/lib/{kamal → dash}/configuration/volume.rb +2 -2
- data/lib/{kamal → dash}/configuration.rb +40 -30
- data/lib/{kamal → dash}/docker.rb +1 -1
- data/lib/{kamal → dash}/env_file.rb +1 -1
- data/lib/{kamal → dash}/git.rb +1 -1
- data/lib/{kamal → dash}/otel_shipper.rb +3 -3
- data/lib/{kamal → dash}/output/base_logger.rb +1 -1
- data/lib/{kamal → dash}/output/file_logger.rb +1 -1
- data/lib/{kamal → dash}/output/formatter.rb +1 -1
- data/lib/{kamal → dash}/output/otel_logger.rb +3 -3
- data/lib/dash/project_directory.rb +28 -0
- data/lib/{kamal → dash}/secrets/adapters/aws_secrets_manager.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters/base.rb +2 -2
- data/lib/{kamal → dash}/secrets/adapters/bitwarden.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters/bitwarden_secrets_manager.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters/doppler.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters/enpass.rb +3 -3
- data/lib/{kamal → dash}/secrets/adapters/gcp_secret_manager.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters/last_pass.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters/one_password.rb +2 -2
- data/lib/{kamal → dash}/secrets/adapters/passbolt.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters/test.rb +1 -1
- data/lib/{kamal → dash}/secrets/adapters.rb +2 -2
- data/lib/{kamal → dash}/secrets/dotenv/inline_command_substitution.rb +5 -3
- data/lib/{kamal → dash}/secrets.rb +6 -6
- data/lib/{kamal → dash}/tags.rb +8 -3
- data/lib/{kamal → dash}/utils/sensitive.rb +1 -1
- data/lib/{kamal → dash}/utils.rb +15 -5
- data/lib/dash/version.rb +3 -0
- data/lib/{kamal.rb → dash.rb} +5 -5
- metadata +171 -216
- data/bin/kamal +0 -18
- data/lib/kamal/cli/alias/command.rb +0 -10
- data/lib/kamal/cli/build/clone.rb +0 -59
- data/lib/kamal/cli/healthcheck/error.rb +0 -2
- data/lib/kamal/cli/templates/sample_hooks/docker-setup.sample +0 -3
- data/lib/kamal/cli/templates/sample_hooks/post-app-boot.sample +0 -3
- data/lib/kamal/cli/templates/sample_hooks/post-app-stop.sample +0 -9
- data/lib/kamal/cli/templates/sample_hooks/post-deploy.sample +0 -14
- data/lib/kamal/cli/templates/sample_hooks/post-proxy-deploy.sample +0 -3
- data/lib/kamal/cli/templates/sample_hooks/post-proxy-reboot.sample +0 -3
- data/lib/kamal/cli/templates/sample_hooks/pre-app-boot.sample +0 -3
- data/lib/kamal/cli/templates/sample_hooks/pre-proxy-deploy.sample +0 -3
- data/lib/kamal/cli/templates/sample_hooks/pre-proxy-reboot.sample +0 -3
- data/lib/kamal/cli/templates/secrets +0 -22
- data/lib/kamal/commands/registry.rb +0 -38
- data/lib/kamal/commands.rb +0 -2
- data/lib/kamal/configuration/validator/configuration.rb +0 -6
- data/lib/kamal/version.rb +0 -3
- /data/lib/{kamal → dash}/configuration/docs/logging.yml +0 -0
- /data/lib/{kamal → dash}/configuration/docs/output.yml +0 -0
- /data/lib/{kamal → dash}/configuration/docs/ssh.yml +0 -0
- /data/lib/{kamal → dash}/configuration/docs/sshkit.yml +0 -0
- /data/lib/{kamal → dash}/sshkit_with_ext.rb +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class Dash::Configuration::Loadbalancer < Dash::Configuration::Proxy
|
|
2
2
|
CONTAINER_NAME = "load-balancer".freeze
|
|
3
3
|
SHARED_CONTAINER_NAME = "kamal-proxy".freeze
|
|
4
4
|
|
|
@@ -40,7 +40,7 @@ class Kamal::Configuration::Loadbalancer < Kamal::Configuration::Proxy
|
|
|
40
40
|
# mount and the run command) to boot from, so fall back to an empty config
|
|
41
41
|
# rather than to nil.
|
|
42
42
|
def run
|
|
43
|
-
@run ||=
|
|
43
|
+
@run ||= Dash::Configuration::Proxy::Run.new(config, run_config: {})
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
# Docker options for the load balancer container: publish/logging/options
|
|
@@ -100,7 +100,7 @@ class Kamal::Configuration::Loadbalancer < Kamal::Configuration::Proxy
|
|
|
100
100
|
|
|
101
101
|
private
|
|
102
102
|
# The edge half of the layering contract (see
|
|
103
|
-
#
|
|
103
|
+
# Dash::Configuration::Proxy::DEPLOY_OPTION_DISPOSITIONS): the load
|
|
104
104
|
# balancer applies the edge and shared concerns, and leaves the per-app
|
|
105
105
|
# ones to the per-host proxies it forwards to.
|
|
106
106
|
def retained_dispositions
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
class
|
|
2
|
-
delegate :optionize, :argumentize, to:
|
|
1
|
+
class Dash::Configuration::Logging
|
|
2
|
+
delegate :optionize, :argumentize, to: Dash::Utils
|
|
3
3
|
|
|
4
|
-
include
|
|
4
|
+
include Dash::Configuration::Validation
|
|
5
5
|
|
|
6
6
|
attr_reader :logging_config
|
|
7
7
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
class
|
|
2
|
-
include
|
|
1
|
+
class Dash::Configuration::Output
|
|
2
|
+
include Dash::Configuration::Validation
|
|
3
3
|
|
|
4
4
|
LOGGER_TYPES = {
|
|
5
|
-
"otel" => "
|
|
6
|
-
"file" => "
|
|
5
|
+
"otel" => "Dash::Output::OtelLogger",
|
|
6
|
+
"file" => "Dash::Output::FileLogger"
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
attr_reader :output_config, :loggers
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
# Credentials go the other way, through an env file uploaded at mode 0600. A DNS
|
|
9
9
|
# API token can rewrite your zone; `docker run --env TOKEN=...` would put it in
|
|
10
10
|
# the host's process listing and in kamal's own audit log.
|
|
11
|
-
class
|
|
11
|
+
class Dash::Configuration::Proxy::Acme
|
|
12
12
|
# The canonical provider names kamal-proxy MINIMUM_VERSION advertises. Kept in
|
|
13
13
|
# step with the proxy by test/proxy_flag_coverage_test.rb, which compares this
|
|
14
14
|
# list against the manifest bin/sync-proxy-flags generates from the image.
|
|
@@ -53,7 +53,7 @@ class Kamal::Configuration::Proxy::Acme
|
|
|
53
53
|
# as a stray argument. Both booleans default to true in the proxy, which makes
|
|
54
54
|
# false the value an operator actually writes.
|
|
55
55
|
def run_command_args
|
|
56
|
-
|
|
56
|
+
Dash::Utils.optionize(run_command_options, with: "=")
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
# compact, not compact_blank: false is a meaningful value for both booleans.
|
|
@@ -63,7 +63,8 @@ class Kamal::Configuration::Proxy::Acme
|
|
|
63
63
|
"acme-dns-provider": dns_provider_entries,
|
|
64
64
|
"acme-directory": acme_config["directory"],
|
|
65
65
|
"acme-prefer-wildcard": acme_config["prefer_wildcard"],
|
|
66
|
-
"acme-http-fallback": acme_config["http_fallback"]
|
|
66
|
+
"acme-http-fallback": acme_config["http_fallback"],
|
|
67
|
+
"acme-release-probe-interval": Dash::Utils.seconds_duration(acme_config["release_probe_interval"])
|
|
67
68
|
}.compact
|
|
68
69
|
end
|
|
69
70
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
class
|
|
1
|
+
class Dash::Configuration::Proxy::Boot
|
|
2
2
|
attr_reader :config
|
|
3
|
-
delegate :argumentize, :optionize, to:
|
|
3
|
+
delegate :argumentize, :optionize, to: Dash::Utils
|
|
4
4
|
|
|
5
5
|
def initialize(config:)
|
|
6
6
|
@config = config
|
|
@@ -11,8 +11,8 @@ class Kamal::Configuration::Proxy::Boot
|
|
|
11
11
|
|
|
12
12
|
(bind_ips || [ nil ]).map do |bind_ip|
|
|
13
13
|
bind_ip = format_bind_ip(bind_ip)
|
|
14
|
-
publish_http = [ bind_ip, http_port,
|
|
15
|
-
publish_https = [ bind_ip, https_port,
|
|
14
|
+
publish_http = [ bind_ip, http_port, Dash::Configuration::Proxy::Run::DEFAULT_HTTP_PORT ].compact.join(":")
|
|
15
|
+
publish_https = [ bind_ip, https_port, Dash::Configuration::Proxy::Run::DEFAULT_HTTPS_PORT ].compact.join(":")
|
|
16
16
|
|
|
17
17
|
argumentize "--publish", [ publish_http, publish_https ]
|
|
18
18
|
end.join(" ")
|
|
@@ -24,8 +24,8 @@ class Kamal::Configuration::Proxy::Boot
|
|
|
24
24
|
|
|
25
25
|
def default_boot_options
|
|
26
26
|
[
|
|
27
|
-
*(publish_args(
|
|
28
|
-
*(logging_args(
|
|
27
|
+
*(publish_args(Dash::Configuration::Proxy::Run::DEFAULT_HTTP_PORT, Dash::Configuration::Proxy::Run::DEFAULT_HTTPS_PORT, nil)),
|
|
28
|
+
*(logging_args(Dash::Configuration::Proxy::Run::DEFAULT_LOG_MAX_SIZE))
|
|
29
29
|
]
|
|
30
30
|
end
|
|
31
31
|
|
|
@@ -34,13 +34,15 @@ class Kamal::Configuration::Proxy::Boot
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def image_name
|
|
37
|
-
"
|
|
37
|
+
"dash-proxy"
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
def image_default
|
|
41
41
|
"#{repository_name}/#{image_name}"
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
# Stays kamal-proxy until the server-artifact rename ships a migration
|
|
45
|
+
# bridge — every deployed host has a running container by this name.
|
|
44
46
|
def container_name
|
|
45
47
|
"kamal-proxy"
|
|
46
48
|
end
|
|
@@ -74,7 +76,7 @@ class Kamal::Configuration::Proxy::Boot
|
|
|
74
76
|
end
|
|
75
77
|
|
|
76
78
|
def apps_volume
|
|
77
|
-
|
|
79
|
+
Dash::Configuration::Volume.new \
|
|
78
80
|
host_path: apps_directory,
|
|
79
81
|
container_path: apps_container_directory
|
|
80
82
|
end
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
class
|
|
2
|
-
MINIMUM_VERSION = "v1.0.0.
|
|
1
|
+
class Dash::Configuration::Proxy::Run
|
|
2
|
+
MINIMUM_VERSION = "v1.0.0.7"
|
|
3
3
|
DEFAULT_HTTP_PORT = 80
|
|
4
4
|
DEFAULT_HTTPS_PORT = 443
|
|
5
5
|
DEFAULT_LOG_MAX_SIZE = "10m"
|
|
6
6
|
|
|
7
7
|
# One env file for everything the proxy must know but nothing may print:
|
|
8
8
|
# ACME DNS credentials and the cache store URL. Also referenced by
|
|
9
|
-
#
|
|
9
|
+
# Dash::Commands::Proxy#remove_proxy_secrets_file, which cleans it up when
|
|
10
10
|
# the config no longer needs it.
|
|
11
11
|
SECRETS_FILENAME = "secrets.env"
|
|
12
12
|
|
|
@@ -15,7 +15,7 @@ class Kamal::Configuration::Proxy::Run
|
|
|
15
15
|
DIGEST_SCHEMA_VERSION = "v1"
|
|
16
16
|
|
|
17
17
|
attr_reader :config, :run_config
|
|
18
|
-
delegate :argumentize, :optionize, :seconds_duration, to:
|
|
18
|
+
delegate :argumentize, :optionize, :seconds_duration, to: Dash::Utils
|
|
19
19
|
|
|
20
20
|
def initialize(config, run_config:, context: "proxy/run")
|
|
21
21
|
@config = config
|
|
@@ -37,13 +37,13 @@ class Kamal::Configuration::Proxy::Run
|
|
|
37
37
|
# running. The values deliberately stay out — the digest is published as a
|
|
38
38
|
# docker label, and hashing secret material into a world-readable label buys
|
|
39
39
|
# an offline guessing target for nothing. Rotating a credential's value or
|
|
40
|
-
# the store URL still needs an explicit `
|
|
40
|
+
# the store URL still needs an explicit `dash proxy reboot`.
|
|
41
41
|
def config_digest
|
|
42
42
|
self.class.digest(image, run_command, *docker_options_args, *secret_names)
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
def acme
|
|
46
|
-
@acme ||=
|
|
46
|
+
@acme ||= Dash::Configuration::Proxy::Acme.new(acme_config: run_config["acme"], secrets: config.secrets)
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
def debug?
|
|
@@ -95,7 +95,7 @@ class Kamal::Configuration::Proxy::Run
|
|
|
95
95
|
end
|
|
96
96
|
|
|
97
97
|
def repository
|
|
98
|
-
run_config.fetch("repository", "ghcr.io/zoolutions/
|
|
98
|
+
run_config.fetch("repository", "ghcr.io/zoolutions/dash-proxy")
|
|
99
99
|
end
|
|
100
100
|
|
|
101
101
|
def image
|
|
@@ -194,14 +194,14 @@ class Kamal::Configuration::Proxy::Run
|
|
|
194
194
|
# wakes - which the operator sees as one hung request, not as a misconfiguration.
|
|
195
195
|
def docker_socket_args
|
|
196
196
|
if docker_socket.present?
|
|
197
|
-
|
|
197
|
+
Dash::Configuration::Volume.new(host_path: docker_socket, container_path: docker_socket).docker_args
|
|
198
198
|
end
|
|
199
199
|
end
|
|
200
200
|
|
|
201
201
|
# Where the proxy's secrets land on the host - the ACME DNS credentials and
|
|
202
202
|
# the cache store URL, which may embed one. Under the proxy's own directory
|
|
203
203
|
# rather than the app's env directory, because the container is host-scoped
|
|
204
|
-
# and shared by every app on the host - and so `
|
|
204
|
+
# and shared by every app on the host - and so `dash proxy remove` takes
|
|
205
205
|
# the secrets with it.
|
|
206
206
|
def secrets_path
|
|
207
207
|
File.join host_directory, SECRETS_FILENAME
|
|
@@ -212,7 +212,7 @@ class Kamal::Configuration::Proxy::Run
|
|
|
212
212
|
end
|
|
213
213
|
|
|
214
214
|
def secrets_io
|
|
215
|
-
|
|
215
|
+
Dash::EnvFile.new(acme.credentials_env.merge(cache_store_env)).to_io
|
|
216
216
|
end
|
|
217
217
|
|
|
218
218
|
def host_directory
|
|
@@ -228,7 +228,7 @@ class Kamal::Configuration::Proxy::Run
|
|
|
228
228
|
end
|
|
229
229
|
|
|
230
230
|
def apps_volume
|
|
231
|
-
|
|
231
|
+
Dash::Configuration::Volume.new \
|
|
232
232
|
host_path: apps_directory,
|
|
233
233
|
container_path: apps_container_directory
|
|
234
234
|
end
|
|
@@ -255,7 +255,7 @@ class Kamal::Configuration::Proxy::Run
|
|
|
255
255
|
end
|
|
256
256
|
|
|
257
257
|
# Whether an operator turned on PROXY protocol without saying who may speak
|
|
258
|
-
# it.
|
|
258
|
+
# it. Dash::Configuration warns about this: the header rewrites the
|
|
259
259
|
# connecting address that allow_ips and rate_limit key on, so honouring it
|
|
260
260
|
# from anywhere is a client-IP spoofing hole.
|
|
261
261
|
def proxy_protocol_unrestricted?
|
|
@@ -264,7 +264,7 @@ class Kamal::Configuration::Proxy::Run
|
|
|
264
264
|
|
|
265
265
|
private
|
|
266
266
|
# The proxy's own listeners and process-level behaviour, as opposed to the
|
|
267
|
-
# per-service deadlines in
|
|
267
|
+
# per-service deadlines in Dash::Configuration::Proxy#deploy_options. Zero
|
|
268
268
|
# disables each of the timeouts, so it is a value rather than an absence.
|
|
269
269
|
def server_options
|
|
270
270
|
{
|
|
@@ -295,7 +295,7 @@ class Kamal::Configuration::Proxy::Run
|
|
|
295
295
|
conflicts = flags.keys.map(&:to_s) & named_run_command_options.keys.map(&:to_s)
|
|
296
296
|
return true if conflicts.empty?
|
|
297
297
|
|
|
298
|
-
raise
|
|
298
|
+
raise Dash::ConfigurationError,
|
|
299
299
|
"#{@context}/flags: #{conflicts.sort.join(", ")} is already set by a named key - remove one of them"
|
|
300
300
|
end
|
|
301
301
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
class
|
|
2
|
-
include
|
|
1
|
+
class Dash::Configuration::Proxy
|
|
2
|
+
include Dash::Configuration::Validation
|
|
3
3
|
|
|
4
4
|
DEFAULT_LOG_REQUEST_HEADERS = [ "Cache-Control", "Last-Modified", "User-Agent" ]
|
|
5
5
|
CONTAINER_NAME = "kamal-proxy"
|
|
@@ -163,12 +163,12 @@ class Kamal::Configuration::Proxy
|
|
|
163
163
|
# where it matters.
|
|
164
164
|
def self.disposition(key)
|
|
165
165
|
DEPLOY_OPTION_DISPOSITIONS.fetch(key) do
|
|
166
|
-
raise
|
|
167
|
-
"proxy deploy option --#{key} has no layering disposition - add it to
|
|
166
|
+
raise Dash::ConfigurationError,
|
|
167
|
+
"proxy deploy option --#{key} has no layering disposition - add it to Dash::Configuration::Proxy::DEPLOY_OPTION_DISPOSITIONS"
|
|
168
168
|
end
|
|
169
169
|
end
|
|
170
170
|
|
|
171
|
-
delegate :argumentize, :optionize, :seconds_duration, to:
|
|
171
|
+
delegate :argumentize, :optionize, :seconds_duration, to: Dash::Utils
|
|
172
172
|
|
|
173
173
|
attr_reader :config, :proxy_config, :role_name, :run, :secrets
|
|
174
174
|
|
|
@@ -182,8 +182,8 @@ class Kamal::Configuration::Proxy
|
|
|
182
182
|
@role_name = role_name
|
|
183
183
|
@load_balanced = load_balanced
|
|
184
184
|
@secrets = secrets
|
|
185
|
-
validate! @proxy_config, with:
|
|
186
|
-
@run =
|
|
185
|
+
validate! @proxy_config, with: Dash::Configuration::Validator::Proxy, context: context
|
|
186
|
+
@run = Dash::Configuration::Proxy::Run.new(config, run_config: @proxy_config["run"], context: "#{context}/run") if @proxy_config && @proxy_config["run"].present?
|
|
187
187
|
end
|
|
188
188
|
|
|
189
189
|
def app_port
|
|
@@ -274,7 +274,7 @@ class Kamal::Configuration::Proxy
|
|
|
274
274
|
ssl_config["on_demand_url"]
|
|
275
275
|
end
|
|
276
276
|
|
|
277
|
-
# The name of a secret in .
|
|
277
|
+
# The name of a secret in .dash/secrets holding the CA bundle client
|
|
278
278
|
# certificates must chain to - mirroring ssl.certificate_pem, not a local
|
|
279
279
|
# file path. Kamal uploads the content into the app's TLS directory, which
|
|
280
280
|
# the proxy container already mounts, and hands the proxy the path it sees
|
|
@@ -287,14 +287,14 @@ class Kamal::Configuration::Proxy
|
|
|
287
287
|
client_ca_pem.present?
|
|
288
288
|
end
|
|
289
289
|
|
|
290
|
-
# Resolved at upload time, not config time, so `
|
|
290
|
+
# Resolved at upload time, not config time, so `dash app logs` and friends
|
|
291
291
|
# work on machines without the secret. A blank secret raises like
|
|
292
292
|
# basic_auth.password_secret - silently deploying without the client CA
|
|
293
293
|
# would turn mTLS off.
|
|
294
294
|
def client_ca_pem_content
|
|
295
295
|
secrets[client_ca_pem].tap do |content|
|
|
296
296
|
if content.blank?
|
|
297
|
-
raise
|
|
297
|
+
raise Dash::ConfigurationError, "proxy/ssl: client_ca_pem secret '#{client_ca_pem}' is empty"
|
|
298
298
|
end
|
|
299
299
|
end
|
|
300
300
|
end
|
|
@@ -405,7 +405,7 @@ class Kamal::Configuration::Proxy
|
|
|
405
405
|
private
|
|
406
406
|
# Which dispositions this layer keeps. The per-app proxy behind a load
|
|
407
407
|
# balancer sheds the edge concerns; without load balancing there is no
|
|
408
|
-
# other layer to defer to.
|
|
408
|
+
# other layer to defer to. Dash::Configuration::Loadbalancer overrides
|
|
409
409
|
# this to keep the edge and shed the per-app concerns.
|
|
410
410
|
def retained_dispositions
|
|
411
411
|
load_balancing? ? %i[ per_app both ] : %i[ edge per_app both ]
|
|
@@ -417,7 +417,7 @@ class Kamal::Configuration::Proxy
|
|
|
417
417
|
|
|
418
418
|
# Auto-activation needs a role the load balancer can actually front. The
|
|
419
419
|
# target list is built from roles where `running_proxy?` (see
|
|
420
|
-
#
|
|
420
|
+
# Dash::Cli::Proxy#loadbalancer), so a proxy-less primary role would boot a
|
|
421
421
|
# load balancer with an empty --target. An explicit `loadbalancer:` setting
|
|
422
422
|
# skips this check — the operator asked for it.
|
|
423
423
|
def auto_load_balanced_primary_role?
|
|
@@ -473,7 +473,7 @@ class Kamal::Configuration::Proxy
|
|
|
473
473
|
# app hosts have the docker socket and the containers).
|
|
474
474
|
#
|
|
475
475
|
# Sleep needs the container runtime socket, which is a run-level setting -
|
|
476
|
-
#
|
|
476
|
+
# Dash::Configuration#ensure_sleep_has_a_docker_socket refuses the pairing
|
|
477
477
|
# rather than letting the first request after an idle period hang.
|
|
478
478
|
def lifecycle_options
|
|
479
479
|
affinity = proxy_config["session_affinity"] || {}
|
|
@@ -602,7 +602,7 @@ class Kamal::Configuration::Proxy
|
|
|
602
602
|
|
|
603
603
|
# kamal-proxy takes the credential as <username>:<password> and cuts at the
|
|
604
604
|
# first colon, so a password may contain colons but a username may not (the
|
|
605
|
-
# validator enforces that). The password is read from .
|
|
605
|
+
# validator enforces that). The password is read from .dash/secrets when
|
|
606
606
|
# password_secret names it, so it need not live in deploy.yml.
|
|
607
607
|
def basic_auth_credential
|
|
608
608
|
basic_auth = proxy_config["basic_auth"]
|
|
@@ -619,13 +619,13 @@ class Kamal::Configuration::Proxy
|
|
|
619
619
|
# means the named secret resolved empty. Fail rather than drop the flag —
|
|
620
620
|
# silently deploying an unprotected service is the worse outcome.
|
|
621
621
|
if password.blank?
|
|
622
|
-
raise
|
|
622
|
+
raise Dash::ConfigurationError, "proxy/basic_auth: password_secret '#{secret_name}' is empty"
|
|
623
623
|
end
|
|
624
624
|
|
|
625
625
|
# Sensitive, so SSHKit redacts the credential wherever kamal prints the
|
|
626
626
|
# deploy command - at :info verbosity it used to land in plain text
|
|
627
627
|
# (registry-login precedent; Utils.optionize passes the marking through).
|
|
628
|
-
|
|
628
|
+
Dash::Utils.sensitive("#{basic_auth["username"]}:#{password}")
|
|
629
629
|
end
|
|
630
630
|
|
|
631
631
|
# Serves both --path-timeout and --path-request-timeout, which kamal-proxy
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
class
|
|
2
|
-
include
|
|
1
|
+
class Dash::Configuration::Registry
|
|
2
|
+
include Dash::Configuration::Validation
|
|
3
3
|
|
|
4
4
|
def initialize(config:, secrets:, context: "registry")
|
|
5
5
|
@registry_config = config["registry"] || {}
|
|
6
6
|
@secrets = secrets
|
|
7
|
-
validate! registry_config, context: context, with:
|
|
7
|
+
validate! registry_config, context: context, with: Dash::Configuration::Validator::Registry
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def server
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class Dash::Configuration::Role::Healthcheck
|
|
2
2
|
DEFAULT_PATH = "/up"
|
|
3
3
|
DEFAULT_INTERVAL = 1
|
|
4
4
|
|
|
@@ -7,7 +7,7 @@ class Kamal::Configuration::Role::Healthcheck
|
|
|
7
7
|
DOCKER_ONLY_KEYS = %w[ cmd port path interval timeout retries start_period start_interval ]
|
|
8
8
|
|
|
9
9
|
attr_reader :healthcheck_config, :context
|
|
10
|
-
delegate :optionize, to:
|
|
10
|
+
delegate :optionize, to: Dash::Utils
|
|
11
11
|
|
|
12
12
|
def initialize(healthcheck_config:, context: "healthcheck")
|
|
13
13
|
@healthcheck_config = healthcheck_config
|
|
@@ -90,6 +90,6 @@ class Kamal::Configuration::Role::Healthcheck
|
|
|
90
90
|
end
|
|
91
91
|
|
|
92
92
|
def error(message, context: nil)
|
|
93
|
-
raise
|
|
93
|
+
raise Dash::ConfigurationError, "#{[ @context, context ].compact.join("/")}: #{message}"
|
|
94
94
|
end
|
|
95
95
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
class
|
|
2
|
-
include
|
|
1
|
+
class Dash::Configuration::Role
|
|
2
|
+
include Dash::Configuration::Validation
|
|
3
3
|
|
|
4
|
-
delegate :argumentize, :optionize, to:
|
|
4
|
+
delegate :argumentize, :optionize, to: Dash::Utils
|
|
5
5
|
|
|
6
6
|
attr_reader :name, :config, :specialized_env, :specialized_logging, :specialized_proxy, :healthcheck
|
|
7
7
|
|
|
@@ -13,20 +13,20 @@ class Kamal::Configuration::Role
|
|
|
13
13
|
role_config,
|
|
14
14
|
example: validation_yml["servers"]["workers"],
|
|
15
15
|
context: "servers/#{name}",
|
|
16
|
-
with:
|
|
16
|
+
with: Dash::Configuration::Validator::Role
|
|
17
17
|
|
|
18
|
-
@specialized_env =
|
|
18
|
+
@specialized_env = Dash::Configuration::Env.new \
|
|
19
19
|
config: specializations.fetch("env", {}),
|
|
20
20
|
secrets: config.secrets,
|
|
21
21
|
context: "servers/#{name}/env"
|
|
22
22
|
|
|
23
|
-
@specialized_logging =
|
|
23
|
+
@specialized_logging = Dash::Configuration::Logging.new \
|
|
24
24
|
logging_config: specializations.fetch("logging", {}),
|
|
25
25
|
context: "servers/#{name}/logging"
|
|
26
26
|
|
|
27
27
|
# `healthcheck: false` is an opt-out, not a healthcheck — it leaves @healthcheck nil.
|
|
28
28
|
if healthcheck_config = specializations["healthcheck"]
|
|
29
|
-
@healthcheck =
|
|
29
|
+
@healthcheck = Dash::Configuration::Role::Healthcheck.new \
|
|
30
30
|
healthcheck_config: healthcheck_config,
|
|
31
31
|
context: "servers/#{name}/healthcheck"
|
|
32
32
|
end
|
|
@@ -79,7 +79,7 @@ class Kamal::Configuration::Role
|
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
# Kept out of option_args on purpose: Commands::App::Execution splats those into
|
|
82
|
-
# one-shot `
|
|
82
|
+
# one-shot `dash app exec` containers, which must not inherit a service healthcheck.
|
|
83
83
|
def healthcheck_args
|
|
84
84
|
healthcheck&.args || []
|
|
85
85
|
end
|
|
@@ -94,13 +94,13 @@ class Kamal::Configuration::Role
|
|
|
94
94
|
# `boot.wait` a second time inside every group.
|
|
95
95
|
#
|
|
96
96
|
# Built on first read rather than in the initializer — Servers.new constructs every Role
|
|
97
|
-
# before
|
|
97
|
+
# before Dash::Configuration#initialize has finished assigning its own collaborators.
|
|
98
98
|
def boot
|
|
99
99
|
return @boot if defined?(@boot)
|
|
100
100
|
|
|
101
101
|
@boot =
|
|
102
102
|
if (boot_config = specializations["boot"])
|
|
103
|
-
|
|
103
|
+
Dash::Configuration::Boot.new \
|
|
104
104
|
config: config, boot_config: boot_config, context: "servers/#{name}/boot"
|
|
105
105
|
end
|
|
106
106
|
end
|
|
@@ -235,7 +235,7 @@ class Kamal::Configuration::Role
|
|
|
235
235
|
|
|
236
236
|
def asset_volume(version = config.version)
|
|
237
237
|
if assets?
|
|
238
|
-
|
|
238
|
+
Dash::Configuration::Volume.new \
|
|
239
239
|
host_path: asset_volume_directory(version), container_path: asset_path, options: asset_path_options
|
|
240
240
|
end
|
|
241
241
|
end
|
|
@@ -255,7 +255,7 @@ class Kamal::Configuration::Role
|
|
|
255
255
|
def ensure_one_host_for_ssl
|
|
256
256
|
# Skip SSL validation when a loadbalancer is present or custom certificates are provided
|
|
257
257
|
if running_proxy? && proxy.ssl? && hosts.size > 1 && !proxy.loadbalancer.present? && !proxy.custom_ssl_certificate?
|
|
258
|
-
raise
|
|
258
|
+
raise Dash::ConfigurationError, "SSL is only supported on a single server unless you provide custom certificates or configure a loadbalancer, found #{hosts.size} servers for role #{name}"
|
|
259
259
|
end
|
|
260
260
|
end
|
|
261
261
|
|
|
@@ -274,7 +274,7 @@ class Kamal::Configuration::Role
|
|
|
274
274
|
if running_proxy?
|
|
275
275
|
proxy_config = proxy_specializations == true || proxy_specializations.nil? ? {} : proxy_specializations
|
|
276
276
|
|
|
277
|
-
@specialized_proxy =
|
|
277
|
+
@specialized_proxy = Dash::Configuration::Proxy.new \
|
|
278
278
|
config: config,
|
|
279
279
|
proxy_config: proxy_config,
|
|
280
280
|
secrets: config.secrets,
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
class
|
|
2
|
-
include
|
|
1
|
+
class Dash::Configuration::Servers
|
|
2
|
+
include Dash::Configuration::Validation
|
|
3
3
|
|
|
4
4
|
attr_reader :config, :servers_config, :roles
|
|
5
5
|
|
|
6
6
|
def initialize(config:)
|
|
7
7
|
@config = config
|
|
8
8
|
@servers_config = config.raw_config.servers
|
|
9
|
-
validate! servers_config, with:
|
|
9
|
+
validate! servers_config, with: Dash::Configuration::Validator::Servers
|
|
10
10
|
|
|
11
|
-
@roles = role_names.map { |role_name|
|
|
11
|
+
@roles = role_names.map { |role_name| Dash::Configuration::Role.new role_name, config: config }
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
private
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
class
|
|
1
|
+
class Dash::Configuration::Ssh
|
|
2
2
|
LOGGER = ::Logger.new(STDERR)
|
|
3
3
|
|
|
4
|
-
include
|
|
4
|
+
include Dash::Configuration::Validation
|
|
5
5
|
|
|
6
6
|
attr_reader :ssh_config, :secrets
|
|
7
7
|
|
|
@@ -43,7 +43,7 @@ class Kamal::Configuration::Ssh
|
|
|
43
43
|
if secrets.key?(k)
|
|
44
44
|
secrets[k]
|
|
45
45
|
else
|
|
46
|
-
warn "Inline key_data usage is deprecated and will be removed in
|
|
46
|
+
warn "Inline key_data usage is deprecated and will be removed in a future dash release. Please store your key_data in a secret."
|
|
47
47
|
k
|
|
48
48
|
end
|
|
49
49
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require "yaml"
|
|
2
2
|
require "active_support/inflector"
|
|
3
3
|
|
|
4
|
-
module
|
|
4
|
+
module Dash::Configuration::Validation
|
|
5
5
|
extend ActiveSupport::Concern
|
|
6
6
|
|
|
7
7
|
class_methods do
|
|
@@ -14,7 +14,7 @@ module Kamal::Configuration::Validation
|
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
def validate!(config, example: nil, context: nil, with:
|
|
17
|
+
def validate!(config, example: nil, context: nil, with: Dash::Configuration::Validator)
|
|
18
18
|
context ||= self.class.validation_config_key
|
|
19
19
|
example ||= validation_yml[self.class.validation_config_key]
|
|
20
20
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class Dash::Configuration::Validator::Alias < Dash::Configuration::Validator
|
|
2
2
|
def validate!
|
|
3
3
|
super
|
|
4
4
|
|
|
@@ -8,7 +8,7 @@ class Kamal::Configuration::Validator::Alias < Kamal::Configuration::Validator
|
|
|
8
8
|
error "Invalid alias name: '#{name}'. Must only contain lowercase letters, alphanumeric, hyphens and underscores."
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
if
|
|
11
|
+
if Dash::Cli::Main.commands.include?(name)
|
|
12
12
|
error "Alias '#{name}' conflicts with a built-in command."
|
|
13
13
|
end
|
|
14
14
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class Dash::Configuration::Validator::Env < Dash::Configuration::Validator
|
|
2
2
|
SPECIAL_KEYS = [ "clear", "secret", "tags" ]
|
|
3
3
|
|
|
4
4
|
def validate!
|
|
@@ -39,7 +39,7 @@ class Kamal::Configuration::Validator::Env < Kamal::Configuration::Validator
|
|
|
39
39
|
with_context(tag) do
|
|
40
40
|
validate_type! value, Hash
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
Dash::Configuration::Validator::Env.new(
|
|
43
43
|
value,
|
|
44
44
|
example: example["tags"].values[1],
|
|
45
45
|
context: context
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class Dash::Configuration::Validator::Proxy < Dash::Configuration::Validator
|
|
2
2
|
def validate!
|
|
3
3
|
unless config.nil?
|
|
4
4
|
super
|
|
@@ -149,7 +149,7 @@ class Kamal::Configuration::Validator::Proxy < Kamal::Configuration::Validator
|
|
|
149
149
|
validate_dns_provider_zones! provider
|
|
150
150
|
elsif provider.present? && !supported_dns_provider?(provider)
|
|
151
151
|
error "unsupported dns_provider '#{provider}'. " \
|
|
152
|
-
"Supported providers: #{
|
|
152
|
+
"Supported providers: #{Dash::Configuration::Proxy::Acme::DNS_PROVIDERS.join(", ")}"
|
|
153
153
|
end
|
|
154
154
|
end
|
|
155
155
|
end
|
|
@@ -175,13 +175,13 @@ class Kamal::Configuration::Validator::Proxy < Kamal::Configuration::Validator
|
|
|
175
175
|
|
|
176
176
|
unless zone_provider.is_a?(String) && supported_dns_provider?(zone_provider)
|
|
177
177
|
error "unsupported dns_provider '#{zone_provider}' for '#{zone}'. " \
|
|
178
|
-
"Supported providers: #{
|
|
178
|
+
"Supported providers: #{Dash::Configuration::Proxy::Acme::DNS_PROVIDERS.join(", ")}"
|
|
179
179
|
end
|
|
180
180
|
end
|
|
181
181
|
end
|
|
182
182
|
|
|
183
183
|
def supported_dns_provider?(provider)
|
|
184
|
-
|
|
184
|
+
Dash::Configuration::Proxy::Acme::SUPPORTED_DNS_PROVIDERS.include?(provider.to_s.downcase)
|
|
185
185
|
end
|
|
186
186
|
|
|
187
187
|
# The whole TLS surface lives in the one `ssl` hash: certificate material,
|
|
@@ -278,7 +278,7 @@ class Kamal::Configuration::Validator::Proxy < Kamal::Configuration::Validator
|
|
|
278
278
|
# Session affinity and scale-to-zero. The one rule NOT here is that sleep
|
|
279
279
|
# needs proxy/run/docker_socket: a role can carry `sleep` while the root
|
|
280
280
|
# carries the socket, and this validator runs against the role's own proxy
|
|
281
|
-
# block before it is merged.
|
|
281
|
+
# block before it is merged. Dash::Configuration checks that pairing on the
|
|
282
282
|
# merged config instead.
|
|
283
283
|
def validate_lifecycle!
|
|
284
284
|
affinity = config["session_affinity"] || {}
|
|
@@ -604,11 +604,11 @@ class Kamal::Configuration::Validator::Proxy < Kamal::Configuration::Validator
|
|
|
604
604
|
end
|
|
605
605
|
|
|
606
606
|
encodings.each do |encoding|
|
|
607
|
-
canonical =
|
|
607
|
+
canonical = Dash::Configuration::Proxy::COMPRESSION_ENCODING_ALIASES.fetch(encoding.to_s, encoding.to_s)
|
|
608
608
|
|
|
609
|
-
unless
|
|
609
|
+
unless Dash::Configuration::Proxy::SUPPORTED_COMPRESSION_ENCODINGS.include?(canonical)
|
|
610
610
|
error "unsupported encoding '#{encoding}'. " \
|
|
611
|
-
"Supported encodings: #{
|
|
611
|
+
"Supported encodings: #{Dash::Configuration::Proxy::SUPPORTED_COMPRESSION_ENCODINGS.join(", ")}"
|
|
612
612
|
end
|
|
613
613
|
end
|
|
614
614
|
|