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