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

configure volumes, directories and files for any role #697

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
19 changes: 1 addition & 18 deletions lib/kamal/cli/accessory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def boot(name, login: true)
else
with_accessory(name) do |accessory|
directories(name)
upload(name)
upload(accessory, accessory.hosts)

on(accessory.hosts) do
execute *KAMAL.registry.login if login
Expand All @@ -19,23 +19,6 @@ def boot(name, login: true)
end
end

desc "upload [NAME]", "Upload accessory files to host", hide: true
def upload(name)
mutating do
with_accessory(name) do |accessory|
on(accessory.hosts) do
accessory.files.each do |(local, remote)|
accessory.ensure_local_file_present(local)

execute *accessory.make_directory_for(remote)
upload! local, remote
execute :chmod, "755", remote
end
end
end
end
end

desc "directories [NAME]", "Create accessory directories on host", hide: true
def directories(name)
mutating do
Expand Down
2 changes: 2 additions & 0 deletions lib/kamal/cli/app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ class Kamal::Cli::App < Kamal::Cli::Base
def boot
mutating do
hold_lock_on_error do
upload(KAMAL.app, KAMAL.hosts)

say "Get most recent version available as an image...", :magenta unless options[:version]
using_version(version_or_latest) do |version|
say "Start container with version #{version} using a #{KAMAL.config.readiness_delay}s readiness delay (or reboot if already running)...", :magenta
Expand Down
27 changes: 26 additions & 1 deletion lib/kamal/cli/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,31 @@ def initialize(*)
initialize_commander(options_with_subcommand_class_options)
end

desc "upload [NAME]", "Upload files and directories to host", hide: true
def upload(role, hosts)
mutating do
on(hosts) do
volumes_config = case role.class.to_s
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not match on role.class?

Copy link
Author

@aka47 aka47 Mar 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be safe, in case of a "Constant not found" exception, and also stay with the convention that exists around this.

when "Kamal::Commands::Accessory"
role.accessory_config.volumes_config
when "Kamal::Commands::App"
role.config.volumes_config
when "Kamal::Commands::Traefik"
role.volumes_config
end

files_and_directories = volumes_config.files.merge(volumes_config.directories_to_upload)
files_and_directories.each do |(local, remote)|
role.ensure_local_file_present(local)

execute *role.make_directory_for(remote)
upload! local, remote, recursive: true
execute :chmod, "755", remote
end
end
end
end

private
def load_envs
if destination = options[:destination]
Expand Down Expand Up @@ -180,5 +205,5 @@ def ensure_run_directory
execute(*KAMAL.server.ensure_run_directory)
end
end
end
end
end
3 changes: 3 additions & 0 deletions lib/kamal/cli/traefik.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ class Kamal::Cli::Traefik < Kamal::Cli::Base
desc "boot", "Boot Traefik on servers"
def boot
mutating do
upload(KAMAL.traefik, KAMAL.traefik_hosts)
on(KAMAL.traefik_hosts) do
execute *KAMAL.registry.login
execute *KAMAL.traefik.start_or_run
Expand All @@ -17,6 +18,8 @@ def reboot
host_groups.each do |hosts|
host_list = Array(hosts).join(",")
run_hook "pre-traefik-reboot", hosts: host_list

upload(KAMAL.traefik, hosts)
on(hosts) do
execute *KAMAL.auditor.record("Rebooted traefik"), verbosity: :debug
execute *KAMAL.registry.login
Expand Down
7 changes: 0 additions & 7 deletions lib/kamal/commands/accessory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,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}"
end
end

def remove_service_directory
[ :rm, "-rf", service_name ]
end
Expand Down
6 changes: 6 additions & 0 deletions lib/kamal/commands/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ def remove_directory(path)
[ :rm, "-r", path ]
end

def ensure_local_file_present(local_file)
if !local_file.is_a?(StringIO) && !Pathname.new(local_file).exist?
raise "Missing file: #{local_file}"
end
end

private
def combine(*commands, by: "&&")
commands
Expand Down
8 changes: 8 additions & 0 deletions lib/kamal/commands/traefik.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
class Kamal::Commands::Traefik < Kamal::Commands::Base
delegate :argumentize, :optionize, to: Kamal::Utils
delegate :volume_args, to: :volumes_config
attr_accessor :volumes_config

DEFAULT_IMAGE = "traefik:v2.9"
CONTAINER_PORT = 80
Expand All @@ -15,6 +17,11 @@ class Kamal::Commands::Traefik < Kamal::Commands::Base
"traefik.http.services.unavailable.loadbalancer.server.port" => "0"
}

def initialize(config)
super(config)
@volumes_config = Kamal::Configuration::VolumesFilesAndDirectories.new "traefik", config.traefik
end

def run
docker :run, "--name traefik",
"--detach",
Expand All @@ -24,6 +31,7 @@ def run
*env_args,
*config.logging_args,
*label_args,
*volume_args,
*docker_options_args,
image,
"--providers.docker",
Expand Down
16 changes: 3 additions & 13 deletions lib/kamal/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
class Kamal::Configuration
delegate :service, :image, :servers, :env, :labels, :registry, :stop_wait_time, :hooks_path, to: :raw_config, allow_nil: true
delegate :argumentize, :optionize, to: Kamal::Utils

attr_reader :destination, :raw_config
delegate :volume_args, to: :volumes_config
attr_reader :destination, :raw_config, :volumes_config

class << self
def create_from(config_file:, destination: nil, version: nil)
Expand Down Expand Up @@ -42,10 +42,10 @@ def initialize(raw_config, destination: nil, version: nil, validate: true)
@raw_config = ActiveSupport::InheritableOptions.new(raw_config)
@destination = destination
@declared_version = version
@volumes_config = Kamal::Configuration::VolumesFilesAndDirectories.new service, @raw_config
valid? if validate
end


def version=(version)
@declared_version = version
end
Expand Down Expand Up @@ -127,15 +127,6 @@ def require_destination?
raw_config.require_destination
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) +
Expand All @@ -145,7 +136,6 @@ def logging_args
end
end


def boot
Kamal::Configuration::Boot.new(config: self)
end
Expand Down
80 changes: 3 additions & 77 deletions lib/kamal/configuration/accessory.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
class Kamal::Configuration::Accessory
delegate :argumentize, :optionize, to: Kamal::Utils

attr_accessor :name, :specifics
delegate :volume_args, :directories, :files, to: :volumes_config
attr_accessor :name, :specifics, :volumes_config

def initialize(name, config:)
@name, @config, @specifics = name.inquiry, config, config.raw_config["accessories"][name]
@volumes_config = Kamal::Configuration::VolumesFilesAndDirectories.new service_name, @specifics
end

def service_name
Expand Down Expand Up @@ -61,28 +62,6 @@ def env_args
argumentize "--env-file", host_env_file_path
end

def files
specifics["files"]&.to_h do |local_to_remote_mapping|
local_file, remote_file = local_to_remote_mapping.split(":")
[ expand_local_file(local_file), expand_remote_file(remote_file) ]
end || {}
end

def directories
specifics["directories"]&.to_h do |host_to_container_mapping|
host_path, container_path = host_to_container_mapping.split(":")
[ expand_host_path(host_path), container_path ]
end || {}
end

def volumes
specific_volumes + remote_files_as_volumes + remote_directories_as_volumes
end

def volume_args
argumentize "--volume", volumes
end

def option_args
if args = specifics["options"]
optionize args
Expand All @@ -102,59 +81,6 @@ def default_labels
{ "service" => service_name }
end

def expand_local_file(local_file)
if local_file.end_with?("erb")
with_clear_env_loaded { read_dynamic_file(local_file) }
else
Pathname.new(File.expand_path(local_file)).to_s
end
end

def with_clear_env_loaded
(env["clear"] || env).each { |k, v| ENV[k] = v }
yield
ensure
(env["clear"] || env).each { |k, v| ENV.delete(k) }
end

def read_dynamic_file(local_file)
StringIO.new(ERB.new(IO.read(local_file)).result)
end

def expand_remote_file(remote_file)
service_name + remote_file
end

def specific_volumes
specifics["volumes"] || []
end

def remote_files_as_volumes
specifics["files"]&.collect do |local_to_remote_mapping|
_, remote_file = local_to_remote_mapping.split(":")
"#{service_data_directory + remote_file}:#{remote_file}"
end || []
end

def remote_directories_as_volumes
specifics["directories"]&.collect do |host_to_container_mapping|
host_path, container_path = host_to_container_mapping.split(":")
[ expand_host_path(host_path), container_path ].join(":")
end || []
end

def expand_host_path(host_path)
absolute_path?(host_path) ? host_path : "#{service_data_directory}/#{host_path}"
end

def absolute_path?(path)
Pathname.new(path).absolute?
end

def service_data_directory
"$PWD/#{service_name}"
end

def hosts_from_host
if specifics.key?("host")
host = specifics["host"]
Expand Down
Loading