cap-rightscale 0.0.12 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -21,6 +21,8 @@ Jeweler::Tasks.new do |gem|
21
21
  gem.authors = ["Satoshi Ohki"]
22
22
  # Include your dependencies below. Runtime dependencies are required when using your gem,
23
23
  # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
24
+ gem.add_runtime_dependency 'capistrano', '> 2.5'
25
+ gem.add_runtime_dependency 'rightresource', '> 0.3.4'
24
26
  # gem.add_runtime_dependency 'jabber4r', '> 0.1'
25
27
  # gem.add_development_dependency 'rspec', '> 1.2.3'
26
28
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.12
1
+ 0.1.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{cap-rightscale}
8
- s.version = "0.0.12"
8
+ s.version = "0.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Satoshi Ohki"]
12
- s.date = %q{2011-02-02}
12
+ s.date = %q{2011-02-03}
13
13
  s.description = %q{Capistrano extension that maps RightScale parameters to Roles.}
14
14
  s.email = %q{roothybrid7@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -41,7 +41,7 @@ Gem::Specification.new do |s|
41
41
  s.homepage = %q{http://github.com/roothybrid7/cap-rightscale}
42
42
  s.licenses = ["MIT"]
43
43
  s.require_paths = ["lib"]
44
- s.rubygems_version = %q{1.5.0}
44
+ s.rubygems_version = %q{1.3.7}
45
45
  s.summary = %q{Capistrano extension that maps RightScale parameters to Roles}
46
46
  s.test_files = [
47
47
  "spec/cap-rightscale_spec.rb",
@@ -49,6 +49,7 @@ Gem::Specification.new do |s|
49
49
  ]
50
50
 
51
51
  if s.respond_to? :specification_version then
52
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
52
53
  s.specification_version = 3
53
54
 
54
55
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
@@ -57,12 +58,16 @@ Gem::Specification.new do |s|
57
58
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
58
59
  s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
59
60
  s.add_development_dependency(%q<rcov>, [">= 0"])
61
+ s.add_runtime_dependency(%q<capistrano>, ["> 2.5"])
62
+ s.add_runtime_dependency(%q<rightresource>, ["> 0.3.4"])
60
63
  else
61
64
  s.add_dependency(%q<rspec>, ["~> 2.3.0"])
62
65
  s.add_dependency(%q<cucumber>, [">= 0"])
63
66
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
64
67
  s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
65
68
  s.add_dependency(%q<rcov>, [">= 0"])
69
+ s.add_dependency(%q<capistrano>, ["> 2.5"])
70
+ s.add_dependency(%q<rightresource>, ["> 0.3.4"])
66
71
  end
67
72
  else
68
73
  s.add_dependency(%q<rspec>, ["~> 2.3.0"])
@@ -70,6 +75,8 @@ Gem::Specification.new do |s|
70
75
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
71
76
  s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
72
77
  s.add_dependency(%q<rcov>, [">= 0"])
78
+ s.add_dependency(%q<capistrano>, ["> 2.5"])
79
+ s.add_dependency(%q<rightresource>, ["> 0.3.4"])
73
80
  end
74
81
  end
75
82
 
@@ -1,3 +1,6 @@
1
+ require 'cap-rightscale/utils/rs_utils.rb'
2
+ require 'ping'
3
+
1
4
  module Capistrano
2
5
  class Configuration
3
6
  module RightScale
@@ -9,6 +12,14 @@ module Capistrano
9
12
  @rs_confpath = path
10
13
  end
11
14
 
15
+ def rs_cache_lifetime(time)
16
+ @lifetime = time # seconds
17
+ end
18
+
19
+ def validate_echo(bool=false)
20
+ @pingecho = bool
21
+ end
22
+
12
23
  # register deploy host's /etc/hosts OR dns record(replace 's/ #/-000/' to ServerArray name)
13
24
  def use_nickname(bool=false)
14
25
  @use_nick = bool
@@ -18,15 +29,6 @@ module Capistrano
18
29
  @domain = domain
19
30
  end
20
31
 
21
- def connect
22
- @auth ||= open(get_rs_confpath) {|f| YAML.load(f)}
23
- @conn ||= RightResource::Connection.new do |c|
24
- c.login(:username => @auth["username"], :password => @auth["password"], :account => @auth["account"])
25
- end
26
-
27
- RightResource::Base.connection = @conn
28
- end
29
-
30
32
  # Get RightScale Server Array
31
33
  # === Parameters
32
34
  # * _role_ - Capistrano role symbol (ex. :app, :web, :db)
@@ -39,25 +41,46 @@ module Capistrano
39
41
  return [] unless check_role(role)
40
42
  raise ArgumentError, ":array_id is not included in params!![#{params}]" unless params.has_key?(:array_id)
41
43
 
42
- start = Time.now
43
- connect
44
44
  logger.info("SETTING ROLE: #{role}")
45
- array = ServerArray.show(params[:array_id])
46
- logger.info("querying rightscale for server_array #{array.nickname}...")
47
- deployment_name = Deployment.show(array.deployment_href.match(/[0-9]+$/).to_s).nickname
48
- logger.info("Deployment #{deployment_name}:")
45
+
46
+ # Set rightscale's parameters
47
+ _array = params[:array_id]
49
48
 
50
49
  params.delete(:array_id) # remove rightscale's parameters
51
50
 
52
- host_list = ServerArray.instances(array.id).select {|i| i[:state] == "operational"}.map do |instance|
53
- hostname = instance[:nickname].sub(/ #[0-9]+$/, "-%03d" % instance[:nickname].match(/[0-9]+$/).to_s.to_i)
54
- hostname << ".#{_domain}" if _domain
55
- ip = instance[:private_ip_address]
56
- logger.info("Found server: #{hostname}(#{ip})")
57
- enable_hostname ? hostname : ip
58
- end
59
- role(role, params) { host_list } if host_list
51
+ host_list = get_server_cache(role) # Get cache
52
+
53
+ if host_list && host_list.size > 0
54
+ logger.info("restore cache of servers:\n#{host_list.pretty_inspect}")
55
+ role(role, params) { host_list } # set cache to role()
56
+ else
57
+ # Request RightScale API
58
+ start = Time.now
59
+ connect
60
+ array = ServerArray.show(_array)
61
+ logger.info("querying rightscale for server_array #{array.nickname}...")
62
+ deployment_name = Deployment.show(array.deployment_href.match(/[0-9]+$/).to_s).nickname
63
+ logger.info("Deployment #{deployment_name}:")
64
+
65
+ host_list = ServerArray.instances(array.id).select {|i| i[:state] == "operational"}.map do |instance|
66
+ hostname = instance[:nickname].sub(/ #[0-9]+$/, "-%03d" % instance[:nickname].match(/[0-9]+$/).to_s.to_i)
67
+ hostname << ".#{_domain}" if _domain
68
+ ip = instance[:private_ip_address]
69
+ if @pingecho
70
+ next unless Ping.pingecho(ip)
71
+ end
72
+
73
+ logger.info("Found server: #{hostname}(#{ip})")
74
+ enable_hostname ? hostname : ip
75
+ end
76
+ host_list.delete(nil)
60
77
  puts "Time: #{Time.now - start}"
78
+ if host_list && host_list.size > 0
79
+ role(role, params) { host_list }
80
+ dump_server_cache(role, host_list) # Dump cache
81
+ end
82
+ end
83
+
61
84
  host_list || []
62
85
  end
63
86
 
@@ -74,27 +97,48 @@ puts "Time: #{Time.now - start}"
74
97
  return [] unless check_role(role)
75
98
  raise ArgumentError, ":deployment is not included in params!![#{params}]" unless params.has_key?(:deployment)
76
99
 
77
- start = Time.now
78
- connect
79
100
  logger.info("SETTING ROLE: #{role}")
80
- dept = Deployment.show(params[:deployment], :server_settings => 'true')
81
- logger.info("querying rightscale for servers #{params[:name_prefix]} in deployment #{dept.nickname}...")
82
- srvs = dept.servers.select {|s| s[:state] == "operational"}
83
- srvs = srvs.select {|s| /#{params[:name_prefix]}/ =~ s[:nickname]} if params[:name_prefix]
84
101
 
85
- # remove rightscale's parameters
102
+ # Set rightscale's parameters
103
+ _dept = params[:deployment]
104
+ _name_prefix = params[:name_prefix]
105
+
86
106
  params.delete(:deployment)
87
107
  params.delete(:name_prefix) if params.has_key?(:name_prefix)
88
108
 
89
- host_list = srvs.map do |server|
90
- hostname = server[:nickname]
91
- hostname << ".#{_domain}" if _domain
92
- ip = server[:settings][:private_ip_address]
93
- logger.info("Found server: #{hostname}(#{ip})")
94
- enable_hostname ? hostname : ip
95
- end
96
- role(role, params) { host_list } if host_list
109
+ host_list = get_server_cache(role) # Get cache
110
+
111
+ if host_list && host_list.size > 0
112
+ logger.info("restore cache of servers:\n#{host_list.pretty_inspect}")
113
+ role(role, params) { host_list } # set cache to role()
114
+ else
115
+ # Request RightScale API
116
+ start = Time.now
117
+ connect
118
+ dept = Deployment.show(_dept, :server_settings => 'true')
119
+ logger.info("querying rightscale for servers #{_name_prefix} in deployment #{dept.nickname}...")
120
+ srvs = dept.servers.select {|s| s[:state] == "operational"}
121
+ srvs = srvs.select {|s| /#{_name_prefix}/ =~ s[:nickname]} if _name_prefix
122
+
123
+ host_list = srvs.map do |server|
124
+ hostname = server[:nickname]
125
+ hostname << ".#{_domain}" if _domain
126
+ ip = server[:settings][:private_ip_address]
127
+ if @pingecho
128
+ next unless Ping.pingecho(ip)
129
+ end
130
+
131
+ logger.info("Found server: #{hostname}(#{ip})")
132
+ enable_hostname ? hostname : ip
133
+ end
134
+ host_list.delete(nil)
97
135
  puts "Time: #{Time.now - start}"
136
+ if host_list && host_list.size > 0
137
+ role(role, params) { host_list }
138
+ dump_server_cache(role, host_list) # Dump cache
139
+ end
140
+ end
141
+
98
142
  host_list || []
99
143
  end
100
144
 
@@ -112,44 +156,122 @@ puts "Time: #{Time.now - start}"
112
156
  raise ArgumentError, ":tags is not included in params!![#{params}]" unless params.has_key?(:tags)
113
157
  raise ArgumentError, ":deployment is not included in params!![#{params}]" unless params.has_key?(:deployment)
114
158
 
115
- start = Time.now
116
- connect
117
159
  logger.info("SETTING ROLE: #{role}")
118
- dept = Deployment.show(params[:deployment], :server_settings => 'true')
119
- logger.info("querying rightscale for servers matching tags #{params[:tags]} in deployment #{dept.nickname}...")
120
- srvs = dept.servers.select {|s| s[:state] == "operational"}
121
160
 
122
- ts_params = {:resource_type => "ec2_instance", :tags => [params[:tags]]}
123
- ts = Tag.search(ts_params).
124
- select {|s| s.state == "operational"}.
125
- select {|s| s.deployment_href.match(/[0-9]+$/).to_s == params[:deployment].to_s}
161
+ # Set rightscale's parameters
162
+ _dept = params[:deployment]
163
+ _tags = params[:tags]
126
164
 
127
- # diff servers in deployment and servers matching tags in deployment
128
- srvs_ids = srvs.map {|s| s[:href].match(/[0-9]+$/).to_s}
129
- ts_ids = ts.map {|s| s.href.sub("/current", "").match(/[0-9]+$/).to_s}
130
- found_ids = srvs_ids & ts_ids
131
-
132
- # remove rightscale's parameters
133
165
  params.delete(:deployment)
134
166
  params.delete(:tags)
135
167
 
136
- host_list = []
137
- if found_ids.size > 0
138
- host_list = srvs.select {|s| found_ids.include?(s[:href].match(/[0-9]+$/).to_s)}.map do |server|
139
- hostname = server[:nickname]
140
- hostname << ".#{_domain}" if _domain
141
- ip = server[:settings][:private_ip_address]
142
- logger.info("Found server: #{hostname}(#{ip})")
143
- enable_hostname ? hostname : ip
144
- end
168
+ host_list = get_server_cache(role) # Get cache
145
169
 
146
- role(role, params) { host_list } if host_list
147
- end
170
+ if host_list && host_list.size > 0
171
+ logger.info("restore cache of servers:\n#{host_list.pretty_inspect}")
172
+ role(role, params) { host_list } # set cache to role()
173
+ else
174
+ # Request RightScale API
175
+ start = Time.now
176
+ connect
177
+ dept = Deployment.show(_dept, :server_settings => 'true')
178
+ logger.info("querying rightscale for servers matching tags #{_tags} in deployment #{dept.nickname}...")
179
+ srvs = dept.servers.select {|s| s[:state] == "operational"}
180
+
181
+ ts_params = {:resource_type => "ec2_instance", :tags => [_tags]}
182
+ ts = Tag.search(ts_params).
183
+ select {|s| s.state == "operational"}.
184
+ select {|s| s.deployment_href.match(/[0-9]+$/).to_s == _dept.to_s}
185
+
186
+ # diff servers in deployment and servers matching tags in deployment
187
+ srvs_ids = srvs.map {|s| s[:href].match(/[0-9]+$/).to_s}
188
+ ts_ids = ts.map {|s| s.href.sub("/current", "").match(/[0-9]+$/).to_s}
189
+ found_ids = srvs_ids & ts_ids
190
+
191
+ if found_ids.size > 0
192
+ host_list = srvs.select {|s| found_ids.include?(s[:href].match(/[0-9]+$/).to_s)}.map do |server|
193
+ hostname = server[:nickname]
194
+ hostname << ".#{_domain}" if _domain
195
+ ip = server[:settings][:private_ip_address]
196
+ if @pingecho
197
+ next unless Ping.pingecho(ip)
198
+ end
199
+
200
+ logger.info("Found server: #{hostname}(#{ip})")
201
+ enable_hostname ? hostname : ip
202
+ end
203
+ host_list.delete(nil)
204
+ end
148
205
  puts "Time: #{Time.now - start}"
206
+ if host_list && host_list.size > 0
207
+ role(role, params) { host_list }
208
+ dump_server_cache(role, host_list) # Dump cache
209
+ end
210
+ end
211
+
149
212
  host_list || []
150
213
  end
151
214
 
152
215
  private
216
+ def connect
217
+ @auth ||= open(get_rs_confpath) {|f| YAML.load(f)}
218
+ @conn ||= RightResource::Connection.new do |c|
219
+ c.login(:username => @auth["username"], :password => @auth["password"], :account => @auth["account"])
220
+ end
221
+
222
+ RightResource::Base.connection = @conn
223
+ end
224
+
225
+ def get_server_cache(role)
226
+ @lifetime ||= 86400
227
+ @server_cache ||= {}
228
+
229
+ begin
230
+ @cache_files ||= Dir.glob("#{Dir.tmpdir}/cap-rightscale-#{ENV['USER']}-*/#{stage}*")
231
+
232
+ @cache_files.each do |c|
233
+ @server_cache.update(Marshal.load(open(c) {|f| f.read}))
234
+ end if @cache_files.size > 0 && @server_cache.empty?
235
+
236
+ return [] if @server_cache.empty? # No cache entry
237
+
238
+ # get servers
239
+ if Time.now - @server_cache[role][:cache] > @lifetime
240
+ @server_cache.delete(role)
241
+ server_list = []
242
+ elsif @server_cache[role][:servers]
243
+ server_list = @server_cache[role][:servers]
244
+ else
245
+ server_list = []
246
+ end
247
+ rescue => e
248
+ return [] if @server_cache.empty?
249
+ end
250
+ server_list
251
+ end
252
+
253
+ def dump_server_cache(role, servers)
254
+ h = {role => {:servers => servers, :cache => Time.now}}
255
+ cache = @server_cache.update(h) # update servers cache
256
+ obj_dump = Marshal.dump(cache)
257
+
258
+ # Get cache directory
259
+ cache_dir = Dir.glob("#{Dir.tmpdir}/cap-rightscale-#{ENV['USER']}-*").first
260
+ if cache_dir.nil?
261
+ RSUtils.mk_rs_cache_dir
262
+ cache_dir = Dir.glob("#{Dir.tmpdir}/cap-rightscale-#{ENV['USER']}-*").first
263
+ exit if cache_dir.nil?
264
+ end
265
+ cache_file = File.join(cache_dir, stage ? "#{stage}" : "default")
266
+
267
+ begin
268
+ open(cache_file, "w") {|f| f.write(obj_dump)}
269
+ rescue => e
270
+ logger.error("#{e.class}: #{e.pretty_inspect}")
271
+ logger.debug {"Backtrace:\n#{e.backtrace.pretty_inspect}"}
272
+ end
273
+ end
274
+
153
275
  def enable_hostname
154
276
  @use_nick ||= false
155
277
  end
@@ -7,9 +7,10 @@ namespace :rightscale do
7
7
  desc "Clear rightscale's server list cache"
8
8
  namespace :cache do
9
9
  task :clear do
10
- puts "Clear cache all"
11
- pp Dir.glob("#{Dir.tmpdir}/cap-rightscale-*/#{stage}*")
12
- FileUtils.rm(Dir.glob("#{Dir.tmpdir}/cap-rightscale-*/#{stage}*"), {:force => true})
10
+ logger.info("Clear cache all")
11
+ pp Dir.glob("#{Dir.tmpdir}/cap-rightscale-#{ENV['USER']}-*/#{stage}*")
12
+ prefix = stage ? "#{stage}" : "default"
13
+ FileUtils.rm(Dir.glob("#{Dir.tmpdir}/cap-rightscale-#{ENV['USER']}-*/#{prefix}*"), {:force => true})
13
14
  end
14
15
  end
15
16
  end
@@ -1,5 +1,5 @@
1
1
  class RSUtils
2
- def self.mk_rs_cache_dir(prefix)
2
+ def self.mk_rs_cache_dir(prefix=nil)
3
3
  tmpdir = Dir.tmpdir
4
4
  _prefix = prefix || "cap-rightscale"
5
5
  begin
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cap-rightscale
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
5
- prerelease:
4
+ hash: 27
5
+ prerelease: false
6
6
  segments:
7
7
  - 0
8
+ - 1
8
9
  - 0
9
- - 12
10
- version: 0.0.12
10
+ version: 0.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Satoshi Ohki
@@ -15,11 +15,11 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-02-02 00:00:00 +09:00
18
+ date: 2011-02-03 00:00:00 +09:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
- name: rspec
22
+ prerelease: false
23
23
  version_requirements: &id001 !ruby/object:Gem::Requirement
24
24
  none: false
25
25
  requirements:
@@ -31,11 +31,11 @@ dependencies:
31
31
  - 3
32
32
  - 0
33
33
  version: 2.3.0
34
- prerelease: false
35
- type: :development
34
+ name: rspec
36
35
  requirement: *id001
36
+ type: :development
37
37
  - !ruby/object:Gem::Dependency
38
- name: cucumber
38
+ prerelease: false
39
39
  version_requirements: &id002 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
@@ -45,11 +45,11 @@ dependencies:
45
45
  segments:
46
46
  - 0
47
47
  version: "0"
48
- prerelease: false
49
- type: :development
48
+ name: cucumber
50
49
  requirement: *id002
50
+ type: :development
51
51
  - !ruby/object:Gem::Dependency
52
- name: bundler
52
+ prerelease: false
53
53
  version_requirements: &id003 !ruby/object:Gem::Requirement
54
54
  none: false
55
55
  requirements:
@@ -61,11 +61,11 @@ dependencies:
61
61
  - 0
62
62
  - 0
63
63
  version: 1.0.0
64
- prerelease: false
65
- type: :development
64
+ name: bundler
66
65
  requirement: *id003
66
+ type: :development
67
67
  - !ruby/object:Gem::Dependency
68
- name: jeweler
68
+ prerelease: false
69
69
  version_requirements: &id004 !ruby/object:Gem::Requirement
70
70
  none: false
71
71
  requirements:
@@ -77,11 +77,11 @@ dependencies:
77
77
  - 5
78
78
  - 2
79
79
  version: 1.5.2
80
- prerelease: false
81
- type: :development
80
+ name: jeweler
82
81
  requirement: *id004
82
+ type: :development
83
83
  - !ruby/object:Gem::Dependency
84
- name: rcov
84
+ prerelease: false
85
85
  version_requirements: &id005 !ruby/object:Gem::Requirement
86
86
  none: false
87
87
  requirements:
@@ -91,9 +91,40 @@ dependencies:
91
91
  segments:
92
92
  - 0
93
93
  version: "0"
94
- prerelease: false
95
- type: :development
94
+ name: rcov
96
95
  requirement: *id005
96
+ type: :development
97
+ - !ruby/object:Gem::Dependency
98
+ prerelease: false
99
+ version_requirements: &id006 !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ">"
103
+ - !ruby/object:Gem::Version
104
+ hash: 9
105
+ segments:
106
+ - 2
107
+ - 5
108
+ version: "2.5"
109
+ name: capistrano
110
+ requirement: *id006
111
+ type: :runtime
112
+ - !ruby/object:Gem::Dependency
113
+ prerelease: false
114
+ version_requirements: &id007 !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ">"
118
+ - !ruby/object:Gem::Version
119
+ hash: 27
120
+ segments:
121
+ - 0
122
+ - 3
123
+ - 4
124
+ version: 0.3.4
125
+ name: rightresource
126
+ requirement: *id007
127
+ type: :runtime
97
128
  description: Capistrano extension that maps RightScale parameters to Roles.
98
129
  email: roothybrid7@gmail.com
99
130
  executables: []
@@ -154,7 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
154
185
  requirements: []
155
186
 
156
187
  rubyforge_project:
157
- rubygems_version: 1.5.0
188
+ rubygems_version: 1.3.7
158
189
  signing_key:
159
190
  specification_version: 3
160
191
  summary: Capistrano extension that maps RightScale parameters to Roles