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 +15 -0
- data/README.md +14 -1
- data/lib/capistrano/deploy_lock.rb +24 -2
- data/lib/capistrano/recipes/deploy_lock.rb +44 -28
- data/lib/capistrano_deploy_lock/version.rb +1 -1
- metadata +5 -13
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 << "\
|
33
|
+
message << "\nLock expires in #{expires_in}"
|
34
34
|
else
|
35
|
-
message << "\
|
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",
|
3
|
-
before "deploy",
|
4
|
-
before "deploy",
|
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
|
8
|
-
_cset :default_lock_expiry, (
|
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[:
|
69
|
-
logger.info '
|
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
|
-
|
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(
|
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
|
-
|
108
|
+
remove_deploy_lock
|
97
109
|
end
|
98
110
|
end
|
99
111
|
|
100
112
|
task :force do
|
101
|
-
|
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[:
|
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
|
116
|
-
|
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
|
-
|
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
|
-
#
|
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
|
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.
|
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:
|
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:
|
54
|
+
rubygems_version: 2.0.5
|
63
55
|
signing_key:
|
64
|
-
specification_version:
|
56
|
+
specification_version: 4
|
65
57
|
summary: Capistrano Deploy Lock
|
66
58
|
test_files: []
|