capistrano-deploy_locker 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7ddff18ae5088deb7d0338f7b49410b39a05d169
4
+ data.tar.gz: fe7ac69700f0ba6bd278db44df3ee795861ae431
5
+ SHA512:
6
+ metadata.gz: 23928bd1519b9b4d35628aed7c2245375530d92b081a1495dd1ba115da1cd7ad644025cced6166383a6e5cae1999c6d1108e9000a9a1bfe90d2a43feca1702e2
7
+ data.tar.gz: d1b639908264163ddc729d8e7f4c752d281eef9a33f76335b82e85460073f4dd4ffb4a15530e72079cde06e7eda4f2b97a99bf2259d5079f63ce935673e0be57
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.sw[pon]
11
+
12
+ # rspec failure tracking
13
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,12 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.0.0
5
+ - 2.1.8
6
+ - 2.2.0
7
+ before_install: gem install bundler -v 1.14.6
8
+ install: bundle _1.14.6_ install
9
+ script: bundle _1.14.6_ exec rake spec
10
+ notifications:
11
+ slack:
12
+ secure: MaiWfXSv4HSSOCYHunEuFIyVEhCaw/uhjWjSsZYDJSiGXcSYPrDfY4L3ccCkAM0j3EueNfxK5rh+aN8f5b0fAFTapmnHlBTlK0prb78kJCDuoxHFKjH5GWQL5UmyPftvr/V1ydtq8PJMMI+Hd4ui1NqE/LbMWdABsznssXM+wVs5yYaf+R4NxSE6nQPQdTAFEjzwXfHq0xmKcvLWKkxjuJSr503FgEdaYxVXndhz0wmsSWH/F/0v07rz75jzmlCJOIqU2zQ/dCZxEouZuq+beHemyT4BQkxj0ashhaHo1R6evBsg3TwxC+gBt8IvoPS7UaJyJbJYMgRezRezMWkUcH8o/cIQ4cHd0l9H/ZAR7WETN1uISvTFUVELFMYLg4vWIH3JJaXpy4YNn7hB/hXU44RBdZdwWhY1IcneN/kXydTRalq2rrl84YyoEp51qjH/f7GenR4K6UNL5ZYGqNxllPdD3vf7+ulGoGcRIc7uxfrIs/qhjNXYrHKSUUo1t/MQmomeWnLgIzz1MBHID6qW4yskw8Vy5YIr8crE8YzRBO5jQ1n1wOL6yiKdGgkBTRPM26GEDmO0kT51os+3AxMqPdtskNv5nolHiJyxNlDFJcj4gDmKstjA6DOrWvXtP4EYdZex3CFXlIwtNRrqjWINicPtHIlJOqngC94WP63vMDg=
@@ -0,0 +1,3 @@
1
+ ## 0.3.0 (2017/4/12)
2
+
3
+ Initial release.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in capistrano-deploy_locker.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 DeNA Co., Ltd., IKEDA Kiyoshi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,69 @@
1
+ [![Gem Version](https://badge.fury.io/rb/capistrano-deploy_locker.svg)](https://badge.fury.io/rb/capistrano-deploy_locker)
2
+ [![Build Status](https://travis-ci.org/DeNADev/capistrano-deploy_locker.svg?branch=master)](https://travis-ci.org/DeNADev/capistrano-deploy_locker)
3
+ # Capistrano::DeployLocker
4
+
5
+ A capistrano plugin to make deployment with exclusive lock.
6
+
7
+ In other words, this protects any two processes from running `cap deploy`
8
+ command at the same time.
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ ```ruby
15
+ gem 'capistrano-deploy_locker'
16
+ ```
17
+
18
+ And then execute:
19
+
20
+ $ bundle
21
+
22
+ Or install it yourself as:
23
+
24
+ $ gem install capistrano-deploy_locker
25
+
26
+
27
+ ## Configuration
28
+
29
+ Set Capistrano variables with `set name, value`.
30
+
31
+ Name | Default | Description
32
+ -----|---------|------------
33
+ deploy_lock_key | `"#{fetch(:application)}.#{fetch(:stage)}"` | String to specify lock target
34
+ deploy_lock_dir | `./.lock` | Directory to write lockfile or other info
35
+ deploy_lock_user | `ENV['USER'] || ENV['LOGIN']` | Who locks deploy
36
+ deploy_lock_reason | `"#{$0} #{ARGV}"` | Why deploy is locked
37
+
38
+ You can provide `:deploy_lock_user` and `:deploy_lock_reason` to show infomation
39
+ of your deployment for other operators who try to get lock in fail.
40
+
41
+ ## Usage
42
+
43
+ Edit Capfile:
44
+
45
+ ```ruby
46
+ # Load DSL and Setup Up Stages
47
+ require 'capistrano/setup'
48
+
49
+ # Includes default deployment tasks
50
+ require 'capistrano/deploy'
51
+
52
+ # Includes tasks from other gems included in your Gemfile
53
+ require 'capistrano/deploy_locker'
54
+ ```
55
+
56
+ Edit your `config/deploy.rb`:
57
+
58
+ ```ruby
59
+ before 'deploy:starting', 'deploy:lock'
60
+ after 'deploy:finished', 'deploy:unlock'
61
+ after 'deploy:failed', 'deploy:unlock'
62
+ ```
63
+
64
+ ## License
65
+
66
+ Available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
67
+
68
+ Copyright (c) 2017 DeNA Co., Ltd., IKEDA Kiyoshi
69
+
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'capistrano/deploy_locker/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'capistrano-deploy_locker'
8
+ spec.version = Capistrano::DeployLocker::VERSION
9
+ spec.authors = ['progrhyme']
10
+
11
+ spec.summary = 'Capistrano Plugin to Lock Deployment'
12
+ spec.description = 'A capistrano 3 plugin which provides locking feature for deployment'
13
+ spec.homepage = 'https://github.com/DeNADev/capistrano-deploy_locker'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_dependency 'capistrano'
22
+
23
+ spec.add_development_dependency 'bundler'
24
+ spec.add_development_dependency 'rake'
25
+ spec.add_development_dependency 'rspec'
26
+ end
File without changes
@@ -0,0 +1 @@
1
+ load File.expand_path('../tasks/deploy_locker.rake', __FILE__)
@@ -0,0 +1,29 @@
1
+ require 'fileutils'
2
+ require 'forwardable'
3
+ require 'json'
4
+ require 'capistrano/configuration'
5
+
6
+ module Capistrano
7
+ module DeployLocker
8
+ require 'capistrano/deploy_locker/provider'
9
+ require 'capistrano/deploy_locker/config'
10
+ require 'capistrano/deploy_locker/version'
11
+
12
+ class << self
13
+ extend ::Forwardable
14
+ def_delegator :provider, :locked?
15
+ def_delegator :provider, :create, :lock
16
+ def_delegator :provider, :clear, :unlock
17
+ end
18
+
19
+ class AlreadyLocked < ::StandardError; end
20
+
21
+ def self.provider
22
+ @provider ||= Capistrano::DeployLocker::Provider.new
23
+ end
24
+
25
+ def self.config
26
+ @config ||= Capistrano::DeployLocker::Config.new
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ require 'capistrano/deploy_locker/base'
2
+
3
+ class Capistrano::DeployLocker::Config
4
+ extend ::Forwardable
5
+ def_delegator :@env, :fetch
6
+
7
+ def initialize(env = Capistrano::Configuration.env)
8
+ @env = env
9
+ end
10
+
11
+ def lock_key
12
+ @lock_key ||= fetch(:deploy_lock_key, nil)
13
+ @lock_key ||= [fetch(:application), fetch(:stage)].join('.')
14
+ end
15
+
16
+ def lock_dir
17
+ @lock_dir ||= fetch(:deploy_lock_dir, File.join(Dir.pwd, '.lock'))
18
+ end
19
+
20
+ def who
21
+ @who ||= fetch(:deploy_lock_user, ENV['USER'] || ENV['LOGIN'] || Etc.getlogin || Etc.getpwuid.name)
22
+ end
23
+
24
+ def why
25
+ @why ||= fetch(:deploy_lock_reason, "#{$PROGRAM_NAME} #{ARGV.join(' ')}")
26
+ end
27
+ end
@@ -0,0 +1,60 @@
1
+ require 'capistrano/deploy_locker/base'
2
+
3
+ class Capistrano::DeployLocker::Provider
4
+ def initialize(config = Capistrano::DeployLocker.config)
5
+ @config = config
6
+ FileUtils.mkpath(config.lock_dir)
7
+ end
8
+
9
+ def locked?
10
+ locked = false
11
+ File.open(lock_file, File::RDWR | File::CREAT, 0o0644) do |f|
12
+ locked = true unless f.flock(File::LOCK_EX | File::LOCK_NB)
13
+ end
14
+ locked
15
+ end
16
+
17
+ def create
18
+ @lock_file = File.open(lock_file, File::RDWR | File::CREAT, 0o0644)
19
+ unless @lock_file.flock(File::LOCK_EX | File::LOCK_NB)
20
+ @lock_file.close
21
+ message = "#{lock_file} is already locked!\n"
22
+ if i = info
23
+ message << "Info: #{i}"
24
+ else
25
+ message << 'No additional info available.'
26
+ end
27
+ raise Capistrano::DeployLocker::AlreadyLocked, message
28
+ end
29
+ update_info
30
+ end
31
+
32
+ def clear
33
+ @lock_file.flock(File::LOCK_UN | File::LOCK_NB)
34
+ @lock_file.close
35
+ end
36
+
37
+ def info
38
+ return unless File.readable?(info_file)
39
+ JSON.parse(File.read(info_file))
40
+ end
41
+
42
+ def update_info
43
+ content = {
44
+ user: @config.who,
45
+ reason: @config.why,
46
+ date: Time.now,
47
+ }.to_json
48
+ File.write(info_file, "#{content}\n")
49
+ end
50
+
51
+ private
52
+
53
+ def lock_file
54
+ File.join(@config.lock_dir, "#{@config.lock_key}.lock")
55
+ end
56
+
57
+ def info_file
58
+ File.join(@config.lock_dir, "#{@config.lock_key}.info")
59
+ end
60
+ end
@@ -0,0 +1,5 @@
1
+ module Capistrano
2
+ module DeployLocker
3
+ VERSION = '0.3.0'
4
+ end
5
+ end
@@ -0,0 +1,32 @@
1
+ require 'capistrano/deploy_locker/base'
2
+
3
+ namespace :deploy do
4
+ namespace :lock do
5
+ task :check do
6
+ Capistrano::DeployLocker.locked?
7
+ end
8
+
9
+ task :create do
10
+ begin
11
+ Capistrano::DeployLocker.lock
12
+ rescue Capistrano::DeployLocker::AlreadyLocked => e
13
+ puts "ERROR! #{e}"
14
+ exit(1)
15
+ end
16
+ end
17
+
18
+ task :clear do
19
+ Capistrano::DeployLocker.unlock
20
+ end
21
+ end
22
+
23
+ desc 'Get lock for Deploy operation'
24
+ task :lock do
25
+ invoke 'deploy:lock:create'
26
+ end
27
+
28
+ desc 'Release lock for Deploy operation'
29
+ task :unlock do
30
+ invoke 'deploy:lock:clear'
31
+ end
32
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capistrano-deploy_locker
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - progrhyme
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-04-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: capistrano
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: A capistrano 3 plugin which provides locking feature for deployment
70
+ email:
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - ".gitignore"
76
+ - ".rspec"
77
+ - ".travis.yml"
78
+ - CHANGELOG.md
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - capistrano-deploy_locker.gemspec
84
+ - lib/capistrano-deploy_locker.rb
85
+ - lib/capistrano/deploy_locker.rb
86
+ - lib/capistrano/deploy_locker/base.rb
87
+ - lib/capistrano/deploy_locker/config.rb
88
+ - lib/capistrano/deploy_locker/provider.rb
89
+ - lib/capistrano/deploy_locker/version.rb
90
+ - lib/capistrano/tasks/deploy_locker.rake
91
+ homepage: https://github.com/DeNADev/capistrano-deploy_locker
92
+ licenses:
93
+ - MIT
94
+ metadata: {}
95
+ post_install_message:
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ requirements: []
110
+ rubyforge_project:
111
+ rubygems_version: 2.6.11
112
+ signing_key:
113
+ specification_version: 4
114
+ summary: Capistrano Plugin to Lock Deployment
115
+ test_files: []