Rename to Kamal
This commit is contained in:
251
lib/kamal/configuration.rb
Normal file
251
lib/kamal/configuration.rb
Normal file
@@ -0,0 +1,251 @@
|
||||
require "active_support/ordered_options"
|
||||
require "active_support/core_ext/string/inquiry"
|
||||
require "active_support/core_ext/module/delegation"
|
||||
require "pathname"
|
||||
require "erb"
|
||||
require "net/ssh/proxy/jump"
|
||||
|
||||
class Kamal::Configuration
|
||||
delegate :service, :image, :servers, :env, :labels, :registry, :stop_wait_time, :hooks_path, to: :raw_config, allow_nil: true
|
||||
delegate :argumentize, :argumentize_env_with_secrets, :optionize, to: Kamal::Utils
|
||||
|
||||
attr_accessor :destination
|
||||
attr_accessor :raw_config
|
||||
|
||||
class << self
|
||||
def create_from(config_file:, destination: nil, version: nil)
|
||||
raw_config = load_config_files(config_file, *destination_config_file(config_file, destination))
|
||||
|
||||
new raw_config, destination: destination, version: version
|
||||
end
|
||||
|
||||
private
|
||||
def load_config_files(*files)
|
||||
files.inject({}) { |config, file| config.deep_merge! load_config_file(file) }
|
||||
end
|
||||
|
||||
def load_config_file(file)
|
||||
if file.exist?
|
||||
YAML.load(ERB.new(IO.read(file)).result).symbolize_keys
|
||||
else
|
||||
raise "Configuration file not found in #{file}"
|
||||
end
|
||||
end
|
||||
|
||||
def destination_config_file(base_config_file, destination)
|
||||
base_config_file.sub_ext(".#{destination}.yml") if destination
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(raw_config, destination: nil, version: nil, validate: true)
|
||||
@raw_config = ActiveSupport::InheritableOptions.new(raw_config)
|
||||
@destination = destination
|
||||
@declared_version = version
|
||||
valid? if validate
|
||||
end
|
||||
|
||||
|
||||
def version=(version)
|
||||
@declared_version = version
|
||||
end
|
||||
|
||||
def version
|
||||
@declared_version.presence || ENV["VERSION"] || git_version
|
||||
end
|
||||
|
||||
def abbreviated_version
|
||||
Kamal::Utils.abbreviate_version(version)
|
||||
end
|
||||
|
||||
|
||||
def roles
|
||||
@roles ||= role_names.collect { |role_name| Role.new(role_name, config: self) }
|
||||
end
|
||||
|
||||
def role(name)
|
||||
roles.detect { |r| r.name == name.to_s }
|
||||
end
|
||||
|
||||
def accessories
|
||||
@accessories ||= raw_config.accessories&.keys&.collect { |name| Kamal::Configuration::Accessory.new(name, config: self) } || []
|
||||
end
|
||||
|
||||
def accessory(name)
|
||||
accessories.detect { |a| a.name == name.to_s }
|
||||
end
|
||||
|
||||
|
||||
def all_hosts
|
||||
roles.flat_map(&:hosts).uniq
|
||||
end
|
||||
|
||||
def primary_web_host
|
||||
role(:web).primary_host
|
||||
end
|
||||
|
||||
def traefik_hosts
|
||||
roles.select(&:running_traefik?).flat_map(&:hosts).uniq
|
||||
end
|
||||
|
||||
def boot
|
||||
Kamal::Configuration::Boot.new(config: self)
|
||||
end
|
||||
|
||||
|
||||
def repository
|
||||
[ raw_config.registry["server"], image ].compact.join("/")
|
||||
end
|
||||
|
||||
def absolute_image
|
||||
"#{repository}:#{version}"
|
||||
end
|
||||
|
||||
def latest_image
|
||||
"#{repository}:latest"
|
||||
end
|
||||
|
||||
def service_with_version
|
||||
"#{service}-#{version}"
|
||||
end
|
||||
|
||||
|
||||
def env_args
|
||||
if raw_config.env.present?
|
||||
argumentize_env_with_secrets(raw_config.env)
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
def volume_args
|
||||
if raw_config.volumes.present?
|
||||
argumentize "--volume", raw_config.volumes
|
||||
else
|
||||
[]
|
||||
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
|
||||
Kamal::Configuration::Ssh.new(config: self)
|
||||
end
|
||||
|
||||
def sshkit
|
||||
Kamal::Configuration::Sshkit.new(config: self)
|
||||
end
|
||||
|
||||
|
||||
def healthcheck
|
||||
{ "path" => "/up", "port" => 3000, "max_attempts" => 7 }.merge(raw_config.healthcheck || {})
|
||||
end
|
||||
|
||||
def readiness_delay
|
||||
raw_config.readiness_delay || 7
|
||||
end
|
||||
|
||||
def minimum_version
|
||||
raw_config.minimum_version
|
||||
end
|
||||
|
||||
def valid?
|
||||
ensure_required_keys_present && ensure_valid_kamal_version
|
||||
end
|
||||
|
||||
|
||||
def to_h
|
||||
{
|
||||
roles: role_names,
|
||||
hosts: all_hosts,
|
||||
primary_host: primary_web_host,
|
||||
version: version,
|
||||
repository: repository,
|
||||
absolute_image: absolute_image,
|
||||
service_with_version: service_with_version,
|
||||
env_args: env_args,
|
||||
volume_args: volume_args,
|
||||
ssh_options: ssh.to_h,
|
||||
sshkit: sshkit.to_h,
|
||||
builder: builder.to_h,
|
||||
accessories: raw_config.accessories,
|
||||
logging: logging_args,
|
||||
healthcheck: healthcheck
|
||||
}.compact
|
||||
end
|
||||
|
||||
def traefik
|
||||
raw_config.traefik || {}
|
||||
end
|
||||
|
||||
def hooks_path
|
||||
raw_config.hooks_path || ".kamal/hooks"
|
||||
end
|
||||
|
||||
def builder
|
||||
Kamal::Configuration::Builder.new(config: self)
|
||||
end
|
||||
|
||||
# Will raise KeyError if any secret ENVs are missing
|
||||
def ensure_env_available
|
||||
env_args
|
||||
roles.each(&:env_args)
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
# Will raise ArgumentError if any required config keys are missing
|
||||
def ensure_required_keys_present
|
||||
%i[ service image registry servers ].each do |key|
|
||||
raise ArgumentError, "Missing required configuration for #{key}" unless raw_config[key].present?
|
||||
end
|
||||
|
||||
if raw_config.registry["username"].blank?
|
||||
raise ArgumentError, "You must specify a username for the registry in config/deploy.yml"
|
||||
end
|
||||
|
||||
if raw_config.registry["password"].blank?
|
||||
raise ArgumentError, "You must specify a password for the registry in config/deploy.yml (or set the ENV variable if that's used)"
|
||||
end
|
||||
|
||||
roles.each do |role|
|
||||
if role.hosts.empty?
|
||||
raise ArgumentError, "No servers specified for the #{role.name} role"
|
||||
end
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def ensure_valid_kamal_version
|
||||
if minimum_version && Gem::Version.new(minimum_version) > Gem::Version.new(Kamal::VERSION)
|
||||
raise ArgumentError, "Current version is #{Kamal::VERSION}, minimum required is #{minimum_version}"
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
|
||||
def role_names
|
||||
raw_config.servers.is_a?(Array) ? [ "web" ] : raw_config.servers.keys.sort
|
||||
end
|
||||
|
||||
def git_version
|
||||
@git_version ||=
|
||||
if system("git rev-parse")
|
||||
uncommitted_suffix = Kamal::Utils.uncommitted_changes.present? ? "_uncommitted_#{SecureRandom.hex(8)}" : ""
|
||||
|
||||
"#{`git rev-parse HEAD`.strip}#{uncommitted_suffix}"
|
||||
else
|
||||
raise "Can't use commit hash as version, no git repository found in #{Dir.pwd}"
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user