bosh_aws_cpi 1.2068.0 → 1.2086.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.
data/README.md CHANGED
@@ -55,6 +55,8 @@ These options are specified under `cloud_options` in the `resource_pools` sectio
55
55
  the EC2 availability zone the VMs should be created in
56
56
  * `instance_type` (required)
57
57
  which [type of instance](http://aws.amazon.com/ec2/instance-types/) the VMs should belong to
58
+ * `spot_bid_price` (optional)
59
+ the [AWS spot instance](http://aws.amazon.com/ec2/purchasing-options/spot-instances/) bid price to use. When specified spot instances are started rather than on demand instances. _NB: this will dramatically slow down resource pool creation._
58
60
 
59
61
  ### Network options
60
62
 
@@ -1,4 +1,5 @@
1
1
  require "common/common"
2
+ require "time"
2
3
 
3
4
  module Bosh::AwsCloud
4
5
  class InstanceManager
@@ -28,18 +29,44 @@ module Bosh::AwsCloud
28
29
  resource_pool["availability_zone"],
29
30
  (@instance_params[:subnet].availability_zone_name if @instance_params[:subnet])
30
31
  )
31
-
32
+
32
33
  @logger.info("Creating new instance with: #{instance_params.inspect}")
33
-
34
- # Retry the create instance operation a couple of times if we are told that the IP
35
- # address is in use - it can happen when the director recreates a VM and AWS
36
- # is too slow to update its state when we have released the IP address and want to
37
- # realocate it again.
38
- errors = [AWS::EC2::Errors::InvalidIPAddress::InUse]
39
- Bosh::Common.retryable(sleep: instance_create_wait_time, tries: 10, on: errors) do |tries, error|
40
- @logger.warn("IP address was in use: #{error}") if tries > 0
41
- @instance = @region.instances.create(instance_params)
42
- end
34
+
35
+ if resource_pool["spot_bid_price"]
36
+ @logger.info("Launching spot instance...")
37
+ security_group_ids = []
38
+ @region.security_groups.each do |group|
39
+ security_group_ids << group.security_group_id if @instance_params[:security_groups].include?(group.name)
40
+ end
41
+ spot_request_spec = create_spot_request_spec(instance_params, security_group_ids, resource_pool["spot_bid_price"])
42
+ @logger.debug("Requesting spot instance with: #{spot_request_spec.inspect}")
43
+ spot_instance_requests = @region.client.request_spot_instances(spot_request_spec)
44
+ @logger.debug("Got spot instance requests: #{spot_instance_requests.inspect}")
45
+
46
+ Bosh::Common.retryable(sleep: instance_create_wait_time*2, tries: 20) do |tries, error|
47
+ @logger.debug("Checking state of spot instance requests...")
48
+ spot_instance_request_ids = spot_instance_requests[:spot_instance_request_set].map { |r| r[:spot_instance_request_id] }
49
+ response = @region.client.describe_spot_instance_requests(:spot_instance_request_ids => spot_instance_request_ids)
50
+ statuses = response[:spot_instance_request_set].map { |rr| rr[:state] }
51
+ @logger.debug("Spot instance request states: #{statuses.inspect}")
52
+ if statuses.all? { |s| s == 'active' }
53
+ @logger.info("Spot request instances fulfilled: #{response.inspect}")
54
+ instance_id = response[:spot_instance_request_set].map { |rr| rr[:instance_id] }[0]
55
+ @instance = @region.instances[instance_id]
56
+ end
57
+ end
58
+ else
59
+ # Retry the create instance operation a couple of times if we are told that the IP
60
+ # address is in use - it can happen when the director recreates a VM and AWS
61
+ # is too slow to update its state when we have released the IP address and want to
62
+ # realocate it again.
63
+ errors = [AWS::EC2::Errors::InvalidIPAddress::InUse]
64
+ Bosh::Common.retryable(sleep: instance_create_wait_time, tries: 10, on: errors) do |tries, error|
65
+ @logger.info("Launching on demand instance...")
66
+ @logger.warn("IP address was in use: #{error}") if tries > 0
67
+ @instance = @region.instances.create(instance_params)
68
+ end
69
+ end
43
70
 
44
71
  # We need to wait here for the instance to be running, as if we are going to
45
72
  # attach to a load balancer, the instance must be running.
@@ -47,6 +74,7 @@ module Bosh::AwsCloud
47
74
  # so we signal the director that it is ok to retry the operation. At the moment this
48
75
  # forever (until the operation is cancelled by the user).
49
76
  begin
77
+ @logger.info("Waiting for instance to be ready...")
50
78
  ResourceWait.for_instance(instance: instance, state: :running)
51
79
  rescue Bosh::Common::RetryCountExceeded => e
52
80
  @logger.warn("timed out waiting for #{instance.id} to be running")
@@ -59,6 +87,30 @@ module Bosh::AwsCloud
59
87
  instance
60
88
  end
61
89
 
90
+ def create_spot_request_spec(instance_params, security_group_ids, spot_price) {
91
+ spot_price: "#{spot_price}",
92
+ instance_count: 1,
93
+ valid_until: "#{(Time.now + 20*60).utc.iso8601}",
94
+ launch_specification: {
95
+ image_id: instance_params[:image_id],
96
+ key_name: instance_params[:key_name],
97
+ instance_type: instance_params[:instance_type],
98
+ user_data: Base64.encode64(instance_params[:user_data]),
99
+ placement: {
100
+ availability_zone: instance_params[:availability_zone]
101
+ },
102
+ network_interfaces: [
103
+ {
104
+ subnet_id: instance_params[:subnet].subnet_id,
105
+ groups: security_group_ids,
106
+ device_index: 0,
107
+ private_ip_address: instance_params[:private_ip_address]
108
+ }
109
+ ]
110
+ }
111
+ }
112
+ end
113
+
62
114
  def terminate(instance_id, fast=false)
63
115
  @instance = @region.instances[instance_id]
64
116
 
@@ -173,4 +225,4 @@ module Bosh::AwsCloud
173
225
 
174
226
  def instance_create_wait_time; 30; end
175
227
  end
176
- end
228
+ end
@@ -1,5 +1,5 @@
1
1
  module Bosh
2
2
  module AwsCloud
3
- VERSION = '1.2068.0'
3
+ VERSION = '1.2086.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bosh_aws_cpi
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2068.0
4
+ version: 1.2086.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-02-26 00:00:00.000000000 Z
12
+ date: 2014-02-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: aws-sdk
@@ -18,7 +18,7 @@ dependencies:
18
18
  requirements:
19
19
  - - '='
20
20
  - !ruby/object:Gem::Version
21
- version: 1.8.5
21
+ version: 1.32.0
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - '='
28
28
  - !ruby/object:Gem::Version
29
- version: 1.8.5
29
+ version: 1.32.0
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: bosh_common
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -34,7 +34,7 @@ dependencies:
34
34
  requirements:
35
35
  - - ~>
36
36
  - !ruby/object:Gem::Version
37
- version: 1.2068.0
37
+ version: 1.2086.0
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
@@ -42,7 +42,7 @@ dependencies:
42
42
  requirements:
43
43
  - - ~>
44
44
  - !ruby/object:Gem::Version
45
- version: 1.2068.0
45
+ version: 1.2086.0
46
46
  - !ruby/object:Gem::Dependency
47
47
  name: bosh_cpi
48
48
  requirement: !ruby/object:Gem::Requirement
@@ -50,7 +50,7 @@ dependencies:
50
50
  requirements:
51
51
  - - ~>
52
52
  - !ruby/object:Gem::Version
53
- version: 1.2068.0
53
+ version: 1.2086.0
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
@@ -58,7 +58,7 @@ dependencies:
58
58
  requirements:
59
59
  - - ~>
60
60
  - !ruby/object:Gem::Version
61
- version: 1.2068.0
61
+ version: 1.2086.0
62
62
  - !ruby/object:Gem::Dependency
63
63
  name: bosh-registry
64
64
  requirement: !ruby/object:Gem::Requirement
@@ -66,7 +66,7 @@ dependencies:
66
66
  requirements:
67
67
  - - ~>
68
68
  - !ruby/object:Gem::Version
69
- version: 1.2068.0
69
+ version: 1.2086.0
70
70
  type: :runtime
71
71
  prerelease: false
72
72
  version_requirements: !ruby/object:Gem::Requirement
@@ -74,7 +74,7 @@ dependencies:
74
74
  requirements:
75
75
  - - ~>
76
76
  - !ruby/object:Gem::Version
77
- version: 1.2068.0
77
+ version: 1.2086.0
78
78
  - !ruby/object:Gem::Dependency
79
79
  name: httpclient
80
80
  requirement: !ruby/object:Gem::Requirement
@@ -109,7 +109,7 @@ dependencies:
109
109
  version: 0.8.2
110
110
  description: ! 'BOSH AWS CPI
111
111
 
112
- 5f63a5'
112
+ 8d26be'
113
113
  email: support@cloudfoundry.com
114
114
  executables:
115
115
  - bosh_aws_console
@@ -159,7 +159,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
159
159
  version: '0'
160
160
  segments:
161
161
  - 0
162
- hash: -3022178171211182225
162
+ hash: -1292915204302962026
163
163
  requirements: []
164
164
  rubyforge_project:
165
165
  rubygems_version: 1.8.23