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" 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 ### 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. 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, *role.env_args,
*config.volume_args, *config.volume_args,
*role.label_args, *role.label_args,
*role.option_args,
config.absolute_image, config.absolute_image,
role.cmd role.cmd
end end

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
class Mrsk::Configuration::Role 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 attr_accessor :name
@@ -35,6 +35,14 @@ class Mrsk::Configuration::Role
specializations["cmd"] specializations["cmd"]
end end
def option_args
if args = specializations["options"]
optionize args
else
[]
end
end
def running_traefik? def running_traefik?
name.web? || specializations["traefik"] name.web? || specializations["traefik"]
end end

View File

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