vagrant-aws-mkubenka 0.7.2.pre.11 → 0.7.2.pre.14
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 +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
|