Pass around Roles instead of Strings
Avoid looking up roles by names everywhere. This avoids the awkward role/role_config naming as well.
This commit is contained in:
@@ -13,9 +13,8 @@ class Kamal::Cli::App < Kamal::Cli::Base
|
|||||||
|
|
||||||
KAMAL.roles_on(host).each do |role|
|
KAMAL.roles_on(host).each do |role|
|
||||||
app = KAMAL.app(role: role)
|
app = KAMAL.app(role: role)
|
||||||
role_config = KAMAL.config.role(role)
|
|
||||||
|
|
||||||
if role_config.assets?
|
if role.assets?
|
||||||
execute *app.extract_assets
|
execute *app.extract_assets
|
||||||
old_version = capture_with_info(*app.current_running_version, raise_on_non_zero_exit: false).strip
|
old_version = capture_with_info(*app.current_running_version, raise_on_non_zero_exit: false).strip
|
||||||
execute *app.sync_asset_volumes(old_version: old_version)
|
execute *app.sync_asset_volumes(old_version: old_version)
|
||||||
@@ -27,7 +26,6 @@ class Kamal::Cli::App < Kamal::Cli::Base
|
|||||||
KAMAL.roles_on(host).each do |role|
|
KAMAL.roles_on(host).each do |role|
|
||||||
app = KAMAL.app(role: role)
|
app = KAMAL.app(role: role)
|
||||||
auditor = KAMAL.auditor(role: role)
|
auditor = KAMAL.auditor(role: role)
|
||||||
role_config = KAMAL.config.role(role)
|
|
||||||
|
|
||||||
if capture_with_info(*app.container_id_for_version(version), raise_on_non_zero_exit: false).present?
|
if capture_with_info(*app.container_id_for_version(version), raise_on_non_zero_exit: false).present?
|
||||||
tmp_version = "#{version}_replaced_#{SecureRandom.hex(8)}"
|
tmp_version = "#{version}_replaced_#{SecureRandom.hex(8)}"
|
||||||
@@ -38,7 +36,7 @@ class Kamal::Cli::App < Kamal::Cli::Base
|
|||||||
|
|
||||||
old_version = capture_with_info(*app.current_running_version, raise_on_non_zero_exit: false).strip
|
old_version = capture_with_info(*app.current_running_version, raise_on_non_zero_exit: false).strip
|
||||||
|
|
||||||
execute *app.tie_cord(role_config.cord_host_file) if role_config.uses_cord?
|
execute *app.tie_cord(role.cord_host_file) if role.uses_cord?
|
||||||
|
|
||||||
execute *auditor.record("Booted app version #{version}"), verbosity: :debug
|
execute *auditor.record("Booted app version #{version}"), verbosity: :debug
|
||||||
|
|
||||||
@@ -47,7 +45,7 @@ class Kamal::Cli::App < Kamal::Cli::Base
|
|||||||
Kamal::Cli::Healthcheck::Poller.wait_for_healthy(pause_after_ready: true) { capture_with_info(*app.status(version: version)) }
|
Kamal::Cli::Healthcheck::Poller.wait_for_healthy(pause_after_ready: true) { capture_with_info(*app.status(version: version)) }
|
||||||
|
|
||||||
if old_version.present?
|
if old_version.present?
|
||||||
if role_config.uses_cord?
|
if role.uses_cord?
|
||||||
cord = capture_with_info(*app.cord(version: old_version), raise_on_non_zero_exit: false).strip
|
cord = capture_with_info(*app.cord(version: old_version), raise_on_non_zero_exit: false).strip
|
||||||
if cord.present?
|
if cord.present?
|
||||||
execute *app.cut_cord(cord)
|
execute *app.cut_cord(cord)
|
||||||
@@ -57,7 +55,7 @@ class Kamal::Cli::App < Kamal::Cli::Base
|
|||||||
|
|
||||||
execute *app.stop(version: old_version), raise_on_non_zero_exit: false
|
execute *app.stop(version: old_version), raise_on_non_zero_exit: false
|
||||||
|
|
||||||
execute *app.clean_up_assets if role_config.assets?
|
execute *app.clean_up_assets if role.assets?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -8,9 +8,8 @@ class Kamal::Cli::Env < Kamal::Cli::Base
|
|||||||
execute *KAMAL.auditor.record("Pushed env files"), verbosity: :debug
|
execute *KAMAL.auditor.record("Pushed env files"), verbosity: :debug
|
||||||
|
|
||||||
KAMAL.roles_on(host).each do |role|
|
KAMAL.roles_on(host).each do |role|
|
||||||
role_config = KAMAL.config.role(role)
|
|
||||||
execute *KAMAL.app(role: role).make_env_directory
|
execute *KAMAL.app(role: role).make_env_directory
|
||||||
upload! StringIO.new(role_config.env_file), role_config.host_env_file_path, mode: 400
|
upload! StringIO.new(role.env_file), role.host_env_file_path, mode: 400
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -36,7 +35,6 @@ class Kamal::Cli::Env < Kamal::Cli::Base
|
|||||||
execute *KAMAL.auditor.record("Deleted env files"), verbosity: :debug
|
execute *KAMAL.auditor.record("Deleted env files"), verbosity: :debug
|
||||||
|
|
||||||
KAMAL.roles_on(host).each do |role|
|
KAMAL.roles_on(host).each do |role|
|
||||||
role_config = KAMAL.config.role(role)
|
|
||||||
execute *KAMAL.app(role: role).remove_env_file
|
execute *KAMAL.app(role: role).remove_env_file
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class Kamal::Commander
|
|||||||
|
|
||||||
def primary_host
|
def primary_host
|
||||||
# Given a list of specific roles, make an effort to match up with the primary_role
|
# Given a list of specific roles, make an effort to match up with the primary_role
|
||||||
specific_hosts&.first || specific_roles&.detect { |role| role.name == config.primary_role }&.primary_host || specific_roles&.first&.primary_host || config.primary_host
|
specific_hosts&.first || specific_roles&.detect { |role| role == config.primary_role }&.primary_host || specific_roles&.first&.primary_host || config.primary_host
|
||||||
end
|
end
|
||||||
|
|
||||||
def primary_role
|
def primary_role
|
||||||
@@ -73,7 +73,7 @@ class Kamal::Commander
|
|||||||
end
|
end
|
||||||
|
|
||||||
def roles_on(host)
|
def roles_on(host)
|
||||||
roles.select { |role| role.hosts.include?(host.to_s) }.map(&:name)
|
roles.select { |role| role.hosts.include?(host.to_s) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def traefik_hosts
|
def traefik_hosts
|
||||||
|
|||||||
@@ -3,12 +3,11 @@ class Kamal::Commands::App < Kamal::Commands::Base
|
|||||||
|
|
||||||
ACTIVE_DOCKER_STATUSES = [ :running, :restarting ]
|
ACTIVE_DOCKER_STATUSES = [ :running, :restarting ]
|
||||||
|
|
||||||
attr_reader :role, :role_config
|
attr_reader :role, :role
|
||||||
|
|
||||||
def initialize(config, role: nil)
|
def initialize(config, role: nil)
|
||||||
super(config)
|
super(config)
|
||||||
@role = role
|
@role = role
|
||||||
@role_config = config.role(self.role)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def run(hostname: nil)
|
def run(hostname: nil)
|
||||||
@@ -19,15 +18,15 @@ class Kamal::Commands::App < Kamal::Commands::Base
|
|||||||
*(["--hostname", hostname] if hostname),
|
*(["--hostname", hostname] if hostname),
|
||||||
"-e", "KAMAL_CONTAINER_NAME=\"#{container_name}\"",
|
"-e", "KAMAL_CONTAINER_NAME=\"#{container_name}\"",
|
||||||
"-e", "KAMAL_VERSION=\"#{config.version}\"",
|
"-e", "KAMAL_VERSION=\"#{config.version}\"",
|
||||||
*role_config.env_args,
|
*role.env_args,
|
||||||
*role_config.health_check_args,
|
*role.health_check_args,
|
||||||
*role_config.logging_args,
|
*role.logging_args,
|
||||||
*config.volume_args,
|
*config.volume_args,
|
||||||
*role_config.asset_volume_args,
|
*role.asset_volume_args,
|
||||||
*role_config.label_args,
|
*role.label_args,
|
||||||
*role_config.option_args,
|
*role.option_args,
|
||||||
config.absolute_image,
|
config.absolute_image,
|
||||||
role_config.cmd
|
role.cmd
|
||||||
end
|
end
|
||||||
|
|
||||||
def start
|
def start
|
||||||
@@ -64,22 +63,22 @@ class Kamal::Commands::App < Kamal::Commands::Base
|
|||||||
def list_versions(*docker_args, statuses: nil)
|
def list_versions(*docker_args, statuses: nil)
|
||||||
pipe \
|
pipe \
|
||||||
docker(:ps, *filter_args(statuses: statuses), *docker_args, "--format", '"{{.Names}}"'),
|
docker(:ps, *filter_args(statuses: statuses), *docker_args, "--format", '"{{.Names}}"'),
|
||||||
%(while read line; do echo ${line##{role_config.container_prefix}-}; done) # Extract SHA from "service-role-dest-SHA"
|
%(while read line; do echo ${line##{role.container_prefix}-}; done) # Extract SHA from "service-role-dest-SHA"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def make_env_directory
|
def make_env_directory
|
||||||
make_directory role_config.host_env_directory
|
make_directory role.host_env_directory
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_env_file
|
def remove_env_file
|
||||||
[ :rm, "-f", role_config.host_env_file_path ]
|
[ :rm, "-f", role.host_env_file_path ]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
private
|
private
|
||||||
def container_name(version = nil)
|
def container_name(version = nil)
|
||||||
[ role_config.container_prefix, version || config.version ].compact.join("-")
|
[ role.container_prefix, version || config.version ].compact.join("-")
|
||||||
end
|
end
|
||||||
|
|
||||||
def filter_args(statuses: nil)
|
def filter_args(statuses: nil)
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
module Kamal::Commands::App::Assets
|
module Kamal::Commands::App::Assets
|
||||||
def extract_assets
|
def extract_assets
|
||||||
asset_container = "#{role_config.container_prefix}-assets"
|
asset_container = "#{role.container_prefix}-assets"
|
||||||
|
|
||||||
combine \
|
combine \
|
||||||
make_directory(role_config.asset_extracted_path),
|
make_directory(role.asset_extracted_path),
|
||||||
[*docker(:stop, "-t 1", asset_container, "2> /dev/null"), "|| true"],
|
[*docker(:stop, "-t 1", asset_container, "2> /dev/null"), "|| true"],
|
||||||
docker(:run, "--name", asset_container, "--detach", "--rm", config.latest_image, "sleep 1000000"),
|
docker(:run, "--name", asset_container, "--detach", "--rm", config.latest_image, "sleep 1000000"),
|
||||||
docker(:cp, "-L", "#{asset_container}:#{role_config.asset_path}/.", role_config.asset_extracted_path),
|
docker(:cp, "-L", "#{asset_container}:#{role.asset_path}/.", role.asset_extracted_path),
|
||||||
docker(:stop, "-t 1", asset_container),
|
docker(:stop, "-t 1", asset_container),
|
||||||
by: "&&"
|
by: "&&"
|
||||||
end
|
end
|
||||||
|
|
||||||
def sync_asset_volumes(old_version: nil)
|
def sync_asset_volumes(old_version: nil)
|
||||||
new_extracted_path, new_volume_path = role_config.asset_extracted_path(config.version), role_config.asset_volume.host_path
|
new_extracted_path, new_volume_path = role.asset_extracted_path(config.version), role.asset_volume.host_path
|
||||||
if old_version.present?
|
if old_version.present?
|
||||||
old_extracted_path, old_volume_path = role_config.asset_extracted_path(old_version), role_config.asset_volume(old_version).host_path
|
old_extracted_path, old_volume_path = role.asset_extracted_path(old_version), role.asset_volume(old_version).host_path
|
||||||
end
|
end
|
||||||
|
|
||||||
commands = [make_directory(new_volume_path), copy_contents(new_extracted_path, new_volume_path)]
|
commands = [make_directory(new_volume_path), copy_contents(new_extracted_path, new_volume_path)]
|
||||||
@@ -29,8 +29,8 @@ module Kamal::Commands::App::Assets
|
|||||||
|
|
||||||
def clean_up_assets
|
def clean_up_assets
|
||||||
chain \
|
chain \
|
||||||
find_and_remove_older_siblings(role_config.asset_extracted_path),
|
find_and_remove_older_siblings(role.asset_extracted_path),
|
||||||
find_and_remove_older_siblings(role_config.asset_volume_path)
|
find_and_remove_older_siblings(role.asset_volume_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@@ -39,7 +39,7 @@ module Kamal::Commands::App::Assets
|
|||||||
:find,
|
:find,
|
||||||
Pathname.new(path).dirname.to_s,
|
Pathname.new(path).dirname.to_s,
|
||||||
"-maxdepth 1",
|
"-maxdepth 1",
|
||||||
"-name", "'#{role_config.container_prefix}-*'",
|
"-name", "'#{role.container_prefix}-*'",
|
||||||
"!", "-name", Pathname.new(path).basename.to_s,
|
"!", "-name", Pathname.new(path).basename.to_s,
|
||||||
"-exec rm -rf \"{}\" +"
|
"-exec rm -rf \"{}\" +"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ module Kamal::Commands::App::Cord
|
|||||||
def cord(version:)
|
def cord(version:)
|
||||||
pipe \
|
pipe \
|
||||||
docker(:inspect, "-f '{{ range .Mounts }}{{printf \"%s %s\\n\" .Source .Destination}}{{ end }}'", container_name(version)),
|
docker(:inspect, "-f '{{ range .Mounts }}{{printf \"%s %s\\n\" .Source .Destination}}{{ end }}'", container_name(version)),
|
||||||
[:awk, "'$2 == \"#{role_config.cord_volume.container_path}\" {print $1}'"]
|
[:awk, "'$2 == \"#{role.cord_volume.container_path}\" {print $1}'"]
|
||||||
end
|
end
|
||||||
|
|
||||||
def tie_cord(cord)
|
def tie_cord(cord)
|
||||||
@@ -12,8 +12,8 @@ module Kamal::Commands::App::Cord
|
|||||||
def cut_cord(cord)
|
def cut_cord(cord)
|
||||||
remove_directory(cord)
|
remove_directory(cord)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def create_empty_file(file)
|
def create_empty_file(file)
|
||||||
chain \
|
chain \
|
||||||
make_directory_for(file),
|
make_directory_for(file),
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ module Kamal::Commands::App::Execution
|
|||||||
docker :run,
|
docker :run,
|
||||||
("-it" if interactive),
|
("-it" if interactive),
|
||||||
"--rm",
|
"--rm",
|
||||||
*role_config&.env_args,
|
*role&.env_args,
|
||||||
*config.volume_args,
|
*config.volume_args,
|
||||||
*role_config&.option_args,
|
*role&.option_args,
|
||||||
config.absolute_image,
|
config.absolute_image,
|
||||||
*command
|
*command
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -92,7 +92,19 @@ class Kamal::Configuration
|
|||||||
end
|
end
|
||||||
|
|
||||||
def primary_host
|
def primary_host
|
||||||
role(primary_role)&.primary_host
|
primary_role&.primary_host
|
||||||
|
end
|
||||||
|
|
||||||
|
def primary_role_name
|
||||||
|
raw_config.primary_role || "web"
|
||||||
|
end
|
||||||
|
|
||||||
|
def primary_role
|
||||||
|
role(primary_role_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
def allow_empty_roles?
|
||||||
|
raw_config.allow_empty_roles
|
||||||
end
|
end
|
||||||
|
|
||||||
def traefik_roles
|
def traefik_roles
|
||||||
@@ -212,14 +224,6 @@ class Kamal::Configuration
|
|||||||
raw_config.asset_path
|
raw_config.asset_path
|
||||||
end
|
end
|
||||||
|
|
||||||
def primary_role
|
|
||||||
raw_config.primary_role || "web"
|
|
||||||
end
|
|
||||||
|
|
||||||
def allow_empty_roles?
|
|
||||||
raw_config.allow_empty_roles
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
def valid?
|
def valid?
|
||||||
ensure_destination_if_required && ensure_required_keys_present && ensure_valid_kamal_version && ensure_retain_containers_valid && ensure_valid_service_name
|
ensure_destination_if_required && ensure_required_keys_present && ensure_valid_kamal_version && ensure_retain_containers_valid && ensure_valid_service_name
|
||||||
@@ -268,12 +272,12 @@ class Kamal::Configuration
|
|||||||
raise ArgumentError, "You must specify a password for the registry in config/deploy.yml (or set the ENV variable if that's used)"
|
raise ArgumentError, "You must specify a password for the registry in config/deploy.yml (or set the ENV variable if that's used)"
|
||||||
end
|
end
|
||||||
|
|
||||||
unless role_names.include?(primary_role)
|
unless role_names.include?(primary_role_name)
|
||||||
raise ArgumentError, "The primary_role #{primary_role} isn't defined"
|
raise ArgumentError, "The primary_role #{primary_role_name} isn't defined"
|
||||||
end
|
end
|
||||||
|
|
||||||
if role(primary_role).hosts.empty?
|
if primary_role.hosts.empty?
|
||||||
raise ArgumentError, "No servers specified for the #{primary_role} primary_role"
|
raise ArgumentError, "No servers specified for the #{primary_role.name} primary_role"
|
||||||
end
|
end
|
||||||
|
|
||||||
unless allow_empty_roles?
|
unless allow_empty_roles?
|
||||||
|
|||||||
@@ -3,9 +3,10 @@ class Kamal::Configuration::Role
|
|||||||
delegate :argumentize, :optionize, to: Kamal::Utils
|
delegate :argumentize, :optionize, to: Kamal::Utils
|
||||||
|
|
||||||
attr_accessor :name
|
attr_accessor :name
|
||||||
|
alias to_s name
|
||||||
|
|
||||||
def initialize(name, config:)
|
def initialize(name, config:)
|
||||||
@name, @config = name.inquiry, config
|
@name, @config = name.inquiry, config
|
||||||
end
|
end
|
||||||
|
|
||||||
def primary_host
|
def primary_host
|
||||||
@@ -113,7 +114,7 @@ class Kamal::Configuration::Role
|
|||||||
end
|
end
|
||||||
|
|
||||||
def primary?
|
def primary?
|
||||||
@config.primary_role == name
|
self == @config.primary_role
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -83,14 +83,14 @@ class CommanderTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "primary_role" do
|
test "primary_role" do
|
||||||
assert_equal "web", @kamal.primary_role
|
assert_equal "web", @kamal.primary_role.name
|
||||||
@kamal.specific_roles = "workers"
|
@kamal.specific_roles = "workers"
|
||||||
assert_equal "workers", @kamal.primary_role
|
assert_equal "workers", @kamal.primary_role.name
|
||||||
end
|
end
|
||||||
|
|
||||||
test "roles_on" do
|
test "roles_on" do
|
||||||
assert_equal [ "web" ], @kamal.roles_on("1.1.1.1")
|
assert_equal [ "web" ], @kamal.roles_on("1.1.1.1").map(&:name)
|
||||||
assert_equal [ "workers" ], @kamal.roles_on("1.1.1.3")
|
assert_equal [ "workers" ], @kamal.roles_on("1.1.1.3").map(&:name)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "default group strategy" do
|
test "default group strategy" do
|
||||||
@@ -120,7 +120,7 @@ class CommanderTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
@kamal.specific_roles = [ "web_*" ]
|
@kamal.specific_roles = [ "web_*" ]
|
||||||
assert_equal [ "web_chicago", "web_tokyo" ], @kamal.roles.map(&:name)
|
assert_equal [ "web_chicago", "web_tokyo" ], @kamal.roles.map(&:name)
|
||||||
assert_equal "web_tokyo", @kamal.primary_role
|
assert_equal "web_tokyo", @kamal.primary_role.name
|
||||||
assert_equal "1.1.1.3", @kamal.primary_host
|
assert_equal "1.1.1.3", @kamal.primary_host
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -400,6 +400,7 @@ class CommandsAppTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
private
|
private
|
||||||
def new_command(role: "web", **additional_config)
|
def new_command(role: "web", **additional_config)
|
||||||
Kamal::Commands::App.new(Kamal::Configuration.new(@config.merge(additional_config), destination: @destination, version: "999"), role: role)
|
config = Kamal::Configuration.new(@config.merge(additional_config), destination: @destination, version: "999")
|
||||||
|
Kamal::Commands::App.new(config, role: config.role(role))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -300,14 +300,14 @@ class ConfigurationTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "primary role" do
|
test "primary role" do
|
||||||
assert_equal "web", @config.primary_role
|
assert_equal "web", @config.primary_role.name
|
||||||
|
|
||||||
config = Kamal::Configuration.new(@deploy_with_roles.deep_merge({
|
config = Kamal::Configuration.new(@deploy_with_roles.deep_merge({
|
||||||
servers: { "alternate_web" => { "hosts" => [ "1.1.1.4", "1.1.1.5" ] } },
|
servers: { "alternate_web" => { "hosts" => [ "1.1.1.4", "1.1.1.5" ] } },
|
||||||
primary_role: "alternate_web" } ))
|
primary_role: "alternate_web" } ))
|
||||||
|
|
||||||
|
|
||||||
assert_equal "alternate_web", config.primary_role
|
assert_equal "alternate_web", config.primary_role.name
|
||||||
assert_equal "1.1.1.4", config.primary_host
|
assert_equal "1.1.1.4", config.primary_host
|
||||||
assert config.role(:alternate_web).primary?
|
assert config.role(:alternate_web).primary?
|
||||||
assert config.role(:alternate_web).running_traefik?
|
assert config.role(:alternate_web).running_traefik?
|
||||||
|
|||||||
Reference in New Issue
Block a user