capistrano_deploy_lock 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NWVmOTJlNzg5NjYzZTY0NzJiOGViMzBiZDFhYzk0ODhmYjQ0OTE5OA==
5
+ data.tar.gz: !binary |-
6
+ MDEzMjM3MDBmMTU1ZjBhZTI3OGM3YTlhNjNhMGZmNGEzNTU1MzVlMQ==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ NjMyYTFhN2U5OTE2MjI1MDlmYjg2NzYyN2NkODhiNzM4Y2M1MDA5YmYzYmU5
10
+ MGJmYzQ0MmQ1MWRlODFhOTA3MWUzYmE4YjE0NDQ3NTQ4ZDgwYjg4ZTU3MGMx
11
+ YjE5YTdiZjI1ZTk2YmQwODQwOWM3YTExN2MyODA1ZTk1MmRjMzY=
12
+ data.tar.gz: !binary |-
13
+ ODgzNjA2NzlhMGIwZTllOTYyN2NmNzg0ZWM5Y2IxNzEyZjIyNmU5YjJjYjNm
14
+ MWMyNGU2NTM1YWJiZTE1YmJmMzk4ZDBlYjE2MjBmYWZiMTEyOTUyNGIyN2Mz
15
+ Nzc5NmQwZGMzZDdjZjE2NzI5OWVkOThkYzIzNWIzMDJmZDMwOWM=
data/README.md CHANGED
@@ -48,7 +48,6 @@ The following task will be run after deploy:
48
48
  * Removes any default deploy locks. If you set a custom lock, it will not be removed at this step.
49
49
  * You can remove a custom deploy lock by running `cap deploy:unlock` by itself, or by chaining `deploy:unlock:force` at the end of the command.
50
50
 
51
-
52
51
  ## Tasks
53
52
 
54
53
  ### `deploy:with_lock`
@@ -102,6 +101,20 @@ The lock file will be created at `#{shared_path}/capistrano.lock.yml` by default
102
101
  set :deploy_lockfile, "path/to/deploy/lock/file"
103
102
 
104
103
 
104
+ ## MOTD script
105
+
106
+ If you install the gem on your server, you can use the `cap_deploy_lock_msg` script to display the lock status when you login via SSH.
107
+
108
+ Usage:
109
+
110
+ cap_deploy_lock_msg <application_name> <stage> <path/to/lock_file.yml>
111
+
112
+ If you are using `update-motd` on Ubuntu, create `/etc/update-motd.d/10-deploy-lock` with the following:
113
+
114
+ #!/bin/sh
115
+ /usr/local/bin/cap_deploy_lock_msg application stage /var/www/apps/application/shared/capistrano.lock.yml
116
+
117
+
105
118
  ## Thanks
106
119
 
107
120
  Special thanks to [David Bock](https://github.com/bokmann), who wrote the [deploy_lock.rb](https://github.com/bokmann/dunce-cap/blob/master/recipes/deploy_lock.rb)
@@ -30,9 +30,31 @@ module Capistrano
30
30
  if deploy_lock[:expire_at]
31
31
  if defined?(Capistrano::DateHelper)
32
32
  expires_in = Capistrano::DateHelper.distance_of_time_in_words_to_now deploy_lock[:expire_at].localtime
33
- message << "\nExpires in #{expires_in}"
33
+ message << "\nLock expires in #{expires_in}"
34
34
  else
35
- message << "\nExpires at #{deploy_lock[:expire_at].localtime.strftime("%H:%M:%S")}"
35
+ message << "\nLock expires at #{deploy_lock[:expire_at].localtime.strftime("%H:%M:%S")}"
36
+ end
37
+ else
38
+ message << "\nLock must be manually removed with: cap #{stage} deploy:unlock"
39
+ end
40
+ end
41
+
42
+ def self.expired_message(application, stage, deploy_lock)
43
+ message = "#{application} (#{stage}) was locked"
44
+ if defined?(Capistrano::DateHelper)
45
+ locked_ago = Capistrano::DateHelper.distance_of_time_in_words_to_now deploy_lock[:created_at].localtime
46
+ message << " #{locked_ago} ago"
47
+ else
48
+ message << " at #{deploy_lock[:created_at].localtime}"
49
+ end
50
+ message << " by '#{deploy_lock[:username]}'\nMessage: #{deploy_lock[:message]}"
51
+
52
+ if deploy_lock[:expire_at]
53
+ if defined?(Capistrano::DateHelper)
54
+ expires_in = Capistrano::DateHelper.distance_of_time_in_words_to_now deploy_lock[:expire_at].localtime
55
+ message << "\nLock expired #{expires_in} ago, unlocking..."
56
+ else
57
+ message << "\nLock expired at #{deploy_lock[:expire_at].localtime.strftime("%H:%M:%S")}"
36
58
  end
37
59
  else
38
60
  message << "\nLock must be manually removed with: cap #{stage} deploy:unlock"
@@ -1,11 +1,11 @@
1
1
  Capistrano::Configuration.instance(:must_exist).load do
2
- before "deploy", "deploy:check_lock"
3
- before "deploy", "deploy:refresh_lock"
4
- before "deploy", "deploy:create_lock"
5
- after "deploy", "deploy:unlock"
2
+ before "deploy:update_code", "deploy:check_lock"
3
+ before "deploy:update_code", "deploy:refresh_lock"
4
+ before "deploy:update_code", "deploy:create_lock"
5
+ after "deploy:create_symlink", "deploy:unlock"
6
6
 
7
- # Default lock expiry of 15 minutes (in case deploy crashes or is interrupted)
8
- _cset :default_lock_expiry, (15 * 60)
7
+ # Default lock expiry of 10 minutes (in case deploy crashes or is interrupted)
8
+ _cset :default_lock_expiry, (10 * 60)
9
9
  _cset(:deploy_lockfile) { "#{shared_path}/capistrano.lock.yml" }
10
10
 
11
11
  # Show lock message as bright red
@@ -14,6 +14,9 @@ Capistrano::Configuration.instance(:must_exist).load do
14
14
  namespace :deploy do
15
15
  # Fetch the deploy lock unless already cached
16
16
  def fetch_deploy_lock
17
+ # Return if we know that the deploy lock has just been removed
18
+ return if self[:deploy_lock_removed]
19
+
17
20
  if self[:deploy_lock].nil?
18
21
  lock_file = capture("[ -e #{deploy_lockfile} ] && cat #{deploy_lockfile} || true").strip
19
22
  if lock_file != ""
@@ -28,6 +31,12 @@ Capistrano::Configuration.instance(:must_exist).load do
28
31
  put deploy_lock.to_yaml, deploy_lockfile, :mode => 0777
29
32
  end
30
33
 
34
+ def remove_deploy_lock
35
+ run "rm -f #{deploy_lockfile}"
36
+ self[:deploy_lock] = nil
37
+ self[:deploy_lock_removed] = true
38
+ end
39
+
31
40
  desc "Deploy with a custom deploy lock"
32
41
  task :with_lock do
33
42
  lock
@@ -37,6 +46,7 @@ Capistrano::Configuration.instance(:must_exist).load do
37
46
  desc "Set deploy lock with a custom lock message and expiry time"
38
47
  task :lock do
39
48
  set :lock_message, Capistrano::CLI.ui.ask("Lock Message: ")
49
+ set :custom_deploy_lock, true
40
50
 
41
51
  while self[:lock_expiry].nil?
42
52
  expiry_str = Capistrano::CLI.ui.ask("Expire lock at? (optional): ")
@@ -60,13 +70,12 @@ Capistrano::Configuration.instance(:must_exist).load do
60
70
  end
61
71
 
62
72
  create_lock
63
- set :custom_deploy_lock, true
64
73
  end
65
74
 
66
75
  desc "Creates a lock file, so that futher deploys will be prevented"
67
76
  task :create_lock do
68
- if self[:custom_deploy_lock]
69
- logger.info 'Custom deploy lock already created.'
77
+ if self[:deploy_lock]
78
+ logger.info 'Deploy lock already created.'
70
79
  next
71
80
  end
72
81
 
@@ -77,13 +86,16 @@ Capistrano::Configuration.instance(:must_exist).load do
77
86
  set :lock_expiry, (Time.now + default_lock_expiry).utc
78
87
  end
79
88
 
80
- deploy_lock = {
89
+ deploy_lock_data = {
81
90
  :created_at => Time.now.utc,
82
91
  :username => ENV['USER'],
83
92
  :expire_at => self[:lock_expiry],
84
- :message => self[:lock_message]
93
+ :message => self[:lock_message],
94
+ :custom => !!self[:custom_deploy_lock]
85
95
  }
86
- write_deploy_lock(deploy_lock)
96
+ write_deploy_lock(deploy_lock_data)
97
+
98
+ self[:deploy_lock] = deploy_lock_data
87
99
  end
88
100
 
89
101
  namespace :unlock do
@@ -93,37 +105,40 @@ Capistrano::Configuration.instance(:must_exist).load do
93
105
  if self[:custom_deploy_lock]
94
106
  logger.info 'Not removing custom deploy lock.'
95
107
  else
96
- force
108
+ remove_deploy_lock
97
109
  end
98
110
  end
99
111
 
100
112
  task :force do
101
- run "rm -f #{deploy_lockfile}"
113
+ remove_deploy_lock
102
114
  end
103
115
  end
104
116
 
105
117
  desc "Checks for a deploy lock. If present, deploy is aborted and message is displayed. Any expired locks are deleted."
106
118
  task :check_lock do
107
119
  # Don't check the lock if we just created it
108
- next if self[:custom_deploy_lock]
120
+ next if self[:deploy_lock]
109
121
 
110
122
  fetch_deploy_lock
111
123
  # Return if no lock
112
124
  next unless self[:deploy_lock]
113
125
 
114
126
  if deploy_lock[:expire_at] && deploy_lock[:expire_at] < Time.now
115
- logger.info "Deleting expired deploy lock..."
116
- unlock
127
+ logger.info Capistrano::DeployLock.expired_message(application, stage, deploy_lock)
128
+ remove_deploy_lock
117
129
  next
118
130
  end
119
131
 
132
+ # Check if lock is a custom lock
133
+ self[:custom_deploy_lock] = deploy_lock[:custom]
134
+
120
135
  # Unexpired lock is present, so display the lock message
121
136
  logger.important Capistrano::DeployLock.message(application, stage, deploy_lock)
122
137
 
123
- # Don't raise exception if current user owns the lock.
124
- # Just sleep so they have a chance to Ctrl-C
125
- if deploy_lock[:username] == ENV['USER']
126
- 4.downto(1) do |i|
138
+ # Don't raise exception if current user owns the lock, and lock has an expiry time.
139
+ # Just sleep for a few seconds so they have a chance to cancel the deploy with Ctrl-C
140
+ if deploy_lock[:expire_at] && deploy_lock[:username] == ENV['USER']
141
+ 5.downto(1) do |i|
127
142
  Kernel.print "\rDeploy lock was created by you (#{ENV['USER']}). Continuing deploy in #{i}..."
128
143
  sleep 1
129
144
  end
@@ -135,22 +150,23 @@ Capistrano::Configuration.instance(:must_exist).load do
135
150
 
136
151
  desc "Refreshes an existing deploy lock's expiry time, if it is less than the default time"
137
152
  task :refresh_lock do
138
- # Don't refresh custom locks
139
- next if self[:custom_deploy_lock]
140
-
141
153
  fetch_deploy_lock
142
154
  next unless self[:deploy_lock]
143
155
 
144
- # Refresh lock expiry time if it's going to expire soon
156
+ # Don't refresh custom locks
157
+ if deploy_lock[:custom]
158
+ logger.info 'Not refreshing custom deploy lock.'
159
+ next
160
+ end
161
+
162
+ # Refresh lock expiry time if it's going to expire
145
163
  if deploy_lock[:expire_at] && deploy_lock[:expire_at] < (Time.now + default_lock_expiry)
146
164
  logger.info "Resetting lock expiry to default..."
165
+ deploy_lock[:username] = ENV['USER']
147
166
  deploy_lock[:expire_at] = (Time.now + default_lock_expiry).utc
148
167
 
149
168
  write_deploy_lock(deploy_lock)
150
169
  end
151
-
152
- # Set the deploy_lock_created flag so that the lock isn't automatically removed after deploy
153
- set :custom_deploy_lock, true
154
170
  end
155
171
  end
156
172
  end
@@ -1,3 +1,3 @@
1
1
  module CapistranoDeployLock
2
- VERSION = "1.1.0"
2
+ VERSION = "1.2.0"
3
3
  end
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capistrano_deploy_lock
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
5
- prerelease:
4
+ version: 1.2.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Nathan Broadbent
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-12-16 00:00:00.000000000 Z
11
+ date: 2013-09-12 00:00:00.000000000 Z
13
12
  dependencies: []
14
13
  description: Lock a server during deploy, to prevent people from deploying at the
15
14
  same time.
@@ -35,32 +34,25 @@ files:
35
34
  homepage: https://github.com/ndbroadbent/capistrano_deploy_lock
36
35
  licenses:
37
36
  - MIT
37
+ metadata: {}
38
38
  post_install_message:
39
39
  rdoc_options: []
40
40
  require_paths:
41
41
  - lib
42
42
  required_ruby_version: !ruby/object:Gem::Requirement
43
- none: false
44
43
  requirements:
45
44
  - - ! '>='
46
45
  - !ruby/object:Gem::Version
47
46
  version: '0'
48
- segments:
49
- - 0
50
- hash: -2094697491794115315
51
47
  required_rubygems_version: !ruby/object:Gem::Requirement
52
- none: false
53
48
  requirements:
54
49
  - - ! '>='
55
50
  - !ruby/object:Gem::Version
56
51
  version: '0'
57
- segments:
58
- - 0
59
- hash: -2094697491794115315
60
52
  requirements: []
61
53
  rubyforge_project:
62
- rubygems_version: 1.8.24
54
+ rubygems_version: 2.0.5
63
55
  signing_key:
64
- specification_version: 3
56
+ specification_version: 4
65
57
  summary: Capistrano Deploy Lock
66
58
  test_files: []