vagrant-aws-mkubenka 0.7.2.pre.11 → 0.7.2.pre.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +7 -1
- data/lib/vagrant-aws/action/run_instance.rb +86 -1
- data/lib/vagrant-aws/config.rb +37 -2
- data/locales/en.yml +3 -1
- data/spec/vagrant-aws/config_spec.rb +4 -0
- data/vendor/bundle/ruby/2.3.0/bundler/gems/vagrant-5333e60e2d38/vagrant.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 57caf99fd4244bccd66fc088a92a36db978117d9
|
4
|
+
data.tar.gz: 313a558229f08330b0dc222f4ab3d3a30170d4cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d9214a0339db2a2e2a539eff94f423c8c1d789560f668d7ddb0c1d599a4dfafb13e5d7b8678dd6d0f55a84f061d759460f027bf11ecd9387bf02bdb89b7fbfbe
|
7
|
+
data.tar.gz: ab5dd8f185416140587b0507e994ac7e828f8076d8d23028bf805bdd3c12b2c16b14ee5b2096b655e371cfaaf48796f420535734b792a03661b3b1c8d213ff1a
|
data/README.md
CHANGED
@@ -18,6 +18,7 @@ EC2 and VPC.
|
|
18
18
|
* Define region-specific configurations so Vagrant can manage machines
|
19
19
|
in multiple regions.
|
20
20
|
* Package running instances into new vagrant-aws friendly boxes
|
21
|
+
* Spot Instance Support
|
21
22
|
|
22
23
|
## Usage
|
23
24
|
|
@@ -26,7 +27,7 @@ installing, `vagrant up` and specify the `aws` provider. An example is
|
|
26
27
|
shown below.
|
27
28
|
|
28
29
|
```
|
29
|
-
$ vagrant plugin install vagrant-aws
|
30
|
+
$ vagrant plugin install vagrant-aws-mkubenka
|
30
31
|
...
|
31
32
|
$ vagrant up --provider=aws
|
32
33
|
...
|
@@ -164,6 +165,11 @@ This provider exposes quite a few provider-specific configuration options:
|
|
164
165
|
when you initiate shutdown from the instance.
|
165
166
|
* `endpoint` - The endpoint URL for connecting to AWS (or an AWS-like service). Only required for non AWS clouds, such as [eucalyptus](https://github.com/eucalyptus/eucalyptus/wiki).
|
166
167
|
|
168
|
+
* `spot_instance` - Boolean value; indicates whether the config is for a spot instance, or on-demand. For more information about spot instances, see the [AWS Documentation](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/how-spot-instances-work.html)
|
169
|
+
* `spot_max_price` - Decimal value; state the maximum bid for your spot instance. If nil, it will compute average price in `region` for selected `instance_type`.
|
170
|
+
* `spot_price_product_description` - The product description for the spot price history used to compute average price. Defaults to 'Linux/UNIX'.
|
171
|
+
* `spot_valid_until` - Timestamp; when this spot instance request should expire, destroying any related instances. Ignored if `spot_instance` is not true.
|
172
|
+
|
167
173
|
These can be set like typical provider-specific configuration:
|
168
174
|
|
169
175
|
```ruby
|
@@ -107,7 +107,11 @@ module VagrantPlugins
|
|
107
107
|
end
|
108
108
|
|
109
109
|
begin
|
110
|
-
server =
|
110
|
+
server = if region_config.spot_instance
|
111
|
+
server_from_spot_request(env, region_config, options)
|
112
|
+
else
|
113
|
+
env[:aws_compute].servers.create(options)
|
114
|
+
end
|
111
115
|
rescue Fog::Compute::AWS::NotFound => e
|
112
116
|
# Invalid subnet doesn't have its own error so we catch and
|
113
117
|
# check the error message here.
|
@@ -212,6 +216,87 @@ module VagrantPlugins
|
|
212
216
|
@app.call(env)
|
213
217
|
end
|
214
218
|
|
219
|
+
# returns a fog server or nil
|
220
|
+
def server_from_spot_request(env, config, options)
|
221
|
+
if config.spot_max_price.nil?
|
222
|
+
spot_price_current = env[:aws_compute].describe_spot_price_history({
|
223
|
+
'StartTime' => Time.now.iso8601,
|
224
|
+
'EndTime' => Time.now.iso8601,
|
225
|
+
'InstanceType' => [config.instance_type],
|
226
|
+
'ProductDescription' => [config.spot_price_product_description.nil? ? 'Linux/UNIX' : config.spot_price_product_description]
|
227
|
+
})
|
228
|
+
|
229
|
+
spot_price_current.body['spotPriceHistorySet'].each do |set|
|
230
|
+
(@price_set ||= []) << set['spotPrice'].to_f
|
231
|
+
end
|
232
|
+
|
233
|
+
if @price_set.nil?
|
234
|
+
raise Errors::FogError,
|
235
|
+
:message => "Could not find any history spot prices."
|
236
|
+
end
|
237
|
+
|
238
|
+
avg_price = @price_set.inject(0.0) { |sum, el| sum + el } / @price_set.size
|
239
|
+
|
240
|
+
# make the bid 10% higher than the average
|
241
|
+
price = (avg_price * 1.1).round(4)
|
242
|
+
else
|
243
|
+
price = config.spot_max_price
|
244
|
+
end
|
245
|
+
|
246
|
+
options.merge!({
|
247
|
+
:price => price,
|
248
|
+
:valid_until => config.spot_valid_until
|
249
|
+
})
|
250
|
+
|
251
|
+
env[:ui].info(I18n.t("vagrant_aws.launching_spot_instance"))
|
252
|
+
env[:ui].info(" -- Price: #{price}")
|
253
|
+
env[:ui].info(" -- Valid until: #{config.spot_valid_until}") if config.spot_valid_until
|
254
|
+
|
255
|
+
# create the spot instance
|
256
|
+
spot_req = env[:aws_compute].spot_requests.create(options)
|
257
|
+
|
258
|
+
@logger.info("Spot request ID: #{spot_req.id}")
|
259
|
+
|
260
|
+
# initialize state
|
261
|
+
status_code = ""
|
262
|
+
while true
|
263
|
+
sleep 5
|
264
|
+
|
265
|
+
spot_req.reload()
|
266
|
+
|
267
|
+
# display something whenever the status code changes
|
268
|
+
if status_code != spot_req.state
|
269
|
+
env[:ui].info(spot_req.fault)
|
270
|
+
status_code = spot_req.state
|
271
|
+
end
|
272
|
+
spot_state = spot_req.state.to_sym
|
273
|
+
case spot_state
|
274
|
+
when :not_created, :open
|
275
|
+
@logger.debug("Spot request #{spot_state} #{status_code}, waiting")
|
276
|
+
when :active
|
277
|
+
break; # :)
|
278
|
+
when :closed, :cancelled, :failed
|
279
|
+
msg = "Spot request #{spot_state} #{status_code}, aborting"
|
280
|
+
@logger.error(msg)
|
281
|
+
raise Errors::FogError, :message => msg
|
282
|
+
else
|
283
|
+
@logger.debug("Unknown spot state #{spot_state} #{status_code}, waiting")
|
284
|
+
end
|
285
|
+
end
|
286
|
+
# cancel the spot request but let the server go thru
|
287
|
+
spot_req.destroy()
|
288
|
+
|
289
|
+
server = env[:aws_compute].servers.get(spot_req.instance_id)
|
290
|
+
|
291
|
+
# Spot Instances don't support tagging arguments on creation
|
292
|
+
# Retrospectively tag the server to handle this
|
293
|
+
if !config.tags.empty?
|
294
|
+
env[:aws_compute].create_tags(server.identity, config.tags)
|
295
|
+
end
|
296
|
+
|
297
|
+
server
|
298
|
+
end
|
299
|
+
|
215
300
|
def recover(env)
|
216
301
|
return if env["vagrant.error"].is_a?(Vagrant::Errors::VagrantError)
|
217
302
|
|
data/lib/vagrant-aws/config.rb
CHANGED
@@ -196,6 +196,26 @@ module VagrantPlugins
|
|
196
196
|
# @return [String]
|
197
197
|
attr_accessor :aws_profile
|
198
198
|
|
199
|
+
# Launch as spot instance
|
200
|
+
#
|
201
|
+
# @return [Boolean]
|
202
|
+
attr_accessor :spot_instance
|
203
|
+
|
204
|
+
# Spot request max price
|
205
|
+
#
|
206
|
+
# @return [String]
|
207
|
+
attr_accessor :spot_max_price
|
208
|
+
|
209
|
+
# Spot request validity
|
210
|
+
#
|
211
|
+
# @return [Time]
|
212
|
+
attr_accessor :spot_valid_until
|
213
|
+
|
214
|
+
# The product description for the spot price history
|
215
|
+
#
|
216
|
+
# @return [String]
|
217
|
+
attr_accessor :spot_price_product_description
|
218
|
+
|
199
219
|
def initialize(region_specific=false)
|
200
220
|
@access_key_id = UNSET_VALUE
|
201
221
|
@ami = UNSET_VALUE
|
@@ -233,6 +253,9 @@ module VagrantPlugins
|
|
233
253
|
@tenancy = UNSET_VALUE
|
234
254
|
@aws_dir = UNSET_VALUE
|
235
255
|
@aws_profile = UNSET_VALUE
|
256
|
+
@spot_instance = UNSET_VALUE
|
257
|
+
@spot_max_price = UNSET_VALUE
|
258
|
+
@spot_valid_until = UNSET_VALUE
|
236
259
|
|
237
260
|
# Internal state (prefix with __ so they aren't automatically
|
238
261
|
# merged)
|
@@ -409,6 +432,18 @@ module VagrantPlugins
|
|
409
432
|
# default to nil
|
410
433
|
@kernel_id = nil if @kernel_id == UNSET_VALUE
|
411
434
|
|
435
|
+
# By default don't use spot requests
|
436
|
+
@spot_instance = false if @spot_instance == UNSET_VALUE
|
437
|
+
|
438
|
+
# default to nil
|
439
|
+
@spot_max_price = nil if @spot_max_price == UNSET_VALUE
|
440
|
+
|
441
|
+
# Default: Request is effective indefinitely.
|
442
|
+
@spot_valid_until = nil if @spot_valid_until == UNSET_VALUE
|
443
|
+
|
444
|
+
# default to nil
|
445
|
+
@spot_price_product_description = nil if @spot_price_product_description == UNSET_VALUE
|
446
|
+
|
412
447
|
# Compile our region specific configurations only within
|
413
448
|
# NON-REGION-SPECIFIC configurations.
|
414
449
|
if !@__region_specific
|
@@ -479,14 +514,14 @@ module VagrantPlugins
|
|
479
514
|
|
480
515
|
|
481
516
|
class Credentials < Vagrant.plugin("2", :config)
|
482
|
-
# This module reads AWS config and credentials.
|
517
|
+
# This module reads AWS config and credentials.
|
483
518
|
# Behaviour aims to mimic what is described in AWS documentation:
|
484
519
|
# http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html
|
485
520
|
# http://docs.aws.amazon.com/cli/latest/topic/config-vars.html
|
486
521
|
# Which is the following (stopping at the first successful case):
|
487
522
|
# 1) read config and credentials from environment variables
|
488
523
|
# 2) read config and credentials from files at location defined by environment variables
|
489
|
-
# 3) read config and credentials from files at default location
|
524
|
+
# 3) read config and credentials from files at default location
|
490
525
|
#
|
491
526
|
# The mandatory fields for a successful "get credentials" are the id and the secret keys.
|
492
527
|
# Region is not required since Config#finalize falls back to sensible defaults.
|
data/locales/en.yml
CHANGED
@@ -18,6 +18,8 @@ en:
|
|
18
18
|
|
19
19
|
launching_instance: |-
|
20
20
|
Launching an instance with the following settings...
|
21
|
+
launching_spot_instance: |-
|
22
|
+
Launching a spot request instance with the following settings...
|
21
23
|
launch_no_keypair: |-
|
22
24
|
Warning! You didn't specify a keypair to launch your instance with.
|
23
25
|
This can sometimes result in not being able to access your instance.
|
@@ -104,7 +106,7 @@ en:
|
|
104
106
|
Error: %{err}
|
105
107
|
instance_package_timeout: |-
|
106
108
|
The AMI failed to become "ready" in AWS. The timeout currently
|
107
|
-
set waiting for the instance to become ready is %{timeout} seconds. For
|
109
|
+
set waiting for the instance to become ready is %{timeout} seconds. For
|
108
110
|
larger instances AMI burning may take long periods of time. Please
|
109
111
|
ensure the timeout is set high enough, it can be changed by adjusting
|
110
112
|
the `instance_package_timeout` configuration on the AWS provider.
|
@@ -58,6 +58,10 @@ describe VagrantPlugins::AWS::Config do
|
|
58
58
|
its("associate_public_ip") { should == false }
|
59
59
|
its("unregister_elb_from_az") { should == true }
|
60
60
|
its("tenancy") { should == "default" }
|
61
|
+
its("spot_instance") { should == false }
|
62
|
+
its("spot_max_price") { should be_nil }
|
63
|
+
its("spot_price_product_description") { should be_nil }
|
64
|
+
its("spot_valid_until") { should be_nil }
|
61
65
|
end
|
62
66
|
|
63
67
|
describe "overriding defaults" do
|
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.3.6".freeze) if s.respond_to? :required_rubygems_version=
|
9
9
|
s.require_paths = ["lib".freeze]
|
10
10
|
s.authors = ["Mitchell Hashimoto".freeze, "John Bender".freeze]
|
11
|
-
s.date = "2017-06-
|
11
|
+
s.date = "2017-06-18"
|
12
12
|
s.description = "Vagrant is a tool for building and distributing virtualized development environments.".freeze
|
13
13
|
s.email = ["mitchell.hashimoto@gmail.com".freeze, "john.m.bender@gmail.com".freeze]
|
14
14
|
s.executables = ["vagrant".freeze]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vagrant-aws-mkubenka
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.2.pre.
|
4
|
+
version: 0.7.2.pre.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mitchell Hashimoto
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-06-
|
11
|
+
date: 2017-06-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fog
|