Skip to content

Commit

Permalink
[Feature] Add optional accessory registry.
Browse files Browse the repository at this point in the history
Add test cases to cover new option.
  • Loading branch information
ShPakvel committed Dec 22, 2024
1 parent 1547089 commit b5aee11
Show file tree
Hide file tree
Showing 12 changed files with 208 additions and 77 deletions.
2 changes: 1 addition & 1 deletion lib/kamal/cli/accessory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ def remove_accessory(name)
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")
Expand Down
6 changes: 1 addition & 5 deletions lib/kamal/commands/accessory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -42,7 +41,6 @@ def info
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"),
Expand All @@ -56,7 +54,6 @@ def follow_logs(timestamps: true, grep: nil, grep_options: nil)
(%(grep "#{grep}"#{" #{grep_options}" if grep_options}) if grep)
end


def execute_in_existing_container(*command, interactive: false)
docker :exec,
("-it" if interactive),
Expand Down Expand Up @@ -87,7 +84,6 @@ def run_over_ssh(command)
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}"
Expand Down
16 changes: 9 additions & 7 deletions lib/kamal/commands/registry.rb
Original file line number Diff line number Diff line change
@@ -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
11 changes: 1 addition & 10 deletions lib/kamal/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def initialize(raw_config, destination: nil, version: nil, validate: true)

# 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) ] } || {}
Expand All @@ -82,7 +82,6 @@ def initialize(raw_config, destination: nil, version: nil, validate: true)
ensure_unique_hosts_for_ssl_roles
end


def version=(version)
@declared_version = version
end
Expand All @@ -106,7 +105,6 @@ def minimum_version
raw_config.minimum_version
end


def roles
servers.roles
end
Expand All @@ -119,7 +117,6 @@ def accessory(name)
accessories.detect { |a| a.name == name.to_s }
end


def all_hosts
(roles + accessories).flat_map(&:hosts).uniq
end
Expand Down Expand Up @@ -180,7 +177,6 @@ def retain_containers
raw_config.retain_containers || 5
end


def volume_args
if raw_config.volumes.present?
argumentize "--volume", raw_config.volumes
Expand All @@ -193,7 +189,6 @@ def logging_args
logging.args
end


def readiness_delay
raw_config.readiness_delay || 7
end
Expand All @@ -206,7 +201,6 @@ def drain_timeout
raw_config.drain_timeout || 30
end


def run_directory
".kamal"
end
Expand All @@ -227,7 +221,6 @@ def assets_directory
File.join app_directory, "assets"
end


def hooks_path
raw_config.hooks_path || ".kamal/hooks"
end
Expand All @@ -236,7 +229,6 @@ def asset_path
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) }
Expand Down Expand Up @@ -277,7 +269,6 @@ def proxy_options_file
File.join proxy_directory, "options"
end


def to_h
{
roles: role_names,
Expand Down
45 changes: 28 additions & 17 deletions lib/kamal/configuration/accessory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -16,20 +16,17 @@ def initialize(name, config:)
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
accessory_config["service"] || "#{config.service}-#{name}"
end

def image
accessory_config["image"]
[ registry&.server, accessory_config["image"] ].compact.join("/")
end

def hosts
Expand Down Expand Up @@ -109,18 +106,32 @@ def cmd
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 }
Expand Down
20 changes: 19 additions & 1 deletion lib/kamal/configuration/docs/accessory.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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`:
Expand Down
12 changes: 6 additions & 6 deletions lib/kamal/configuration/registry.rb
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -22,6 +20,8 @@ def password
end

private
attr_reader :registry_config, :secrets

def lookup(key)
if registry_config[key].is_a?(Array)
secrets[registry_config[key].first]
Expand Down
Loading

0 comments on commit b5aee11

Please sign in to comment.