vagrant-gecko-aws 0.8.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.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +6 -0
  5. data/CHANGELOG.md +96 -0
  6. data/Gemfile +10 -0
  7. data/LICENSE +8 -0
  8. data/README.md +329 -0
  9. data/Rakefile +22 -0
  10. data/dummy.box +0 -0
  11. data/example_box/README.md +13 -0
  12. data/example_box/metadata.json +3 -0
  13. data/lib/vagrant-aws/action/connect_aws.rb +48 -0
  14. data/lib/vagrant-aws/action/elb_deregister_instance.rb +24 -0
  15. data/lib/vagrant-aws/action/elb_register_instance.rb +24 -0
  16. data/lib/vagrant-aws/action/is_created.rb +18 -0
  17. data/lib/vagrant-aws/action/is_stopped.rb +18 -0
  18. data/lib/vagrant-aws/action/message_already_created.rb +16 -0
  19. data/lib/vagrant-aws/action/message_not_created.rb +16 -0
  20. data/lib/vagrant-aws/action/message_will_not_destroy.rb +16 -0
  21. data/lib/vagrant-aws/action/package_instance.rb +192 -0
  22. data/lib/vagrant-aws/action/read_ssh_info.rb +53 -0
  23. data/lib/vagrant-aws/action/read_state.rb +38 -0
  24. data/lib/vagrant-aws/action/run_instance.rb +314 -0
  25. data/lib/vagrant-aws/action/start_instance.rb +81 -0
  26. data/lib/vagrant-aws/action/stop_instance.rb +28 -0
  27. data/lib/vagrant-aws/action/terminate_instance.rb +51 -0
  28. data/lib/vagrant-aws/action/timed_provision.rb +21 -0
  29. data/lib/vagrant-aws/action/wait_for_state.rb +41 -0
  30. data/lib/vagrant-aws/action/warn_networks.rb +19 -0
  31. data/lib/vagrant-aws/action.rb +210 -0
  32. data/lib/vagrant-aws/config.rb +572 -0
  33. data/lib/vagrant-aws/errors.rb +43 -0
  34. data/lib/vagrant-aws/plugin.rb +73 -0
  35. data/lib/vagrant-aws/provider.rb +50 -0
  36. data/lib/vagrant-aws/util/elb.rb +58 -0
  37. data/lib/vagrant-aws/util/timer.rb +17 -0
  38. data/lib/vagrant-aws/version.rb +5 -0
  39. data/lib/vagrant-aws.rb +18 -0
  40. data/locales/en.yml +159 -0
  41. data/spec/spec_helper.rb +1 -0
  42. data/spec/vagrant-aws/config_spec.rb +374 -0
  43. data/templates/metadata.json.erb +3 -0
  44. data/templates/vagrant-aws_package_Vagrantfile.erb +5 -0
  45. data/vagrant-aws.gemspec +58 -0
  46. metadata +156 -0
@@ -0,0 +1,81 @@
1
+ require "log4r"
2
+
3
+ require 'vagrant/util/retryable'
4
+
5
+ require 'vagrant-aws/util/timer'
6
+
7
+ module VagrantPlugins
8
+ module AWS
9
+ module Action
10
+ # This starts a stopped instance.
11
+ class StartInstance
12
+ include Vagrant::Util::Retryable
13
+
14
+ def initialize(app, env)
15
+ @app = app
16
+ @logger = Log4r::Logger.new("vagrant_aws::action::start_instance")
17
+ end
18
+
19
+ def call(env)
20
+ # Initialize metrics if they haven't been
21
+ env[:metrics] ||= {}
22
+
23
+ server = env[:aws_compute].servers.get(env[:machine].id)
24
+
25
+ env[:ui].info(I18n.t("vagrant_aws.starting"))
26
+
27
+ begin
28
+ server.start
29
+
30
+ region = env[:machine].provider_config.region
31
+ region_config = env[:machine].provider_config.get_region_config(region)
32
+
33
+ # Wait for the instance to be ready first
34
+ env[:metrics]["instance_ready_time"] = Util::Timer.time do
35
+ tries = region_config.instance_ready_timeout / 2
36
+
37
+ env[:ui].info(I18n.t("vagrant_aws.waiting_for_ready"))
38
+ begin
39
+ retryable(:on => Fog::Errors::TimeoutError, :tries => tries) do
40
+ # If we're interrupted don't worry about waiting
41
+ next if env[:interrupted]
42
+
43
+ # Wait for the server to be ready
44
+ server.wait_for(2) { ready? }
45
+ end
46
+ rescue Fog::Errors::TimeoutError
47
+ # Notify the user
48
+ raise Errors::InstanceReadyTimeout,
49
+ timeout: region_config.instance_ready_timeout
50
+ end
51
+ end
52
+ rescue Fog::Compute::AWS::Error => e
53
+ raise Errors::FogError, :message => e.message
54
+ end
55
+
56
+ @logger.info("Time to instance ready: #{env[:metrics]["instance_ready_time"]}")
57
+
58
+ if !env[:interrupted]
59
+ env[:metrics]["instance_ssh_time"] = Util::Timer.time do
60
+ # Wait for SSH to be ready.
61
+ env[:ui].info(I18n.t("vagrant_aws.waiting_for_ssh"))
62
+ while true
63
+ # If we're interrupted then just back out
64
+ break if env[:interrupted]
65
+ break if env[:machine].communicate.ready?
66
+ sleep 2
67
+ end
68
+ end
69
+
70
+ @logger.info("Time for SSH ready: #{env[:metrics]["instance_ssh_time"]}")
71
+
72
+ # Ready and booted!
73
+ env[:ui].info(I18n.t("vagrant_aws.ready"))
74
+ end
75
+
76
+ @app.call(env)
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,28 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module AWS
5
+ module Action
6
+ # This stops the running instance.
7
+ class StopInstance
8
+ def initialize(app, env)
9
+ @app = app
10
+ @logger = Log4r::Logger.new("vagrant_aws::action::stop_instance")
11
+ end
12
+
13
+ def call(env)
14
+ server = env[:aws_compute].servers.get(env[:machine].id)
15
+
16
+ if env[:machine].state.id == :stopped
17
+ env[:ui].info(I18n.t("vagrant_aws.already_status", :status => env[:machine].state.id))
18
+ else
19
+ env[:ui].info(I18n.t("vagrant_aws.stopping"))
20
+ server.stop(!!env[:force_halt])
21
+ end
22
+
23
+ @app.call(env)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,51 @@
1
+ require "log4r"
2
+ require "json"
3
+
4
+ module VagrantPlugins
5
+ module AWS
6
+ module Action
7
+ # This terminates the running instance.
8
+ class TerminateInstance
9
+ def initialize(app, env)
10
+ @app = app
11
+ @logger = Log4r::Logger.new("vagrant_aws::action::terminate_instance")
12
+ end
13
+
14
+ def call(env)
15
+ server = env[:aws_compute].servers.get(env[:machine].id)
16
+ region = env[:machine].provider_config.region
17
+ region_config = env[:machine].provider_config.get_region_config(region)
18
+
19
+ elastic_ip = region_config.elastic_ip
20
+
21
+ # Release the elastic IP
22
+ ip_file = env[:machine].data_dir.join('elastic_ip')
23
+ if ip_file.file?
24
+ release_address(env,ip_file.read)
25
+ ip_file.delete
26
+ end
27
+
28
+ # Destroy the server and remove the tracking ID
29
+ env[:ui].info(I18n.t("vagrant_aws.terminating"))
30
+ server.destroy
31
+ env[:machine].id = nil
32
+
33
+ @app.call(env)
34
+ end
35
+
36
+ # Release an elastic IP address
37
+ def release_address(env,eip)
38
+ h = JSON.parse(eip)
39
+ # Use association_id and allocation_id for VPC, use public IP for EC2
40
+ if h['association_id']
41
+ env[:aws_compute].disassociate_address(nil,h['association_id'])
42
+ env[:aws_compute].release_address(h['allocation_id'])
43
+ else
44
+ env[:aws_compute].disassociate_address(h['public_ip'])
45
+ env[:aws_compute].release_address(h['public_ip'])
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,21 @@
1
+ require "vagrant-aws/util/timer"
2
+
3
+ module VagrantPlugins
4
+ module AWS
5
+ module Action
6
+ # This is the same as the builtin provision except it times the
7
+ # provisioner runs.
8
+ class TimedProvision < Vagrant::Action::Builtin::Provision
9
+ def run_provisioner(env, name, p)
10
+ timer = Util::Timer.time do
11
+ super
12
+ end
13
+
14
+ env[:metrics] ||= {}
15
+ env[:metrics]["provisioner_times"] ||= []
16
+ env[:metrics]["provisioner_times"] << [name, timer]
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,41 @@
1
+ require "log4r"
2
+ require "timeout"
3
+
4
+ module VagrantPlugins
5
+ module AWS
6
+ module Action
7
+ # This action will wait for a machine to reach a specific state or quit by timeout
8
+ class WaitForState
9
+ # env[:result] will be false in case of timeout.
10
+ # @param [Symbol] state Target machine state.
11
+ # @param [Number] timeout Timeout in seconds.
12
+ def initialize(app, env, state, timeout)
13
+ @app = app
14
+ @logger = Log4r::Logger.new("vagrant_aws::action::wait_for_state")
15
+ @state = state
16
+ @timeout = timeout
17
+ end
18
+
19
+ def call(env)
20
+ env[:result] = true
21
+ if env[:machine].state.id == @state
22
+ @logger.info(I18n.t("vagrant_aws.already_status", :status => @state))
23
+ else
24
+ @logger.info("Waiting for machine to reach state #{@state}")
25
+ begin
26
+ Timeout.timeout(@timeout) do
27
+ until env[:machine].state.id == @state
28
+ sleep 2
29
+ end
30
+ end
31
+ rescue Timeout::Error
32
+ env[:result] = false # couldn't reach state in time
33
+ end
34
+ end
35
+
36
+ @app.call(env)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,19 @@
1
+ module VagrantPlugins
2
+ module AWS
3
+ module Action
4
+ class WarnNetworks
5
+ def initialize(app, env)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ if env[:machine].config.vm.networks.length > 0
11
+ env[:ui].warn(I18n.t("vagrant_aws.warn_networks"))
12
+ end
13
+
14
+ @app.call(env)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,210 @@
1
+ require "pathname"
2
+
3
+ require "vagrant/action/builder"
4
+
5
+ module VagrantPlugins
6
+ module AWS
7
+ module Action
8
+ # Include the built-in modules so we can use them as top-level things.
9
+ include Vagrant::Action::Builtin
10
+
11
+ def self.action_package
12
+ Vagrant::Action::Builder.new.tap do |b|
13
+ b.use Call, IsCreated do |env, b2|
14
+ if !env[:result]
15
+ b2.use MessageNotCreated
16
+ next
17
+ end
18
+
19
+ # Connect to AWS and then Create a package from the server instance
20
+ b2.use ConnectAWS
21
+ b2.use PackageInstance
22
+ end
23
+ end
24
+ end
25
+
26
+ # This action is called to halt the remote machine.
27
+ def self.action_halt
28
+ Vagrant::Action::Builder.new.tap do |b|
29
+ b.use ConfigValidate
30
+ b.use Call, IsCreated do |env, b2|
31
+ if !env[:result]
32
+ b2.use MessageNotCreated
33
+ next
34
+ end
35
+
36
+ b2.use ConnectAWS
37
+ b2.use StopInstance
38
+ end
39
+ end
40
+ end
41
+
42
+ # This action is called to terminate the remote machine.
43
+ def self.action_destroy
44
+ Vagrant::Action::Builder.new.tap do |b|
45
+ b.use Call, DestroyConfirm do |env, b2|
46
+ if env[:result]
47
+ b2.use ConfigValidate
48
+ b2.use Call, IsCreated do |env2, b3|
49
+ if !env2[:result]
50
+ b3.use MessageNotCreated
51
+ next
52
+ end
53
+
54
+ b3.use ConnectAWS
55
+ b3.use ElbDeregisterInstance
56
+ b3.use ProvisionerCleanup, :before if defined?(ProvisionerCleanup)
57
+ b3.use TerminateInstance
58
+ end
59
+ else
60
+ b2.use MessageWillNotDestroy
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ # This action is called when `vagrant provision` is called.
67
+ def self.action_provision
68
+ Vagrant::Action::Builder.new.tap do |b|
69
+ b.use ConfigValidate
70
+ b.use Call, IsCreated do |env, b2|
71
+ if !env[:result]
72
+ b2.use MessageNotCreated
73
+ next
74
+ end
75
+
76
+ b2.use Provision
77
+ end
78
+ end
79
+ end
80
+
81
+ # This action is called to read the SSH info of the machine. The
82
+ # resulting state is expected to be put into the `:machine_ssh_info`
83
+ # key.
84
+ def self.action_read_ssh_info
85
+ Vagrant::Action::Builder.new.tap do |b|
86
+ b.use ConfigValidate
87
+ b.use ConnectAWS
88
+ b.use ReadSSHInfo
89
+ end
90
+ end
91
+
92
+ # This action is called to read the state of the machine. The
93
+ # resulting state is expected to be put into the `:machine_state_id`
94
+ # key.
95
+ def self.action_read_state
96
+ Vagrant::Action::Builder.new.tap do |b|
97
+ b.use ConfigValidate
98
+ b.use ConnectAWS
99
+ b.use ReadState
100
+ end
101
+ end
102
+
103
+ # This action is called to SSH into the machine.
104
+ def self.action_ssh
105
+ Vagrant::Action::Builder.new.tap do |b|
106
+ b.use ConfigValidate
107
+ b.use Call, IsCreated do |env, b2|
108
+ if !env[:result]
109
+ b2.use MessageNotCreated
110
+ next
111
+ end
112
+
113
+ b2.use SSHExec
114
+ end
115
+ end
116
+ end
117
+
118
+ def self.action_ssh_run
119
+ Vagrant::Action::Builder.new.tap do |b|
120
+ b.use ConfigValidate
121
+ b.use Call, IsCreated do |env, b2|
122
+ if !env[:result]
123
+ b2.use MessageNotCreated
124
+ next
125
+ end
126
+
127
+ b2.use SSHRun
128
+ end
129
+ end
130
+ end
131
+
132
+ def self.action_prepare_boot
133
+ Vagrant::Action::Builder.new.tap do |b|
134
+ b.use Provision
135
+ b.use SyncedFolders
136
+ b.use WarnNetworks
137
+ b.use ElbRegisterInstance
138
+ end
139
+ end
140
+
141
+ # This action is called to bring the box up from nothing.
142
+ def self.action_up
143
+ Vagrant::Action::Builder.new.tap do |b|
144
+ b.use HandleBox
145
+ b.use ConfigValidate
146
+ b.use BoxCheckOutdated
147
+ b.use ConnectAWS
148
+ b.use Call, IsCreated do |env1, b1|
149
+ if env1[:result]
150
+ b1.use Call, IsStopped do |env2, b2|
151
+ if env2[:result]
152
+ b2.use action_prepare_boot
153
+ b2.use StartInstance # restart this instance
154
+ else
155
+ b2.use MessageAlreadyCreated # TODO write a better message
156
+ end
157
+ end
158
+ else
159
+ b1.use action_prepare_boot
160
+ b1.use RunInstance # launch a new instance
161
+ end
162
+ end
163
+ end
164
+ end
165
+
166
+ def self.action_reload
167
+ Vagrant::Action::Builder.new.tap do |b|
168
+ b.use ConfigValidate
169
+ b.use ConnectAWS
170
+ b.use Call, IsCreated do |env, b2|
171
+ if !env[:result]
172
+ b2.use MessageNotCreated
173
+ next
174
+ end
175
+
176
+ b2.use action_halt
177
+ b2.use Call, WaitForState, :stopped, 120 do |env2, b3|
178
+ if env2[:result]
179
+ b3.use action_up
180
+ else
181
+ # TODO we couldn't reach :stopped, what now?
182
+ end
183
+ end
184
+ end
185
+ end
186
+ end
187
+
188
+ # The autoload farm
189
+ action_root = Pathname.new(File.expand_path("../action", __FILE__))
190
+ autoload :ConnectAWS, action_root.join("connect_aws")
191
+ autoload :IsCreated, action_root.join("is_created")
192
+ autoload :IsStopped, action_root.join("is_stopped")
193
+ autoload :MessageAlreadyCreated, action_root.join("message_already_created")
194
+ autoload :MessageNotCreated, action_root.join("message_not_created")
195
+ autoload :MessageWillNotDestroy, action_root.join("message_will_not_destroy")
196
+ autoload :PackageInstance, action_root.join("package_instance")
197
+ autoload :ReadSSHInfo, action_root.join("read_ssh_info")
198
+ autoload :ReadState, action_root.join("read_state")
199
+ autoload :RunInstance, action_root.join("run_instance")
200
+ autoload :StartInstance, action_root.join("start_instance")
201
+ autoload :StopInstance, action_root.join("stop_instance")
202
+ autoload :TerminateInstance, action_root.join("terminate_instance")
203
+ autoload :TimedProvision, action_root.join("timed_provision") # some plugins now expect this action to exist
204
+ autoload :WaitForState, action_root.join("wait_for_state")
205
+ autoload :WarnNetworks, action_root.join("warn_networks")
206
+ autoload :ElbRegisterInstance, action_root.join("elb_register_instance")
207
+ autoload :ElbDeregisterInstance, action_root.join("elb_deregister_instance")
208
+ end
209
+ end
210
+ end