Move hosts/roles specification to cli args instead of ENV

This commit is contained in:
David Heinemeier Hansson
2023-01-20 16:57:25 +01:00
parent 0388495819
commit 79b5ed179e
13 changed files with 87 additions and 66 deletions

View File

@@ -23,20 +23,20 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
option :version, desc: "Defaults to the most recent git-hash in local repository"
def start
if (version = options[:version]).present?
on(MRSK.config.hosts) { execute *MRSK.app.start(version: version) }
on(MRSK.hosts) { execute *MRSK.app.start(version: version) }
else
on(MRSK.config.hosts) { execute *MRSK.app.start, raise_on_non_zero_exit: false }
on(MRSK.hosts) { execute *MRSK.app.start, raise_on_non_zero_exit: false }
end
end
desc "stop", "Stop app on servers"
def stop
on(MRSK.config.hosts) { execute *MRSK.app.stop, raise_on_non_zero_exit: false }
on(MRSK.hosts) { execute *MRSK.app.stop, raise_on_non_zero_exit: false }
end
desc "details", "Display details about app containers"
def details
on(MRSK.config.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.info) }
on(MRSK.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.info) }
end
desc "exec [CMD]", "Execute a custom task on servers passed in as CMD='bin/rake some:task'"
@@ -48,7 +48,7 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
if options[:once]
on(MRSK.config.primary_host) { puts capture_with_info(*MRSK.app.send(runner, cmd)) }
else
on(MRSK.config.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.send(runner, cmd)) }
on(MRSK.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.send(runner, cmd)) }
end
end
@@ -80,18 +80,18 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
if options[:once]
on(MRSK.config.primary_host) { puts capture_with_info(*MRSK.app.exec("bin/rails", "runner", "'#{expression}'")) }
else
on(MRSK.config.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.exec("bin/rails", "runner", "'#{expression}'")) }
on(MRSK.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.exec("bin/rails", "runner", "'#{expression}'")) }
end
end
desc "containers", "List all the app containers currently on servers"
def containers
on(MRSK.config.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.list_containers) }
on(MRSK.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.list_containers) }
end
desc "current", "Return the current running container ID"
def current
on(MRSK.config.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.current_container_id) }
on(MRSK.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.current_container_id) }
end
desc "logs", "Show last 100 log lines from app on servers"
@@ -105,7 +105,7 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
lines = options[:lines]
grep = options[:grep]
on(MRSK.config.hosts) do |host|
on(MRSK.hosts) do |host|
begin
puts_by_host host, capture_with_info(*MRSK.app.logs(since: since, lines: lines, grep: grep))
rescue SSHKit::Command::Failed
@@ -119,12 +119,12 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
def remove
case options[:only]
when "containers"
on(MRSK.config.hosts) { execute *MRSK.app.remove_containers }
on(MRSK.hosts) { execute *MRSK.app.remove_containers }
when "images"
on(MRSK.config.hosts) { execute *MRSK.app.remove_images }
on(MRSK.hosts) { execute *MRSK.app.remove_images }
else
on(MRSK.config.hosts) { execute *MRSK.app.remove_containers }
on(MRSK.config.hosts) { execute *MRSK.app.remove_images }
on(MRSK.hosts) { execute *MRSK.app.remove_containers }
on(MRSK.hosts) { execute *MRSK.app.remove_images }
end
end
end

View File

@@ -9,6 +9,9 @@ module Mrsk::Cli
class_option :verbose, type: :boolean, aliases: "-v", desc: "Detailed logging"
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 :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)"
@@ -22,6 +25,8 @@ module Mrsk::Cli
MRSK.tap do |commander|
commander.config_file = Pathname.new(File.expand_path(options[:config_file]))
commander.destination = options[:destination]
commander.hosts = options[:hosts]&.split(",")
commander.roles = options[:roles]&.split(",")
commander.verbose = options[:verbose]
end
end

View File

@@ -26,7 +26,7 @@ class Mrsk::Cli::Build < Mrsk::Cli::Base
desc "pull", "Pull app image from the registry onto servers"
def pull
on(MRSK.config.hosts) { execute *MRSK.builder.pull }
on(MRSK.hosts) { execute *MRSK.builder.pull }
end
desc "create", "Create a local build setup"

View File

@@ -32,7 +32,7 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base
desc "rollback [VERSION]", "Rollback the app to VERSION (that must already be on servers)"
def rollback(version)
on(MRSK.config.hosts) do
on(MRSK.hosts) do
execute *MRSK.app.stop, raise_on_non_zero_exit: false
execute *MRSK.app.start(version: version)
end

View File

@@ -9,11 +9,11 @@ class Mrsk::Cli::Prune < Mrsk::Cli::Base
desc "images", "Prune unused images older than 30 days"
def images
on(MRSK.config.hosts) { execute *MRSK.prune.images }
on(MRSK.hosts) { execute *MRSK.prune.images }
end
desc "containers", "Prune stopped containers for the service older than 3 days"
def containers
on(MRSK.config.hosts) { execute *MRSK.prune.containers }
on(MRSK.hosts) { execute *MRSK.prune.containers }
end
end

View File

@@ -4,14 +4,14 @@ class Mrsk::Cli::Registry < Mrsk::Cli::Base
desc "login", "Login to the registry locally and remotely"
def login
run_locally { execute *MRSK.registry.login }
on(MRSK.config.hosts) { execute *MRSK.registry.login }
on(MRSK.hosts) { execute *MRSK.registry.login }
rescue ArgumentError => e
puts e.message
end
desc "logout", "Logout of the registry remotely"
def logout
on(MRSK.config.hosts) { execute *MRSK.registry.logout }
on(MRSK.hosts) { execute *MRSK.registry.logout }
rescue ArgumentError => e
puts e.message
end

View File

@@ -3,6 +3,6 @@ require "mrsk/cli/base"
class Mrsk::Cli::Server < Mrsk::Cli::Base
desc "bootstrap", "Ensure Docker is installed on the servers"
def bootstrap
on(MRSK.config.hosts) { execute "which docker || (apt-get update -y && apt-get install docker.io -y)" }
on(MRSK.hosts) { execute "which docker || (apt-get update -y && apt-get install docker.io -y)" }
end
end

View File

@@ -3,17 +3,17 @@ require "mrsk/cli/base"
class Mrsk::Cli::Traefik < Mrsk::Cli::Base
desc "boot", "Boot Traefik on servers"
def boot
on(MRSK.config.traefik_hosts) { execute *MRSK.traefik.run, raise_on_non_zero_exit: false }
on(MRSK.traefik_hosts) { execute *MRSK.traefik.run, raise_on_non_zero_exit: false }
end
desc "start", "Start existing Traefik on servers"
def start
on(MRSK.config.traefik_hosts) { execute *MRSK.traefik.start, raise_on_non_zero_exit: false }
on(MRSK.traefik_hosts) { execute *MRSK.traefik.start, raise_on_non_zero_exit: false }
end
desc "stop", "Stop Traefik on servers"
def stop
on(MRSK.config.traefik_hosts) { execute *MRSK.traefik.stop, raise_on_non_zero_exit: false }
on(MRSK.traefik_hosts) { execute *MRSK.traefik.stop, raise_on_non_zero_exit: false }
end
desc "restart", "Restart Traefik on servers"
@@ -24,19 +24,19 @@ class Mrsk::Cli::Traefik < Mrsk::Cli::Base
desc "details", "Display details about Traefik containers from servers"
def details
on(MRSK.config.traefik_hosts) { |host| puts_by_host host, capture_with_info(*MRSK.traefik.info), type: "Traefik" }
on(MRSK.traefik_hosts) { |host| puts_by_host host, capture_with_info(*MRSK.traefik.info), type: "Traefik" }
end
desc "logs", "Show last 100 log lines from Traefik on servers"
def logs
on(MRSK.config.hosts) { |host| puts_by_host host, capture(*MRSK.traefik.logs), type: "Traefik" }
on(MRSK.hosts) { |host| puts_by_host host, capture(*MRSK.traefik.logs), type: "Traefik" }
end
desc "remove", "Remove Traefik container and image from servers"
def remove
invoke :stop
on(MRSK.config.traefik_hosts) do
on(MRSK.traefik_hosts) do
execute *MRSK.traefik.remove_container
execute *MRSK.traefik.remove_image
end

View File

@@ -16,6 +16,22 @@ class Mrsk::Commander
@config ||= Mrsk::Configuration.create_from(config_file, destination: destination).tap { |config| setup_with(config) }
end
def hosts=(hosts)
@hosts = hosts if hosts.present?
end
def roles=(role_names)
@hosts = config.roles.select { |r| role_names.include?(r.name) }.flat_map(&:hosts) if role_names.present?
end
def hosts
@hosts || config.all_hosts
end
def traefik_hosts
@hosts || config.traefik_hosts
end
def app
@app ||= Mrsk::Commands::App.new(config)

View File

@@ -48,23 +48,8 @@ class Mrsk::Configuration
roles.detect { |r| r.name == name.to_s }
end
def hosts
hosts =
case
when ENV["HOSTS"]
ENV["HOSTS"].split(",")
when ENV["ROLES"]
role_names = ENV["ROLES"].split(",")
roles.select { |r| role_names.include?(r.name) }.flat_map(&:hosts)
else
roles.flat_map(&:hosts)
end
if hosts.any?
hosts
else
raise ArgumentError, "No hosts found"
end
def all_hosts
roles.flat_map(&:hosts)
end
def primary_host