Escape newlines in docker env files

When env variables were passed via `-e` newlines were escaped. This
updates the env file to do the same thing.
This commit is contained in:
Donal McBreen
2023-09-12 13:56:08 +01:00
parent 70a3c7195a
commit df2b76aee1
2 changed files with 32 additions and 5 deletions

View File

@@ -92,6 +92,13 @@ module Kamal::Utils
.gsub(DOLLAR_SIGN_WITHOUT_SHELL_EXPANSION_REGEX, '\$') .gsub(DOLLAR_SIGN_WITHOUT_SHELL_EXPANSION_REGEX, '\$')
end end
# Escape a value to make it safe to dump in a docker file.
def escape_docker_env_file_value(value)
# Doublequotes are treated literally in docker env files
# so remove leading and trailing ones and unescape any others
value.to_s.dump[1..-2].gsub(/\\"/, "\"")
end
# Abbreviate a git revhash for concise display # Abbreviate a git revhash for concise display
def abbreviate_version(version) def abbreviate_version(version)
if version if version
@@ -109,10 +116,6 @@ module Kamal::Utils
end end
def docker_env_file_line(key, value) def docker_env_file_line(key, value)
if key.include?("\n") || value.to_s.include?("\n") "#{key.to_s}=#{escape_docker_env_file_value(value)}\n"
raise ArgumentError, "docker env file format does not support newlines in keys or values, key: #{key}"
end
"#{key.to_s}=#{value.to_s}\n"
end end
end end

View File

@@ -49,6 +49,30 @@ class UtilsTest < ActiveSupport::TestCase
ENV.delete "PASSWORD" ENV.delete "PASSWORD"
end end
test "env file secret escaped newline" do
ENV["PASSWORD"] = "hello\\nthere"
env = {
"secret" => [ "PASSWORD" ]
}
assert_equal "PASSWORD=hello\\\\nthere\n", \
Kamal::Utils.env_file_with_secrets(env)
ensure
ENV.delete "PASSWORD"
end
test "env file secret newline" do
ENV["PASSWORD"] = "hello\nthere"
env = {
"secret" => [ "PASSWORD" ]
}
assert_equal "PASSWORD=hello\\nthere\n", \
Kamal::Utils.env_file_with_secrets(env)
ensure
ENV.delete "PASSWORD"
end
test "env file missing secret" do test "env file missing secret" do
env = { env = {
"secret" => [ "PASSWORD" ] "secret" => [ "PASSWORD" ]