lib/capistrano/deploylock.rb
require "capistrano/deploylock/version"
require 'capistrano'
module Capistrano::Deploylock
def self.load_into(configuration)
configuration.load do
_cset :deploy_lock_basename, "deploy_lock"
_cset(:deploy_lock_dirname) { "#{shared_path}/system" }
_cset(:deploy_lock_template_path) { File.join(File.dirname(__FILE__), "templates", "deploy_lock.yml") }
_cset(:deploy_lock_remote_path) { "#{deploy_lock_dirname}/#{deploy_lock_basename}.yml" }
_cset(:deploy_lock_remote_log_path) {"#{deploy_lock_dirname}/#{deploy_lock_basename}.log" }
_cset(:deploy_lock_file_local_path) {"./public/system/#{deploy_lock_basename}.yml" }
def remote_file_exists?(full_path)
'true' == capture("if [ -e #{full_path} ]; then echo 'true'; fi").strip
end
def lock_force_end(with_log=false)
if remote_file_exists?(deploy_lock_remote_path)
puts '[SKIP] ロックファイルを削除します'
lock_end_log if with_log
run "rm -f #{deploy_lock_remote_path}"
end
end
def lock_start_log
run "echo [started], #{Time.now}, #{git_config_user_name} >> #{deploy_lock_remote_log_path}"
end
def lock_end_log
run "echo [ended], #{Time.now}, #{git_config_user_name} >> #{deploy_lock_remote_log_path}"
end
def git_config_user_name
`git config --get user.name`
end
def remove_local_file
FileUtils.rm deploy_lock_file_local_path, force: true
end
namespace :deploy do
namespace :lock do
desc 'デプロイロックを確認する'
task :start, roles: :web do
on_rollback { run "rm -f #{deploy_lock_remote_path}" }
require 'erb'
puts "\n**** [DEPLOY LOCK] ****"
puts "24時間後まであなたの名前を元に他人のデプロイをロックします。"
puts "この操作は下記のコマンドで取り消しできます。"
puts "bundle exedc cap $STAGENAME deploy:lock:end"
# 対話用
# print "\n今日から何日間ロックしますか? [1-10/n]: "
# STDOUT.flush
# ans= STDIN.gets.chomp
# if ["", 'n'].include? ans
# puts "[SKIPPED] デプロイロックをスキップしました。"
# exit
# end
#
# day = ans.to_i
# unless (1..10).include?(day)
# puts "[FAILED] days must set [1-10/n]"
# exit
# end
day = 1
expired_at = Time.now + (day * (60 * 60 * 24))
user = git_config_user_name
puts "\n**** [LOCKED] #{rails_env}はロックされ、有効期限内が設定されました. **** "
puts "\n locked_user : #{user}"
puts " expired_at : #{expired_at}\n\n"
erb = ERB.new(File.read("#{deploy_lock_template_path}.erb")).result(binding)
put erb, "#{deploy_lock_remote_path}", mode: 0644
lock_start_log
end
desc 'デプロイロックを解除する'
task :end, roles: :web do
lock_force_end(true)
end
desc 'デプロイロックを設定する'
task :check, roles: :web do
unless remote_file_exists?(deploy_lock_remote_path)
puts '[SKIP] ロックファイルがありません.'
next
end
FileUtils.rm deploy_lock_file_local_path, force: true
FileUtils.mkdir_p './public/system'
get deploy_lock_remote_path, deploy_lock_file_local_path
lock = YAML.load_file deploy_lock_file_local_path
if Time.now > lock["expired_at"]
puts '[SKIP] ロックファイルの設定期限が過ぎています.'
remove_local_file
lock_force_end(false)
next
end
current_user = git_config_user_name.chomp
if lock["user"] == current_user
puts '[SKIP] あなたのロックファイルです.'
remove_local_file
next
end
puts "\n**** [LOCKED] #{rails_env}はロックされ、有効期限内です. **** "
puts "\n locked_user : #{lock["user"]}"
puts " expired_at : #{lock["expired_at"]}\n\n"
puts "ロックは下記のコマンドで取り消しできます。"
puts "bundle exedc cap $STAGENAME deploy:lock:end"
remove_local_file
run "hostname; exit 1"
end
end
end
end
end
end
if Capistrano::Configuration.instance
Capistrano::Deploylock.load_into(Capistrano::Configuration.instance)
end