Merge branch 'main' into pr/99
* main: Wording Remove accessory images using tags rather than labels Update readme to point to ghcr.io/mrsked/mrsk Validate that all roles have hosts Commander needn't accumulate configuration Pull latest image tag, so we can identity it Default to deploying the config version Remove unneeded Dockerfile.dind, update Readme add D-in-D dockerfile, update Readme
This commit is contained in:
@@ -2,7 +2,7 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
|
||||
desc "boot", "Boot app on servers (or reboot app if already running)"
|
||||
def boot
|
||||
say "Get most recent version available as an image...", :magenta unless options[:version]
|
||||
using_version(options[:version] || most_recent_version_available) do |version|
|
||||
using_version(version_or_latest) do |version|
|
||||
say "Start container with version #{version} using a #{MRSK.config.readiness_delay}s readiness delay (or reboot if already running)...", :magenta
|
||||
|
||||
cli = self
|
||||
@@ -42,7 +42,7 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
|
||||
roles = MRSK.roles_on(host)
|
||||
|
||||
roles.each do |role|
|
||||
execute *MRSK.auditor(role: role).record("Started app version #{MRSK.version}"), verbosity: :debug
|
||||
execute *MRSK.auditor.record("Started app version #{MRSK.config.version}"), verbosity: :debug
|
||||
execute *MRSK.app(role: role).start, raise_on_non_zero_exit: false
|
||||
end
|
||||
end
|
||||
@@ -86,7 +86,7 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
|
||||
|
||||
when options[:interactive]
|
||||
say "Get most recent version available as an image...", :magenta unless options[:version]
|
||||
using_version(options[:version] || most_recent_version_available) do |version|
|
||||
using_version(version_or_latest) do |version|
|
||||
say "Launching interactive command with version #{version} via SSH from new container on #{MRSK.primary_host}...", :magenta
|
||||
run_locally { exec MRSK.app.execute_in_new_container_over_ssh(cmd, host: MRSK.primary_host) }
|
||||
end
|
||||
@@ -108,7 +108,7 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
|
||||
|
||||
else
|
||||
say "Get most recent version available as an image...", :magenta unless options[:version]
|
||||
using_version(options[:version] || most_recent_version_available) do |version|
|
||||
using_version(version_or_latest) do |version|
|
||||
say "Launching command with version #{version} from new container...", :magenta
|
||||
on(MRSK.hosts) do |host|
|
||||
execute *MRSK.auditor.record("Executed cmd '#{cmd}' on app version #{version}"), verbosity: :debug
|
||||
@@ -217,20 +217,13 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
|
||||
end
|
||||
end
|
||||
|
||||
def most_recent_version_available(host: MRSK.primary_host)
|
||||
version = nil
|
||||
on(host) { version = capture_with_info(*MRSK.app.most_recent_version_from_available_images).strip }
|
||||
|
||||
if version == "<none>"
|
||||
raise "Most recent image available was not tagged with a version (returned <none>)"
|
||||
else
|
||||
version.presence
|
||||
end
|
||||
end
|
||||
|
||||
def current_running_version(host: MRSK.primary_host)
|
||||
version = nil
|
||||
on(host) { version = capture_with_info(*MRSK.app.current_running_version).strip }
|
||||
version.presence
|
||||
end
|
||||
|
||||
def version_or_latest
|
||||
options[:version] || "latest"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -39,14 +39,6 @@ module Mrsk::Cli
|
||||
|
||||
def initialize_commander(options)
|
||||
MRSK.tap do |commander|
|
||||
commander.config_file = Pathname.new(File.expand_path(options[:config_file]))
|
||||
commander.destination = options[:destination]
|
||||
commander.version = options[:version]
|
||||
|
||||
commander.specific_hosts = options[:hosts]&.split(",")
|
||||
commander.specific_roles = options[:roles]&.split(",")
|
||||
commander.specific_primary! if options[:primary]
|
||||
|
||||
if options[:verbose]
|
||||
ENV["VERBOSE"] = "1" # For backtraces via cli/start
|
||||
commander.verbosity = :debug
|
||||
@@ -55,6 +47,15 @@ module Mrsk::Cli
|
||||
if options[:quiet]
|
||||
commander.verbosity = :error
|
||||
end
|
||||
|
||||
commander.configure \
|
||||
config_file: Pathname.new(File.expand_path(options[:config_file])),
|
||||
destination: options[:destination],
|
||||
version: options[:version]
|
||||
|
||||
commander.specific_hosts = options[:hosts]&.split(",")
|
||||
commander.specific_roles = options[:roles]&.split(",")
|
||||
commander.specific_primary! if options[:primary]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ class Mrsk::Cli::Build < Mrsk::Cli::Base
|
||||
desc "pull", "Pull app image from registry onto servers"
|
||||
def pull
|
||||
on(MRSK.hosts) do
|
||||
execute *MRSK.auditor.record("Pulled image with version #{MRSK.version}"), verbosity: :debug
|
||||
execute *MRSK.auditor.record("Pulled image with version #{MRSK.config.version}"), verbosity: :debug
|
||||
execute *MRSK.builder.clean, raise_on_non_zero_exit: false
|
||||
execute *MRSK.builder.pull
|
||||
end
|
||||
|
||||
@@ -11,7 +11,7 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base
|
||||
desc "deploy", "Deploy app to servers"
|
||||
option :skip_push, aliases: "-P", type: :boolean, default: false, desc: "Skip image build and push"
|
||||
def deploy
|
||||
invoke_options = options.without(:skip_push)
|
||||
invoke_options = deploy_options
|
||||
|
||||
runtime = print_runtime do
|
||||
say "Ensure curl and Docker are installed...", :magenta
|
||||
@@ -46,7 +46,7 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base
|
||||
desc "redeploy", "Deploy app to servers without bootstrapping servers, starting Traefik, pruning, and registry login"
|
||||
option :skip_push, aliases: "-P", type: :boolean, default: false, desc: "Skip image build and push"
|
||||
def redeploy
|
||||
invoke_options = options.without(:skip_push)
|
||||
invoke_options = deploy_options
|
||||
|
||||
runtime = print_runtime do
|
||||
if options[:skip_push]
|
||||
@@ -68,7 +68,7 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base
|
||||
|
||||
desc "rollback [VERSION]", "Rollback app to VERSION"
|
||||
def rollback(version)
|
||||
MRSK.version = version
|
||||
MRSK.config.version = version
|
||||
|
||||
if container_name_available?(MRSK.config.service_with_version)
|
||||
say "Start version #{version}, then wait #{MRSK.config.readiness_delay}s for app to boot before stopping the old version...", :magenta
|
||||
@@ -207,6 +207,10 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base
|
||||
Array(container_names).include?(container_name)
|
||||
end
|
||||
|
||||
def deploy_options
|
||||
{ "version" => MRSK.config.version }.merge(options.without("skip_push"))
|
||||
end
|
||||
|
||||
def service_version(version = MRSK.config.abbreviated_version)
|
||||
[ MRSK.config.service, version ].compact.join("@")
|
||||
end
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
require "active_support/core_ext/enumerable"
|
||||
require "active_support/core_ext/module/delegation"
|
||||
|
||||
class Mrsk::Commander
|
||||
attr_accessor :config_file, :destination, :verbosity, :version
|
||||
attr_accessor :verbosity
|
||||
|
||||
def initialize(config_file: nil, destination: nil, verbosity: :info)
|
||||
@config_file, @destination, @verbosity = config_file, destination, verbosity
|
||||
def initialize
|
||||
self.verbosity = :info
|
||||
end
|
||||
|
||||
def config
|
||||
@config ||= \
|
||||
Mrsk::Configuration
|
||||
.create_from(config_file, destination: destination, version: cascading_version)
|
||||
.tap { |config| configure_sshkit_with(config) }
|
||||
@config ||= Mrsk::Configuration.create_from(**@config_kwargs).tap do |config|
|
||||
@config_kwargs = nil
|
||||
configure_sshkit_with(config)
|
||||
end
|
||||
end
|
||||
|
||||
def configure(**kwargs)
|
||||
@config, @config_kwargs = nil, kwargs
|
||||
end
|
||||
|
||||
attr_reader :specific_roles, :specific_hosts
|
||||
@@ -106,26 +111,15 @@ class Mrsk::Commander
|
||||
SSHKit.config.output_verbosity = old_level
|
||||
end
|
||||
|
||||
|
||||
# Test-induced damage!
|
||||
def reset
|
||||
@config = @config_file = @destination = @version = nil
|
||||
@config = nil
|
||||
@app = @builder = @traefik = @registry = @prune = @auditor = nil
|
||||
@verbosity = :info
|
||||
end
|
||||
|
||||
private
|
||||
def cascading_version
|
||||
version.presence || ENV["VERSION"] || current_commit_hash
|
||||
end
|
||||
|
||||
def current_commit_hash
|
||||
if system("git rev-parse")
|
||||
`git rev-parse HEAD`.strip
|
||||
else
|
||||
raise "Can't use commit hash as version, no git repository found in #{Dir.pwd}"
|
||||
end
|
||||
end
|
||||
|
||||
# Lazy setup of SSHKit
|
||||
def configure_sshkit_with(config)
|
||||
SSHKit::Backend::Netssh.configure { |ssh| ssh.ssh_options = config.ssh_options }
|
||||
|
||||
@@ -100,7 +100,7 @@ class Mrsk::Commands::Accessory < Mrsk::Commands::Base
|
||||
end
|
||||
|
||||
def remove_image
|
||||
docker :image, :prune, "--all", "--force", *service_filter
|
||||
docker :image, :rm, "--force", image
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -94,19 +94,6 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
|
||||
"tail -n 1"
|
||||
end
|
||||
|
||||
def most_recent_version_from_available_images
|
||||
pipe \
|
||||
docker(:image, :ls, "--format", '"{{.Tag}}"', config.repository),
|
||||
"head -n 1"
|
||||
end
|
||||
|
||||
def all_versions_from_available_containers
|
||||
pipe \
|
||||
docker(:image, :ls, "--format", '"{{.Tag}}"', config.repository),
|
||||
"head -n 1"
|
||||
end
|
||||
|
||||
|
||||
def list_containers
|
||||
docker :container, :ls, "--all", *filter_args
|
||||
end
|
||||
|
||||
@@ -7,6 +7,7 @@ class Mrsk::Commands::Builder::Base < Mrsk::Commands::Base
|
||||
|
||||
def pull
|
||||
docker :pull, config.absolute_image
|
||||
docker :pull, config.latest_image
|
||||
end
|
||||
|
||||
def build_options
|
||||
|
||||
@@ -9,13 +9,12 @@ class Mrsk::Configuration
|
||||
delegate :service, :image, :servers, :env, :labels, :registry, :builder, to: :raw_config, allow_nil: true
|
||||
delegate :argumentize, :argumentize_env_with_secrets, to: Mrsk::Utils
|
||||
|
||||
attr_accessor :version
|
||||
attr_accessor :destination
|
||||
attr_accessor :raw_config
|
||||
|
||||
class << self
|
||||
def create_from(base_config_file, destination: nil, version: "missing")
|
||||
raw_config = load_config_files(base_config_file, *destination_config_file(base_config_file, destination))
|
||||
def create_from(config_file:, destination: nil, version: nil)
|
||||
raw_config = load_config_files(config_file, *destination_config_file(config_file, destination))
|
||||
|
||||
new raw_config, destination: destination, version: version
|
||||
end
|
||||
@@ -38,14 +37,22 @@ class Mrsk::Configuration
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(raw_config, destination: nil, version: "missing", validate: true)
|
||||
def initialize(raw_config, destination: nil, version: nil, validate: true)
|
||||
@raw_config = ActiveSupport::InheritableOptions.new(raw_config)
|
||||
@destination = destination
|
||||
@version = version
|
||||
@declared_version = version
|
||||
valid? if validate
|
||||
end
|
||||
|
||||
|
||||
def version=(version)
|
||||
@declared_version = version
|
||||
end
|
||||
|
||||
def version
|
||||
@declared_version.presence || ENV["VERSION"] || current_commit_hash
|
||||
end
|
||||
|
||||
def abbreviated_version
|
||||
Mrsk::Utils.abbreviate_version(version)
|
||||
end
|
||||
@@ -73,7 +80,7 @@ class Mrsk::Configuration
|
||||
end
|
||||
|
||||
def primary_web_host
|
||||
role(:web).hosts.first
|
||||
role(:web).primary_host
|
||||
end
|
||||
|
||||
def traefik_hosts
|
||||
@@ -189,6 +196,12 @@ class Mrsk::Configuration
|
||||
raise ArgumentError, "You must specify a password for the registry in config/deploy.yml (or set the ENV variable if that's used)"
|
||||
end
|
||||
|
||||
roles.each do |role|
|
||||
if role.hosts.empty?
|
||||
raise ArgumentError, "No servers specified for the #{role.name} role"
|
||||
end
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
@@ -203,4 +216,13 @@ class Mrsk::Configuration
|
||||
def role_names
|
||||
raw_config.servers.is_a?(Array) ? [ "web" ] : raw_config.servers.keys.sort
|
||||
end
|
||||
|
||||
def current_commit_hash
|
||||
@current_commit_hash ||=
|
||||
if system("git rev-parse")
|
||||
`git rev-parse HEAD`.strip
|
||||
else
|
||||
raise "Can't use commit hash as version, no git repository found in #{Dir.pwd}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,6 +7,10 @@ class Mrsk::Configuration::Role
|
||||
@name, @config = name.inquiry, config
|
||||
end
|
||||
|
||||
def primary_host
|
||||
hosts.first
|
||||
end
|
||||
|
||||
def hosts
|
||||
@hosts ||= extract_hosts_from_config
|
||||
end
|
||||
@@ -55,7 +59,7 @@ class Mrsk::Configuration::Role
|
||||
config.servers
|
||||
else
|
||||
servers = config.servers[name]
|
||||
servers.is_a?(Array) ? servers : servers["hosts"]
|
||||
servers.is_a?(Array) ? servers : Array(servers["hosts"])
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user