bosh_aws_cpi 1.2624.0 → 1.2640.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.
- checksums.yaml +7 -0
- data/lib/cloud/aws/instance_manager.rb +3 -55
- data/lib/cloud/aws/spot_manager.rb +127 -0
- data/lib/cloud/aws/version.rb +1 -1
- data/lib/cloud/aws.rb +1 -0
- metadata +28 -44
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: c1b37050bd67d039345b8b90bf88c0e868aacd3e
|
|
4
|
+
data.tar.gz: a28a34c9e788be45602aea0374f5c26341097b36
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 6e5a5175fa211acd62d96f28d206af92b92a8ed71e411560f20652f529a713c6a39889db9922668b43379edd4e724d0f4bfbfbca200a3eac2bdb79f0deda4d7c
|
|
7
|
+
data.tar.gz: f9c44f0e8cb3f1d9e5d4be9e27aecb38d7ae0ae5bf65890bb76a6d283d87de38ff69766ad14652291e68da2eedb3e164427799a9af6f20d82a1e6484756921b7
|
|
@@ -34,16 +34,8 @@ module Bosh::AwsCloud
|
|
|
34
34
|
|
|
35
35
|
if resource_pool["spot_bid_price"]
|
|
36
36
|
@logger.info("Launching spot instance...")
|
|
37
|
-
|
|
38
|
-
@
|
|
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
|
-
wait_for_spot_instance_request_to_be_active spot_instance_requests
|
|
37
|
+
spot_manager = Bosh::AwsCloud::SpotManager.new(@region)
|
|
38
|
+
@instance = spot_manager.create(instance_params, resource_pool["spot_bid_price"])
|
|
47
39
|
else
|
|
48
40
|
# Retry the create instance operation a couple of times if we are told that the IP
|
|
49
41
|
# address is in use - it can happen when the director recreates a VM and AWS
|
|
@@ -76,50 +68,6 @@ module Bosh::AwsCloud
|
|
|
76
68
|
instance
|
|
77
69
|
end
|
|
78
70
|
|
|
79
|
-
def create_spot_request_spec(instance_params, security_group_ids, spot_price) {
|
|
80
|
-
spot_price: "#{spot_price}",
|
|
81
|
-
instance_count: 1,
|
|
82
|
-
valid_until: "#{(Time.now + 20*60).utc.iso8601}",
|
|
83
|
-
launch_specification: {
|
|
84
|
-
image_id: instance_params[:image_id],
|
|
85
|
-
key_name: instance_params[:key_name],
|
|
86
|
-
instance_type: instance_params[:instance_type],
|
|
87
|
-
user_data: Base64.encode64(instance_params[:user_data]),
|
|
88
|
-
placement: {
|
|
89
|
-
availability_zone: instance_params[:availability_zone]
|
|
90
|
-
},
|
|
91
|
-
network_interfaces: [
|
|
92
|
-
{
|
|
93
|
-
subnet_id: instance_params[:subnet].subnet_id,
|
|
94
|
-
groups: security_group_ids,
|
|
95
|
-
device_index: 0,
|
|
96
|
-
private_ip_address: instance_params[:private_ip_address]
|
|
97
|
-
}
|
|
98
|
-
]
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def wait_for_spot_instance_request_to_be_active(spot_instance_requests)
|
|
104
|
-
# Query the spot request state until it becomes "active".
|
|
105
|
-
# This can result in the errors listed below; this is normally because AWS has
|
|
106
|
-
# been slow to update its state so the correct response is to wait a bit and try again.
|
|
107
|
-
errors = [AWS::EC2::Errors::InvalidSpotInstanceRequestID::NotFound]
|
|
108
|
-
Bosh::Common.retryable(sleep: instance_create_wait_time*2, tries: 20, on: errors) do |tries, error|
|
|
109
|
-
@logger.warn("Retrying after expected error: #{error}") if error
|
|
110
|
-
@logger.debug("Checking state of spot instance requests...")
|
|
111
|
-
spot_instance_request_ids = spot_instance_requests[:spot_instance_request_set].map { |r| r[:spot_instance_request_id] }
|
|
112
|
-
response = @region.client.describe_spot_instance_requests(:spot_instance_request_ids => spot_instance_request_ids)
|
|
113
|
-
statuses = response[:spot_instance_request_set].map { |rr| rr[:state] }
|
|
114
|
-
@logger.debug("Spot instance request states: #{statuses.inspect}")
|
|
115
|
-
if statuses.all? { |s| s == 'active' }
|
|
116
|
-
@logger.info("Spot request instances fulfilled: #{response.inspect}")
|
|
117
|
-
instance_id = response[:spot_instance_request_set].map { |rr| rr[:instance_id] }[0]
|
|
118
|
-
@instance = @region.instances[instance_id]
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
|
|
123
71
|
def terminate(instance_id, fast=false)
|
|
124
72
|
@instance = @region.instances[instance_id]
|
|
125
73
|
|
|
@@ -241,4 +189,4 @@ module Bosh::AwsCloud
|
|
|
241
189
|
|
|
242
190
|
def instance_create_wait_time; 30; end
|
|
243
191
|
end
|
|
244
|
-
end
|
|
192
|
+
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
require "common/common"
|
|
2
|
+
require "time"
|
|
3
|
+
|
|
4
|
+
module Bosh::AwsCloud
|
|
5
|
+
class SpotManager
|
|
6
|
+
TOTAL_WAIT_TIME_IN_SECONDS = 300
|
|
7
|
+
RETRY_COUNT = 10
|
|
8
|
+
|
|
9
|
+
def initialize(region)
|
|
10
|
+
@region = region
|
|
11
|
+
@logger = Bosh::Clouds::Config.logger
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def create(instance_params, spot_bid_price)
|
|
15
|
+
spot_request_spec = create_spot_request_spec(instance_params, spot_bid_price)
|
|
16
|
+
@logger.debug("Requesting spot instance with: #{spot_request_spec.inspect}")
|
|
17
|
+
|
|
18
|
+
begin
|
|
19
|
+
@spot_instance_requests = @region.client.request_spot_instances(spot_request_spec)
|
|
20
|
+
@logger.debug("Got spot instance requests: #{@spot_instance_requests.inspect}")
|
|
21
|
+
rescue => e
|
|
22
|
+
raise Bosh::Clouds::VMCreationFailed.new(false), e.inspect
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
request_spot_instance
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def request_spot_instance
|
|
31
|
+
instance = nil
|
|
32
|
+
|
|
33
|
+
# Query the spot request state until it becomes "active".
|
|
34
|
+
# This can result in the errors listed below; this is normally because AWS has
|
|
35
|
+
# been slow to update its state so the correct response is to wait a bit and try again.
|
|
36
|
+
errors = [AWS::EC2::Errors::InvalidSpotInstanceRequestID::NotFound]
|
|
37
|
+
Bosh::Common.retryable(sleep: TOTAL_WAIT_TIME_IN_SECONDS/RETRY_COUNT, tries: RETRY_COUNT, on: errors) do |_, error|
|
|
38
|
+
@logger.warn("Retrying after expected error: #{error}") if error
|
|
39
|
+
|
|
40
|
+
status = spot_instance_request_status
|
|
41
|
+
case status[:state]
|
|
42
|
+
when 'failed'
|
|
43
|
+
fail_spot_creation("VM spot instance creation failed: #{status.inspect}")
|
|
44
|
+
when 'open'
|
|
45
|
+
if status[:status] != nil && status[:status][:code] == 'price-too-low'
|
|
46
|
+
fail_spot_creation("Cannot create VM spot instance because bid price is too low: #{status.inspect}")
|
|
47
|
+
end
|
|
48
|
+
when 'active'
|
|
49
|
+
@logger.info("Spot request instances fulfilled: #{status.inspect}")
|
|
50
|
+
instance = @region.instances[status[:instance_id]]
|
|
51
|
+
true
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
instance
|
|
56
|
+
rescue Bosh::Common::RetryCountExceeded
|
|
57
|
+
@logger.warn("Timed out waiting for spot request #{@spot_instance_requests.inspect} to be fulfilled")
|
|
58
|
+
cancel_pending_spot_requests
|
|
59
|
+
raise Bosh::Clouds::VMCreationFailed.new(true)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def create_spot_request_spec(instance_params, spot_price)
|
|
63
|
+
spec = {
|
|
64
|
+
spot_price: "#{spot_price}",
|
|
65
|
+
instance_count: 1,
|
|
66
|
+
launch_specification: {
|
|
67
|
+
image_id: instance_params[:image_id],
|
|
68
|
+
key_name: instance_params[:key_name],
|
|
69
|
+
instance_type: instance_params[:instance_type],
|
|
70
|
+
user_data: Base64.encode64(instance_params[:user_data]),
|
|
71
|
+
placement: {
|
|
72
|
+
availability_zone: instance_params[:availability_zone]
|
|
73
|
+
},
|
|
74
|
+
network_interfaces: [
|
|
75
|
+
{
|
|
76
|
+
subnet_id: instance_params[:subnet].subnet_id,
|
|
77
|
+
device_index: 0,
|
|
78
|
+
private_ip_address: instance_params[:private_ip_address]
|
|
79
|
+
}
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
security_groups = resolve_security_group_ids(instance_params[:security_groups])
|
|
84
|
+
unless security_groups.empty?
|
|
85
|
+
spec[:launch_specification][:network_interfaces][0][:groups] = security_groups
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
spec
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def spot_instance_request_status
|
|
92
|
+
@logger.debug('Checking state of spot instance requests...')
|
|
93
|
+
response = @region.client.describe_spot_instance_requests(
|
|
94
|
+
spot_instance_request_ids: spot_instance_request_ids
|
|
95
|
+
)
|
|
96
|
+
status = response[:spot_instance_request_set][0] # There is only ever 1
|
|
97
|
+
@logger.debug("Spot instance request status: #{status.inspect}")
|
|
98
|
+
status
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def fail_spot_creation(message)
|
|
102
|
+
@logger.error(message)
|
|
103
|
+
cancel_pending_spot_requests
|
|
104
|
+
raise Bosh::Clouds::VMCreationFailed.new(false), message
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def spot_instance_request_ids
|
|
108
|
+
@spot_instance_requests[:spot_instance_request_set].map { |r| r[:spot_instance_request_id] }
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def cancel_pending_spot_requests
|
|
112
|
+
@logger.warn("Failed to create spot instance: #{@spot_instance_requests.inspect}. Cancelling request...")
|
|
113
|
+
cancel_response = @region.client.cancel_spot_instance_requests(
|
|
114
|
+
spot_instance_request_ids: spot_instance_request_ids
|
|
115
|
+
)
|
|
116
|
+
@logger.warn("Spot cancel request returned: #{cancel_response.inspect}")
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def resolve_security_group_ids(security_group_names)
|
|
120
|
+
return [] unless security_group_names
|
|
121
|
+
@region.security_groups.inject([]) do |security_group_ids, group|
|
|
122
|
+
security_group_ids << group.security_group_id if security_group_names.include?(group.name)
|
|
123
|
+
security_group_ids
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
data/lib/cloud/aws/version.rb
CHANGED
data/lib/cloud/aws.rb
CHANGED
|
@@ -32,6 +32,7 @@ require "cloud/aws/dynamic_network"
|
|
|
32
32
|
require "cloud/aws/manual_network"
|
|
33
33
|
require "cloud/aws/vip_network"
|
|
34
34
|
require "cloud/aws/instance_manager"
|
|
35
|
+
require "cloud/aws/spot_manager"
|
|
35
36
|
require "cloud/aws/tag_manager"
|
|
36
37
|
require "cloud/aws/availability_zone_selector"
|
|
37
38
|
require "cloud/aws/resource_wait"
|
metadata
CHANGED
|
@@ -1,84 +1,74 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bosh_aws_cpi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
5
|
-
prerelease:
|
|
4
|
+
version: 1.2640.0
|
|
6
5
|
platform: ruby
|
|
7
6
|
authors:
|
|
8
7
|
- VMware
|
|
9
8
|
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date: 2014-07-
|
|
11
|
+
date: 2014-07-08 00:00:00.000000000 Z
|
|
13
12
|
dependencies:
|
|
14
13
|
- !ruby/object:Gem::Dependency
|
|
15
14
|
name: aws-sdk
|
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
|
17
|
-
none: false
|
|
18
16
|
requirements:
|
|
19
17
|
- - '='
|
|
20
18
|
- !ruby/object:Gem::Version
|
|
21
|
-
version: 1.
|
|
19
|
+
version: 1.44.0
|
|
22
20
|
type: :runtime
|
|
23
21
|
prerelease: false
|
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
-
none: false
|
|
26
23
|
requirements:
|
|
27
24
|
- - '='
|
|
28
25
|
- !ruby/object:Gem::Version
|
|
29
|
-
version: 1.
|
|
26
|
+
version: 1.44.0
|
|
30
27
|
- !ruby/object:Gem::Dependency
|
|
31
28
|
name: bosh_common
|
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
|
33
|
-
none: false
|
|
34
30
|
requirements:
|
|
35
|
-
- - ~>
|
|
31
|
+
- - "~>"
|
|
36
32
|
- !ruby/object:Gem::Version
|
|
37
|
-
version: 1.
|
|
33
|
+
version: 1.2640.0
|
|
38
34
|
type: :runtime
|
|
39
35
|
prerelease: false
|
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
-
none: false
|
|
42
37
|
requirements:
|
|
43
|
-
- - ~>
|
|
38
|
+
- - "~>"
|
|
44
39
|
- !ruby/object:Gem::Version
|
|
45
|
-
version: 1.
|
|
40
|
+
version: 1.2640.0
|
|
46
41
|
- !ruby/object:Gem::Dependency
|
|
47
42
|
name: bosh_cpi
|
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
|
49
|
-
none: false
|
|
50
44
|
requirements:
|
|
51
|
-
- - ~>
|
|
45
|
+
- - "~>"
|
|
52
46
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: 1.
|
|
47
|
+
version: 1.2640.0
|
|
54
48
|
type: :runtime
|
|
55
49
|
prerelease: false
|
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
-
none: false
|
|
58
51
|
requirements:
|
|
59
|
-
- - ~>
|
|
52
|
+
- - "~>"
|
|
60
53
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: 1.
|
|
54
|
+
version: 1.2640.0
|
|
62
55
|
- !ruby/object:Gem::Dependency
|
|
63
56
|
name: bosh-registry
|
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
|
65
|
-
none: false
|
|
66
58
|
requirements:
|
|
67
|
-
- - ~>
|
|
59
|
+
- - "~>"
|
|
68
60
|
- !ruby/object:Gem::Version
|
|
69
|
-
version: 1.
|
|
61
|
+
version: 1.2640.0
|
|
70
62
|
type: :runtime
|
|
71
63
|
prerelease: false
|
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
-
none: false
|
|
74
65
|
requirements:
|
|
75
|
-
- - ~>
|
|
66
|
+
- - "~>"
|
|
76
67
|
- !ruby/object:Gem::Version
|
|
77
|
-
version: 1.
|
|
68
|
+
version: 1.2640.0
|
|
78
69
|
- !ruby/object:Gem::Dependency
|
|
79
70
|
name: httpclient
|
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
|
81
|
-
none: false
|
|
82
72
|
requirements:
|
|
83
73
|
- - '='
|
|
84
74
|
- !ruby/object:Gem::Version
|
|
@@ -86,7 +76,6 @@ dependencies:
|
|
|
86
76
|
type: :runtime
|
|
87
77
|
prerelease: false
|
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
89
|
-
none: false
|
|
90
79
|
requirements:
|
|
91
80
|
- - '='
|
|
92
81
|
- !ruby/object:Gem::Version
|
|
@@ -94,28 +83,27 @@ dependencies:
|
|
|
94
83
|
- !ruby/object:Gem::Dependency
|
|
95
84
|
name: yajl-ruby
|
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
|
97
|
-
none: false
|
|
98
86
|
requirements:
|
|
99
|
-
- -
|
|
87
|
+
- - ">="
|
|
100
88
|
- !ruby/object:Gem::Version
|
|
101
89
|
version: 0.8.2
|
|
102
90
|
type: :runtime
|
|
103
91
|
prerelease: false
|
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
105
|
-
none: false
|
|
106
93
|
requirements:
|
|
107
|
-
- -
|
|
94
|
+
- - ">="
|
|
108
95
|
- !ruby/object:Gem::Version
|
|
109
96
|
version: 0.8.2
|
|
110
|
-
description:
|
|
111
|
-
|
|
112
|
-
|
|
97
|
+
description: |-
|
|
98
|
+
BOSH AWS CPI
|
|
99
|
+
986896
|
|
113
100
|
email: support@cloudfoundry.com
|
|
114
101
|
executables:
|
|
115
102
|
- bosh_aws_console
|
|
116
103
|
extensions: []
|
|
117
104
|
extra_rdoc_files: []
|
|
118
105
|
files:
|
|
106
|
+
- README.md
|
|
119
107
|
- bin/bosh_aws_console
|
|
120
108
|
- lib/bosh_aws_cpi.rb
|
|
121
109
|
- lib/cloud/aws.rb
|
|
@@ -130,6 +118,7 @@ files:
|
|
|
130
118
|
- lib/cloud/aws/network.rb
|
|
131
119
|
- lib/cloud/aws/network_configurator.rb
|
|
132
120
|
- lib/cloud/aws/resource_wait.rb
|
|
121
|
+
- lib/cloud/aws/spot_manager.rb
|
|
133
122
|
- lib/cloud/aws/stemcell.rb
|
|
134
123
|
- lib/cloud/aws/stemcell_creator.rb
|
|
135
124
|
- lib/cloud/aws/stemcell_finder.rb
|
|
@@ -137,33 +126,28 @@ files:
|
|
|
137
126
|
- lib/cloud/aws/version.rb
|
|
138
127
|
- lib/cloud/aws/vip_network.rb
|
|
139
128
|
- scripts/stemcell-copy.sh
|
|
140
|
-
- README.md
|
|
141
129
|
homepage: https://github.com/cloudfoundry/bosh
|
|
142
130
|
licenses:
|
|
143
131
|
- Apache 2.0
|
|
132
|
+
metadata: {}
|
|
144
133
|
post_install_message:
|
|
145
134
|
rdoc_options: []
|
|
146
135
|
require_paths:
|
|
147
136
|
- lib
|
|
148
137
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
149
|
-
none: false
|
|
150
138
|
requirements:
|
|
151
|
-
- -
|
|
139
|
+
- - ">="
|
|
152
140
|
- !ruby/object:Gem::Version
|
|
153
141
|
version: 1.9.3
|
|
154
142
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
155
|
-
none: false
|
|
156
143
|
requirements:
|
|
157
|
-
- -
|
|
144
|
+
- - ">="
|
|
158
145
|
- !ruby/object:Gem::Version
|
|
159
146
|
version: '0'
|
|
160
|
-
segments:
|
|
161
|
-
- 0
|
|
162
|
-
hash: 3736547469633169504
|
|
163
147
|
requirements: []
|
|
164
148
|
rubyforge_project:
|
|
165
|
-
rubygems_version:
|
|
149
|
+
rubygems_version: 2.2.2
|
|
166
150
|
signing_key:
|
|
167
|
-
specification_version:
|
|
151
|
+
specification_version: 4
|
|
168
152
|
summary: BOSH AWS CPI
|
|
169
153
|
test_files: []
|