Module: Capistrano::Deploylock

Defined in:
lib/capistrano/deploylock/version.rb,
lib/capistrano/deploylock.rb

Constant Summary collapse

VERSION =
"0.0.4"

Class Method Summary collapse

Class Method Details

.load_into(configuration) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/capistrano/deploylock.rb', line 6

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 = `users`.chomp
          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