Merge pull request #95 from mrsked/cmd-args-for-roles

Custom options per role
This commit is contained in:
David Heinemeier Hansson
2023-03-09 10:20:50 +00:00
committed by GitHub
7 changed files with 49 additions and 8 deletions

View File

@@ -282,6 +282,27 @@ servers:
my-label: "50"
```
### Using container options
You can specialize the options used to start containers using the `options` definitions:
```yaml
servers:
web:
- 192.168.0.1
- 192.168.0.2
job:
hosts:
- 192.168.0.3
- 192.168.0.4
cmd: bin/jobs
options:
cap-add: true
cpu-count: 4
```
That'll start the job containers with `docker run ... --cap-add --cpu-count 4 ...`.
### Using remote builder for native multi-arch
If you're developing on ARM64 (like Apple Silicon), but you want to deploy on AMD64 (x86 64-bit), you can use multi-architecture images. By default, MRSK will setup a local buildx configuration that does this through QEMU emulation. But this can be quite slow, especially on the first build.

View File

@@ -10,6 +10,7 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
*role.env_args,
*config.volume_args,
*role.label_args,
*role.option_args,
config.absolute_image,
role.cmd
end

View File

@@ -1,6 +1,6 @@
module Mrsk::Commands
class Base
delegate :redact, :argumentize_for_cmd, to: Mrsk::Utils
delegate :redact, to: Mrsk::Utils
MAX_LOG_SIZE = "10m"

View File

@@ -1,4 +1,6 @@
class Mrsk::Commands::Traefik < Mrsk::Commands::Base
delegate :optionize, to: Mrsk::Utils
CONTAINER_PORT = 80
def run
@@ -11,7 +13,7 @@ class Mrsk::Commands::Traefik < Mrsk::Commands::Base
"traefik",
"--providers.docker",
"--log.level=DEBUG",
*cmd_args
*cmd_option_args
end
def start
@@ -52,9 +54,9 @@ class Mrsk::Commands::Traefik < Mrsk::Commands::Base
end
private
def cmd_args
def cmd_option_args
if args = config.raw_config.dig(:traefik, "args")
argumentize_for_cmd args
optionize args
else
[]
end

View File

@@ -1,5 +1,5 @@
class Mrsk::Configuration::Role
delegate :argumentize, :argumentize_env_with_secrets, to: Mrsk::Utils
delegate :argumentize, :argumentize_env_with_secrets, :optionize, to: Mrsk::Utils
attr_accessor :name
@@ -35,6 +35,14 @@ class Mrsk::Configuration::Role
specializations["cmd"]
end
def option_args
if args = specializations["options"]
optionize args
else
[]
end
end
def running_traefik?
name.web? || specializations["traefik"]
end

View File

@@ -23,9 +23,9 @@ 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
# Returns a list of shell-dashed option arguments. If the value is true, it's treated like a value-less option.
def optionize(args)
args.collect { |(key, value)| [ "--#{key}", value == true ? nil : escape_shell_value(value) ] }.flatten.compact
end
# Copied from SSHKit::Backend::Abstract#redact to be available inside Commands classes

View File

@@ -34,6 +34,15 @@ class CommandsAppTest < ActiveSupport::TestCase
@app.run.join(" ")
end
test "run with custom options" do
@config[:servers] = { "web" => [ "1.1.1.1" ], "jobs" => { "hosts" => [ "1.1.1.2" ], "cmd" => "bin/jobs", "options" => { "mount" => "somewhere", "cap-add" => true } } }
@app = Mrsk::Commands::App.new Mrsk::Configuration.new(@config).tap { |c| c.version = "999" }
assert_equal \
"docker run --detach --restart unless-stopped --log-opt max-size=10m --name app-999 -e RAILS_MASTER_KEY=\"456\" --label service=\"app\" --label role=\"jobs\" --mount \"somewhere\" --cap-add dhh/app:999 bin/jobs",
@app.run(role: :jobs).join(" ")
end
test "start" do
assert_equal \
"docker start app-999",