[Feature] Add optional accessory registry.
Add test cases to cover new option.
This commit is contained in:
@@ -292,7 +292,7 @@ class Kamal::Cli::Accessory < Kamal::Cli::Base
|
||||
def prepare(name)
|
||||
with_accessory(name) do |accessory, hosts|
|
||||
on(hosts) do
|
||||
execute *KAMAL.registry.login
|
||||
execute *KAMAL.registry.login(registry_config: accessory.registry)
|
||||
execute *KAMAL.docker.create_network
|
||||
rescue SSHKit::Command::Failed => e
|
||||
raise unless e.message.include?("already exists")
|
||||
|
||||
@@ -4,11 +4,10 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base
|
||||
attr_reader :accessory_config
|
||||
delegate :service_name, :image, :hosts, :port, :files, :directories, :cmd,
|
||||
:network_args, :publish_args, :env_args, :volume_args, :label_args, :option_args,
|
||||
:secrets_io, :secrets_path, :env_directory, :proxy, :running_proxy?,
|
||||
:secrets_io, :secrets_path, :env_directory, :proxy, :running_proxy?, :registry,
|
||||
to: :accessory_config
|
||||
delegate :proxy_container_name, to: :config
|
||||
|
||||
|
||||
def initialize(config, name:)
|
||||
super(config)
|
||||
@accessory_config = config.accessory(name)
|
||||
@@ -42,7 +41,6 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base
|
||||
docker :ps, *service_filter
|
||||
end
|
||||
|
||||
|
||||
def logs(timestamps: true, since: nil, lines: nil, grep: nil, grep_options: nil)
|
||||
pipe \
|
||||
docker(:logs, service_name, (" --since #{since}" if since), (" --tail #{lines}" if lines), ("--timestamps" if timestamps), "2>&1"),
|
||||
@@ -56,7 +54,6 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base
|
||||
(%(grep "#{grep}"#{" #{grep_options}" if grep_options}) if grep)
|
||||
end
|
||||
|
||||
|
||||
def execute_in_existing_container(*command, interactive: false)
|
||||
docker :exec,
|
||||
("-it" if interactive),
|
||||
@@ -87,7 +84,6 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base
|
||||
super command, host: hosts.first
|
||||
end
|
||||
|
||||
|
||||
def ensure_local_file_present(local_file)
|
||||
if !local_file.is_a?(StringIO) && !Pathname.new(local_file).exist?
|
||||
raise "Missing file: #{local_file}"
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
class Kamal::Commands::Registry < Kamal::Commands::Base
|
||||
delegate :registry, to: :config
|
||||
def login(registry_config: nil)
|
||||
registry_config ||= config.registry
|
||||
|
||||
def login
|
||||
docker :login,
|
||||
registry.server,
|
||||
"-u", sensitive(Kamal::Utils.escape_shell_value(registry.username)),
|
||||
"-p", sensitive(Kamal::Utils.escape_shell_value(registry.password))
|
||||
registry_config.server,
|
||||
"-u", sensitive(Kamal::Utils.escape_shell_value(registry_config.username)),
|
||||
"-p", sensitive(Kamal::Utils.escape_shell_value(registry_config.password))
|
||||
end
|
||||
|
||||
def logout
|
||||
docker :logout, registry.server
|
||||
def logout(registry_config: nil)
|
||||
registry_config ||= config.registry
|
||||
|
||||
docker :logout, registry_config.server
|
||||
end
|
||||
end
|
||||
|
||||
@@ -59,7 +59,7 @@ class Kamal::Configuration
|
||||
|
||||
# Eager load config to validate it, these are first as they have dependencies later on
|
||||
@servers = Servers.new(config: self)
|
||||
@registry = Registry.new(config: self)
|
||||
@registry = Registry.new(config: raw_config, secrets: secrets)
|
||||
|
||||
@accessories = @raw_config.accessories&.keys&.collect { |name| Accessory.new(name, config: self) } || []
|
||||
@aliases = @raw_config.aliases&.keys&.to_h { |name| [ name, Alias.new(name, config: self) ] } || {}
|
||||
@@ -82,7 +82,6 @@ class Kamal::Configuration
|
||||
ensure_unique_hosts_for_ssl_roles
|
||||
end
|
||||
|
||||
|
||||
def version=(version)
|
||||
@declared_version = version
|
||||
end
|
||||
@@ -106,7 +105,6 @@ class Kamal::Configuration
|
||||
raw_config.minimum_version
|
||||
end
|
||||
|
||||
|
||||
def roles
|
||||
servers.roles
|
||||
end
|
||||
@@ -119,7 +117,6 @@ class Kamal::Configuration
|
||||
accessories.detect { |a| a.name == name.to_s }
|
||||
end
|
||||
|
||||
|
||||
def all_hosts
|
||||
(roles + accessories).flat_map(&:hosts).uniq
|
||||
end
|
||||
@@ -180,7 +177,6 @@ class Kamal::Configuration
|
||||
raw_config.retain_containers || 5
|
||||
end
|
||||
|
||||
|
||||
def volume_args
|
||||
if raw_config.volumes.present?
|
||||
argumentize "--volume", raw_config.volumes
|
||||
@@ -193,7 +189,6 @@ class Kamal::Configuration
|
||||
logging.args
|
||||
end
|
||||
|
||||
|
||||
def readiness_delay
|
||||
raw_config.readiness_delay || 7
|
||||
end
|
||||
@@ -206,7 +201,6 @@ class Kamal::Configuration
|
||||
raw_config.drain_timeout || 30
|
||||
end
|
||||
|
||||
|
||||
def run_directory
|
||||
".kamal"
|
||||
end
|
||||
@@ -227,7 +221,6 @@ class Kamal::Configuration
|
||||
File.join app_directory, "assets"
|
||||
end
|
||||
|
||||
|
||||
def hooks_path
|
||||
raw_config.hooks_path || ".kamal/hooks"
|
||||
end
|
||||
@@ -236,7 +229,6 @@ class Kamal::Configuration
|
||||
raw_config.asset_path
|
||||
end
|
||||
|
||||
|
||||
def env_tags
|
||||
@env_tags ||= if (tags = raw_config.env["tags"])
|
||||
tags.collect { |name, config| Env::Tag.new(name, config: config, secrets: secrets) }
|
||||
@@ -277,7 +269,6 @@ class Kamal::Configuration
|
||||
File.join proxy_directory, "options"
|
||||
end
|
||||
|
||||
|
||||
def to_h
|
||||
{
|
||||
roles: role_names,
|
||||
|
||||
@@ -5,7 +5,7 @@ class Kamal::Configuration::Accessory
|
||||
|
||||
delegate :argumentize, :optionize, to: Kamal::Utils
|
||||
|
||||
attr_reader :name, :accessory_config, :env, :proxy
|
||||
attr_reader :name, :env, :proxy, :registry
|
||||
|
||||
def initialize(name, config:)
|
||||
@name, @config, @accessory_config = name.inquiry, config, config.raw_config["accessories"][name]
|
||||
@@ -16,12 +16,9 @@ class Kamal::Configuration::Accessory
|
||||
context: "accessories/#{name}",
|
||||
with: Kamal::Configuration::Validator::Accessory
|
||||
|
||||
@env = Kamal::Configuration::Env.new \
|
||||
config: accessory_config.fetch("env", {}),
|
||||
secrets: config.secrets,
|
||||
context: "accessories/#{name}/env"
|
||||
|
||||
initialize_proxy if running_proxy?
|
||||
@env = initialize_env
|
||||
@proxy = initialize_proxy if running_proxy?
|
||||
@registry = initialize_registry if accessory_config["registry"].present?
|
||||
end
|
||||
|
||||
def service_name
|
||||
@@ -29,7 +26,7 @@ class Kamal::Configuration::Accessory
|
||||
end
|
||||
|
||||
def image
|
||||
accessory_config["image"]
|
||||
[ registry&.server, accessory_config["image"] ].compact.join("/")
|
||||
end
|
||||
|
||||
def hosts
|
||||
@@ -109,18 +106,32 @@ class Kamal::Configuration::Accessory
|
||||
end
|
||||
|
||||
def running_proxy?
|
||||
@accessory_config["proxy"].present?
|
||||
end
|
||||
|
||||
def initialize_proxy
|
||||
@proxy = Kamal::Configuration::Proxy.new \
|
||||
config: config,
|
||||
proxy_config: accessory_config["proxy"],
|
||||
context: "accessories/#{name}/proxy"
|
||||
accessory_config["proxy"].present?
|
||||
end
|
||||
|
||||
private
|
||||
attr_accessor :config
|
||||
attr_reader :config, :accessory_config
|
||||
|
||||
def initialize_env
|
||||
Kamal::Configuration::Env.new \
|
||||
config: accessory_config.fetch("env", {}),
|
||||
secrets: config.secrets,
|
||||
context: "accessories/#{name}/env"
|
||||
end
|
||||
|
||||
def initialize_proxy
|
||||
Kamal::Configuration::Proxy.new \
|
||||
config: config,
|
||||
proxy_config: accessory_config["proxy"],
|
||||
context: "accessories/#{name}/proxy"
|
||||
end
|
||||
|
||||
def initialize_registry
|
||||
Kamal::Configuration::Registry.new \
|
||||
config: accessory_config,
|
||||
secrets: config.secrets,
|
||||
context: "accessories/#{name}/registry"
|
||||
end
|
||||
|
||||
def default_labels
|
||||
{ "service" => service_name }
|
||||
|
||||
@@ -23,9 +23,27 @@ accessories:
|
||||
|
||||
# Image
|
||||
#
|
||||
# The Docker image to use, prefix it with a registry if not using Docker Hub:
|
||||
# The Docker image to use.
|
||||
# Prefix it with its server when using root level registry different from Docker Hub.
|
||||
# Define registry directly or via anchors when it differs from root level registry.
|
||||
image: mysql:8.0
|
||||
|
||||
# Registry
|
||||
#
|
||||
# By default accessories use Docker Hub registry.
|
||||
# You can specify different registry per accessory with this option.
|
||||
# Don't prefix image with this registry server.
|
||||
# Use anchors if you need to set the same specific registry for several accessories.
|
||||
#
|
||||
# ```yml
|
||||
# registry:
|
||||
# <<: *specific-registry
|
||||
# ```
|
||||
#
|
||||
# See kamal docs registry for more information:
|
||||
registry:
|
||||
...
|
||||
|
||||
# Accessory hosts
|
||||
#
|
||||
# Specify one of `host`, `hosts`, or `roles`:
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
class Kamal::Configuration::Registry
|
||||
include Kamal::Configuration::Validation
|
||||
|
||||
attr_reader :registry_config, :secrets
|
||||
|
||||
def initialize(config:)
|
||||
@registry_config = config.raw_config.registry || {}
|
||||
@secrets = config.secrets
|
||||
validate! registry_config, with: Kamal::Configuration::Validator::Registry
|
||||
def initialize(config:, secrets:, context: "registry")
|
||||
@registry_config = config["registry"] || {}
|
||||
@secrets = secrets
|
||||
validate! registry_config, context: context, with: Kamal::Configuration::Validator::Registry
|
||||
end
|
||||
|
||||
def server
|
||||
@@ -22,6 +20,8 @@ class Kamal::Configuration::Registry
|
||||
end
|
||||
|
||||
private
|
||||
attr_reader :registry_config, :secrets
|
||||
|
||||
def lookup(key)
|
||||
if registry_config[key].is_a?(Array)
|
||||
secrets[registry_config[key].first]
|
||||
|
||||
Reference in New Issue
Block a user