Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Registry for accessory #1320

Merged
merged 2 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading