rubber 2.5.5 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ec1e12978f936ceec04c66adb0faaee47bd40b58
4
- data.tar.gz: f9d9ad4325c684e4d51c7ac677e96e4613c70107
3
+ metadata.gz: 3ec3be4c2c2b486ddd2528e9db6b72b96d1fbf2f
4
+ data.tar.gz: ad0afb86cac74f88bc397e87a851434015d6683c
5
5
  SHA512:
6
- metadata.gz: e820367d0dce0f9636d08ffd9b2e94bf418cf575bd8b510754924f60b5d7e2a52471118b5e500c1a6ecfa38df9b752e6cfbd1cfd82684929d5c4d92cac8825ce
7
- data.tar.gz: 546e2c34cb91151d0012b7c379d8964348960a9403344b7ffa536c0d620ba84bc5c06316299f7f92a46540768bc631c460e1e43f684e1f88c87ff8fe9cfbd29b
6
+ metadata.gz: 1184ac231a4cbdaad613d17749e53bf4a993d6affae6830ffd0b65a1ea9ea7af9a2a2965e86cc0408344cb4625f97a8071a1d8ac9b27963490687ba53a20f280
7
+ data.tar.gz: 3f25823f1f87443b3d4f9f0b189e5c3572a74dd5deafd3cdc7368339168308b2d50181b3b717d33343308918049e3742ada873919d1c17e051ced82914efb3bd
data/CHANGELOG CHANGED
@@ -1,9 +1,24 @@
1
+ 2.6.0 (11/05/2013)
2
+
3
+ New Features:
4
+ ============
5
+
6
+ [core] Added a new provider for vSphere. See https://github.com/rubber/rubber/wiki/Providers for configuration details.
7
+
8
+ Improvements:
9
+ ============
10
+
11
+ [base] Upgraded to ruby-build 20131030 <214423d>
12
+ [base] Enhances database.yml to respond to active environment, not just 'production' <3843caf>
13
+
14
+
1
15
  2.5.5 (10/16/2013)
2
16
 
3
17
  New Features:
4
18
  ============
5
19
 
6
20
  [base, core, postgresql] Added a uniform way of handling private network address blocks <61c5e0c>
21
+ [core] Added cleanup hook for 'vagrant destroy' for Vagrant version >= 1.3.0. <2a3c441>
7
22
 
8
23
  Improvements:
9
24
  ============
@@ -3,6 +3,7 @@ source "https://rubygems.org"
3
3
  gem 'jruby-openssl', :platform => :jruby
4
4
  gem 'unlimited-strength-crypto', :platform => :jruby
5
5
  gem 'nokogiri', '~>1.5.0'
6
+ gem 'mime-types', '~>1.25'
6
7
 
7
8
  # Specify your gem's dependencies in rubber.gemspec
8
9
  gemspec
@@ -301,21 +301,27 @@ module Rubber
301
301
  groups
302
302
  end
303
303
 
304
- def create_volume(size, zone)
305
- volume = @compute_provider.volumes.create(:size => size.to_s, :availability_zone => zone)
306
- return volume.id
304
+ def create_volume(instance, volume_spec)
305
+ volume = @compute_provider.volumes.create(:size => volume_spec['size'], :availability_zone => volume_spec['zone'])
306
+ volume.id
307
307
  end
308
308
 
309
- def attach_volume(volume_id, instance_id, device)
309
+ def after_create_volume(instance, volume_id, volume_spec)
310
+ # After we create an EBS volume, we need to attach it to the instance.
310
311
  volume = @compute_provider.volumes.get(volume_id)
311
- server = @compute_provider.servers.get(instance_id)
312
+ server = @compute_provider.servers.get(instance.instance_id)
312
313
  volume.device = device
313
314
  volume.server = server
314
315
  end
315
316
 
316
- def detach_volume(volume_id, force=true)
317
+ def before_destroy_volume(volume_id)
318
+ # Before we can destroy an EBS volume, we must detach it from any running instances.
317
319
  volume = @compute_provider.volumes.get(volume_id)
318
- force ? volume.force_detach : (volume.server = nil)
320
+ volume.force_detach
321
+ end
322
+
323
+ def destroy_volume(volume_id)
324
+ @compute_provider.volumes.get(volume_id).destroy
319
325
  end
320
326
 
321
327
  def describe_volumes(volume_id=nil)
@@ -323,21 +329,21 @@ module Rubber
323
329
  opts = {}
324
330
  opts[:'volume-id'] = volume_id if volume_id
325
331
  response = @compute_provider.volumes.all(opts)
332
+
326
333
  response.each do |item|
327
334
  volume = {}
328
335
  volume[:id] = item.id
329
336
  volume[:status] = item.state
337
+
330
338
  if item.server_id
331
339
  volume[:attachment_instance_id] = item.server_id
332
340
  volume[:attachment_status] = item.attached_at ? "attached" : "waiting"
333
341
  end
342
+
334
343
  volumes << volume
335
344
  end
336
- return volumes
337
- end
338
345
 
339
- def destroy_volume(volume_id)
340
- @compute_provider.volumes.get(volume_id).destroy
346
+ volumes
341
347
  end
342
348
 
343
349
  # resource_id is any Amazon resource ID (e.g., instance ID or volume ID)
@@ -190,6 +190,10 @@ module Rubber
190
190
  groups
191
191
  end
192
192
 
193
+ def should_disable_password_based_ssh_login?
194
+ false
195
+ end
196
+
193
197
  end
194
198
 
195
199
  end
@@ -31,7 +31,8 @@ module Rubber
31
31
  :flavor_id => ami_type,
32
32
  :groups => security_groups,
33
33
  :availability_zone => availability_zone,
34
- :key_name => env.key_name)
34
+ :key_name => env.key_name,
35
+ :name => instance_alias)
35
36
 
36
37
  response.id
37
38
  end
@@ -120,6 +121,34 @@ module Rubber
120
121
  def describe_load_balancers(name=nil)
121
122
  raise NotImplementedError, "describe_load_balancers not implemented in generic fog adapter"
122
123
  end
124
+
125
+ def before_create_volume(instance, volume_spec)
126
+ # No-op by default.
127
+ end
128
+
129
+ def create_volume(instance, volume_spec)
130
+ # No-op by default.
131
+ end
132
+
133
+ def after_create_volume(instance, volume_id, volume_spec)
134
+ # No-op by default.
135
+ end
136
+
137
+ def before_destroy_volume(volume_id)
138
+ # No-op by default.
139
+ end
140
+
141
+ def destroy_volume(volume_id)
142
+ # No-op by default.
143
+ end
144
+
145
+ def after_destroy_volume(volume_id)
146
+ # No-op by default.
147
+ end
148
+
149
+ def should_destroy_volume_when_instance_destroyed?
150
+ false
151
+ end
123
152
  end
124
153
 
125
154
  end
@@ -0,0 +1,291 @@
1
+ require 'rubber/cloud/fog'
2
+
3
+ module Rubber
4
+ module Cloud
5
+ class Vsphere < Fog
6
+ def initialize(env, capistrano)
7
+ compute_credentials = {
8
+ :provider => 'vsphere',
9
+ :vsphere_username => env.vcenter_username,
10
+ :vsphere_password => env.vcenter_password,
11
+ :vsphere_server => env.vcenter_host,
12
+ :vsphere_expected_pubkey_hash => env.expected_pubkey_hash
13
+ }
14
+
15
+ if env.cloud_providers && env.cloud_providers.aws
16
+ storage_credentials = {
17
+ :provider => 'AWS',
18
+ :aws_access_key_id => env.cloud_providers.aws.access_key,
19
+ :aws_secret_access_key => env.cloud_providers.aws.secret_access_key
20
+ }
21
+
22
+ storage_credentials[:region] = env.cloud_providers.aws.region
23
+
24
+ env['storage_credentials'] = storage_credentials
25
+ end
26
+
27
+ env['compute_credentials'] = compute_credentials
28
+ super(env, capistrano)
29
+ end
30
+
31
+ def create_instance(instance_alias, image_name, image_type, security_groups, availability_zone, datacenter)
32
+ if env.domain.nil?
33
+ raise "'domain' value must be configured"
34
+ end
35
+
36
+ rubber_cfg = Rubber::Configuration.get_configuration(Rubber.env)
37
+ host_env = rubber_cfg.environment.bind(nil, instance_alias)
38
+
39
+ if host_env.public_nic.nil? && host_env.private_nic.nil?
40
+ raise "You must configure a private or a public NIC for this host in your rubber YAML"
41
+ end
42
+
43
+ if host_env.public_nic && env.public_network_name.nil?
44
+ raise "You must configure the 'public_network_name' in the provider configuration"
45
+ end
46
+
47
+ if host_env.private_nic && env.private_network_name.nil?
48
+ raise "You must configure the 'private_network_name' in the provider configuration"
49
+ end
50
+
51
+ nics = []
52
+
53
+ if host_env.public_nic
54
+ nic = nic_to_vsphere_config(host_env.public_nic, env.public_nic || {})
55
+ validate_nic_vsphere_config(nic, :public)
56
+ nics << nic
57
+ end
58
+
59
+ if host_env.private_nic
60
+ nic = nic_to_vsphere_config(host_env.private_nic, env.private_nic || {})
61
+ validate_nic_vsphere_config(nic, :private)
62
+ nics << nic
63
+ end
64
+
65
+ vm_clone_options = {
66
+ 'datacenter' => datacenter,
67
+ 'template_path' => image_name,
68
+ 'name' => instance_alias,
69
+ 'power_on' => false
70
+ }
71
+
72
+ if host_env.memory
73
+ vm_clone_options['memoryMB'] = host_env.memory
74
+ end
75
+
76
+ if host_env.cpus
77
+ vm_clone_options['numCPUs'] = host_env.cpus
78
+ end
79
+
80
+ vm = compute_provider.vm_clone(vm_clone_options)
81
+
82
+ server = compute_provider.servers.get(vm['new_vm']['id'])
83
+
84
+ # Destroy all existing NICs. We need the public and private IPs to line up with the NICs attached to the
85
+ # correct virtual switches. Rather than take the cross-product and try to work that out, it's easier to
86
+ # just start fresh and guarantee everything works as intended.
87
+ server.interfaces.each(&:destroy)
88
+
89
+ server.interfaces.create(:network => env.public_network_name) if host_env.public_nic
90
+ server.interfaces.create(:network => env.private_network_name) if host_env.private_nic
91
+
92
+ vm_ref = compute_provider.send(:get_vm_ref, server.id)
93
+ vm_ref.CustomizeVM_Task(:spec => customization_spec(instance_alias, nics))
94
+
95
+ server.start
96
+
97
+ vm['new_vm']['id']
98
+ end
99
+
100
+ def describe_instances(instance_id=nil)
101
+ instances = []
102
+ opts = {}
103
+
104
+ if instance_id
105
+ response = [compute_provider.servers.get(instance_id)]
106
+ else
107
+ response = compute_provider.servers.all(opts)
108
+ end
109
+
110
+ response.each do |item|
111
+ rubber_cfg = Rubber::Configuration.get_configuration(Rubber.env)
112
+ host_env = rubber_cfg.environment.bind(nil, item.name)
113
+
114
+ instance = {}
115
+ instance[:id] = item.id
116
+ instance[:state] = item.tools_state
117
+
118
+ # We can't trust the describe operation when the instance is newly created because the VM customization
119
+ # step likely hasn't completed yet. This means we'll get back the IP address for the VM template, rather
120
+ # than the one we just configured.
121
+ if host_env.public_nic
122
+ instance[:external_ip] = host_env.public_nic.ip_address
123
+
124
+ if host_env.private_nic.nil?
125
+ instance[:internal_ip] = host_env.public_nic.ip_address
126
+ end
127
+ end
128
+
129
+ if host_env.private_nic
130
+ instance[:internal_ip] = host_env.private_nic.ip_address
131
+
132
+ if host_env.public_nic.nil?
133
+ instance[:external_ip] = host_env.private_nic.ip_address
134
+ end
135
+ end
136
+
137
+ instance[:region_id] = item.datacenter
138
+ instance[:provider] = 'vsphere'
139
+ instance[:platform] = 'linux'
140
+ instances << instance
141
+ end
142
+
143
+ return instances
144
+ end
145
+
146
+ def active_state
147
+ 'toolsOk'
148
+ end
149
+
150
+ def create_volume(instance, volume_spec)
151
+ server = @compute_provider.servers.get(instance.instance_id)
152
+ datastore = volume_spec['datastore']
153
+ thin_disk = volume_spec.has_key?('thin') ? volume_spec['thin'] : true
154
+
155
+ # This craziness here is so we can map the device name to an appropriate SCSI channel index, which is zero-based.
156
+ # E.g., /dev/sdc would correspond to a unit_number of 2. We do this by chopping off the SCSI device letter and
157
+ # then doing some ASCII value math to convert to the appropriate decimal value.
158
+ unit_number = volume_spec['device'][-1].ord - 97
159
+
160
+ config = { :size_gb => volume_spec['size'], :unit_number => unit_number }
161
+
162
+ if datastore
163
+ config[:datastore] = datastore
164
+ end
165
+
166
+ unless thin_disk
167
+ eager_zero = volume_spec.has_key?('eager_zero') ? volume_spec['eager_zero'] : false
168
+
169
+ config[:thin] = false
170
+ config[:eager_zero] = eager_zero
171
+ end
172
+
173
+ volume = server.volumes.create(config)
174
+
175
+ volume.id
176
+ end
177
+
178
+ def destroy_volume(volume_id)
179
+ # TODO (nirvdrum 10/28/13): Fog currently lacks the ability to fetch a volume by ID, so we need to fetch all volumes for all servers to find the volume we want. This is terribly inefficient and fog should be updated.
180
+ volume = @compute_provider.servers.collect { |s| s.volumes.all }.flatten.find { |v| v.id == volume_id }
181
+
182
+ if volume.unit_number == 0
183
+ raise "Cannot destroy volume because it is the VM root device. Destroy the VM if you really want to free this volume."
184
+ end
185
+
186
+ volume.destroy
187
+ end
188
+
189
+ def describe_volumes(volume_id=nil)
190
+ volumes = []
191
+ opts = {}
192
+ opts[:'volume-id'] = volume_id if volume_id
193
+
194
+ if volume_id
195
+ response = [@compute_provider.servers.collect { |s| s.volumes.all }.flatten.find { |v| v.id == volume_id }]
196
+ else
197
+ response = @compute_provider.servers.collect { |s| s.volumes.all }.flatten
198
+ end
199
+
200
+ response.each do |item|
201
+ volume = {}
202
+ volume[:id] = item.id
203
+ volume[:status] = item.unit_number == 0 ? 'root' : 'extra'
204
+
205
+ if item.server_id
206
+ volume[:attachment_instance_id] = item.server_id
207
+ volume[:attachment_status] = Thread.current[:detach_volume] == item.id ? 'detached' : 'attached'
208
+ end
209
+
210
+ volumes << volume
211
+ end
212
+
213
+ volumes
214
+ end
215
+
216
+ def should_destroy_volume_when_instance_destroyed?
217
+ true
218
+ end
219
+
220
+ def should_disable_password_based_ssh_login?
221
+ true
222
+ end
223
+
224
+ private
225
+
226
+ def validate_nic_vsphere_config(nic_config, type)
227
+ %w[ip subnetMask dnsServerList].each do |attr|
228
+ if nic_config[attr].nil?
229
+ raise "Missing '#{attr}' for #{type} NIC configuaration"
230
+ end
231
+ end
232
+
233
+ nic_config
234
+ end
235
+
236
+ def nic_to_vsphere_config(nic, default_nic)
237
+ hash = {
238
+ 'ip' => nic['ip_address'],
239
+ 'subnetMask' => nic['subnet_mask'] || default_nic['subnet_mask'],
240
+ 'dnsServerList' => nic['dns_servers'] || default_nic['dns_servers']
241
+ }
242
+
243
+ # We want to allow overriding the gateway on a per-host basis by setting the value to nil. As such, we
244
+ # can't fall back to the default config just because the value is nil.
245
+ if nic.has_key?('gateway')
246
+
247
+ # Null values are represented as "null" in YAML, but Rubyists tend to use "nil", which will get translated
248
+ # to the literal String "nil". Which guarding against this is arguably bad, letting "nil" go through as a valid
249
+ # gateway value is even worse.
250
+ puts "\n\nGateway: #{nic['gateway']}\n\n"
251
+ if nic['gateway'] && nic['gateway'] != 'nil'
252
+ hash['gateway'] = [nic['gateway']]
253
+ end
254
+
255
+ elsif default_nic['gateway']
256
+ hash['gateway'] = [default_nic['gateway']]
257
+ end
258
+
259
+ hash
260
+ end
261
+
262
+ def customization_spec(instance_alias, ip_settings)
263
+ nics = []
264
+
265
+ ip_settings.each do |nic|
266
+ custom_ip_settings = RbVmomi::VIM::CustomizationIPSettings.new(nic)
267
+ custom_ip_settings.ip = RbVmomi::VIM::CustomizationFixedIp("ipAddress" => nic['ip'])
268
+ custom_ip_settings.dnsDomain = env.domain
269
+
270
+ nics << custom_ip_settings
271
+ end
272
+
273
+ custom_global_ip_settings = RbVmomi::VIM::CustomizationGlobalIPSettings.new
274
+ custom_global_ip_settings.dnsServerList = nics.first.dnsServerList
275
+ custom_global_ip_settings.dnsSuffixList = [env.domain]
276
+
277
+ custom_adapter_mapping = nics.collect { |nic| RbVmomi::VIM::CustomizationAdapterMapping.new("adapter" => nic) }
278
+
279
+ custom_prep = RbVmomi::VIM::CustomizationLinuxPrep.new(
280
+ :domain => env.domain,
281
+ :hostName => RbVmomi::VIM::CustomizationFixedName.new(:name => instance_alias))
282
+
283
+ puts "Adapters: #{custom_adapter_mapping}"
284
+
285
+ RbVmomi::VIM::CustomizationSpec.new(:identity => custom_prep,
286
+ :globalIPSettings => custom_global_ip_settings,
287
+ :nicSettingMap => custom_adapter_mapping)
288
+ end
289
+ end
290
+ end
291
+ end
@@ -440,8 +440,8 @@ namespace :rubber do
440
440
  end
441
441
 
442
442
  if instance_item.volumes
443
- value = Capistrano::CLI.ui.ask("Instance has persistent volumes, do you want to destroy them? [y/N]?: ") unless force
444
- if value =~ /^y/ || force
443
+ value = Capistrano::CLI.ui.ask("Instance has persistent volumes, do you want to destroy them? [y/N]?: ") unless force || cloud.should_destroy_volume_when_instance_destroyed?
444
+ if value =~ /^y/ || force || cloud.should_destroy_volume_when_instance_destroyed?
445
445
  instance_item.volumes.clone.each do |volume_id|
446
446
  destroy_volume(volume_id)
447
447
  end
@@ -26,7 +26,15 @@ namespace :rubber do
26
26
  # We special-case the 'ubuntu' user since the Canonical AMIs on EC2 don't set the password for
27
27
  # this account, making any password prompt potentially confusing.
28
28
  orig_password = fetch(:password)
29
- set(:password, initial_ssh_user == 'ubuntu' || ENV.has_key?('RUN_FROM_VAGRANT') ? nil : Capistrano::CLI.password_prompt("Password for #{initial_ssh_user} @ #{ip}: "))
29
+ initial_ssh_password = fetch(:initial_ssh_password, nil)
30
+
31
+ if initial_ssh_user == 'ubuntu' || ENV.has_key?('RUN_FROM_VAGRANT')
32
+ set(:password, nil)
33
+ elsif initial_ssh_password
34
+ set(:password, initial_ssh_password)
35
+ else
36
+ set(:password, Capistrano::CLI.password_prompt("Password for #{initial_ssh_user} @ #{ip}: "))
37
+ end
30
38
 
31
39
  task :_ensure_key_file_present, :hosts => "#{initial_ssh_user}@#{ip}" do
32
40
  public_key_filename = "#{cloud.env.key_file}.pub"
@@ -50,9 +58,19 @@ namespace :rubber do
50
58
  rsudo "mkdir -p /root/.ssh && cp /home/#{initial_ssh_user}/.ssh/authorized_keys /root/.ssh/"
51
59
  end
52
60
 
61
+ task :_disable_password_based_ssh_login, :hosts => "#{initial_ssh_user}@#{ip}" do
62
+ rubber.sudo_script 'disable_password_based_ssh_login', <<-ENDSCRIPT
63
+ if ! grep -q 'PasswordAuthentication no' /etc/ssh/sshd_config; then
64
+ echo 'PasswordAuthentication no' >> /etc/ssh/sshd_config
65
+ service ssh restart
66
+ fi
67
+ ENDSCRIPT
68
+ end
69
+
53
70
  begin
54
71
  _ensure_key_file_present
55
72
  _allow_root_ssh
73
+ _disable_password_based_ssh_login if cloud.should_disable_password_based_ssh_login?
56
74
  rescue ConnectionError => e
57
75
  if e.message =~ /Net::SSH::AuthenticationFailed/
58
76
  logger.info "Can't connect as user #{initial_ssh_user} to #{ip}, assuming root allowed"
@@ -332,7 +350,8 @@ namespace :rubber do
332
350
  core_packages = [
333
351
  'python-software-properties', # Needed for add-apt-repository, which we use for adding PPAs.
334
352
  'bc', # Needed for comparing version numbers in bash, which we do for various setup functions.
335
- 'update-notifier-common' # Needed for notifying us when a package upgrade requires a reboot.
353
+ 'update-notifier-common', # Needed for notifying us when a package upgrade requires a reboot.
354
+ 'scsitools' # Needed to rescan SCSI channels for any added devices.
336
355
  ]
337
356
 
338
357
  rsudo "apt-get -q update"
@@ -38,6 +38,10 @@ namespace :rubber do
38
38
  setup_lvm_group(ic, lvm_volume_group_spec)
39
39
  end
40
40
  end
41
+
42
+ # The act of setting up volumes might blow away previously deployed code, so reset the update state so it can
43
+ # be deployed again if needed.
44
+ set :rubber_code_was_updated, false
41
45
  end
42
46
 
43
47
  desc <<-DESC
@@ -72,26 +76,18 @@ namespace :rubber do
72
76
  detach_volume(volume_id)
73
77
  end
74
78
 
75
- def create_volume(size, zone)
76
- volumeId = cloud.create_volume(size.to_s, zone)
77
- fatal "Failed to create volume" if volumeId.nil?
78
- return volumeId
79
- end
80
-
81
- def attach_volume(vol_id, instance_id, device)
82
- cloud.attach_volume(vol_id, instance_id, device)
83
- end
84
-
85
79
  def setup_volume(ic, vol_spec)
86
80
  created = nil
87
81
  key = "#{ic.name}_#{vol_spec['device']}"
88
82
  artifacts = rubber_instances.artifacts
89
83
  vol_id = artifacts['volumes'][key]
90
84
 
85
+ cloud.before_create_volume(ic, vol_spec)
86
+
91
87
  # first create the volume if we don't have a global record (artifacts) for it
92
88
  if ! vol_id
93
89
  logger.info "Creating volume for #{ic.full_name}:#{vol_spec['device']}"
94
- vol_id = create_volume(vol_spec['size'], vol_spec['zone'])
90
+ vol_id = cloud.create_volume(ic, vol_spec)
95
91
  artifacts['volumes'][key] = vol_id
96
92
  rubber_instances.save
97
93
  created = vol_spec['device']
@@ -101,7 +97,7 @@ namespace :rubber do
101
97
  ic.volumes ||= []
102
98
  if ! ic.volumes.include?(vol_id)
103
99
  logger.info "Attaching volume #{vol_id} to #{ic.full_name}:#{vol_spec['device']}"
104
- attach_volume(vol_id, ic.instance_id, vol_spec['device'])
100
+ cloud.after_create_volume(ic, vol_id, vol_spec)
105
101
  ic.volumes << vol_id
106
102
  rubber_instances.save
107
103
 
@@ -119,13 +115,16 @@ namespace :rubber do
119
115
  # then format/mount/etc if we don't have an entry in hosts file
120
116
  task :_setup_volume, :hosts => ic.external_ip do
121
117
  rubber.sudo_script 'setup_volume', <<-ENDSCRIPT
118
+ # Make sure the newly added volume was found.
119
+ rescan-scsi-bus || true
120
+
122
121
  if ! grep -q '#{vol_spec['mount']}' /etc/fstab; then
123
122
  if mount | grep -q '#{vol_spec['mount']}'; then
124
123
  umount '#{vol_spec['mount']}'
125
124
  fi
126
125
  mv /etc/fstab /etc/fstab.bak
127
126
  cat /etc/fstab.bak | grep -v '#{vol_spec['mount']}' > /etc/fstab
128
- if [ `lsb_release -r -s | sed 's/[.].*//'` -gt "10" ]; then
127
+ if [ #{rubber_env.cloud_provider == 'aws'} && `lsb_release -r -s | sed 's/[.].*//'` -gt "10" ]; then
129
128
  device=`echo #{vol_spec['device']} | sed 's/sd/xvd/'`
130
129
  else
131
130
  device='#{vol_spec['device']}'
@@ -416,11 +415,13 @@ namespace :rubber do
416
415
  end
417
416
 
418
417
  def destroy_volume(volume_id)
419
- detach_volume(volume_id)
418
+ cloud.before_destroy_volume(volume_id)
420
419
 
421
420
  logger.info "Deleting volume #{volume_id}"
422
421
  cloud.destroy_volume(volume_id) rescue logger.info("Volume did not exist in cloud")
423
422
 
423
+ cloud.after_destroy_volume(volume_id)
424
+
424
425
  logger.info "Removing volume #{volume_id} from rubber instances file"
425
426
  artifacts = rubber_instances.artifacts
426
427
  artifacts['volumes'].delete_if {|k,v| v == volume_id}
@@ -1,3 +1,3 @@
1
1
  module Rubber
2
- VERSION = "2.5.5"
2
+ VERSION = "2.6.0"
3
3
  end
@@ -33,7 +33,7 @@ Gem::Specification.new do |s|
33
33
  s.add_dependency 'thor'
34
34
  s.add_dependency 'clamp'
35
35
  s.add_dependency 'open4'
36
- s.add_dependency 'fog', '~> 1.6', '< 1.16.0'
36
+ s.add_dependency 'fog', '~> 1.6'
37
37
  s.add_dependency 'json'
38
38
 
39
39
  s.add_development_dependency('rake')
@@ -12,7 +12,7 @@ packages: [build-essential, git-core, subversion, curl, autoconf, bison, ruby, z
12
12
 
13
13
  # REQUIRED: The version of ruby-build to use for building ruby.
14
14
  # It must be one of the versions from https://github.com/sstephenson/ruby-build/blob/master/CHANGELOG.md
15
- ruby_build_version: 20130923
15
+ ruby_build_version: 20131030
16
16
 
17
17
  # REQUIRED: Set to the version string for the ruby version you wish to use
18
18
  # Run "ruby-build --definitions" to see the list of possible options or look through the list of
@@ -3,7 +3,7 @@
3
3
  %>
4
4
 
5
5
  <%= Rubber.env %>:
6
- adapter: <%= YAML::load(File.open("#{Rubber.root}/config/database.yml"))["production"]["adapter"] %>
6
+ adapter: <%= YAML::load(File.open("#{Rubber.root}/config/database.yml"))[Rubber.env]["adapter"] %>
7
7
  encoding: utf8
8
8
  database: <%= rubber_env.db_name %>
9
9
  username: <%= rubber_env.db_user %>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubber
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.5
4
+ version: 2.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Conway
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-16 00:00:00.000000000 Z
12
+ date: 2013-11-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: capistrano
@@ -88,9 +88,6 @@ dependencies:
88
88
  - - ~>
89
89
  - !ruby/object:Gem::Version
90
90
  version: '1.6'
91
- - - <
92
- - !ruby/object:Gem::Version
93
- version: 1.16.0
94
91
  type: :runtime
95
92
  prerelease: false
96
93
  version_requirements: !ruby/object:Gem::Requirement
@@ -98,9 +95,6 @@ dependencies:
98
95
  - - ~>
99
96
  - !ruby/object:Gem::Version
100
97
  version: '1.6'
101
- - - <
102
- - !ruby/object:Gem::Version
103
- version: 1.16.0
104
98
  - !ruby/object:Gem::Dependency
105
99
  name: json
106
100
  requirement: !ruby/object:Gem::Requirement
@@ -223,6 +217,7 @@ files:
223
217
  - lib/rubber/cloud/fog_storage.rb
224
218
  - lib/rubber/cloud/generic.rb
225
219
  - lib/rubber/cloud/vagrant.rb
220
+ - lib/rubber/cloud/vsphere.rb
226
221
  - lib/rubber/commands/config.rb
227
222
  - lib/rubber/commands/cron.rb
228
223
  - lib/rubber/commands/util.rb