221 lines
5.2 KiB
Ruby
221 lines
5.2 KiB
Ruby
class Kamal::Configuration::Role
|
|
include Kamal::Configuration::Validation
|
|
|
|
delegate :argumentize, :optionize, to: Kamal::Utils
|
|
|
|
attr_reader :name, :config, :specialized_env, :specialized_logging, :specialized_proxy
|
|
|
|
alias to_s name
|
|
|
|
def initialize(name, config:)
|
|
@name, @config = name.inquiry, config
|
|
validate! \
|
|
specializations,
|
|
example: validation_yml["servers"]["workers"],
|
|
context: "servers/#{name}",
|
|
with: Kamal::Configuration::Validator::Role
|
|
|
|
@specialized_env = Kamal::Configuration::Env.new \
|
|
config: specializations.fetch("env", {}),
|
|
secrets: config.secrets,
|
|
context: "servers/#{name}/env"
|
|
|
|
@specialized_logging = Kamal::Configuration::Logging.new \
|
|
logging_config: specializations.fetch("logging", {}),
|
|
context: "servers/#{name}/logging"
|
|
|
|
initialize_specialized_proxy
|
|
end
|
|
|
|
def primary_host
|
|
hosts.first
|
|
end
|
|
|
|
def hosts
|
|
tagged_hosts.keys
|
|
end
|
|
|
|
def env_tags(host)
|
|
tagged_hosts.fetch(host).collect { |tag| config.env_tag(tag) }
|
|
end
|
|
|
|
def cmd
|
|
specializations["cmd"]
|
|
end
|
|
|
|
def option_args
|
|
if args = specializations["options"]
|
|
optionize args
|
|
else
|
|
[]
|
|
end
|
|
end
|
|
|
|
def labels
|
|
default_labels.merge(custom_labels)
|
|
end
|
|
|
|
def label_args
|
|
argumentize "--label", labels
|
|
end
|
|
|
|
def logging_args
|
|
logging.args
|
|
end
|
|
|
|
def logging
|
|
@logging ||= config.logging.merge(specialized_logging)
|
|
end
|
|
|
|
def proxy
|
|
@proxy ||= config.proxy.merge(specialized_proxy) if running_proxy?
|
|
end
|
|
|
|
def running_proxy?
|
|
@running_proxy
|
|
end
|
|
|
|
def ssl?
|
|
running_proxy? && proxy.ssl?
|
|
end
|
|
|
|
def stop_args
|
|
# When deploying with the proxy, kamal-proxy will drain request before returning so we don't need to wait.
|
|
timeout = running_proxy? ? nil : config.drain_timeout
|
|
|
|
[ *argumentize("-t", timeout) ]
|
|
end
|
|
|
|
def env(host)
|
|
@envs ||= {}
|
|
@envs[host] ||= [ config.env, specialized_env, *env_tags(host).map(&:env) ].reduce(:merge)
|
|
end
|
|
|
|
def env_args(host)
|
|
[ *env(host).clear_args, *argumentize("--env-file", secrets_path) ]
|
|
end
|
|
|
|
def env_directory
|
|
File.join(config.env_directory, "roles")
|
|
end
|
|
|
|
def secrets_io(host)
|
|
env(host).secrets_io
|
|
end
|
|
|
|
def secrets_path
|
|
File.join(config.env_directory, "roles", "#{name}.env")
|
|
end
|
|
|
|
def asset_volume_args
|
|
asset_volume&.docker_args
|
|
end
|
|
|
|
|
|
def primary?
|
|
name == @config.primary_role_name
|
|
end
|
|
|
|
|
|
def container_name(version = nil)
|
|
[ container_prefix, version || config.version ].compact.join("-")
|
|
end
|
|
|
|
def container_prefix
|
|
[ config.service, name, config.destination ].compact.join("-")
|
|
end
|
|
|
|
|
|
def asset_path
|
|
specializations["asset_path"] || config.asset_path
|
|
end
|
|
|
|
def assets?
|
|
asset_path.present? && running_proxy?
|
|
end
|
|
|
|
def asset_volume(version = config.version)
|
|
if assets?
|
|
Kamal::Configuration::Volume.new \
|
|
host_path: asset_volume_directory(version), container_path: asset_path
|
|
end
|
|
end
|
|
|
|
def asset_extracted_directory(version = config.version)
|
|
File.join config.assets_directory, "extracted", [ name, version ].join("-")
|
|
end
|
|
|
|
def asset_volume_directory(version = config.version)
|
|
File.join config.assets_directory, "volumes", [ name, version ].join("-")
|
|
end
|
|
|
|
def ensure_one_host_for_ssl
|
|
if running_proxy? && proxy.ssl? && hosts.size > 1
|
|
raise Kamal::ConfigurationError, "SSL is only supported on a single server, found #{hosts.size} servers for role #{name}"
|
|
end
|
|
end
|
|
|
|
private
|
|
def initialize_specialized_proxy
|
|
proxy_specializations = specializations["proxy"]
|
|
|
|
if primary?
|
|
# only false means no proxy for non-primary roles
|
|
@running_proxy = proxy_specializations != false
|
|
else
|
|
# false and nil both mean no proxy for non-primary roles
|
|
@running_proxy = !!proxy_specializations
|
|
end
|
|
|
|
if running_proxy?
|
|
proxy_config = proxy_specializations == true || proxy_specializations.nil? ? {} : proxy_specializations
|
|
|
|
@specialized_proxy = Kamal::Configuration::Proxy.new \
|
|
config: config,
|
|
proxy_config: proxy_config,
|
|
context: "servers/#{name}/proxy"
|
|
end
|
|
end
|
|
|
|
def tagged_hosts
|
|
{}.tap do |tagged_hosts|
|
|
extract_hosts_from_config.map do |host_config|
|
|
if host_config.is_a?(Hash)
|
|
host, tags = host_config.first
|
|
tagged_hosts[host] = Array(tags)
|
|
elsif host_config.is_a?(String)
|
|
tagged_hosts[host_config] = []
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def extract_hosts_from_config
|
|
if config.raw_config.servers.is_a?(Array)
|
|
config.raw_config.servers
|
|
else
|
|
servers = config.raw_config.servers[name]
|
|
servers.is_a?(Array) ? servers : Array(servers["hosts"])
|
|
end
|
|
end
|
|
|
|
def default_labels
|
|
{ "service" => config.service, "role" => name, "destination" => config.destination }
|
|
end
|
|
|
|
def specializations
|
|
if config.raw_config.servers.is_a?(Array) || config.raw_config.servers[name].is_a?(Array)
|
|
{}
|
|
else
|
|
config.raw_config.servers[name]
|
|
end
|
|
end
|
|
|
|
def custom_labels
|
|
Hash.new.tap do |labels|
|
|
labels.merge!(config.labels) if config.labels.present?
|
|
labels.merge!(specializations["labels"]) if specializations["labels"].present?
|
|
end
|
|
end
|
|
end
|