diff --git a/lib/mrsk/cli/accessory.rb b/lib/mrsk/cli/accessory.rb index 6e37f71a..0bd847b1 100644 --- a/lib/mrsk/cli/accessory.rb +++ b/lib/mrsk/cli/accessory.rb @@ -6,61 +6,69 @@ class Mrsk::Cli::Accessory < Mrsk::Cli::Base if name == "all" MRSK.accessory_names.each { |accessory_name| boot(accessory_name) } else - directories(name) - upload(name) - - accessory = MRSK.accessory(name) - on(accessory.host) { execute *accessory.run } + with_accessory(name) do |accessory| + directories(name) + upload(name) + on(accessory.host) { execute *accessory.run } + end end end desc "upload [NAME]", "Upload accessory files to host" def upload(name) - accessory = MRSK.accessory(name) - on(accessory.host) do - accessory.files.each do |(local, remote)| - accessory.ensure_local_file_present(local) + with_accessory(name) do |accessory| + on(accessory.host) 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 + execute *accessory.make_directory_for(remote) + upload! local, remote + execute :chmod, "755", remote + end end end end desc "directories [NAME]", "Create accessory directories on host" def directories(name) - accessory = MRSK.accessory(name) - on(accessory.host) do - accessory.directories.keys.each do |host_path| - execute *accessory.make_directory(host_path) + with_accessory(name) do |accessory| + on(accessory.host) do + accessory.directories.keys.each do |host_path| + execute *accessory.make_directory(host_path) + end end end end desc "reboot [NAME]", "Reboot accessory on host (stop container, remove container, start new container)" def reboot(name) - stop(name) - remove_container(name) - boot(name) + with_accessory(name) do |accessory| + stop(name) + remove_container(name) + boot(name) + end end desc "start [NAME]", "Start existing accessory on host" def start(name) - accessory = MRSK.accessory(name) - on(accessory.host) { execute *accessory.start } + with_accessory(name) do |accessory| + on(accessory.host) { execute *accessory.start } + end end desc "stop [NAME]", "Stop accessory on host" def stop(name) - accessory = MRSK.accessory(name) - on(accessory.host) { execute *accessory.stop, raise_on_non_zero_exit: false } + with_accessory(name) do |accessory| + on(accessory.host) { execute *accessory.stop, raise_on_non_zero_exit: false } + end end desc "restart [NAME]", "Restart accessory on host" def restart(name) - stop(name) - start(name) + with_accessory(name) do + stop(name) + start(name) + end end desc "details [NAME]", "Display details about accessory on host (use NAME=all to boot all accessories)" @@ -68,27 +76,28 @@ class Mrsk::Cli::Accessory < Mrsk::Cli::Base if name == "all" MRSK.accessory_names.each { |accessory_name| details(accessory_name) } else - accessory = MRSK.accessory(name) - on(accessory.host) { puts capture_with_info(*accessory.info) } + with_accessory(name) do |accessory| + on(accessory.host) { puts capture_with_info(*accessory.info) } + end end end desc "exec [NAME] [CMD]", "Execute a custom command on accessory host" option :run, type: :boolean, default: false, desc: "Start a new container to run the command rather than reusing existing" def exec(name, cmd) - accessory = MRSK.accessory(name) - - runner = options[:run] ? :run_exec : :exec - on(accessory.host) { |host| puts_by_host host, capture_with_info(*accessory.send(runner, cmd)) } + with_accessory(name) do |accessory| + runner = options[:run] ? :run_exec : :exec + on(accessory.host) { |host| puts_by_host host, capture_with_info(*accessory.send(runner, cmd)) } + end end desc "bash [NAME]", "Start a bash session on primary host (or specific host set by --hosts)" def bash(name) - accessory = MRSK.accessory(name) - - run_locally do - info "Launching bash session on #{accessory.host}" - exec accessory.bash(host: accessory.host) + with_accessory(name) do |accessory| + run_locally do + info "Launching bash session on #{accessory.host}" + exec accessory.bash(host: accessory.host) + end end end @@ -98,22 +107,22 @@ class Mrsk::Cli::Accessory < Mrsk::Cli::Base option :grep, aliases: "-g", desc: "Show lines with grep match only (use this to fetch specific requests by id)" option :follow, aliases: "-f", desc: "Follow logs on primary server (or specific host set by --hosts)" def logs(name) - accessory = MRSK.accessory(name) + with_accessory(name) do |accessory| + grep = options[:grep] - grep = options[:grep] + if options[:follow] + run_locally do + info "Following logs on #{accessory.host}..." + info accessory.follow_logs(grep: grep) + exec accessory.follow_logs(grep: grep) + end + else + since = options[:since] + lines = options[:lines] - if options[:follow] - run_locally do - info "Following logs on #{accessory.host}..." - info accessory.follow_logs(grep: grep) - exec accessory.follow_logs(grep: grep) - end - else - since = options[:since] - lines = options[:lines] - - on(accessory.host) do - puts capture_with_info(*accessory.logs(since: since, lines: lines, grep: grep)) + on(accessory.host) do + puts capture_with_info(*accessory.logs(since: since, lines: lines, grep: grep)) + end end end end @@ -123,28 +132,50 @@ class Mrsk::Cli::Accessory < Mrsk::Cli::Base if name == "all" MRSK.accessory_names.each { |accessory_name| remove(accessory_name) } else - stop(name) - remove_container(name) - remove_image(name) - remove_service_directory(name) + with_accessory(name) do + stop(name) + remove_container(name) + remove_image(name) + remove_service_directory(name) + end end end desc "remove_container [NAME]", "Remove accessory container from host" def remove_container(name) - accessory = MRSK.accessory(name) - on(accessory.host) { execute *accessory.remove_container } + with_accessory(name) do |accessory| + on(accessory.host) { execute *accessory.remove_container } + end end desc "remove_container [NAME]", "Remove accessory image from host" def remove_image(name) - accessory = MRSK.accessory(name) - on(accessory.host) { execute *accessory.remove_image } + with_accessory(name) do |accessory| + on(accessory.host) { execute *accessory.remove_image } + end end desc "remove_service_directory [NAME]", "Remove accessory directory used for uploaded files and data directories from host" def remove_service_directory(name) - accessory = MRSK.accessory(name) - on(accessory.host) { execute *accessory.remove_service_directory } + with_accessory(name) do |accessory| + on(accessory.host) { execute *accessory.remove_service_directory } + end end + + private + def with_accessory(name) + if accessory = MRSK.accessory(name) + yield accessory + else + error_on_missing_accessory(name) + end + end + + def error_on_missing_accessory(name) + options = MRSK.accessory_names.presence + + error \ + "No accessory by the name of '#{name}'" + + (options ? " (options: #{options.to_sentence})" : "") + end end diff --git a/lib/mrsk/commander.rb b/lib/mrsk/commander.rb index 9baf68fe..8861fc15 100644 --- a/lib/mrsk/commander.rb +++ b/lib/mrsk/commander.rb @@ -49,7 +49,7 @@ class Mrsk::Commander end def accessory_names - config.accessories.collect(&:name) + config.accessories&.collect(&:name) || [] end @@ -74,7 +74,7 @@ class Mrsk::Commander end def accessory(name) - (@accessories ||= {})[name] ||= Mrsk::Commands::Accessory.new(config, name: name) + config.accessories.detect { |a| a.name == name } end