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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 15df03a2eb010846077263a557dbf98e17cfbc37
4
- data.tar.gz: 89676c658bd181bff522dfa70bef4b5a88140079
3
+ metadata.gz: 57caf99fd4244bccd66fc088a92a36db978117d9
4
+ data.tar.gz: 313a558229f08330b0dc222f4ab3d3a30170d4cd
5
5
  SHA512:
6
- metadata.gz: 331cd583f8c2c1914945c96527b68bc06f62257fd0fcb3067c5fc8e5ff268b015bd221e494ed3e1bbcbe90c7efdaa5ee609cf76f57da720010bef3ea13a3fcff
7
- data.tar.gz: bdd1a94500047ce36ad95c447d0ee17070106222ffe984acb84a67190cf43c9446a6f86576defa51d60643029c7ba9d91b3aa2e4afa88458920ec5095015cbf0
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 = env[:aws_compute].servers.create(options)
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
 
@@ -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-17"
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.11
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-17 00:00:00.000000000 Z
11
+ date: 2017-06-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fog