Add option for two-part configs with the destination option

This commit is contained in:
David Heinemeier Hansson
2023-01-17 13:35:55 +01:00
parent 98af1d3d96
commit 9a84460754
8 changed files with 75 additions and 16 deletions

View File

@@ -1,9 +1,9 @@
require "mrsk" require "mrsk"
MRSK = Mrsk::Commander.new \
config_file: Pathname.new(File.expand_path("config/deploy.yml"))
module Mrsk::Cli module Mrsk::Cli
end end
# SSHKit uses instance eval, so we need a global const for ergonomics
MRSK = Mrsk::Commander.new
require "mrsk/cli/main" require "mrsk/cli/main"

View File

@@ -10,12 +10,23 @@ module Mrsk::Cli
class_option :verbose, type: :boolean, aliases: "-v", desc: "Detailed logging" class_option :verbose, type: :boolean, aliases: "-v", desc: "Detailed logging"
class_option :config_file, aliases: "-c", default: "config/deploy.yml", desc: "Path to config file (default: config/deploy.yml)"
class_option :destination, aliases: "-d", desc: "Specify destination to be used for config file (west -> deploy.west.yml)"
def initialize(*) def initialize(*)
super super
MRSK.verbose = options[:verbose] initialize_commander(options)
end end
private private
def initialize_commander(options)
MRSK.tap do |commander|
commander.config_file = Pathname.new(File.expand_path(options[:config_file]))
commander.destination = options[:destination]
commander.verbose = options[:verbose]
end
end
def print_runtime def print_runtime
started_at = Time.now started_at = Time.now
yield yield

View File

@@ -6,15 +6,14 @@ require "mrsk/commands/traefik"
require "mrsk/commands/registry" require "mrsk/commands/registry"
class Mrsk::Commander class Mrsk::Commander
attr_reader :config attr_accessor :config_file, :destination, :verbose
attr_accessor :verbose
def initialize(config_file:) def initialize(config_file: nil, destination: nil, verbose: false)
@config_file = config_file @config_file, @destination, @verbose = config_file, destination, verbose
end end
def config def config
@config ||= Mrsk::Configuration.load_file(@config_file).tap { |config| setup_with(config) } @config ||= Mrsk::Configuration.create_from(config_file, destination: destination).tap { |config| setup_with(config) }
end end

View File

@@ -9,17 +9,32 @@ class Mrsk::Configuration
delegate :service, :image, :servers, :env, :labels, :registry, :builder, to: :config, allow_nil: true delegate :service, :image, :servers, :env, :labels, :registry, :builder, to: :config, allow_nil: true
class << self class << self
def load_file(file) def create_from(base_config_file, destination: nil)
if file.exist? new(load_config_file(base_config_file).tap do |config|
new YAML.load(ERB.new(IO.read(file)).result).symbolize_keys if destination
else config.merge! \
raise "Configuration file not found in #{file}" load_config_file destination_config_file(base_config_file, destination)
end end
end)
end end
def argumentize(argument, attributes, redacted: false) def argumentize(argument, attributes, redacted: false)
attributes.flat_map { |k, v| [ argument, redacted ? Mrsk::Utils.redact("#{k}=#{v}") : "#{k}=#{v}" ] } attributes.flat_map { |k, v| [ argument, redacted ? Mrsk::Utils.redact("#{k}=#{v}") : "#{k}=#{v}" ] }
end end
private
def load_config_file(file)
if file.exist?
YAML.load(ERB.new(IO.read(file)).result).symbolize_keys
else
raise "Configuration file not found in #{file}"
end
end
def destination_config_file(base_config_file, destination)
dir, basename = base_config_file.split
dir.join basename.to_s.remove(".yml") + ".#{destination}.yml"
end
end end
def initialize(config, validate: true) def initialize(config, validate: true)

View File

@@ -111,7 +111,25 @@ class ConfigurationTest < ActiveSupport::TestCase
test "erb evaluation of yml config" do test "erb evaluation of yml config" do
config = Mrsk::Configuration.load_file Pathname.new(File.expand_path("fixtures/deploy.erb.yml", __dir__)) config = Mrsk::Configuration.create_from Pathname.new(File.expand_path("fixtures/deploy.erb.yml", __dir__))
assert_equal "my-user", config.registry["username"] assert_equal "my-user", config.registry["username"]
end end
test "destination yml config merge" do
dest_config_file = Pathname.new(File.expand_path("fixtures/deploy_for_dest.yml", __dir__))
config = Mrsk::Configuration.create_from dest_config_file, destination: "world"
assert_equal "1.1.1.1", config.hosts.first
config = Mrsk::Configuration.create_from dest_config_file, destination: "mars"
assert_equal "1.1.1.3", config.hosts.first
end
test "destination yml config file missing" do
dest_config_file = Pathname.new(File.expand_path("fixtures/deploy_for_dest.yml", __dir__))
assert_raises(RuntimeError) do
config = Mrsk::Configuration.create_from dest_config_file, destination: "missing"
end
end
end end

View File

@@ -0,0 +1,5 @@
servers:
- 1.1.1.3
- 1.1.1.4
env:
REDIS_URL: redis://a/b

View File

@@ -0,0 +1,5 @@
servers:
- 1.1.1.1
- 1.1.1.2
env:
REDIS_URL: redis://x/y

6
test/fixtures/deploy_for_dest.yml vendored Normal file
View File

@@ -0,0 +1,6 @@
service: app
image: dhh/app
registry:
server: registry.digitalocean.com
username: <%= "my-user" %>
password: <%= "my-password" %>