Created
March 22, 2017 21:51
-
-
Save jrochkind/044c9c7ed78b04341eab9b88d32b28d6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace :invoke do | |
# cap <stage> invoke:rake TASK=chf:data_fix:something[,other:task] | |
desc "Execute a rake task on a remote server" | |
task :rake do | |
if ENV['TASK'] | |
tasks = ENV['TASK'].split(',') | |
on roles(:app) do | |
within current_path do | |
with rails_env: fetch(:rails_env) do | |
tasks.each do |task| | |
# warning, may be executing this on multiple servers if we have | |
# multiple 'app' servers later, which would be bad. | |
# Will have to deal with that then, not sure best way. | |
execute :rake, task, interaction_handler: CHF::CapistranoHelp::StreamOutputInteractionHandler.new(:stderr) | |
info("finished rake #{task}") | |
end | |
end | |
end | |
end | |
else | |
# Not really sure why we can't just use `error` method, maybe not since | |
# cap 4? | |
SSHKit.config.output.error "\n\nFailed! You need to specify the 'TASK' parameter!\n" + | |
"Usage: cap <stage> invoke:rake TASK=your:task[,other:task]" | |
end | |
end | |
namespace :rake do | |
# TASK=your:task[,other:task] REASON=reason UNTIL="12pm Eastern Time" cap <stage> invoke:rake:with_maintenance | |
# | |
# By default maintenance mode is turned off again even if interrupted | |
# with an error. If you'd like to leave it on, set enf SAFE_MAINT=false | |
desc "Execute a rake task on remote serer with maintenance enable/disable" | |
task :with_maintenance do | |
error_encountered = false | |
begin | |
SSHKit.config.output.info("Turning on maintenance mode") | |
invoke("maintenance:enable") | |
invoke("invoke:rake") | |
# Catch Ctrl-C Interrupt, so we still turn off maint mode. | |
# And errors raised by our rake tasks. | |
rescue Interrupt, SSHKit::Runner::ExecuteError => e | |
SSHKit.config.output.error("Error caught when executing rake task: #{e.inspect}") | |
# tell the ensure block | |
error_encountered = true | |
# Raise it again so our cap task has non-zero exit code, don't | |
# know how else to make that so... | |
raise e | |
ensure | |
if error_encountered && ENV['SAFE_MAINT'] == "false" | |
SSHKit.config.output.warn("\n\nMAINTENANCE MODE STILL ON!\n\n\n") | |
else | |
SSHKit.config.output.info("Turning off maintenance mode") | |
invoke("maintenance:disable") | |
end | |
end | |
end | |
end | |
end | |
# Can't for the life of me figure out how to define this somewhere | |
# else and `require` it, not sure why. That'd be better. | |
# based on sshkit's MappingInteractionHandler, but all | |
# we want to do is log it as we get it! Not really an interactin handler at all, | |
# just a stream logger. | |
module CHF | |
module CapistranoHelp | |
class StreamOutputInteractionHandler | |
# set log level to :stderr, and it will be written directly to stderr console | |
# instead of capistrano logging, which works to get byte-by-byte output | |
# before newlines, like progress bars. | |
def initialize(log_level=:info) | |
@log_level = log_level | |
end | |
def on_data(_command, stream_name, data, channel) | |
if @log_level == :stderr | |
$stderr.print data | |
else | |
log(data) | |
end | |
end | |
private | |
def log(message) | |
SSHKit.config.output.send(@log_level, message) unless @log_level.nil? | |
end | |
end | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment