Allow hosts to be tagged so we can have host specific env variables.
We might want host specific env variables for things like datacenter
specific tags or testing GC settings on a specific host.
Right now you either need to set up a separate role, or have the app
be host aware.
Now you can define tag env variables and assign those to hosts.
For example:
```
servers:
- 1.1.1.1
- 1.1.1.2: tag1
- 1.1.1.2: tag2
- 1.1.1.3: [ tag1, tag2 ]
env_tags:
tag1:
ENV1: value1
tag2:
ENV2: value2
```
The tag env supports the full env format, allowing you to set secret and
clear values.
161 lines
3.6 KiB
Ruby
161 lines
3.6 KiB
Ruby
require "active_support/core_ext/enumerable"
|
|
require "active_support/core_ext/module/delegation"
|
|
|
|
class Kamal::Commander
|
|
attr_accessor :verbosity, :holding_lock, :hold_lock_on_error
|
|
delegate :hosts, :roles, :primary_host, :primary_role, :roles_on, :traefik_hosts, :accessory_hosts, to: :specifics
|
|
|
|
def initialize
|
|
self.verbosity = :info
|
|
self.holding_lock = false
|
|
self.hold_lock_on_error = false
|
|
@specifics = nil
|
|
end
|
|
|
|
def config
|
|
@config ||= Kamal::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!
|
|
@specifics = nil
|
|
self.specific_hosts = [ config.primary_host ]
|
|
end
|
|
|
|
def specific_roles=(role_names)
|
|
@specifics = nil
|
|
if role_names.present?
|
|
@specific_roles = Kamal::Utils.filter_specific_items(role_names, config.roles)
|
|
|
|
if @specific_roles.empty?
|
|
raise ArgumentError, "No --roles match for #{role_names.join(',')}"
|
|
end
|
|
|
|
@specific_roles
|
|
end
|
|
end
|
|
|
|
def specific_hosts=(hosts)
|
|
@specifics = nil
|
|
if hosts.present?
|
|
@specific_hosts = Kamal::Utils.filter_specific_items(hosts, config.all_hosts)
|
|
|
|
if @specific_hosts.empty?
|
|
raise ArgumentError, "No --hosts match for #{hosts.join(',')}"
|
|
end
|
|
|
|
@specific_hosts
|
|
end
|
|
end
|
|
|
|
def accessory_names
|
|
config.accessories&.collect(&:name) || []
|
|
end
|
|
|
|
def accessories_on(host)
|
|
config.accessories.select { |accessory| accessory.hosts.include?(host.to_s) }.map(&:name)
|
|
end
|
|
|
|
|
|
def app(role: nil, host: nil)
|
|
Kamal::Commands::App.new(config, role: role, host: host)
|
|
end
|
|
|
|
def accessory(name)
|
|
Kamal::Commands::Accessory.new(config, name: name)
|
|
end
|
|
|
|
def auditor(**details)
|
|
Kamal::Commands::Auditor.new(config, **details)
|
|
end
|
|
|
|
def builder
|
|
@builder ||= Kamal::Commands::Builder.new(config)
|
|
end
|
|
|
|
def docker
|
|
@docker ||= Kamal::Commands::Docker.new(config)
|
|
end
|
|
|
|
def healthcheck
|
|
@healthcheck ||= Kamal::Commands::Healthcheck.new(config)
|
|
end
|
|
|
|
def hook
|
|
@hook ||= Kamal::Commands::Hook.new(config)
|
|
end
|
|
|
|
def lock
|
|
@lock ||= Kamal::Commands::Lock.new(config)
|
|
end
|
|
|
|
def prune
|
|
@prune ||= Kamal::Commands::Prune.new(config)
|
|
end
|
|
|
|
def registry
|
|
@registry ||= Kamal::Commands::Registry.new(config)
|
|
end
|
|
|
|
def server
|
|
@server ||= Kamal::Commands::Server.new(config)
|
|
end
|
|
|
|
def traefik
|
|
@traefik ||= Kamal::Commands::Traefik.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 boot_strategy
|
|
if config.boot.limit.present?
|
|
{ in: :groups, limit: config.boot.limit, wait: config.boot.wait }
|
|
else
|
|
{}
|
|
end
|
|
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.pool.idle_timeout = config.sshkit.pool_idle_timeout
|
|
SSHKit::Backend::Netssh.configure do |sshkit|
|
|
sshkit.max_concurrent_starts = config.sshkit.max_concurrent_starts
|
|
sshkit.ssh_options = config.ssh.options
|
|
end
|
|
SSHKit.config.command_map[:docker] = "docker" # No need to use /usr/bin/env, just clogs up the logs
|
|
SSHKit.config.output_verbosity = verbosity
|
|
end
|
|
|
|
def specifics
|
|
@specifics ||= Kamal::Commander::Specifics.new(config, specific_hosts, specific_roles)
|
|
end
|
|
end
|