vagrant-gecko-aws 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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