Files
kamal/lib/mrsk/commander.rb
Donal McBreen 051556674f Minimise holding the deploy lock
If we get an error we'll only hold the deploy lock if it occurs while
trying to switch the running containers.

We'll also move tagging the latest image from when the image is pulled
to just before the container switch. This ensures that earlier errors
don't leave the hosts with an updated latest tag while still running the
older version.
2023-04-12 12:09:56 +01:00

135 lines
2.9 KiB
Ruby

require "active_support/core_ext/enumerable"
require "active_support/core_ext/module/delegation"
class Mrsk::Commander
attr_accessor :verbosity, :holding_lock, :hold_lock_on_error
def initialize
self.verbosity = :info
self.holding_lock = false
self.hold_lock_on_error = false
end
def config
@config ||= Mrsk::Configuration.create_from(**@config_kwargs).tap do |config|
@config_kwargs = nil
configure_sshkit_with(config)
end
end
def configure(**kwargs)
@config, @config_kwargs = nil, kwargs
end
attr_reader :specific_roles, :specific_hosts
def specific_primary!
self.specific_hosts = [ config.primary_web_host ]
end
def specific_roles=(role_names)
@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
def primary_host
specific_hosts&.first || config.primary_web_host
end
def roles
(specific_roles || config.roles).select do |role|
((specific_hosts || config.all_hosts) & role.hosts).any?
end
end
def 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
def traefik_hosts
specific_hosts || config.traefik_hosts
end
def accessory_hosts
specific_hosts || config.accessories.flat_map(&:hosts)
end
def accessory_names
config.accessories&.collect(&:name) || []
end
def app(role: nil)
Mrsk::Commands::App.new(config, role: role)
end
def accessory(name)
Mrsk::Commands::Accessory.new(config, name: name)
end
def auditor(role: nil)
Mrsk::Commands::Auditor.new(config, role: role)
end
def builder
@builder ||= Mrsk::Commands::Builder.new(config)
end
def healthcheck
@healthcheck ||= Mrsk::Commands::Healthcheck.new(config)
end
def prune
@prune ||= Mrsk::Commands::Prune.new(config)
end
def registry
@registry ||= Mrsk::Commands::Registry.new(config)
end
def traefik
@traefik ||= Mrsk::Commands::Traefik.new(config)
end
def lock
@lock ||= Mrsk::Commands::Lock.new(config)
end
def with_verbosity(level)
old_level = self.verbosity
self.verbosity = level
SSHKit.config.output_verbosity = level
yield
ensure
self.verbosity = old_level
SSHKit.config.output_verbosity = old_level
end
def holding_lock?
self.holding_lock
end
def hold_lock_on_error?
self.hold_lock_on_error
end
private
# Lazy setup of SSHKit
def configure_sshkit_with(config)
SSHKit::Backend::Netssh.configure { |ssh| ssh.ssh_options = config.ssh_options }
SSHKit.config.command_map[:docker] = "docker" # No need to use /usr/bin/env, just clogs up the logs
SSHKit.config.output_verbosity = verbosity
end
end