capistrano-hivequeen 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
@@ -6,7 +6,7 @@ Gem::Specification.new do |s|
|
|
6
6
|
## If your rubyforge_project name is different, then edit it and comment out
|
7
7
|
## the sub! line in the Rakefile
|
8
8
|
s.name = 'capistrano-hivequeen'
|
9
|
-
s.version = '0.
|
9
|
+
s.version = '0.6.0'
|
10
10
|
s.date = Time.now.strftime("%Y-%m-%d")
|
11
11
|
|
12
12
|
## Make sure your summary is short. The description may be as long
|
data/lib/capistrano/hivequeen.rb
CHANGED
@@ -16,6 +16,10 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
16
16
|
set :repository, HiveQueen.repository
|
17
17
|
set :scm, :git
|
18
18
|
|
19
|
+
# By default, don't override deployments if there's another deployment in progress.
|
20
|
+
# From the command line, use -s override=true to force a deployment
|
21
|
+
set :override, false
|
22
|
+
|
19
23
|
# Load capistrano multi-stage extension
|
20
24
|
require 'fileutils' # required until https://github.com/capistrano/capistrano-ext/commit/930ca840a0b4adad0ec53546790b3f5ffe726538 is released
|
21
25
|
require 'capistrano/ext/multistage'
|
@@ -8,6 +8,28 @@ Capistrano::Configuration.instance.load do
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
+
before "deploy:update", "hivequeen:start"
|
12
|
+
before "setup", "hivequeen:start"
|
13
|
+
namespace :hivequeen do
|
14
|
+
desc "[internal] Start a deployment in hivequeen"
|
15
|
+
task :start do
|
16
|
+
# TODO: is there a better way to determine what cap tasks are running?
|
17
|
+
tasks = ARGV.reject{|task_name| stage.to_s == task_name}
|
18
|
+
params = {
|
19
|
+
:task => tasks.join(' '),
|
20
|
+
:commit => real_revision,
|
21
|
+
:override => override
|
22
|
+
}
|
23
|
+
begin
|
24
|
+
deployment = HiveQueen.start_deployment(environment_id, params)
|
25
|
+
set :deployment_id, deployment['id']
|
26
|
+
at_exit { HiveQueen.finish_deployment(environment_id, deployment['id']) }
|
27
|
+
rescue HiveQueen::DeploymentError
|
28
|
+
abort "Cannot start deployment. Errors: #{$!.message}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
11
33
|
desc "Deploy without migrations"
|
12
34
|
task(:hotfix) { deploy.default }
|
13
35
|
|
@@ -8,11 +8,14 @@ require 'base64'
|
|
8
8
|
# - environment not found
|
9
9
|
# - environment not ready: fail
|
10
10
|
class HiveQueen
|
11
|
+
class DeploymentError < Exception; end
|
12
|
+
class InsecureCredentials < Exception; end
|
13
|
+
|
11
14
|
class << self
|
12
15
|
attr_accessor :endpoint, :logger, :project, :username, :password
|
13
16
|
|
14
17
|
def project_data
|
15
|
-
@project_data ||=
|
18
|
+
@project_data ||= get("/projects/#{project}.json")
|
16
19
|
end
|
17
20
|
|
18
21
|
def environments
|
@@ -30,18 +33,40 @@ class HiveQueen
|
|
30
33
|
def roles(env_id)
|
31
34
|
env_id = env_id.to_sym
|
32
35
|
@roles ||= {}
|
33
|
-
@roles[env_id] ||=
|
36
|
+
@roles[env_id] ||= get("/environments/#{env_id}.json")
|
37
|
+
end
|
38
|
+
|
39
|
+
def start_deployment(environment_id, params)
|
40
|
+
required_params = [:task, :commit]
|
41
|
+
required_params.each do |key|
|
42
|
+
raise ArgumentError.new("#{key} is a required param") unless params.key?(key)
|
43
|
+
end
|
44
|
+
put_or_post('POST', "/environments/#{environment_id}/deployments.json", :deployment => params)
|
45
|
+
end
|
46
|
+
|
47
|
+
def finish_deployment(environment_id, deployment_id)
|
48
|
+
state = $! ? 'failed' : 'succeeded'
|
49
|
+
puts "Finishing deployment in Hivequeen. State: #{state}"
|
50
|
+
params = {:deployment => {:state => state}}
|
51
|
+
put_or_post('PUT', "/environments/#{environment_id}/deployments/#{deployment_id}.json", params)
|
34
52
|
end
|
35
53
|
|
36
54
|
# Load credentials from ~/.hivequeen
|
37
55
|
def get_credentials!
|
38
56
|
@username, @password = File.read(credential_path).chomp.split(':')
|
39
57
|
raise unless username && password
|
58
|
+
# Check that credentials are not accessible to world or group
|
59
|
+
mode = File.stat(credential_path).mode
|
60
|
+
raise InsecureCredentials unless (mode % 64 == 0)
|
61
|
+
rescue InsecureCredentials
|
62
|
+
puts "#{credential_path} is insecure. Please change you password and run"
|
63
|
+
puts "chmod 600 #{credential_path}"
|
64
|
+
exit 1
|
40
65
|
rescue Errno::ENOENT, RuntimeError
|
41
66
|
puts "Could not read HiveQueen credentials from #{credential_path}."
|
42
67
|
puts "#{credential_path} should contain your username and password seperated by a colon"
|
43
68
|
puts "Run this command with your credentials:"
|
44
|
-
puts " $ echo username:password > #{credential_path}"
|
69
|
+
puts " $ echo username:password > #{credential_path}; chmod 600 #{credential_path}"
|
45
70
|
exit 1
|
46
71
|
end
|
47
72
|
|
@@ -59,7 +84,7 @@ class HiveQueen
|
|
59
84
|
{ 'Authorization' => "Basic #{value}" }
|
60
85
|
end
|
61
86
|
|
62
|
-
def
|
87
|
+
def get(path)
|
63
88
|
url = "#{endpoint}#{path}"
|
64
89
|
logger.trace "Fetching #{url}"
|
65
90
|
response = connection.request(:method => 'GET', :path => path, :headers => auth_header)
|
@@ -69,5 +94,19 @@ class HiveQueen
|
|
69
94
|
JSON.parse(response.body)
|
70
95
|
end
|
71
96
|
|
97
|
+
def put_or_post(method, path, data)
|
98
|
+
headers = auth_header.merge("Content-type"=>"application/json", "Accept"=>"application/json")
|
99
|
+
response = connection.request(:path => path, :method => method, :headers => headers, :body => data.to_json)
|
100
|
+
case response.status
|
101
|
+
when (200..299)
|
102
|
+
JSON.parse(response.body)
|
103
|
+
when (400..499)
|
104
|
+
errors = JSON.parse(response.body)
|
105
|
+
raise DeploymentError.new(errors.inspect)
|
106
|
+
else
|
107
|
+
raise "Request to #{path} returned #{response.status} status"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
72
111
|
end
|
73
112
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capistrano-hivequeen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 7
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 6
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.6.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Aaron Suggs
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-10-
|
18
|
+
date: 2011-10-20 00:00:00 -04:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|