bosh_aws_cpi 1.2068.0 → 1.2086.0

Sign up to get free protection for your applications and to get access to all the features.
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