Merge branch 'main' into pr/154
* main: (32 commits) Inline default as with other options Symbols! Fix tests test stop with custom stop wait time No need to replicate Docker default Describe purpose rather than elements Style and ordering Customizable stop wait time Fix tests Ensure it also works when configuring just log options without setting a driver Add accessory test Undo change Improve test Update README Ensure default log option `max-size=10m` #142 Allow to customize container options in accessories Fix flaky test Fix tests More resilient tests Fix other tests ...
This commit is contained in:
26
README.md
26
README.md
@@ -333,6 +333,29 @@ servers:
|
|||||||
|
|
||||||
That'll start the job containers with `docker run ... --cap-add --cpu-count 4 ...`.
|
That'll start the job containers with `docker run ... --cap-add --cpu-count 4 ...`.
|
||||||
|
|
||||||
|
### Configuring logging
|
||||||
|
|
||||||
|
You can configure the logging driver and options passed to Docker using `logging`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
logging:
|
||||||
|
driver: awslogs
|
||||||
|
options:
|
||||||
|
awslogs-region: "eu-central-2"
|
||||||
|
awslogs-group: "my-app"
|
||||||
|
```
|
||||||
|
|
||||||
|
If nothing is configured, the default option `max-size=10m` is used for all containers. The default logging driver of Docker is `json-file`.
|
||||||
|
|
||||||
|
### Using a different stop wait time
|
||||||
|
|
||||||
|
On a new deploy, each old running container is gracefully shut down with a `SIGTERM`, and after a grace period of `10` seconds a `SIGKILL` is sent.
|
||||||
|
You can configure this value via the `stop_wait_time` option:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
stop_wait_time: 30
|
||||||
|
```
|
||||||
|
|
||||||
### 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.
|
||||||
@@ -512,6 +535,9 @@ accessories:
|
|||||||
- MYSQL_ROOT_PASSWORD
|
- MYSQL_ROOT_PASSWORD
|
||||||
volumes:
|
volumes:
|
||||||
- /var/lib/mysql:/var/lib/mysql
|
- /var/lib/mysql:/var/lib/mysql
|
||||||
|
options:
|
||||||
|
cpus: 4
|
||||||
|
memory: "2GB"
|
||||||
redis:
|
redis:
|
||||||
image: redis:latest
|
image: redis:latest
|
||||||
host: 1.1.1.4
|
host: 1.1.1.4
|
||||||
|
|||||||
@@ -8,24 +8,26 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
|
|||||||
|
|
||||||
cli = self
|
cli = self
|
||||||
|
|
||||||
MRSK.config.roles.each do |role|
|
on(MRSK.hosts) do |host|
|
||||||
on(role.hosts) do |host|
|
roles = MRSK.roles_on(host)
|
||||||
execute *MRSK.auditor.record("Booted app version #{version}"), verbosity: :debug
|
|
||||||
|
roles.each do |role|
|
||||||
|
execute *MRSK.auditor(role: role).record("Booted app version #{version}"), verbosity: :debug
|
||||||
|
|
||||||
begin
|
begin
|
||||||
old_version = capture_with_info(*MRSK.app.current_running_version).strip
|
old_version = capture_with_info(*MRSK.app(role: role).current_running_version).strip
|
||||||
execute *MRSK.app.run(role: role.name)
|
execute *MRSK.app(role: role).run
|
||||||
sleep MRSK.config.readiness_delay
|
sleep MRSK.config.readiness_delay
|
||||||
execute *MRSK.app.stop(version: old_version), raise_on_non_zero_exit: false if old_version.present?
|
execute *MRSK.app(role: role).stop(version: old_version), raise_on_non_zero_exit: false if old_version.present?
|
||||||
|
|
||||||
rescue SSHKit::Command::Failed => e
|
rescue SSHKit::Command::Failed => e
|
||||||
if e.message =~ /already in use/
|
if e.message =~ /already in use/
|
||||||
error "Rebooting container with same version #{version} already deployed on #{host} (may cause gap in zero-downtime promise!)"
|
error "Rebooting container with same version #{version} already deployed on #{host} (may cause gap in zero-downtime promise!)"
|
||||||
execute *MRSK.auditor.record("Rebooted app version #{version}"), verbosity: :debug
|
execute *MRSK.auditor(role: role).record("Rebooted app version #{version}"), verbosity: :debug
|
||||||
|
|
||||||
execute *MRSK.app.stop(version: version)
|
execute *MRSK.app(role: role).stop(version: version)
|
||||||
execute *MRSK.app.remove_container(version: version)
|
execute *MRSK.app(role: role).remove_container(version: version)
|
||||||
execute *MRSK.app.run(role: role.name)
|
execute *MRSK.app(role: role).run
|
||||||
else
|
else
|
||||||
raise
|
raise
|
||||||
end
|
end
|
||||||
@@ -39,9 +41,13 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
|
|||||||
desc "start", "Start existing app container on servers"
|
desc "start", "Start existing app container on servers"
|
||||||
def start
|
def start
|
||||||
with_lock do
|
with_lock do
|
||||||
on(MRSK.hosts) do
|
on(MRSK.hosts) do |host|
|
||||||
execute *MRSK.auditor.record("Started app version #{MRSK.config.version}"), verbosity: :debug
|
roles = MRSK.roles_on(host)
|
||||||
execute *MRSK.app.start, raise_on_non_zero_exit: false
|
|
||||||
|
roles.each do |role|
|
||||||
|
execute *MRSK.auditor.record("Started app version #{MRSK.config.version}"), verbosity: :debug
|
||||||
|
execute *MRSK.app(role: role).start, raise_on_non_zero_exit: false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -49,9 +55,13 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
|
|||||||
desc "stop", "Stop app container on servers"
|
desc "stop", "Stop app container on servers"
|
||||||
def stop
|
def stop
|
||||||
with_lock do
|
with_lock do
|
||||||
on(MRSK.hosts) do
|
on(MRSK.hosts) do |host|
|
||||||
execute *MRSK.auditor.record("Stopped app"), verbosity: :debug
|
roles = MRSK.roles_on(host)
|
||||||
execute *MRSK.app.stop, raise_on_non_zero_exit: false
|
|
||||||
|
roles.each do |role|
|
||||||
|
execute *MRSK.auditor(role: role).record("Stopped app"), verbosity: :debug
|
||||||
|
execute *MRSK.app(role: role).stop, raise_on_non_zero_exit: false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -59,7 +69,13 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
|
|||||||
# FIXME: Drop in favor of just containers?
|
# FIXME: Drop in favor of just containers?
|
||||||
desc "details", "Show details about app containers"
|
desc "details", "Show details about app containers"
|
||||||
def details
|
def details
|
||||||
on(MRSK.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.info) }
|
on(MRSK.hosts) do |host|
|
||||||
|
roles = MRSK.roles_on(host)
|
||||||
|
|
||||||
|
roles.each do |role|
|
||||||
|
puts_by_host host, capture_with_info(*MRSK.app(role: role).info)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "exec [CMD]", "Execute a custom command on servers (use --help to show options)"
|
desc "exec [CMD]", "Execute a custom command on servers (use --help to show options)"
|
||||||
@@ -71,7 +87,7 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
|
|||||||
say "Get current version of running container...", :magenta unless options[:version]
|
say "Get current version of running container...", :magenta unless options[:version]
|
||||||
using_version(options[:version] || current_running_version) do |version|
|
using_version(options[:version] || current_running_version) do |version|
|
||||||
say "Launching interactive command with version #{version} via SSH from existing container on #{MRSK.primary_host}...", :magenta
|
say "Launching interactive command with version #{version} via SSH from existing container on #{MRSK.primary_host}...", :magenta
|
||||||
run_locally { exec MRSK.app.execute_in_existing_container_over_ssh(cmd, host: MRSK.primary_host) }
|
run_locally { exec MRSK.app(role: "web").execute_in_existing_container_over_ssh(cmd, host: MRSK.primary_host) }
|
||||||
end
|
end
|
||||||
|
|
||||||
when options[:interactive]
|
when options[:interactive]
|
||||||
@@ -87,8 +103,12 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
|
|||||||
say "Launching command with version #{version} from existing container...", :magenta
|
say "Launching command with version #{version} from existing container...", :magenta
|
||||||
|
|
||||||
on(MRSK.hosts) do |host|
|
on(MRSK.hosts) do |host|
|
||||||
execute *MRSK.auditor.record("Executed cmd '#{cmd}' on app version #{version}"), verbosity: :debug
|
roles = MRSK.roles_on(host)
|
||||||
puts_by_host host, capture_with_info(*MRSK.app.execute_in_existing_container(cmd))
|
|
||||||
|
roles.each do |role|
|
||||||
|
execute *MRSK.auditor(role: role).record("Executed cmd '#{cmd}' on app version #{version}"), verbosity: :debug
|
||||||
|
puts_by_host host, capture_with_info(*MRSK.app(role: role).execute_in_existing_container(cmd))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -156,9 +176,13 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
|
|||||||
desc "remove_container [VERSION]", "Remove app container with given version from servers", hide: true
|
desc "remove_container [VERSION]", "Remove app container with given version from servers", hide: true
|
||||||
def remove_container(version)
|
def remove_container(version)
|
||||||
with_lock do
|
with_lock do
|
||||||
on(MRSK.hosts) do
|
on(MRSK.hosts) do |host|
|
||||||
execute *MRSK.auditor.record("Removed app container with version #{version}"), verbosity: :debug
|
roles = MRSK.roles_on(host)
|
||||||
execute *MRSK.app.remove_container(version: version)
|
|
||||||
|
roles.each do |role|
|
||||||
|
execute *MRSK.auditor(role: role).record("Removed app container with version #{version}"), verbosity: :debug
|
||||||
|
execute *MRSK.app(role: role).remove_container(version: version)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -166,9 +190,13 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
|
|||||||
desc "remove_containers", "Remove all app containers from servers", hide: true
|
desc "remove_containers", "Remove all app containers from servers", hide: true
|
||||||
def remove_containers
|
def remove_containers
|
||||||
with_lock do
|
with_lock do
|
||||||
on(MRSK.hosts) do
|
on(MRSK.hosts) do |host|
|
||||||
execute *MRSK.auditor.record("Removed all app containers"), verbosity: :debug
|
roles = MRSK.roles_on(host)
|
||||||
execute *MRSK.app.remove_containers
|
|
||||||
|
roles.each do |role|
|
||||||
|
execute *MRSK.auditor(role: role).record("Removed all app containers"), verbosity: :debug
|
||||||
|
execute *MRSK.app(role: role).remove_containers
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ class Mrsk::Commander
|
|||||||
self.lock_count = 0
|
self.lock_count = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def config
|
def config
|
||||||
@config ||= Mrsk::Configuration.create_from(**@config_kwargs).tap do |config|
|
@config ||= Mrsk::Configuration.create_from(**@config_kwargs).tap do |config|
|
||||||
@config_kwargs = nil
|
@config_kwargs = nil
|
||||||
@@ -21,23 +20,38 @@ class Mrsk::Commander
|
|||||||
@config, @config_kwargs = nil, kwargs
|
@config, @config_kwargs = nil, kwargs
|
||||||
end
|
end
|
||||||
|
|
||||||
|
attr_reader :specific_roles, :specific_hosts
|
||||||
attr_accessor :specific_hosts
|
|
||||||
|
|
||||||
def specific_primary!
|
def specific_primary!
|
||||||
self.specific_hosts = [ config.primary_web_host ]
|
self.specific_hosts = [ config.primary_web_host ]
|
||||||
end
|
end
|
||||||
|
|
||||||
def specific_roles=(role_names)
|
def specific_roles=(role_names)
|
||||||
self.specific_hosts = config.roles.select { |r| role_names.include?(r.name) }.flat_map(&:hosts) if role_names.present?
|
@specific_roles = config.roles.select { |r| role_names.include?(r.name) } if role_names.present?
|
||||||
|
end
|
||||||
|
|
||||||
|
def specific_hosts=(hosts)
|
||||||
|
@specific_hosts = config.all_hosts & hosts if hosts.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def primary_host
|
def primary_host
|
||||||
specific_hosts&.first || config.primary_web_host
|
specific_hosts&.first || config.primary_web_host
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def roles
|
||||||
|
(specific_roles || config.roles).select do |role|
|
||||||
|
((specific_hosts || config.all_hosts) & role.hosts).any?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def hosts
|
def hosts
|
||||||
specific_hosts || config.all_hosts
|
(specific_hosts || config.all_hosts).select do |host|
|
||||||
|
(specific_roles || config.roles).flat_map(&:hosts).include?(host)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def roles_on(host)
|
||||||
|
roles.select { |role| role.hosts.include?(host.to_s) }.map(&:name)
|
||||||
end
|
end
|
||||||
|
|
||||||
def traefik_hosts
|
def traefik_hosts
|
||||||
@@ -53,16 +67,16 @@ class Mrsk::Commander
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def app
|
def app(role: nil)
|
||||||
@app ||= Mrsk::Commands::App.new(config)
|
Mrsk::Commands::App.new(config, role: role)
|
||||||
end
|
end
|
||||||
|
|
||||||
def accessory(name)
|
def accessory(name)
|
||||||
Mrsk::Commands::Accessory.new(config, name: name)
|
Mrsk::Commands::Accessory.new(config, name: name)
|
||||||
end
|
end
|
||||||
|
|
||||||
def auditor
|
def auditor(role: nil)
|
||||||
@auditor ||= Mrsk::Commands::Auditor.new(config)
|
Mrsk::Commands::Auditor.new(config, role: role)
|
||||||
end
|
end
|
||||||
|
|
||||||
def builder
|
def builder
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
class Mrsk::Commands::Accessory < Mrsk::Commands::Base
|
class Mrsk::Commands::Accessory < Mrsk::Commands::Base
|
||||||
attr_reader :accessory_config
|
attr_reader :accessory_config
|
||||||
delegate :service_name, :image, :host, :port, :files, :directories, :publish_args, :env_args, :volume_args, :label_args, to: :accessory_config
|
delegate :service_name, :image, :host, :port, :files, :directories, :publish_args, :env_args, :volume_args,
|
||||||
|
:label_args, :option_args, to: :accessory_config
|
||||||
|
|
||||||
def initialize(config, name:)
|
def initialize(config, name:)
|
||||||
super(config)
|
super(config)
|
||||||
@@ -12,11 +13,12 @@ class Mrsk::Commands::Accessory < Mrsk::Commands::Base
|
|||||||
"--name", service_name,
|
"--name", service_name,
|
||||||
"--detach",
|
"--detach",
|
||||||
"--restart", "unless-stopped",
|
"--restart", "unless-stopped",
|
||||||
"--log-opt", "max-size=#{MAX_LOG_SIZE}",
|
*config.logging_args,
|
||||||
*publish_args,
|
*publish_args,
|
||||||
*env_args,
|
*env_args,
|
||||||
*volume_args,
|
*volume_args,
|
||||||
*label_args,
|
*label_args,
|
||||||
|
*option_args,
|
||||||
image
|
image
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,21 @@
|
|||||||
class Mrsk::Commands::App < Mrsk::Commands::Base
|
class Mrsk::Commands::App < Mrsk::Commands::Base
|
||||||
def run(role: :web)
|
attr_reader :role
|
||||||
role = config.role(role)
|
|
||||||
|
def initialize(config, role: nil)
|
||||||
|
super(config)
|
||||||
|
@role = role
|
||||||
|
end
|
||||||
|
|
||||||
|
def run
|
||||||
|
role = config.role(self.role)
|
||||||
|
|
||||||
docker :run,
|
docker :run,
|
||||||
"--detach",
|
"--detach",
|
||||||
"--restart unless-stopped",
|
"--restart unless-stopped",
|
||||||
"--log-opt", "max-size=#{MAX_LOG_SIZE}",
|
"--name", container_name,
|
||||||
"--name", service_with_version_and_destination,
|
"-e", "MRSK_CONTAINER_NAME=\"#{container_name}\"",
|
||||||
"-e", "MRSK_CONTAINER_NAME=\"#{service_with_version_and_destination}\"",
|
|
||||||
*role.env_args,
|
*role.env_args,
|
||||||
|
*config.logging_args,
|
||||||
*config.volume_args,
|
*config.volume_args,
|
||||||
*role.label_args,
|
*role.label_args,
|
||||||
*role.option_args,
|
*role.option_args,
|
||||||
@@ -17,13 +24,13 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def start
|
def start
|
||||||
docker :start, service_with_version_and_destination
|
docker :start, container_name
|
||||||
end
|
end
|
||||||
|
|
||||||
def stop(version: nil)
|
def stop(version: nil)
|
||||||
pipe \
|
pipe \
|
||||||
version ? container_id_for_version(version) : current_container_id,
|
version ? container_id_for_version(version) : current_container_id,
|
||||||
xargs(docker(:stop))
|
xargs(config.stop_wait_time ? docker(:stop, "-t", config.stop_wait_time) : docker(:stop))
|
||||||
end
|
end
|
||||||
|
|
||||||
def info
|
def info
|
||||||
@@ -52,7 +59,7 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
|
|||||||
def execute_in_existing_container(*command, interactive: false)
|
def execute_in_existing_container(*command, interactive: false)
|
||||||
docker :exec,
|
docker :exec,
|
||||||
("-it" if interactive),
|
("-it" if interactive),
|
||||||
service_with_version_and_destination,
|
container_name,
|
||||||
*command
|
*command
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -97,7 +104,7 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
|
|||||||
|
|
||||||
def remove_container(version:)
|
def remove_container(version:)
|
||||||
pipe \
|
pipe \
|
||||||
container_id_for(container_name: service_with_version_and_destination(version)),
|
container_id_for(container_name: container_name(version)),
|
||||||
xargs(docker(:container, :rm))
|
xargs(docker(:container, :rm))
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -115,12 +122,12 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
|
|||||||
|
|
||||||
|
|
||||||
private
|
private
|
||||||
def service_with_version_and_destination(version = nil)
|
def container_name(version = nil)
|
||||||
[ config.service, config.destination, version || config.version ].compact.join("-")
|
[ config.service, role, config.destination, version || config.version ].compact.join("-")
|
||||||
end
|
end
|
||||||
|
|
||||||
def container_id_for_version(version)
|
def container_id_for_version(version)
|
||||||
container_id_for(container_name: service_with_version_and_destination(version))
|
container_id_for(container_name: container_name(version))
|
||||||
end
|
end
|
||||||
|
|
||||||
def filter_args
|
def filter_args
|
||||||
@@ -130,6 +137,7 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
|
|||||||
def filters
|
def filters
|
||||||
[ "label=service=#{config.service}" ].tap do |filters|
|
[ "label=service=#{config.service}" ].tap do |filters|
|
||||||
filters << "label=destination=#{config.destination}" if config.destination
|
filters << "label=destination=#{config.destination}" if config.destination
|
||||||
|
filters << "label=role=#{role}" if role
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
require "active_support/core_ext/time/conversions"
|
require "active_support/core_ext/time/conversions"
|
||||||
|
|
||||||
class Mrsk::Commands::Auditor < Mrsk::Commands::Base
|
class Mrsk::Commands::Auditor < Mrsk::Commands::Base
|
||||||
|
attr_reader :role
|
||||||
|
|
||||||
|
def initialize(config, role: nil)
|
||||||
|
super(config)
|
||||||
|
@role = role
|
||||||
|
end
|
||||||
|
|
||||||
# Runs remotely
|
# Runs remotely
|
||||||
def record(line)
|
def record(line)
|
||||||
append \
|
append \
|
||||||
@@ -25,18 +32,26 @@ class Mrsk::Commands::Auditor < Mrsk::Commands::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def tagged_record_line(line)
|
def tagged_record_line(line)
|
||||||
"'#{recorded_at_tag} #{performer_tag} #{line}'"
|
tagged_line recorded_at_tag, performer_tag, role_tag, line
|
||||||
end
|
end
|
||||||
|
|
||||||
def tagged_broadcast_line(line)
|
def tagged_broadcast_line(line)
|
||||||
"'#{performer_tag} #{line}'"
|
tagged_line performer_tag, role_tag, line
|
||||||
|
end
|
||||||
|
|
||||||
|
def tagged_line(*tags_and_line)
|
||||||
|
"'#{tags_and_line.compact.join(" ")}'"
|
||||||
|
end
|
||||||
|
|
||||||
|
def recorded_at_tag
|
||||||
|
"[#{Time.now.to_fs(:db)}]"
|
||||||
end
|
end
|
||||||
|
|
||||||
def performer_tag
|
def performer_tag
|
||||||
"[#{`whoami`.strip}]"
|
"[#{`whoami`.strip}]"
|
||||||
end
|
end
|
||||||
|
|
||||||
def recorded_at_tag
|
def role_tag
|
||||||
"[#{Time.now.to_fs(:db)}]"
|
"[#{role}]" if role
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ module Mrsk::Commands
|
|||||||
class Base
|
class Base
|
||||||
delegate :redact, :argumentize, to: Mrsk::Utils
|
delegate :redact, :argumentize, to: Mrsk::Utils
|
||||||
|
|
||||||
MAX_LOG_SIZE = "10m"
|
|
||||||
|
|
||||||
attr_accessor :config
|
attr_accessor :config
|
||||||
|
|
||||||
def initialize(config)
|
def initialize(config)
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ class Mrsk::Commands::Traefik < Mrsk::Commands::Base
|
|||||||
docker :run, "--name traefik",
|
docker :run, "--name traefik",
|
||||||
"--detach",
|
"--detach",
|
||||||
"--restart", "unless-stopped",
|
"--restart", "unless-stopped",
|
||||||
"--log-opt", "max-size=#{MAX_LOG_SIZE}",
|
|
||||||
"--publish", port,
|
"--publish", port,
|
||||||
"--volume", "/var/run/docker.sock:/var/run/docker.sock",
|
"--volume", "/var/run/docker.sock:/var/run/docker.sock",
|
||||||
|
*config.logging_args,
|
||||||
*docker_options_args,
|
*docker_options_args,
|
||||||
"traefik",
|
"traefik",
|
||||||
"--providers.docker",
|
"--providers.docker",
|
||||||
@@ -50,7 +50,7 @@ class Mrsk::Commands::Traefik < Mrsk::Commands::Base
|
|||||||
docker :image, :prune, "--all", "--force", "--filter", "label=org.opencontainers.image.title=Traefik"
|
docker :image, :prune, "--all", "--force", "--filter", "label=org.opencontainers.image.title=Traefik"
|
||||||
end
|
end
|
||||||
|
|
||||||
def port
|
def port
|
||||||
"#{host_port}:#{CONTAINER_PORT}"
|
"#{host_port}:#{CONTAINER_PORT}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ require "erb"
|
|||||||
require "net/ssh/proxy/jump"
|
require "net/ssh/proxy/jump"
|
||||||
|
|
||||||
class Mrsk::Configuration
|
class Mrsk::Configuration
|
||||||
delegate :service, :image, :servers, :env, :labels, :registry, :builder, to: :raw_config, allow_nil: true
|
delegate :service, :image, :servers, :env, :labels, :registry, :builder, :stop_wait_time, to: :raw_config, allow_nil: true
|
||||||
delegate :argumentize, :argumentize_env_with_secrets, to: Mrsk::Utils
|
delegate :argumentize, :argumentize_env_with_secrets, :optionize, to: Mrsk::Utils
|
||||||
|
|
||||||
attr_accessor :destination
|
attr_accessor :destination
|
||||||
attr_accessor :raw_config
|
attr_accessor :raw_config
|
||||||
@@ -76,7 +76,7 @@ class Mrsk::Configuration
|
|||||||
|
|
||||||
|
|
||||||
def all_hosts
|
def all_hosts
|
||||||
roles.flat_map(&:hosts)
|
roles.flat_map(&:hosts).uniq
|
||||||
end
|
end
|
||||||
|
|
||||||
def primary_web_host
|
def primary_web_host
|
||||||
@@ -84,7 +84,7 @@ class Mrsk::Configuration
|
|||||||
end
|
end
|
||||||
|
|
||||||
def traefik_hosts
|
def traefik_hosts
|
||||||
roles.select(&:running_traefik?).flat_map(&:hosts)
|
roles.select(&:running_traefik?).flat_map(&:hosts).uniq
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -121,6 +121,15 @@ class Mrsk::Configuration
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def logging_args
|
||||||
|
if raw_config.logging.present?
|
||||||
|
optionize({ "log-driver" => raw_config.logging["driver"] }.compact) +
|
||||||
|
argumentize("--log-opt", raw_config.logging["options"])
|
||||||
|
else
|
||||||
|
argumentize("--log-opt", { "max-size" => "10m" })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
def ssh_user
|
def ssh_user
|
||||||
if raw_config.ssh.present?
|
if raw_config.ssh.present?
|
||||||
@@ -173,6 +182,7 @@ class Mrsk::Configuration
|
|||||||
ssh_options: ssh_options,
|
ssh_options: ssh_options,
|
||||||
builder: raw_config.builder,
|
builder: raw_config.builder,
|
||||||
accessories: raw_config.accessories,
|
accessories: raw_config.accessories,
|
||||||
|
logging: logging_args,
|
||||||
healthcheck: healthcheck
|
healthcheck: healthcheck
|
||||||
}.compact
|
}.compact
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
class Mrsk::Configuration::Accessory
|
class Mrsk::Configuration::Accessory
|
||||||
delegate :argumentize, :argumentize_env_with_secrets, to: Mrsk::Utils
|
delegate :argumentize, :argumentize_env_with_secrets, :optionize, to: Mrsk::Utils
|
||||||
|
|
||||||
attr_accessor :name, :specifics
|
attr_accessor :name, :specifics
|
||||||
|
|
||||||
@@ -67,6 +67,14 @@ class Mrsk::Configuration::Accessory
|
|||||||
argumentize "--volume", volumes
|
argumentize "--volume", volumes
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def option_args
|
||||||
|
if args = specifics["options"]
|
||||||
|
optionize args
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
attr_accessor :config
|
attr_accessor :config
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ class CliAccessoryTest < CliTestCase
|
|||||||
|
|
||||||
run_command("boot", "mysql").tap do |output|
|
run_command("boot", "mysql").tap do |output|
|
||||||
assert_match /docker login.*on 1.1.1.3/, output
|
assert_match /docker login.*on 1.1.1.3/, output
|
||||||
assert_match "docker run --name app-mysql --detach --restart unless-stopped --log-opt max-size=10m --publish 3306:3306 -e [REDACTED] -e MYSQL_ROOT_HOST=\"%\" --volume $PWD/app-mysql/etc/mysql/my.cnf:/etc/mysql/my.cnf --volume $PWD/app-mysql/data:/var/lib/mysql --label service=\"app-mysql\" mysql:5.7 on 1.1.1.3", output
|
assert_match "docker run --name app-mysql --detach --restart unless-stopped --log-opt max-size=\"10m\" --publish 3306:3306 -e [REDACTED] -e MYSQL_ROOT_HOST=\"%\" --volume $PWD/app-mysql/etc/mysql/my.cnf:/etc/mysql/my.cnf --volume $PWD/app-mysql/data:/var/lib/mysql --label service=\"app-mysql\" mysql:5.7 on 1.1.1.3", output
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -20,8 +20,8 @@ class CliAccessoryTest < CliTestCase
|
|||||||
run_command("boot", "all").tap do |output|
|
run_command("boot", "all").tap do |output|
|
||||||
assert_match /docker login.*on 1.1.1.3/, output
|
assert_match /docker login.*on 1.1.1.3/, output
|
||||||
assert_match /docker login.*on 1.1.1.4/, output
|
assert_match /docker login.*on 1.1.1.4/, output
|
||||||
assert_match "docker run --name app-mysql --detach --restart unless-stopped --log-opt max-size=10m --publish 3306:3306 -e [REDACTED] -e MYSQL_ROOT_HOST=\"%\" --volume $PWD/app-mysql/etc/mysql/my.cnf:/etc/mysql/my.cnf --volume $PWD/app-mysql/data:/var/lib/mysql --label service=\"app-mysql\" mysql:5.7 on 1.1.1.3", output
|
assert_match "docker run --name app-mysql --detach --restart unless-stopped --log-opt max-size=\"10m\" --publish 3306:3306 -e [REDACTED] -e MYSQL_ROOT_HOST=\"%\" --volume $PWD/app-mysql/etc/mysql/my.cnf:/etc/mysql/my.cnf --volume $PWD/app-mysql/data:/var/lib/mysql --label service=\"app-mysql\" mysql:5.7 on 1.1.1.3", output
|
||||||
assert_match "docker run --name app-redis --detach --restart unless-stopped --log-opt max-size=10m --publish 6379:6379 --volume $PWD/app-redis/data:/data --label service=\"app-redis\" redis:latest on 1.1.1.4", output
|
assert_match "docker run --name app-redis --detach --restart unless-stopped --log-opt max-size=\"10m\" --publish 6379:6379 --volume $PWD/app-redis/data:/data --label service=\"app-redis\" redis:latest on 1.1.1.4", output
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,11 @@ require_relative "cli_test_case"
|
|||||||
class CliAppTest < CliTestCase
|
class CliAppTest < CliTestCase
|
||||||
test "boot" do
|
test "boot" do
|
||||||
# Stub current version fetch
|
# Stub current version fetch
|
||||||
SSHKit::Backend::Abstract.any_instance.stubs(:capture)
|
SSHKit::Backend::Abstract.any_instance.stubs(:capture).returns("123") # old version
|
||||||
.returns("999") # new version
|
|
||||||
.then
|
|
||||||
.returns("123") # old version
|
|
||||||
|
|
||||||
run_command("boot").tap do |output|
|
run_command("boot").tap do |output|
|
||||||
assert_match "docker run --detach --restart unless-stopped", output
|
assert_match "docker run --detach --restart unless-stopped", output
|
||||||
assert_match "docker container ls --all --filter name=app-123 --quiet | xargs docker stop", output
|
assert_match "docker container ls --all --filter name=app-web-123 --quiet | xargs docker stop", output
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -20,16 +17,14 @@ class CliAppTest < CliTestCase
|
|||||||
# Prevent expected failures from outputting to terminal
|
# Prevent expected failures from outputting to terminal
|
||||||
Thread.report_on_exception = false
|
Thread.report_on_exception = false
|
||||||
|
|
||||||
MRSK.app.stubs(:run)
|
Mrsk::Commands::App.any_instance.stubs(:run)
|
||||||
.raises(SSHKit::Command::Failed.new("already in use"))
|
|
||||||
.then
|
|
||||||
.raises(SSHKit::Command::Failed.new("already in use"))
|
.raises(SSHKit::Command::Failed.new("already in use"))
|
||||||
.then
|
.then
|
||||||
.returns([ :docker, :run ])
|
.returns([ :docker, :run ])
|
||||||
|
|
||||||
run_command("boot").tap do |output|
|
run_command("boot").tap do |output|
|
||||||
assert_match "Rebooting container with same version latest already deployed", output # Can't start what's already running
|
assert_match "Rebooting container with same version latest already deployed", output # Can't start what's already running
|
||||||
assert_match "docker container ls --all --filter name=app-latest --quiet | xargs docker container rm", output # Remove old container
|
assert_match "docker container ls --all --filter name=app-web-latest --quiet | xargs docker container rm", output # Remove old container
|
||||||
assert_match "docker run", output # Start new container
|
assert_match "docker run", output # Start new container
|
||||||
end
|
end
|
||||||
ensure
|
ensure
|
||||||
@@ -38,32 +33,58 @@ class CliAppTest < CliTestCase
|
|||||||
|
|
||||||
test "start" do
|
test "start" do
|
||||||
run_command("start").tap do |output|
|
run_command("start").tap do |output|
|
||||||
assert_match "docker start app-999", output
|
assert_match "docker start app-web-999", output
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "stop" do
|
test "stop" do
|
||||||
run_command("stop").tap do |output|
|
run_command("stop").tap do |output|
|
||||||
assert_match "docker ps --quiet --filter label=service=app | xargs docker stop", output
|
assert_match "docker ps --quiet --filter label=service=app --filter label=role=web | xargs docker stop", output
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "details" do
|
test "details" do
|
||||||
run_command("details").tap do |output|
|
run_command("details").tap do |output|
|
||||||
assert_match "docker ps --filter label=service=app", output
|
assert_match "docker ps --filter label=service=app --filter label=role=web", output
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "remove" do
|
||||||
|
run_command("remove").tap do |output|
|
||||||
|
assert_match /#{Regexp.escape("docker ps --quiet --filter label=service=app --filter label=role=web | xargs docker stop")}/, output
|
||||||
|
assert_match /#{Regexp.escape("docker container prune --force --filter label=service=app")}/, output
|
||||||
|
assert_match /#{Regexp.escape("docker image prune --all --force --filter label=service=app")}/, output
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "remove_container" do
|
||||||
|
run_command("remove_container", "1234567").tap do |output|
|
||||||
|
assert_match "docker container ls --all --filter name=app-web-1234567 --quiet | xargs docker container rm", output
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "remove_containers" do
|
||||||
|
run_command("remove_containers").tap do |output|
|
||||||
|
assert_match "docker container prune --force --filter label=service=app", output
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "remove_images" do
|
||||||
|
run_command("remove_images").tap do |output|
|
||||||
|
assert_match "docker image prune --all --force --filter label=service=app", output
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "exec" do
|
test "exec" do
|
||||||
run_command("exec", "ruby -v").tap do |output|
|
run_command("exec", "ruby -v").tap do |output|
|
||||||
assert_match "ruby -v", output
|
assert_match "docker run --rm dhh/app:latest ruby -v", output
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "exec with reuse" do
|
test "exec with reuse" do
|
||||||
run_command("exec", "--reuse", "ruby -v").tap do |output|
|
run_command("exec", "--reuse", "ruby -v").tap do |output|
|
||||||
assert_match "docker ps --filter label=service=app --format \"{{.Names}}\" | sed 's/-/\\n/g' | tail -n 1", output # Get current version
|
assert_match "docker ps --filter label=service=app --format \"{{.Names}}\" | sed 's/-/\\n/g' | tail -n 1", output # Get current version
|
||||||
assert_match "docker exec app-999 ruby -v", output
|
assert_match "docker exec app-web-999 ruby -v", output
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -93,32 +114,6 @@ class CliAppTest < CliTestCase
|
|||||||
assert_match "docker ps --quiet --filter label=service=app | xargs docker logs --timestamps --tail 10 --follow 2>&1", run_command("logs", "--follow")
|
assert_match "docker ps --quiet --filter label=service=app | xargs docker logs --timestamps --tail 10 --follow 2>&1", run_command("logs", "--follow")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "remove" do
|
|
||||||
Mrsk::Cli::App.any_instance.expects(:stop)
|
|
||||||
Mrsk::Cli::App.any_instance.expects(:remove_containers)
|
|
||||||
Mrsk::Cli::App.any_instance.expects(:remove_images)
|
|
||||||
|
|
||||||
run_command("remove")
|
|
||||||
end
|
|
||||||
|
|
||||||
test "remove_container" do
|
|
||||||
run_command("remove_container", "1234567").tap do |output|
|
|
||||||
assert_match "docker container ls --all --filter name=app-1234567 --quiet | xargs docker container rm", output
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
test "remove_containers" do
|
|
||||||
run_command("remove_containers").tap do |output|
|
|
||||||
assert_match "docker container prune --force --filter label=service=app", output
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
test "remove_images" do
|
|
||||||
run_command("remove_images").tap do |output|
|
|
||||||
assert_match "docker image prune --all --force --filter label=service=app", output
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
test "version" do
|
test "version" do
|
||||||
run_command("version").tap do |output|
|
run_command("version").tap do |output|
|
||||||
assert_match "docker ps --filter label=service=app --format \"{{.Names}}\" | sed 's/-/\\n/g' | tail -n 1", output
|
assert_match "docker ps --filter label=service=app --format \"{{.Names}}\" | sed 's/-/\\n/g' | tail -n 1", output
|
||||||
@@ -127,6 +122,6 @@ class CliAppTest < CliTestCase
|
|||||||
|
|
||||||
private
|
private
|
||||||
def run_command(*command)
|
def run_command(*command)
|
||||||
stdouted { Mrsk::Cli::App.start([*command, "-c", "test/fixtures/deploy_with_accessories.yml"]) }
|
stdouted { Mrsk::Cli::App.start([*command, "-c", "test/fixtures/deploy_with_accessories.yml", "--hosts", "1.1.1.1"]) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ class CliMainTest < CliTestCase
|
|||||||
|
|
||||||
test "rollback good version" do
|
test "rollback good version" do
|
||||||
Mrsk::Cli::Main.any_instance.stubs(:container_name_available?).returns(true)
|
Mrsk::Cli::Main.any_instance.stubs(:container_name_available?).returns(true)
|
||||||
SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info).with(:docker, :ps, "--filter", "label=service=app", "--format", "\"{{.Names}}\"", "|", "sed 's/-/\\n/g'", "|", "tail -n 1").returns("version-to-rollback\n").times(2)
|
SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info).with(:docker, :ps, "--filter", "label=service=app", "--format", "\"{{.Names}}\"", "|", "sed 's/-/\\n/g'", "|", "tail -n 1").returns("version-to-rollback\n").at_least_once
|
||||||
|
|
||||||
run_command("rollback", "123").tap do |output|
|
run_command("rollback", "123").tap do |output|
|
||||||
assert_match "Start version 123", output
|
assert_match "Start version 123", output
|
||||||
@@ -101,7 +101,7 @@ class CliMainTest < CliTestCase
|
|||||||
|
|
||||||
test "rollback without old version" do
|
test "rollback without old version" do
|
||||||
Mrsk::Cli::Main.any_instance.stubs(:container_name_available?).returns(true)
|
Mrsk::Cli::Main.any_instance.stubs(:container_name_available?).returns(true)
|
||||||
SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info).with(:docker, :ps, "--filter", "label=service=app", "--format", "\"{{.Names}}\"", "|", "sed 's/-/\\n/g'", "|", "tail -n 1").returns("").times(2)
|
SSHKit::Backend::Abstract.any_instance.expects(:capture_with_info).with(:docker, :ps, "--filter", "label=service=app", "--format", "\"{{.Names}}\"", "|", "sed 's/-/\\n/g'", "|", "tail -n 1").returns("").at_least_once
|
||||||
|
|
||||||
run_command("rollback", "123").tap do |output|
|
run_command("rollback", "123").tap do |output|
|
||||||
assert_match "Start version 123", output
|
assert_match "Start version 123", output
|
||||||
@@ -122,8 +122,6 @@ class CliMainTest < CliTestCase
|
|||||||
run_command("audit").tap do |output|
|
run_command("audit").tap do |output|
|
||||||
assert_match /tail -n 50 mrsk-app-audit.log on 1.1.1.1/, output
|
assert_match /tail -n 50 mrsk-app-audit.log on 1.1.1.1/, output
|
||||||
assert_match /App Host: 1.1.1.1/, output
|
assert_match /App Host: 1.1.1.1/, output
|
||||||
assert_match /tail -n 50 mrsk-app-audit.log on 1.1.1.2/, output
|
|
||||||
assert_match /App Host: 1.1.1.2/, output
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -10,15 +10,13 @@ class CliPruneTest < CliTestCase
|
|||||||
|
|
||||||
test "images" do
|
test "images" do
|
||||||
run_command("images").tap do |output|
|
run_command("images").tap do |output|
|
||||||
assert_match "docker image prune --all --force --filter label=service=app --filter until=168h on 1.1.1.1", output
|
assert_match /docker image prune --all --force --filter label=service=app --filter until=168h on 1.1.1.\d/, output
|
||||||
assert_match "docker image prune --all --force --filter label=service=app --filter until=168h on 1.1.1.2", output
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "containers" do
|
test "containers" do
|
||||||
run_command("containers").tap do |output|
|
run_command("containers").tap do |output|
|
||||||
assert_match "docker container prune --force --filter label=service=app --filter until=72h on 1.1.1.1", output
|
assert_match /docker container prune --force --filter label=service=app --filter until=72h on 1.1.1.\d/, output
|
||||||
assert_match "docker container prune --force --filter label=service=app --filter until=72h on 1.1.1.2", output
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -4,15 +4,13 @@ class CliRegistryTest < CliTestCase
|
|||||||
test "login" do
|
test "login" do
|
||||||
run_command("login").tap do |output|
|
run_command("login").tap do |output|
|
||||||
assert_match /docker login -u \[REDACTED\] -p \[REDACTED\] as .*@localhost/, output
|
assert_match /docker login -u \[REDACTED\] -p \[REDACTED\] as .*@localhost/, output
|
||||||
assert_match "docker login -u [REDACTED] -p [REDACTED] on 1.1.1.1", output
|
assert_match /docker login -u \[REDACTED\] -p \[REDACTED\] on 1.1.1.\d/, output
|
||||||
assert_match "docker login -u [REDACTED] -p [REDACTED] on 1.1.1.2", output
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "logout" do
|
test "logout" do
|
||||||
run_command("logout").tap do |output|
|
run_command("logout").tap do |output|
|
||||||
assert_match "docker logout on 1.1.1.1", output
|
assert_match /docker logout on 1.1.1.\d/, output
|
||||||
assert_match "docker logout on 1.1.1.2", output
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ require_relative "cli_test_case"
|
|||||||
class CliTraefikTest < CliTestCase
|
class CliTraefikTest < CliTestCase
|
||||||
test "boot" do
|
test "boot" do
|
||||||
run_command("boot").tap do |output|
|
run_command("boot").tap do |output|
|
||||||
assert_match "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", output
|
assert_match "docker run --name traefik --detach --restart unless-stopped --publish 80:80 --volume /var/run/docker.sock:/var/run/docker.sock --log-opt max-size=\"10m\" traefik --providers.docker --log.level=DEBUG", output
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -14,18 +14,29 @@ class CommanderTest < ActiveSupport::TestCase
|
|||||||
test "overwriting hosts" do
|
test "overwriting hosts" do
|
||||||
assert_equal [ "1.1.1.1", "1.1.1.2", "1.1.1.3", "1.1.1.4" ], @mrsk.hosts
|
assert_equal [ "1.1.1.1", "1.1.1.2", "1.1.1.3", "1.1.1.4" ], @mrsk.hosts
|
||||||
|
|
||||||
@mrsk.specific_hosts = [ "1.2.3.4", "1.2.3.5" ]
|
@mrsk.specific_hosts = [ "1.1.1.1", "1.1.1.2" ]
|
||||||
assert_equal [ "1.2.3.4", "1.2.3.5" ], @mrsk.hosts
|
assert_equal [ "1.1.1.1", "1.1.1.2" ], @mrsk.hosts
|
||||||
end
|
end
|
||||||
|
|
||||||
test "overwriting hosts with roles" do
|
test "filtering hosts by filtering roles" do
|
||||||
assert_equal [ "1.1.1.1", "1.1.1.2", "1.1.1.3", "1.1.1.4" ], @mrsk.hosts
|
assert_equal [ "1.1.1.1", "1.1.1.2", "1.1.1.3", "1.1.1.4" ], @mrsk.hosts
|
||||||
|
|
||||||
@mrsk.specific_roles = [ "workers", "web" ]
|
@mrsk.specific_roles = [ "web" ]
|
||||||
assert_equal [ "1.1.1.1", "1.1.1.2", "1.1.1.3", "1.1.1.4" ], @mrsk.hosts
|
assert_equal [ "1.1.1.1", "1.1.1.2" ], @mrsk.hosts
|
||||||
|
end
|
||||||
|
|
||||||
|
test "filtering roles" do
|
||||||
|
assert_equal [ "web", "workers" ], @mrsk.roles.map(&:name)
|
||||||
|
|
||||||
@mrsk.specific_roles = [ "workers" ]
|
@mrsk.specific_roles = [ "workers" ]
|
||||||
assert_equal [ "1.1.1.3", "1.1.1.4" ], @mrsk.hosts
|
assert_equal [ "workers" ], @mrsk.roles.map(&:name)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "filtering roles by filtering hosts" do
|
||||||
|
assert_equal [ "web", "workers" ], @mrsk.roles.map(&:name)
|
||||||
|
|
||||||
|
@mrsk.specific_hosts = [ "1.1.1.3" ]
|
||||||
|
assert_equal [ "workers" ], @mrsk.roles.map(&:name)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "overwriting hosts with primary" do
|
test "overwriting hosts with primary" do
|
||||||
@@ -39,4 +50,9 @@ class CommanderTest < ActiveSupport::TestCase
|
|||||||
@mrsk.specific_roles = "web"
|
@mrsk.specific_roles = "web"
|
||||||
assert_equal "1.1.1.1", @mrsk.primary_host
|
assert_equal "1.1.1.1", @mrsk.primary_host
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "roles_on" do
|
||||||
|
assert_equal [ "web" ], @mrsk.roles_on("1.1.1.1")
|
||||||
|
assert_equal [ "workers" ], @mrsk.roles_on("1.1.1.3")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -40,11 +40,6 @@ class CommandsAccessoryTest < ActiveSupport::TestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@config = Mrsk::Configuration.new(@config)
|
|
||||||
@mysql = Mrsk::Commands::Accessory.new(@config, name: :mysql)
|
|
||||||
@redis = Mrsk::Commands::Accessory.new(@config, name: :redis)
|
|
||||||
@busybox = Mrsk::Commands::Accessory.new(@config, name: :busybox)
|
|
||||||
|
|
||||||
ENV["MYSQL_ROOT_PASSWORD"] = "secret123"
|
ENV["MYSQL_ROOT_PASSWORD"] = "secret123"
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -54,60 +49,68 @@ class CommandsAccessoryTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
test "run" do
|
test "run" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker run --name app-mysql --detach --restart unless-stopped --log-opt max-size=10m --publish 3306:3306 -e MYSQL_ROOT_PASSWORD=\"secret123\" -e MYSQL_ROOT_HOST=\"%\" --label service=\"app-mysql\" private.registry/mysql:8.0",
|
"docker run --name app-mysql --detach --restart unless-stopped --log-opt max-size=\"10m\" --publish 3306:3306 -e MYSQL_ROOT_PASSWORD=\"secret123\" -e MYSQL_ROOT_HOST=\"%\" --label service=\"app-mysql\" private.registry/mysql:8.0",
|
||||||
@mysql.run.join(" ")
|
new_command(:mysql).run.join(" ")
|
||||||
|
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker run --name app-redis --detach --restart unless-stopped --log-opt max-size=10m --publish 6379:6379 -e SOMETHING=\"else\" --volume /var/lib/redis:/data --label service=\"app-redis\" --label cache=\"true\" redis:latest",
|
"docker run --name app-redis --detach --restart unless-stopped --log-opt max-size=\"10m\" --publish 6379:6379 -e SOMETHING=\"else\" --volume /var/lib/redis:/data --label service=\"app-redis\" --label cache=\"true\" redis:latest",
|
||||||
@redis.run.join(" ")
|
new_command(:redis).run.join(" ")
|
||||||
|
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker run --name app-busybox --detach --restart unless-stopped --log-opt max-size=10m --label service=\"app-busybox\" busybox:latest",
|
"docker run --name app-busybox --detach --restart unless-stopped --log-opt max-size=\"10m\" --label service=\"app-busybox\" busybox:latest",
|
||||||
@busybox.run.join(" ")
|
new_command(:busybox).run.join(" ")
|
||||||
|
end
|
||||||
|
|
||||||
|
test "run with logging config" do
|
||||||
|
@config[:logging] = { "driver" => "local", "options" => { "max-size" => "100m", "max-file" => "3" } }
|
||||||
|
|
||||||
|
assert_equal \
|
||||||
|
"docker run --name app-busybox --detach --restart unless-stopped --log-driver \"local\" --log-opt max-size=\"100m\" --log-opt max-file=\"3\" --label service=\"app-busybox\" busybox:latest",
|
||||||
|
new_command(:busybox).run.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "start" do
|
test "start" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker container start app-mysql",
|
"docker container start app-mysql",
|
||||||
@mysql.start.join(" ")
|
new_command(:mysql).start.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "stop" do
|
test "stop" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker container stop app-mysql",
|
"docker container stop app-mysql",
|
||||||
@mysql.stop.join(" ")
|
new_command(:mysql).stop.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "info" do
|
test "info" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker ps --filter label=service=app-mysql",
|
"docker ps --filter label=service=app-mysql",
|
||||||
@mysql.info.join(" ")
|
new_command(:mysql).info.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
test "execute in new container" do
|
test "execute in new container" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker run --rm -e MYSQL_ROOT_PASSWORD=\"secret123\" -e MYSQL_ROOT_HOST=\"%\" private.registry/mysql:8.0 mysql -u root",
|
"docker run --rm -e MYSQL_ROOT_PASSWORD=\"secret123\" -e MYSQL_ROOT_HOST=\"%\" private.registry/mysql:8.0 mysql -u root",
|
||||||
@mysql.execute_in_new_container("mysql", "-u", "root").join(" ")
|
new_command(:mysql).execute_in_new_container("mysql", "-u", "root").join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "execute in existing container" do
|
test "execute in existing container" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker exec app-mysql mysql -u root",
|
"docker exec app-mysql mysql -u root",
|
||||||
@mysql.execute_in_existing_container("mysql", "-u", "root").join(" ")
|
new_command(:mysql).execute_in_existing_container("mysql", "-u", "root").join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "execute in new container over ssh" do
|
test "execute in new container over ssh" do
|
||||||
@mysql.stub(:run_over_ssh, ->(cmd) { cmd.join(" ") }) do
|
new_command(:mysql).stub(:run_over_ssh, ->(cmd) { cmd.join(" ") }) do
|
||||||
assert_match %r|docker run -it --rm -e MYSQL_ROOT_PASSWORD=\"secret123\" -e MYSQL_ROOT_HOST=\"%\" private.registry/mysql:8.0 mysql -u root|,
|
assert_match %r|docker run -it --rm -e MYSQL_ROOT_PASSWORD=\"secret123\" -e MYSQL_ROOT_HOST=\"%\" private.registry/mysql:8.0 mysql -u root|,
|
||||||
@mysql.execute_in_new_container_over_ssh("mysql", "-u", "root")
|
new_command(:mysql).execute_in_new_container_over_ssh("mysql", "-u", "root")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "execute in existing container over ssh" do
|
test "execute in existing container over ssh" do
|
||||||
@mysql.stub(:run_over_ssh, ->(cmd) { cmd.join(" ") }) do
|
new_command(:mysql).stub(:run_over_ssh, ->(cmd) { cmd.join(" ") }) do
|
||||||
assert_match %r|docker exec -it app-mysql mysql -u root|,
|
assert_match %r|docker exec -it app-mysql mysql -u root|,
|
||||||
@mysql.execute_in_existing_container_over_ssh("mysql", "-u", "root")
|
new_command(:mysql).execute_in_existing_container_over_ssh("mysql", "-u", "root")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -116,28 +119,33 @@ class CommandsAccessoryTest < ActiveSupport::TestCase
|
|||||||
test "logs" do
|
test "logs" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker logs app-mysql --timestamps 2>&1",
|
"docker logs app-mysql --timestamps 2>&1",
|
||||||
@mysql.logs.join(" ")
|
new_command(:mysql).logs.join(" ")
|
||||||
|
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker logs app-mysql --since 5m --tail 100 --timestamps 2>&1 | grep 'thing'",
|
"docker logs app-mysql --since 5m --tail 100 --timestamps 2>&1 | grep 'thing'",
|
||||||
@mysql.logs(since: "5m", lines: 100, grep: "thing").join(" ")
|
new_command(:mysql).logs(since: "5m", lines: 100, grep: "thing").join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "follow logs" do
|
test "follow logs" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"ssh -t root@1.1.1.5 'docker logs app-mysql --timestamps --tail 10 --follow 2>&1'",
|
"ssh -t root@1.1.1.5 'docker logs app-mysql --timestamps --tail 10 --follow 2>&1'",
|
||||||
@mysql.follow_logs
|
new_command(:mysql).follow_logs
|
||||||
end
|
end
|
||||||
|
|
||||||
test "remove container" do
|
test "remove container" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker container prune --force --filter label=service=app-mysql",
|
"docker container prune --force --filter label=service=app-mysql",
|
||||||
@mysql.remove_container.join(" ")
|
new_command(:mysql).remove_container.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "remove image" do
|
test "remove image" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker image rm --force private.registry/mysql:8.0",
|
"docker image rm --force private.registry/mysql:8.0",
|
||||||
@mysql.remove_image.join(" ")
|
new_command(:mysql).remove_image.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def new_command(accessory)
|
||||||
|
Mrsk::Commands::Accessory.new(Mrsk::Configuration.new(@config), name: accessory)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class CommandsAppTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
test "run" do
|
test "run" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker run --detach --restart unless-stopped --log-opt max-size=10m --name app-999 -e MRSK_CONTAINER_NAME=\"app-999\" -e RAILS_MASTER_KEY=\"456\" --label service=\"app\" --label role=\"web\" --label traefik.http.routers.app.rule=\"PathPrefix(\\`/\\`)\" --label traefik.http.services.app.loadbalancer.healthcheck.path=\"/up\" --label traefik.http.services.app.loadbalancer.healthcheck.interval=\"1s\" --label traefik.http.middlewares.app-retry.retry.attempts=\"5\" --label traefik.http.middlewares.app-retry.retry.initialinterval=\"500ms\" --label traefik.http.routers.app.middlewares=\"app-retry@docker\" dhh/app:999",
|
"docker run --detach --restart unless-stopped --name app-web-999 -e MRSK_CONTAINER_NAME=\"app-web-999\" -e RAILS_MASTER_KEY=\"456\" --log-opt max-size=\"10m\" --label service=\"app\" --label role=\"web\" --label traefik.http.routers.app.rule=\"PathPrefix(\\`/\\`)\" --label traefik.http.services.app.loadbalancer.healthcheck.path=\"/up\" --label traefik.http.services.app.loadbalancer.healthcheck.interval=\"1s\" --label traefik.http.middlewares.app-retry.retry.attempts=\"5\" --label traefik.http.middlewares.app-retry.retry.initialinterval=\"500ms\" --label traefik.http.routers.app.middlewares=\"app-retry@docker\" dhh/app:999",
|
||||||
new_command.run.join(" ")
|
new_command.run.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ class CommandsAppTest < ActiveSupport::TestCase
|
|||||||
@config[:volumes] = ["/local/path:/container/path" ]
|
@config[:volumes] = ["/local/path:/container/path" ]
|
||||||
|
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker run --detach --restart unless-stopped --log-opt max-size=10m --name app-999 -e MRSK_CONTAINER_NAME=\"app-999\" -e RAILS_MASTER_KEY=\"456\" --volume /local/path:/container/path --label service=\"app\" --label role=\"web\" --label traefik.http.routers.app.rule=\"PathPrefix(\\`/\\`)\" --label traefik.http.services.app.loadbalancer.healthcheck.path=\"/up\" --label traefik.http.services.app.loadbalancer.healthcheck.interval=\"1s\" --label traefik.http.middlewares.app-retry.retry.attempts=\"5\" --label traefik.http.middlewares.app-retry.retry.initialinterval=\"500ms\" --label traefik.http.routers.app.middlewares=\"app-retry@docker\" dhh/app:999",
|
"docker run --detach --restart unless-stopped --name app-web-999 -e MRSK_CONTAINER_NAME=\"app-web-999\" -e RAILS_MASTER_KEY=\"456\" --log-opt max-size=\"10m\" --volume /local/path:/container/path --label service=\"app\" --label role=\"web\" --label traefik.http.routers.app.rule=\"PathPrefix(\\`/\\`)\" --label traefik.http.services.app.loadbalancer.healthcheck.path=\"/up\" --label traefik.http.services.app.loadbalancer.healthcheck.interval=\"1s\" --label traefik.http.middlewares.app-retry.retry.attempts=\"5\" --label traefik.http.middlewares.app-retry.retry.initialinterval=\"500ms\" --label traefik.http.routers.app.middlewares=\"app-retry@docker\" dhh/app:999",
|
||||||
new_command.run.join(" ")
|
new_command.run.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -29,90 +29,104 @@ class CommandsAppTest < ActiveSupport::TestCase
|
|||||||
@config[:healthcheck] = { "path" => "/healthz" }
|
@config[:healthcheck] = { "path" => "/healthz" }
|
||||||
|
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker run --detach --restart unless-stopped --log-opt max-size=10m --name app-999 -e MRSK_CONTAINER_NAME=\"app-999\" -e RAILS_MASTER_KEY=\"456\" --label service=\"app\" --label role=\"web\" --label traefik.http.routers.app.rule=\"PathPrefix(\\`/\\`)\" --label traefik.http.services.app.loadbalancer.healthcheck.path=\"/healthz\" --label traefik.http.services.app.loadbalancer.healthcheck.interval=\"1s\" --label traefik.http.middlewares.app-retry.retry.attempts=\"5\" --label traefik.http.middlewares.app-retry.retry.initialinterval=\"500ms\" --label traefik.http.routers.app.middlewares=\"app-retry@docker\" dhh/app:999",
|
"docker run --detach --restart unless-stopped --name app-web-999 -e MRSK_CONTAINER_NAME=\"app-web-999\" -e RAILS_MASTER_KEY=\"456\" --log-opt max-size=\"10m\" --label service=\"app\" --label role=\"web\" --label traefik.http.routers.app.rule=\"PathPrefix(\\`/\\`)\" --label traefik.http.services.app.loadbalancer.healthcheck.path=\"/healthz\" --label traefik.http.services.app.loadbalancer.healthcheck.interval=\"1s\" --label traefik.http.middlewares.app-retry.retry.attempts=\"5\" --label traefik.http.middlewares.app-retry.retry.initialinterval=\"500ms\" --label traefik.http.routers.app.middlewares=\"app-retry@docker\" dhh/app:999",
|
||||||
new_command.run.join(" ")
|
new_command.run.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "run with custom options" do
|
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 } } }
|
@config[:servers] = { "web" => [ "1.1.1.1" ], "jobs" => { "hosts" => [ "1.1.1.2" ], "cmd" => "bin/jobs", "options" => { "mount" => "somewhere", "cap-add" => true } } }
|
||||||
|
assert_equal \
|
||||||
|
"docker run --detach --restart unless-stopped --name app-jobs-999 -e MRSK_CONTAINER_NAME=\"app-jobs-999\" -e RAILS_MASTER_KEY=\"456\" --log-opt max-size=\"10m\" --label service=\"app\" --label role=\"jobs\" --mount \"somewhere\" --cap-add dhh/app:999 bin/jobs",
|
||||||
|
new_command(role: "jobs").run.join(" ")
|
||||||
|
end
|
||||||
|
|
||||||
|
test "run with logging config" do
|
||||||
|
@config[:logging] = { "driver" => "local", "options" => { "max-size" => "100m", "max-file" => "3" } }
|
||||||
|
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker run --detach --restart unless-stopped --log-opt max-size=10m --name app-999 -e MRSK_CONTAINER_NAME=\"app-999\" -e RAILS_MASTER_KEY=\"456\" --label service=\"app\" --label role=\"jobs\" --mount \"somewhere\" --cap-add dhh/app:999 bin/jobs",
|
"docker run --detach --restart unless-stopped --name app-web-999 -e MRSK_CONTAINER_NAME=\"app-web-999\" -e RAILS_MASTER_KEY=\"456\" --log-driver \"local\" --log-opt max-size=\"100m\" --log-opt max-file=\"3\" --label service=\"app\" --label role=\"web\" --label traefik.http.routers.app.rule=\"PathPrefix(\\`/\\`)\" --label traefik.http.services.app.loadbalancer.healthcheck.path=\"/up\" --label traefik.http.services.app.loadbalancer.healthcheck.interval=\"1s\" --label traefik.http.middlewares.app-retry.retry.attempts=\"5\" --label traefik.http.middlewares.app-retry.retry.initialinterval=\"500ms\" --label traefik.http.routers.app.middlewares=\"app-retry@docker\" dhh/app:999",
|
||||||
new_command.run(role: :jobs).join(" ")
|
new_command.run.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "start" do
|
test "start" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker start app-999",
|
"docker start app-web-999",
|
||||||
new_command.start.join(" ")
|
new_command.start.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "start with destination" do
|
test "start with destination" do
|
||||||
@destination = "staging"
|
@destination = "staging"
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker start app-staging-999",
|
"docker start app-web-staging-999",
|
||||||
new_command.start.join(" ")
|
new_command.start.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "stop" do
|
test "stop" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker ps --quiet --filter label=service=app | xargs docker stop",
|
"docker ps --quiet --filter label=service=app --filter label=role=web | xargs docker stop",
|
||||||
|
new_command.stop.join(" ")
|
||||||
|
end
|
||||||
|
|
||||||
|
test "stop with custom stop wait time" do
|
||||||
|
@config[:stop_wait_time] = 30
|
||||||
|
assert_equal \
|
||||||
|
"docker ps --quiet --filter label=service=app --filter label=role=web | xargs docker stop -t 30",
|
||||||
new_command.stop.join(" ")
|
new_command.stop.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "stop with version" do
|
test "stop with version" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker container ls --all --filter name=app-123 --quiet | xargs docker stop",
|
"docker container ls --all --filter name=app-web-123 --quiet | xargs docker stop",
|
||||||
new_command.stop(version: "123").join(" ")
|
new_command.stop(version: "123").join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "info" do
|
test "info" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker ps --filter label=service=app",
|
"docker ps --filter label=service=app --filter label=role=web",
|
||||||
new_command.info.join(" ")
|
new_command.info.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "info with destination" do
|
test "info with destination" do
|
||||||
@destination = "staging"
|
@destination = "staging"
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker ps --filter label=service=app --filter label=destination=staging",
|
"docker ps --filter label=service=app --filter label=destination=staging --filter label=role=web",
|
||||||
new_command.info.join(" ")
|
new_command.info.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
test "logs" do
|
test "logs" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker ps --quiet --filter label=service=app | xargs docker logs 2>&1",
|
"docker ps --quiet --filter label=service=app --filter label=role=web | xargs docker logs 2>&1",
|
||||||
new_command.logs.join(" ")
|
new_command.logs.join(" ")
|
||||||
|
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker ps --quiet --filter label=service=app | xargs docker logs --since 5m 2>&1",
|
"docker ps --quiet --filter label=service=app --filter label=role=web | xargs docker logs --since 5m 2>&1",
|
||||||
new_command.logs(since: "5m").join(" ")
|
new_command.logs(since: "5m").join(" ")
|
||||||
|
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker ps --quiet --filter label=service=app | xargs docker logs --tail 100 2>&1",
|
"docker ps --quiet --filter label=service=app --filter label=role=web | xargs docker logs --tail 100 2>&1",
|
||||||
new_command.logs(lines: "100").join(" ")
|
new_command.logs(lines: "100").join(" ")
|
||||||
|
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker ps --quiet --filter label=service=app | xargs docker logs --since 5m --tail 100 2>&1",
|
"docker ps --quiet --filter label=service=app --filter label=role=web | xargs docker logs --since 5m --tail 100 2>&1",
|
||||||
new_command.logs(since: "5m", lines: "100").join(" ")
|
new_command.logs(since: "5m", lines: "100").join(" ")
|
||||||
|
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker ps --quiet --filter label=service=app | xargs docker logs 2>&1 | grep 'my-id'",
|
"docker ps --quiet --filter label=service=app --filter label=role=web | xargs docker logs 2>&1 | grep 'my-id'",
|
||||||
new_command.logs(grep: "my-id").join(" ")
|
new_command.logs(grep: "my-id").join(" ")
|
||||||
|
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker ps --quiet --filter label=service=app | xargs docker logs --since 5m 2>&1 | grep 'my-id'",
|
"docker ps --quiet --filter label=service=app --filter label=role=web | xargs docker logs --since 5m 2>&1 | grep 'my-id'",
|
||||||
new_command.logs(since: "5m", grep: "my-id").join(" ")
|
new_command.logs(since: "5m", grep: "my-id").join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "follow logs" do
|
test "follow logs" do
|
||||||
assert_match \
|
assert_match \
|
||||||
"docker ps --quiet --filter label=service=app | xargs docker logs --timestamps --tail 10 --follow 2>&1",
|
"docker ps --quiet --filter label=service=app --filter label=role=web | xargs docker logs --timestamps --tail 10 --follow 2>&1",
|
||||||
new_command.follow_logs(host: "app-1")
|
new_command.follow_logs(host: "app-1")
|
||||||
|
|
||||||
assert_match \
|
assert_match \
|
||||||
"docker ps --quiet --filter label=service=app | xargs docker logs --timestamps --tail 10 --follow 2>&1 | grep \"Completed\"",
|
"docker ps --quiet --filter label=service=app --filter label=role=web | xargs docker logs --timestamps --tail 10 --follow 2>&1 | grep \"Completed\"",
|
||||||
new_command.follow_logs(host: "app-1", grep: "Completed")
|
new_command.follow_logs(host: "app-1", grep: "Completed")
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -125,7 +139,7 @@ class CommandsAppTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
test "execute in existing container" do
|
test "execute in existing container" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker exec app-999 bin/rails db:setup",
|
"docker exec app-web-999 bin/rails db:setup",
|
||||||
new_command.execute_in_existing_container("bin/rails", "db:setup").join(" ")
|
new_command.execute_in_existing_container("bin/rails", "db:setup").join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -135,7 +149,7 @@ class CommandsAppTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "execute in existing container over ssh" do
|
test "execute in existing container over ssh" do
|
||||||
assert_match %r|docker exec -it app-999 bin/rails c|,
|
assert_match %r|docker exec -it app-web-999 bin/rails c|,
|
||||||
new_command.execute_in_existing_container_over_ssh("bin/rails", "c", host: "app-1")
|
new_command.execute_in_existing_container_over_ssh("bin/rails", "c", host: "app-1")
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -166,14 +180,14 @@ class CommandsAppTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
test "current_container_id" do
|
test "current_container_id" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker ps --quiet --filter label=service=app",
|
"docker ps --quiet --filter label=service=app --filter label=role=web",
|
||||||
new_command.current_container_id.join(" ")
|
new_command.current_container_id.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "current_container_id with destination" do
|
test "current_container_id with destination" do
|
||||||
@destination = "staging"
|
@destination = "staging"
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker ps --quiet --filter label=service=app --filter label=destination=staging",
|
"docker ps --quiet --filter label=service=app --filter label=destination=staging --filter label=role=web",
|
||||||
new_command.current_container_id.join(" ")
|
new_command.current_container_id.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -185,52 +199,52 @@ class CommandsAppTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
test "current_running_version" do
|
test "current_running_version" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker ps --filter label=service=app --format \"{{.Names}}\" | sed 's/-/\\n/g' | tail -n 1",
|
"docker ps --filter label=service=app --filter label=role=web --format \"{{.Names}}\" | sed 's/-/\\n/g' | tail -n 1",
|
||||||
new_command.current_running_version.join(" ")
|
new_command.current_running_version.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "list_containers" do
|
test "list_containers" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker container ls --all --filter label=service=app",
|
"docker container ls --all --filter label=service=app --filter label=role=web",
|
||||||
new_command.list_containers.join(" ")
|
new_command.list_containers.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "list_containers with destination" do
|
test "list_containers with destination" do
|
||||||
@destination = "staging"
|
@destination = "staging"
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker container ls --all --filter label=service=app --filter label=destination=staging",
|
"docker container ls --all --filter label=service=app --filter label=destination=staging --filter label=role=web",
|
||||||
new_command.list_containers.join(" ")
|
new_command.list_containers.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "list_container_names" do
|
test "list_container_names" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker container ls --all --filter label=service=app --format '{{ .Names }}'",
|
"docker container ls --all --filter label=service=app --filter label=role=web --format '{{ .Names }}'",
|
||||||
new_command.list_container_names.join(" ")
|
new_command.list_container_names.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "remove_container" do
|
test "remove_container" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker container ls --all --filter name=app-999 --quiet | xargs docker container rm",
|
"docker container ls --all --filter name=app-web-999 --quiet | xargs docker container rm",
|
||||||
new_command.remove_container(version: "999").join(" ")
|
new_command.remove_container(version: "999").join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "remove_container with destination" do
|
test "remove_container with destination" do
|
||||||
@destination = "staging"
|
@destination = "staging"
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker container ls --all --filter name=app-staging-999 --quiet | xargs docker container rm",
|
"docker container ls --all --filter name=app-web-staging-999 --quiet | xargs docker container rm",
|
||||||
new_command.remove_container(version: "999").join(" ")
|
new_command.remove_container(version: "999").join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "remove_containers" do
|
test "remove_containers" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker container prune --force --filter label=service=app",
|
"docker container prune --force --filter label=service=app --filter label=role=web",
|
||||||
new_command.remove_containers.join(" ")
|
new_command.remove_containers.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "remove_containers with destination" do
|
test "remove_containers with destination" do
|
||||||
@destination = "staging"
|
@destination = "staging"
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker container prune --force --filter label=service=app --filter label=destination=staging",
|
"docker container prune --force --filter label=service=app --filter label=destination=staging --filter label=role=web",
|
||||||
new_command.remove_containers.join(" ")
|
new_command.remove_containers.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -242,19 +256,19 @@ class CommandsAppTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
test "remove_images" do
|
test "remove_images" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker image prune --all --force --filter label=service=app",
|
"docker image prune --all --force --filter label=service=app --filter label=role=web",
|
||||||
new_command.remove_images.join(" ")
|
new_command.remove_images.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "remove_images with destination" do
|
test "remove_images with destination" do
|
||||||
@destination = "staging"
|
@destination = "staging"
|
||||||
assert_equal \
|
assert_equal \
|
||||||
"docker image prune --all --force --filter label=service=app --filter label=destination=staging",
|
"docker image prune --all --force --filter label=service=app --filter label=destination=staging --filter label=role=web",
|
||||||
new_command.remove_images.join(" ")
|
new_command.remove_images.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def new_command
|
def new_command(role: "web")
|
||||||
Mrsk::Commands::App.new(Mrsk::Configuration.new(@config, destination: @destination, version: "999"))
|
Mrsk::Commands::App.new(Mrsk::Configuration.new(@config, destination: @destination, version: "999"), role: role)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -22,6 +22,14 @@ class CommandsAuditorTest < ActiveSupport::TestCase
|
|||||||
new_command.record("app removed container").join(" ")
|
new_command.record("app removed container").join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "record with role" do
|
||||||
|
@role = "web"
|
||||||
|
|
||||||
|
assert_match \
|
||||||
|
/echo '.* \[web\] app removed container' >> mrsk-app-audit.log/,
|
||||||
|
new_command.record("app removed container").join(" ")
|
||||||
|
end
|
||||||
|
|
||||||
test "broadcast" do
|
test "broadcast" do
|
||||||
assert_match \
|
assert_match \
|
||||||
/bin\/audit_broadcast '\[.*\] app removed container'/,
|
/bin\/audit_broadcast '\[.*\] app removed container'/,
|
||||||
@@ -30,6 +38,6 @@ class CommandsAuditorTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
private
|
private
|
||||||
def new_command
|
def new_command
|
||||||
Mrsk::Commands::Auditor.new(Mrsk::Configuration.new(@config, destination: @destination, version: "123"))
|
Mrsk::Commands::Auditor.new(Mrsk::Configuration.new(@config, destination: @destination, version: "123"), role: @role)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -10,45 +10,45 @@ class CommandsTraefikTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
test "run" do
|
test "run" do
|
||||||
assert_equal \
|
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\" --api.insecure --metrics.prometheus.buckets=\"0.1,0.3,1.2,5.0\"",
|
"docker run --name traefik --detach --restart unless-stopped --publish 80:80 --volume /var/run/docker.sock:/var/run/docker.sock --log-opt max-size=\"10m\" traefik --providers.docker --log.level=DEBUG --accesslog.format=\"json\" --api.insecure --metrics.prometheus.buckets=\"0.1,0.3,1.2,5.0\"",
|
||||||
new_command.run.join(" ")
|
new_command.run.join(" ")
|
||||||
|
|
||||||
@config[:traefik]["host_port"] = "8080"
|
@config[:traefik]["host_port"] = "8080"
|
||||||
assert_equal \
|
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\" --api.insecure --metrics.prometheus.buckets=\"0.1,0.3,1.2,5.0\"",
|
"docker run --name traefik --detach --restart unless-stopped --publish 8080:80 --volume /var/run/docker.sock:/var/run/docker.sock --log-opt max-size=\"10m\" traefik --providers.docker --log.level=DEBUG --accesslog.format=\"json\" --api.insecure --metrics.prometheus.buckets=\"0.1,0.3,1.2,5.0\"",
|
||||||
new_command.run.join(" ")
|
new_command.run.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "run with ports configured" do
|
test "run with ports configured" do
|
||||||
assert_equal \
|
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\" --api.insecure --metrics.prometheus.buckets=\"0.1,0.3,1.2,5.0\"",
|
"docker run --name traefik --detach --restart unless-stopped --publish 80:80 --volume /var/run/docker.sock:/var/run/docker.sock --log-opt max-size=\"10m\" traefik --providers.docker --log.level=DEBUG --accesslog.format=\"json\" --api.insecure --metrics.prometheus.buckets=\"0.1,0.3,1.2,5.0\"",
|
||||||
new_command.run.join(" ")
|
new_command.run.join(" ")
|
||||||
|
|
||||||
@config[:traefik]["options"] = {"publish" => %w[9000:9000 9001:9001]}
|
@config[:traefik]["options"] = {"publish" => %w[9000:9000 9001:9001]}
|
||||||
assert_equal \
|
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 --publish \"9000:9000\" --publish \"9001:9001\" traefik --providers.docker --log.level=DEBUG --accesslog.format=\"json\" --api.insecure --metrics.prometheus.buckets=\"0.1,0.3,1.2,5.0\"",
|
"docker run --name traefik --detach --restart unless-stopped --publish 80:80 --volume /var/run/docker.sock:/var/run/docker.sock --log-opt max-size=\"10m\" --publish \"9000:9000\" --publish \"9001:9001\" traefik --providers.docker --log.level=DEBUG --accesslog.format=\"json\" --api.insecure --metrics.prometheus.buckets=\"0.1,0.3,1.2,5.0\"",
|
||||||
new_command.run.join(" ")
|
new_command.run.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "run with volumes configured" do
|
test "run with volumes configured" do
|
||||||
assert_equal \
|
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\" --api.insecure --metrics.prometheus.buckets=\"0.1,0.3,1.2,5.0\"",
|
"docker run --name traefik --detach --restart unless-stopped --publish 80:80 --volume /var/run/docker.sock:/var/run/docker.sock --log-opt max-size=\"10m\" traefik --providers.docker --log.level=DEBUG --accesslog.format=\"json\" --api.insecure --metrics.prometheus.buckets=\"0.1,0.3,1.2,5.0\"",
|
||||||
new_command.run.join(" ")
|
new_command.run.join(" ")
|
||||||
|
|
||||||
@config[:traefik]["options"] = {"volume" => %w[./letsencrypt/acme.json:/letsencrypt/acme.json] }
|
@config[:traefik]["options"] = {"volume" => %w[./letsencrypt/acme.json:/letsencrypt/acme.json] }
|
||||||
assert_equal \
|
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 --volume \"./letsencrypt/acme.json:/letsencrypt/acme.json\" traefik --providers.docker --log.level=DEBUG --accesslog.format=\"json\" --api.insecure --metrics.prometheus.buckets=\"0.1,0.3,1.2,5.0\"",
|
"docker run --name traefik --detach --restart unless-stopped --publish 80:80 --volume /var/run/docker.sock:/var/run/docker.sock --log-opt max-size=\"10m\" --volume \"./letsencrypt/acme.json:/letsencrypt/acme.json\" traefik --providers.docker --log.level=DEBUG --accesslog.format=\"json\" --api.insecure --metrics.prometheus.buckets=\"0.1,0.3,1.2,5.0\"",
|
||||||
new_command.run.join(" ")
|
new_command.run.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "run with several options configured" do
|
test "run with several options configured" do
|
||||||
assert_equal \
|
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\" --api.insecure --metrics.prometheus.buckets=\"0.1,0.3,1.2,5.0\"",
|
"docker run --name traefik --detach --restart unless-stopped --publish 80:80 --volume /var/run/docker.sock:/var/run/docker.sock --log-opt max-size=\"10m\" traefik --providers.docker --log.level=DEBUG --accesslog.format=\"json\" --api.insecure --metrics.prometheus.buckets=\"0.1,0.3,1.2,5.0\"",
|
||||||
new_command.run.join(" ")
|
new_command.run.join(" ")
|
||||||
|
|
||||||
@config[:traefik]["options"] = {"volume" => %w[./letsencrypt/acme.json:/letsencrypt/acme.json], "publish" => %w[8080:8080], "memory" => "512m"}
|
@config[:traefik]["options"] = {"volume" => %w[./letsencrypt/acme.json:/letsencrypt/acme.json], "publish" => %w[8080:8080], "memory" => "512m"}
|
||||||
assert_equal \
|
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 --volume \"./letsencrypt/acme.json:/letsencrypt/acme.json\" --publish \"8080:8080\" --memory \"512m\" traefik --providers.docker --log.level=DEBUG --accesslog.format=\"json\" --api.insecure --metrics.prometheus.buckets=\"0.1,0.3,1.2,5.0\"",
|
"docker run --name traefik --detach --restart unless-stopped --publish 80:80 --volume /var/run/docker.sock:/var/run/docker.sock --log-opt max-size=\"10m\" --volume \"./letsencrypt/acme.json:/letsencrypt/acme.json\" --publish \"8080:8080\" --memory \"512m\" traefik --providers.docker --log.level=DEBUG --accesslog.format=\"json\" --api.insecure --metrics.prometheus.buckets=\"0.1,0.3,1.2,5.0\"",
|
||||||
new_command.run.join(" ")
|
new_command.run.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -56,7 +56,15 @@ class CommandsTraefikTest < ActiveSupport::TestCase
|
|||||||
@config.delete(:traefik)
|
@config.delete(:traefik)
|
||||||
|
|
||||||
assert_equal \
|
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",
|
"docker run --name traefik --detach --restart unless-stopped --publish 80:80 --volume /var/run/docker.sock:/var/run/docker.sock --log-opt max-size=\"10m\" traefik --providers.docker --log.level=DEBUG",
|
||||||
|
new_command.run.join(" ")
|
||||||
|
end
|
||||||
|
|
||||||
|
test "run with logging config" do
|
||||||
|
@config[:logging] = { "driver" => "local", "options" => { "max-size" => "100m", "max-file" => "3" } }
|
||||||
|
|
||||||
|
assert_equal \
|
||||||
|
"docker run --name traefik --detach --restart unless-stopped --publish 80:80 --volume /var/run/docker.sock:/var/run/docker.sock --log-driver \"local\" --log-opt max-size=\"100m\" --log-opt max-file=\"3\" traefik --providers.docker --log.level=DEBUG --accesslog.format=\"json\" --api.insecure --metrics.prometheus.buckets=\"0.1,0.3,1.2,5.0\"",
|
||||||
new_command.run.join(" ")
|
new_command.run.join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,11 @@ class ConfigurationAccessoryTest < ActiveSupport::TestCase
|
|||||||
},
|
},
|
||||||
"volumes" => [
|
"volumes" => [
|
||||||
"/var/lib/redis:/data"
|
"/var/lib/redis:/data"
|
||||||
]
|
],
|
||||||
|
"options" => {
|
||||||
|
"cpus" => 4,
|
||||||
|
"memory" => "2GB"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,4 +108,8 @@ class ConfigurationAccessoryTest < ActiveSupport::TestCase
|
|||||||
test "directories" do
|
test "directories" do
|
||||||
assert_equal({"$PWD/app-mysql/data"=>"/var/lib/mysql"}, @config.accessory(:mysql).directories)
|
assert_equal({"$PWD/app-mysql/data"=>"/var/lib/mysql"}, @config.accessory(:mysql).directories)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "options" do
|
||||||
|
assert_equal ["--cpus", "\"4\"", "--memory", "\"2GB\""], @config.accessory(:redis).option_args
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class ConfigurationTest < ActiveSupport::TestCase
|
|||||||
@config = Mrsk::Configuration.new(@deploy)
|
@config = Mrsk::Configuration.new(@deploy)
|
||||||
|
|
||||||
@deploy_with_roles = @deploy.dup.merge({
|
@deploy_with_roles = @deploy.dup.merge({
|
||||||
servers: { "web" => [ "1.1.1.1", "1.1.1.2" ], "workers" => { "hosts" => [ "1.1.1.3", "1.1.1.4" ] } } })
|
servers: { "web" => [ "1.1.1.1", "1.1.1.2" ], "workers" => { "hosts" => [ "1.1.1.1", "1.1.1.3" ] } } })
|
||||||
|
|
||||||
@config_with_roles = Mrsk::Configuration.new(@deploy_with_roles)
|
@config_with_roles = Mrsk::Configuration.new(@deploy_with_roles)
|
||||||
end
|
end
|
||||||
@@ -55,7 +55,7 @@ class ConfigurationTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
test "all hosts" do
|
test "all hosts" do
|
||||||
assert_equal [ "1.1.1.1", "1.1.1.2"], @config.all_hosts
|
assert_equal [ "1.1.1.1", "1.1.1.2"], @config.all_hosts
|
||||||
assert_equal [ "1.1.1.1", "1.1.1.2", "1.1.1.3", "1.1.1.4" ], @config_with_roles.all_hosts
|
assert_equal [ "1.1.1.1", "1.1.1.2", "1.1.1.3" ], @config_with_roles.all_hosts
|
||||||
end
|
end
|
||||||
|
|
||||||
test "primary web host" do
|
test "primary web host" do
|
||||||
@@ -69,7 +69,7 @@ class ConfigurationTest < ActiveSupport::TestCase
|
|||||||
@deploy_with_roles[:servers]["workers"]["traefik"] = true
|
@deploy_with_roles[:servers]["workers"]["traefik"] = true
|
||||||
config = Mrsk::Configuration.new(@deploy_with_roles)
|
config = Mrsk::Configuration.new(@deploy_with_roles)
|
||||||
|
|
||||||
assert_equal [ "1.1.1.1", "1.1.1.2", "1.1.1.3", "1.1.1.4" ], config.traefik_hosts
|
assert_equal [ "1.1.1.1", "1.1.1.2", "1.1.1.3" ], config.traefik_hosts
|
||||||
end
|
end
|
||||||
|
|
||||||
test "version" do
|
test "version" do
|
||||||
@@ -209,6 +209,20 @@ class ConfigurationTest < ActiveSupport::TestCase
|
|||||||
assert_equal ["--volume", "/local/path:/container/path"], @config.volume_args
|
assert_equal ["--volume", "/local/path:/container/path"], @config.volume_args
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "logging args default" do
|
||||||
|
assert_equal ["--log-opt", "max-size=\"10m\""], @config.logging_args
|
||||||
|
end
|
||||||
|
|
||||||
|
test "logging args with configured options" do
|
||||||
|
config = Mrsk::Configuration.new(@deploy.tap { |c| c.merge!(logging: { "options" => { "max-size" => "100m", "max-file" => 5 } }) })
|
||||||
|
assert_equal ["--log-opt", "max-size=\"100m\"", "--log-opt", "max-file=\"5\""], @config.logging_args
|
||||||
|
end
|
||||||
|
|
||||||
|
test "logging args with configured driver and options" do
|
||||||
|
config = Mrsk::Configuration.new(@deploy.tap { |c| c.merge!(logging: { "driver" => "local", "options" => { "max-size" => "100m", "max-file" => 5 } }) })
|
||||||
|
assert_equal ["--log-driver", "\"local\"", "--log-opt", "max-size=\"100m\"", "--log-opt", "max-file=\"5\""], @config.logging_args
|
||||||
|
end
|
||||||
|
|
||||||
test "erb evaluation of yml config" do
|
test "erb evaluation of yml config" do
|
||||||
config = Mrsk::Configuration.create_from config_file: Pathname.new(File.expand_path("fixtures/deploy.erb.yml", __dir__))
|
config = Mrsk::Configuration.create_from config_file: Pathname.new(File.expand_path("fixtures/deploy.erb.yml", __dir__))
|
||||||
assert_equal "my-user", config.registry["username"]
|
assert_equal "my-user", config.registry["username"]
|
||||||
@@ -233,6 +247,6 @@ class ConfigurationTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "to_h" do
|
test "to_h" do
|
||||||
assert_equal({ :roles=>["web"], :hosts=>["1.1.1.1", "1.1.1.2"], :primary_host=>"1.1.1.1", :version=>"missing", :repository=>"dhh/app", :absolute_image=>"dhh/app:missing", :service_with_version=>"app-missing", :env_args=>["-e", "REDIS_URL=\"redis://x/y\""], :ssh_options=>{:user=>"root", :auth_methods=>["publickey"]}, :volume_args=>["--volume", "/local/path:/container/path"], :healthcheck=>{"path"=>"/up", "port"=>3000 }}, @config.to_h)
|
assert_equal({ :roles=>["web"], :hosts=>["1.1.1.1", "1.1.1.2"], :primary_host=>"1.1.1.1", :version=>"missing", :repository=>"dhh/app", :absolute_image=>"dhh/app:missing", :service_with_version=>"app-missing", :env_args=>["-e", "REDIS_URL=\"redis://x/y\""], :ssh_options=>{:user=>"root", :auth_methods=>["publickey"]}, :volume_args=>["--volume", "/local/path:/container/path"], :logging=>["--log-opt", "max-size=\"10m\""], :healthcheck=>{"path"=>"/up", "port"=>3000 }}, @config.to_h)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
2
test/fixtures/deploy_with_accessories.yml
vendored
2
test/fixtures/deploy_with_accessories.yml
vendored
@@ -28,4 +28,4 @@ accessories:
|
|||||||
directories:
|
directories:
|
||||||
- data:/data
|
- data:/data
|
||||||
|
|
||||||
readiness_delay: 0
|
readiness_delay: 0
|
||||||
|
|||||||
Reference in New Issue
Block a user