Allow custom version to be passed in via CLI
This commit is contained in:
@@ -9,6 +9,8 @@ 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 :version, desc: "Run commands against a specific app version"
|
||||||
|
|
||||||
class_option :primary, type: :boolean, aliases: "-p", desc: "Run commands only on primary host instead of all"
|
class_option :primary, type: :boolean, aliases: "-p", desc: "Run commands only on primary host instead of all"
|
||||||
class_option :hosts, aliases: "-h", desc: "Run commands on these hosts instead of all (separate by comma)"
|
class_option :hosts, aliases: "-h", desc: "Run commands on these hosts instead of all (separate by comma)"
|
||||||
class_option :roles, aliases: "-r", desc: "Run commands on these roles instead of all (separate by comma)"
|
class_option :roles, aliases: "-r", desc: "Run commands on these roles instead of all (separate by comma)"
|
||||||
@@ -27,6 +29,7 @@ module Mrsk::Cli
|
|||||||
commander.config_file = Pathname.new(File.expand_path(options[:config_file]))
|
commander.config_file = Pathname.new(File.expand_path(options[:config_file]))
|
||||||
commander.destination = options[:destination]
|
commander.destination = options[:destination]
|
||||||
commander.verbose = options[:verbose]
|
commander.verbose = options[:verbose]
|
||||||
|
commander.version = options[:version]
|
||||||
|
|
||||||
commander.specific_hosts = options[:hosts]&.split(",")
|
commander.specific_hosts = options[:hosts]&.split(",")
|
||||||
commander.specific_roles = options[:roles]&.split(",")
|
commander.specific_roles = options[:roles]&.split(",")
|
||||||
|
|||||||
@@ -8,14 +8,17 @@ require "mrsk/commands/traefik"
|
|||||||
require "mrsk/commands/registry"
|
require "mrsk/commands/registry"
|
||||||
|
|
||||||
class Mrsk::Commander
|
class Mrsk::Commander
|
||||||
attr_accessor :config_file, :destination, :verbose
|
attr_accessor :config_file, :destination, :verbose, :version
|
||||||
|
|
||||||
def initialize(config_file: nil, destination: nil, verbose: false)
|
def initialize(config_file: nil, destination: nil, verbose: false)
|
||||||
@config_file, @destination, @verbose = config_file, destination, verbose
|
@config_file, @destination, @verbose = config_file, destination, verbose
|
||||||
end
|
end
|
||||||
|
|
||||||
def config
|
def config
|
||||||
@config ||= Mrsk::Configuration.create_from(config_file, destination: destination).tap { |config| setup_with(config) }
|
@config ||= \
|
||||||
|
Mrsk::Configuration
|
||||||
|
.create_from(config_file, destination: destination, version: cascading_version)
|
||||||
|
.tap { |config| configure_sshkit_with(config) }
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_accessor :specific_hosts
|
attr_accessor :specific_hosts
|
||||||
@@ -71,8 +74,12 @@ class Mrsk::Commander
|
|||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
def cascading_version
|
||||||
|
version.presence || ENV["VERSION"] || `git rev-parse HEAD`.strip
|
||||||
|
end
|
||||||
|
|
||||||
# Lazy setup of SSHKit
|
# Lazy setup of SSHKit
|
||||||
def setup_with(config)
|
def configure_sshkit_with(config)
|
||||||
SSHKit::Backend::Netssh.configure { |ssh| ssh.ssh_options = config.ssh_options }
|
SSHKit::Backend::Netssh.configure { |ssh| ssh.ssh_options = config.ssh_options }
|
||||||
SSHKit.config.command_map[:docker] = "docker" # No need to use /usr/bin/env, just clogs up the logs
|
SSHKit.config.command_map[:docker] = "docker" # No need to use /usr/bin/env, just clogs up the logs
|
||||||
SSHKit.config.output_verbosity = :debug if verbose
|
SSHKit.config.output_verbosity = :debug if verbose
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ class Mrsk::Configuration
|
|||||||
delegate :argumentize, to: Mrsk::Utils
|
delegate :argumentize, to: Mrsk::Utils
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
def create_from(base_config_file, destination: nil)
|
def create_from(base_config_file, destination: nil, version: "missing")
|
||||||
new(load_config_file(base_config_file).tap do |config|
|
new(load_config_file(base_config_file).tap do |config|
|
||||||
if destination
|
if destination
|
||||||
config.merge! \
|
config.merge! \
|
||||||
load_config_file destination_config_file(base_config_file, destination)
|
load_config_file destination_config_file(base_config_file, destination)
|
||||||
end
|
end
|
||||||
end)
|
end, version: version)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@@ -34,8 +34,9 @@ class Mrsk::Configuration
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(config, validate: true)
|
def initialize(config, version: "missing", validate: true)
|
||||||
@config = ActiveSupport::InheritableOptions.new(config)
|
@config = ActiveSupport::InheritableOptions.new(config)
|
||||||
|
@version = version
|
||||||
ensure_required_keys_present if validate
|
ensure_required_keys_present if validate
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -62,7 +63,7 @@ class Mrsk::Configuration
|
|||||||
|
|
||||||
|
|
||||||
def version
|
def version
|
||||||
@version ||= ENV["VERSION"] || `git rev-parse HEAD`.strip
|
@version
|
||||||
end
|
end
|
||||||
|
|
||||||
def repository
|
def repository
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ require "test_helper"
|
|||||||
require "mrsk/configuration"
|
require "mrsk/configuration"
|
||||||
require "mrsk/commands/app"
|
require "mrsk/commands/app"
|
||||||
|
|
||||||
ENV["VERSION"] = "123"
|
|
||||||
ENV["RAILS_MASTER_KEY"] = "456"
|
ENV["RAILS_MASTER_KEY"] = "456"
|
||||||
|
|
||||||
class CommandsAppTest < ActiveSupport::TestCase
|
class CommandsAppTest < ActiveSupport::TestCase
|
||||||
@@ -13,12 +12,12 @@ class CommandsAppTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
test "run" do
|
test "run" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
[:docker, :run, "-d", "--restart unless-stopped", "--name", "app-123", "-e", "RAILS_MASTER_KEY=456", "--label", "service=app", "--label", "role=web", "--label", "traefik.http.routers.app.rule='PathPrefix(`/`)'", "--label", "traefik.http.services.app.loadbalancer.healthcheck.path=/up", "--label", "traefik.http.services.app.loadbalancer.healthcheck.interval=1s", "--label", "traefik.http.middlewares.app.retry.attempts=3", "--label", "traefik.http.middlewares.app.retry.initialinterval=500ms", "dhh/app:123"], @app.run
|
[:docker, :run, "-d", "--restart unless-stopped", "--name", "app-missing", "-e", "RAILS_MASTER_KEY=456", "--label", "service=app", "--label", "role=web", "--label", "traefik.http.routers.app.rule='PathPrefix(`/`)'", "--label", "traefik.http.services.app.loadbalancer.healthcheck.path=/up", "--label", "traefik.http.services.app.loadbalancer.healthcheck.interval=1s", "--label", "traefik.http.middlewares.app.retry.attempts=3", "--label", "traefik.http.middlewares.app.retry.initialinterval=500ms", "dhh/app:missing"], @app.run
|
||||||
end
|
end
|
||||||
|
|
||||||
test "run with" do
|
test "run with" do
|
||||||
assert_equal \
|
assert_equal \
|
||||||
[ :docker, :run, "--rm", "-e", "RAILS_MASTER_KEY=456", "dhh/app:123", "bin/rails", "db:setup" ],
|
[ :docker, :run, "--rm", "-e", "RAILS_MASTER_KEY=456", "dhh/app:missing", "bin/rails", "db:setup" ],
|
||||||
@app.run_exec("bin/rails", "db:setup")
|
@app.run_exec("bin/rails", "db:setup")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -8,42 +8,44 @@ class CommandsBuilderTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "target multiarch by default" do
|
test "target multiarch by default" do
|
||||||
builder = Mrsk::Commands::Builder.new(Mrsk::Configuration.new(@config))
|
assert new_builder_command.multiarch?
|
||||||
assert builder.multiarch?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "target native when multiarch is off" do
|
test "target native when multiarch is off" do
|
||||||
builder = Mrsk::Commands::Builder.new(Mrsk::Configuration.new(@config.merge({ builder: { "multiarch" => false } })))
|
assert new_builder_command(builder: { "multiarch" => false }).native?
|
||||||
assert builder.native?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "target multiarch remote when local and remote is set" do
|
test "target multiarch remote when local and remote is set" do
|
||||||
builder = Mrsk::Commands::Builder.new(Mrsk::Configuration.new(@config.merge({ builder: { "local" => { }, "remote" => { } } })))
|
assert new_builder_command(builder: { "local" => { }, "remote" => { } }).remote?
|
||||||
assert builder.remote?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "build args" do
|
test "build args" do
|
||||||
builder = Mrsk::Commands::Builder.new(Mrsk::Configuration.new(@config.merge({ builder: { "args" => { "a" => 1, "b" => 2 } } })))
|
builder = new_builder_command(builder: { "args" => { "a" => 1, "b" => 2 } })
|
||||||
assert_equal [ "--build-arg", "a=1", "--build-arg", "b=2" ], builder.target.build_args
|
assert_equal [ "--build-arg", "a=1", "--build-arg", "b=2" ], builder.target.build_args
|
||||||
end
|
end
|
||||||
|
|
||||||
test "build secrets" do
|
test "build secrets" do
|
||||||
builder = Mrsk::Commands::Builder.new(Mrsk::Configuration.new(@config.merge({ builder: { "secrets" => ["token_a", "token_b"] } })))
|
builder = new_builder_command(builder: { "secrets" => ["token_a", "token_b"] })
|
||||||
assert_equal [ "--secret", "id=token_a", "--secret", "id=token_b" ], builder.target.build_secrets
|
assert_equal [ "--secret", "id=token_a", "--secret", "id=token_b" ], builder.target.build_secrets
|
||||||
end
|
end
|
||||||
|
|
||||||
test "native push with build args" do
|
test "native push with build args" do
|
||||||
builder = Mrsk::Commands::Builder.new(Mrsk::Configuration.new(@config.merge({ builder: { "multiarch" => false, "args" => { "a" => 1, "b" => 2 } } })))
|
builder = new_builder_command(builder: { "multiarch" => false, "args" => { "a" => 1, "b" => 2 } })
|
||||||
assert_equal [ :docker, :build, "-t", "--build-arg", "a=1", "--build-arg", "b=2", "dhh/app:123", ".", "&&", :docker, :push, "dhh/app:123" ], builder.push
|
assert_equal [ :docker, :build, "-t", "--build-arg", "a=1", "--build-arg", "b=2", "dhh/app:123", ".", "&&", :docker, :push, "dhh/app:123" ], builder.push
|
||||||
end
|
end
|
||||||
|
|
||||||
test "multiarch push with build args" do
|
test "multiarch push with build args" do
|
||||||
builder = Mrsk::Commands::Builder.new(Mrsk::Configuration.new(@config.merge({ builder: { "args" => { "a" => 1, "b" => 2 } } })))
|
builder = new_builder_command(builder: { "args" => { "a" => 1, "b" => 2 } })
|
||||||
assert_equal [ :docker, :buildx, :build, "--push", "--platform linux/amd64,linux/arm64", "-t", "dhh/app:123", "--build-arg", "a=1", "--build-arg", "b=2", "." ], builder.push
|
assert_equal [ :docker, :buildx, :build, "--push", "--platform linux/amd64,linux/arm64", "-t", "dhh/app:123", "--build-arg", "a=1", "--build-arg", "b=2", "." ], builder.push
|
||||||
end
|
end
|
||||||
|
|
||||||
test "native push with with build secrets" do
|
test "native push with with build secrets" do
|
||||||
builder = Mrsk::Commands::Builder.new(Mrsk::Configuration.new(@config.merge({ builder: { "multiarch" => false, "secrets" => [ "a", "b" ] } })))
|
builder = new_builder_command(builder: { "multiarch" => false, "secrets" => [ "a", "b" ] })
|
||||||
assert_equal [ :docker, :build, "-t", "--secret", "id=a", "--secret", "id=b", "dhh/app:123", ".", "&&", :docker, :push, "dhh/app:123" ], builder.push
|
assert_equal [ :docker, :build, "-t", "--secret", "id=a", "--secret", "id=b", "dhh/app:123", ".", "&&", :docker, :push, "dhh/app:123" ], builder.push
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def new_builder_command(additional_config = {})
|
||||||
|
Mrsk::Commands::Builder.new(Mrsk::Configuration.new(@config.merge(additional_config), version: "123"))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
require "test_helper"
|
require "test_helper"
|
||||||
require "mrsk/configuration"
|
require "mrsk/configuration"
|
||||||
|
|
||||||
ENV["VERSION"] = "123"
|
|
||||||
|
|
||||||
class ConfigurationRoleTest < ActiveSupport::TestCase
|
class ConfigurationRoleTest < ActiveSupport::TestCase
|
||||||
setup do
|
setup do
|
||||||
@deploy = {
|
@deploy = {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
require "test_helper"
|
require "test_helper"
|
||||||
require "mrsk/configuration"
|
require "mrsk/configuration"
|
||||||
|
|
||||||
ENV["VERSION"] = "123"
|
|
||||||
ENV["RAILS_MASTER_KEY"] = "456"
|
ENV["RAILS_MASTER_KEY"] = "456"
|
||||||
|
|
||||||
class ConfigurationTest < ActiveSupport::TestCase
|
class ConfigurationTest < ActiveSupport::TestCase
|
||||||
@@ -63,7 +62,8 @@ class ConfigurationTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "version" do
|
test "version" do
|
||||||
assert_equal "123", @config.version
|
assert_equal "missing", @config.version
|
||||||
|
assert_equal "123", Mrsk::Configuration.new(@deploy, version: "123").version
|
||||||
end
|
end
|
||||||
|
|
||||||
test "repository" do
|
test "repository" do
|
||||||
@@ -74,14 +74,14 @@ class ConfigurationTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "absolute image" do
|
test "absolute image" do
|
||||||
assert_equal "dhh/app:123", @config.absolute_image
|
assert_equal "dhh/app:missing", @config.absolute_image
|
||||||
|
|
||||||
config = Mrsk::Configuration.new(@deploy.tap { |c| c[:registry].merge!({ "server" => "ghcr.io" }) })
|
config = Mrsk::Configuration.new(@deploy.tap { |c| c[:registry].merge!({ "server" => "ghcr.io" }) })
|
||||||
assert_equal "ghcr.io/dhh/app:123", config.absolute_image
|
assert_equal "ghcr.io/dhh/app:missing", config.absolute_image
|
||||||
end
|
end
|
||||||
|
|
||||||
test "service with version" do
|
test "service with version" do
|
||||||
assert_equal "app-123", @config.service_with_version
|
assert_equal "app-missing", @config.service_with_version
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -125,6 +125,6 @@ class ConfigurationTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "to_h" do
|
test "to_h" do
|
||||||
assert_equal({ :roles=>["web"], :hosts=>["1.1.1.1", "1.1.1.2"], :primary_host=>"1.1.1.1", :version=>"123", :repository=>"dhh/app", :absolute_image=>"dhh/app:123", :service_with_version=>"app-123", :env_args=>["-e", "REDIS_URL=redis://x/y"], :ssh_options=>{:user=>"root", :auth_methods=>["publickey"]} }, @config.to_h)
|
assert_equal({ :roles=>["web"], :hosts=>["1.1.1.1", "1.1.1.2"], :primary_host=>"1.1.1.1", :version=>"missing", :repository=>"dhh/app", :absolute_image=>"dhh/app:missing", :service_with_version=>"app-missing", :env_args=>["-e", "REDIS_URL=redis://x/y"], :ssh_options=>{:user=>"root", :auth_methods=>["publickey"]} }, @config.to_h)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user