diff --git a/lib/mrsk/commands/base.rb b/lib/mrsk/commands/base.rb index e453dddc..a9815c91 100644 --- a/lib/mrsk/commands/base.rb +++ b/lib/mrsk/commands/base.rb @@ -1,6 +1,6 @@ module Mrsk::Commands class Base - delegate :redact, to: Mrsk::Utils + delegate :redact, :argumentize_for_cmd, to: Mrsk::Utils MAX_LOG_SIZE = "10m" diff --git a/lib/mrsk/commands/traefik.rb b/lib/mrsk/commands/traefik.rb index b8cbe343..34e9c907 100644 --- a/lib/mrsk/commands/traefik.rb +++ b/lib/mrsk/commands/traefik.rb @@ -53,7 +53,11 @@ class Mrsk::Commands::Traefik < Mrsk::Commands::Base private def cmd_args - (config.raw_config.dig(:traefik, "args") || { }).collect { |(key, value)| [ "--#{key}", value ] }.flatten + if args = config.raw_config.dig(:traefik, "args") + argumentize_for_cmd args + else + [] + end end def host_port diff --git a/lib/mrsk/utils.rb b/lib/mrsk/utils.rb index 73bc5485..62a193ea 100644 --- a/lib/mrsk/utils.rb +++ b/lib/mrsk/utils.rb @@ -5,7 +5,7 @@ module Mrsk::Utils def argumentize(argument, attributes, redacted: false) Array(attributes).flat_map do |key, value| if value.present? - escaped_pair = [ key, value.to_s.dump.gsub(/`/, '\\\\`') ].join("=") + escaped_pair = [ key, escape_shell_value(value) ].join("=") [ argument, redacted ? redact(escaped_pair) : escaped_pair ] else [ argument, key ] @@ -23,8 +23,18 @@ module Mrsk::Utils end end + # Returns a list of shell-dashed arguments to be used to start a command. + def argumentize_for_cmd(args) + args.collect { |(key, value)| [ "--#{key}", escape_shell_value(value) ] }.flatten + end + # Copied from SSHKit::Backend::Abstract#redact to be available inside Commands classes def redact(arg) # Used in execute_command to hide redact() args a user passes in arg.to_s.extend(SSHKit::Redaction) # to_s due to our inability to extend Integer, etc end + + # Escape a value to make it safe for shell use. + def escape_shell_value(value) + value.to_s.dump.gsub(/`/, '\\\\`') + end end diff --git a/test/commands/traefik_test.rb b/test/commands/traefik_test.rb index 54bc260a..97310623 100644 --- a/test/commands/traefik_test.rb +++ b/test/commands/traefik_test.rb @@ -10,12 +10,12 @@ class CommandsTraefikTest < ActiveSupport::TestCase test "run" do assert_equal \ - "docker run --name traefik --detach --restart unless-stopped --log-opt max-size=10m --publish 80:80 --volume /var/run/docker.sock:/var/run/docker.sock traefik --providers.docker --log.level=DEBUG --accesslog.format json --metrics.prometheus.buckets 0.1,0.3,1.2,5.0", + "docker run --name traefik --detach --restart unless-stopped --log-opt max-size=10m --publish 80:80 --volume /var/run/docker.sock:/var/run/docker.sock traefik --providers.docker --log.level=DEBUG --accesslog.format \"json\" --metrics.prometheus.buckets \"0.1,0.3,1.2,5.0\"", new_command.run.join(" ") @config[:traefik]["host_port"] = "8080" assert_equal \ - "docker run --name traefik --detach --restart unless-stopped --log-opt max-size=10m --publish 8080:80 --volume /var/run/docker.sock:/var/run/docker.sock traefik --providers.docker --log.level=DEBUG --accesslog.format json --metrics.prometheus.buckets 0.1,0.3,1.2,5.0", + "docker run --name traefik --detach --restart unless-stopped --log-opt max-size=10m --publish 8080:80 --volume /var/run/docker.sock:/var/run/docker.sock traefik --providers.docker --log.level=DEBUG --accesslog.format \"json\" --metrics.prometheus.buckets \"0.1,0.3,1.2,5.0\"", new_command.run.join(" ") end