vagrant-cloudstack 0.0.7 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +7 -0
- data/lib/vagrant-cloudstack/action/is_stopped.rb +18 -0
- data/lib/vagrant-cloudstack/action/message_already_created.rb +1 -1
- data/lib/vagrant-cloudstack/action/message_will_not_destroy.rb +16 -0
- data/lib/vagrant-cloudstack/action/read_ssh_info.rb +28 -5
- data/lib/vagrant-cloudstack/action/read_state.rb +2 -2
- data/lib/vagrant-cloudstack/action/run_instance.rb +88 -7
- data/lib/vagrant-cloudstack/action/start_instance.rb +81 -0
- data/lib/vagrant-cloudstack/action/stop_instance.rb +28 -0
- data/lib/vagrant-cloudstack/action/terminate_instance.rb +21 -1
- data/lib/vagrant-cloudstack/action/wait_for_state.rb +41 -0
- data/lib/vagrant-cloudstack/action.rb +76 -9
- data/lib/vagrant-cloudstack/config.rb +45 -0
- data/lib/vagrant-cloudstack/plugin.rb +1 -2
- data/lib/vagrant-cloudstack/version.rb +1 -1
- data/locales/en.yml +25 -4
- data/spec/vagrant-cloudstack/config_spec.rb +20 -0
- data/vagrant-cloudstack.gemspec +1 -1
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e63f390567590eef3c9213dfac92b9d2d8d5f1b
|
4
|
+
data.tar.gz: 283ca0b998a55fdd780756abc76646152f2a6793
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c848430cc6bffd286e66d8baa99403197ff3a1871130f541d88adcc834ac1c3660a6947d2db66ae266c2ddffae755fe6b2ccfbd83502dde5210cb52c83688659
|
7
|
+
data.tar.gz: c2a967dd880d8a3daa7209ec99afd8e44ffa0d2b8850d90deed017ea3d58890deb56bfa36a22631240362ea7d178741ed06eedac80dc7ae9eb16fcbe234d8f14
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
# 0.1.0
|
2
|
+
* Plugin now enables parallelization by default.
|
3
|
+
* This behaviour can be turned off by invoking vagrant with
|
4
|
+
--no-parallel (this flag requires vagrant 1.2.1)
|
5
|
+
* Added support for starting, stoping and reloading machines.
|
6
|
+
* Added support for portforwarding and adding ssh keys.
|
7
|
+
* Added support for basic network type.
|
8
|
+
* Basic means that there is no need to specify a network_id
|
9
|
+
to connecto to.
|
10
|
+
* Default network type is advanced.
|
11
|
+
|
1
12
|
# 0.0.2 (May 3, 2013)
|
2
13
|
|
3
14
|
* Renamed module from CloudStack to Cloudstack
|
data/README.md
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
[![Build Status](https://travis-ci.org/klarna/vagrant-cloudstack.png?branch=master)](https://travis-ci.org/klarna/vagrant-cloudstack)
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/vagrant-cloudstack.png)](http://badge.fury.io/rb/vagrant-cloudstack)
|
5
|
+
[![Dependency Status](https://gemnasium.com/klarna/vagrant-cloudstack.png)](https://gemnasium.com/klarna/vagrant-cloudstack)
|
5
6
|
|
6
7
|
This is a fork of [mitchellh AWS Provider](https://github.com/mitchellh/vagrant-aws/).
|
7
8
|
|
@@ -64,6 +65,7 @@ Vagrant.configure("2") do |config|
|
|
64
65
|
cloudstack.network_id = "AAAAAAAAAAAAAAAAAAA"
|
65
66
|
cloudstack.zone_id = "AAAAAAAAAAAAAAAAAAA"
|
66
67
|
cloudstack.project_id = "AAAAAAAAAAAAAAAAAAA"
|
68
|
+
cloudstack.network_type = "Advanced" # or "Basic"
|
67
69
|
end
|
68
70
|
end
|
69
71
|
```
|
@@ -101,10 +103,15 @@ This provider exposes quite a few provider-specific configuration options:
|
|
101
103
|
to become "ready" in Cloudstack. Defaults to 120 seconds.
|
102
104
|
* `domain_id` - Domain id to launch the instance into
|
103
105
|
* `network_id` - Network uuid that the instance should use
|
106
|
+
* `network_type` - CloudStack Network Type(default: Advanced)
|
104
107
|
* `project_id` - Project uuid that the instance should belong to
|
105
108
|
* `service_offering_id`- Service offering uuid to use for the instance
|
106
109
|
* `template_id` - Template uuid to use for the instance
|
107
110
|
* `zone_id` - Zone uuid to launch the instance into
|
111
|
+
* `keypair` - SSH keypair name
|
112
|
+
* `pf_ip_address_id` - IP address ID for port forwarding rule
|
113
|
+
* `pf_public_port` - Public port for port forwarding rule
|
114
|
+
* `pf_private_port` - Private port for port forwarding rule
|
108
115
|
|
109
116
|
These can be set like typical provider-specific configuration:
|
110
117
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Cloudstack
|
3
|
+
module Action
|
4
|
+
# This can be used with "Call" built-in to check if the machine
|
5
|
+
# is stopped and branch in the middleware.
|
6
|
+
class IsStopped
|
7
|
+
def initialize(app, env)
|
8
|
+
@app = app
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
env[:result] = env[:machine].state.id == :stopped
|
13
|
+
@app.call(env)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Cloudstack
|
3
|
+
module Action
|
4
|
+
class MessageWillNotDestroy
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
env[:ui].info(I18n.t("vagrant_cloudstack.will_not_destroy", name: env[:machine].name))
|
11
|
+
@app.call(env)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -29,11 +29,34 @@ module VagrantPlugins
|
|
29
29
|
return nil
|
30
30
|
end
|
31
31
|
|
32
|
-
#
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
32
|
+
# Get the Port forwarding config
|
33
|
+
domain = machine.provider_config.domain
|
34
|
+
domain_config = machine.provider_config.get_domain_config(domain)
|
35
|
+
|
36
|
+
pf_ip_address_id = domain_config.pf_ip_address_id
|
37
|
+
pf_public_port = domain_config.pf_public_port
|
38
|
+
|
39
|
+
if pf_ip_address_id and pf_public_port
|
40
|
+
begin
|
41
|
+
response = cloudstack.list_public_ip_addresses({:id => pf_ip_address_id})
|
42
|
+
rescue Fog::Compute::Cloudstack::Error => e
|
43
|
+
raise Errors::FogError, :message => e.message
|
44
|
+
end
|
45
|
+
|
46
|
+
if response["listpublicipaddressesresponse"]["count"] == 0
|
47
|
+
@logger.info("IP address #{pf_ip_address_id} not exists.")
|
48
|
+
env[:ui].info(I18n.t("IP address #{pf_ip_address_id} not exists."))
|
49
|
+
pf_ip_address = nil
|
50
|
+
else
|
51
|
+
pf_ip_address = response["listpublicipaddressesresponse"]["publicipaddress"][0]["ipaddress"]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
unless pf_ip_address.nil?
|
56
|
+
return {:host => pf_ip_address, :port => pf_public_port}
|
57
|
+
else
|
58
|
+
return {:host => server.nics[0]['ipaddress'], :port => 22}
|
59
|
+
end
|
37
60
|
end
|
38
61
|
end
|
39
62
|
end
|
@@ -22,7 +22,7 @@ module VagrantPlugins
|
|
22
22
|
|
23
23
|
# Find the machine
|
24
24
|
server = cloudstack.servers.get(machine.id)
|
25
|
-
if server.nil? || [:"shutting-down", :terminated].include?(server.state.to_sym)
|
25
|
+
if server.nil? || [:"shutting-down", :terminated].include?(server.state.downcase.to_sym)
|
26
26
|
# The machine can't be found
|
27
27
|
@logger.info("Machine not found or terminated, assuming it got destroyed.")
|
28
28
|
machine.id = nil
|
@@ -30,7 +30,7 @@ module VagrantPlugins
|
|
30
30
|
end
|
31
31
|
|
32
32
|
# Return the state
|
33
|
-
return server.state.to_sym
|
33
|
+
return server.state.downcase.to_sym
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
@@ -28,9 +28,20 @@ module VagrantPlugins
|
|
28
28
|
domain_config = env[:machine].provider_config.get_domain_config(domain)
|
29
29
|
zone_id = domain_config.zone_id
|
30
30
|
network_id = domain_config.network_id
|
31
|
+
network_type = domain_config.network_type
|
31
32
|
project_id = domain_config.project_id
|
32
33
|
service_offering_id = domain_config.service_offering_id
|
33
34
|
template_id = domain_config.template_id
|
35
|
+
keypair = domain_config.keypair
|
36
|
+
|
37
|
+
pf_ip_address_id = domain_config.pf_ip_address_id
|
38
|
+
pf_public_port = domain_config.pf_public_port
|
39
|
+
pf_private_port = domain_config.pf_private_port
|
40
|
+
|
41
|
+
# If there is no keypair then warn the user
|
42
|
+
if !keypair
|
43
|
+
env[:ui].warn(I18n.t("vagrant_cloudstack.launch_no_keypair"))
|
44
|
+
end
|
34
45
|
|
35
46
|
# Launch!
|
36
47
|
env[:ui].info(I18n.t("vagrant_cloudstack.launching_instance"))
|
@@ -39,6 +50,7 @@ module VagrantPlugins
|
|
39
50
|
env[:ui].info(" -- Project UUID: #{project_id}") if project_id != nil
|
40
51
|
env[:ui].info(" -- Zone UUID: #{zone_id}")
|
41
52
|
env[:ui].info(" -- Network UUID: #{network_id}") if network_id
|
53
|
+
env[:ui].info(" -- Keypair: #{keypair}") if keypair
|
42
54
|
|
43
55
|
local_user = ENV['USER'].dup
|
44
56
|
local_user.gsub!(/[^-a-z0-9_]/i, "")
|
@@ -47,15 +59,26 @@ module VagrantPlugins
|
|
47
59
|
display_name = local_user + "_" + prefix + "_#{Time.now.to_i}"
|
48
60
|
|
49
61
|
begin
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
62
|
+
case network_type
|
63
|
+
when "Advanced"
|
64
|
+
options = {
|
65
|
+
:display_name => display_name,
|
66
|
+
:zone_id => zone_id,
|
67
|
+
:flavor_id => service_offering_id,
|
68
|
+
:image_id => template_id,
|
69
|
+
:network_ids => [network_id]
|
70
|
+
}
|
71
|
+
when "Basic"
|
72
|
+
options = {
|
73
|
+
:display_name => display_name,
|
74
|
+
:zone_id => zone_id,
|
75
|
+
:flavor_id => service_offering_id,
|
76
|
+
:image_id => template_id
|
77
|
+
}
|
78
|
+
end
|
57
79
|
|
58
80
|
options['project_id'] = project_id if project_id != nil
|
81
|
+
options['key_name'] = keypair if keypair != nil
|
59
82
|
|
60
83
|
server = env[:cloudstack_compute].servers.create(options)
|
61
84
|
rescue Fog::Compute::Cloudstack::NotFound => e
|
@@ -102,6 +125,11 @@ module VagrantPlugins
|
|
102
125
|
|
103
126
|
@logger.info("Time to instance ready: #{env[:metrics]["instance_ready_time"]}")
|
104
127
|
|
128
|
+
if pf_ip_address_id and pf_public_port and pf_private_port
|
129
|
+
create_port_forwarding_rule(env, pf_ip_address_id,
|
130
|
+
pf_public_port, pf_private_port)
|
131
|
+
end
|
132
|
+
|
105
133
|
if !env[:interrupted]
|
106
134
|
env[:metrics]["instance_ssh_time"] = Util::Timer.time do
|
107
135
|
# Wait for SSH to be ready.
|
@@ -135,6 +163,59 @@ module VagrantPlugins
|
|
135
163
|
end
|
136
164
|
end
|
137
165
|
|
166
|
+
def create_port_forwarding_rule(env, pf_ip_address_id, pf_public_port, pf_private_port)
|
167
|
+
env[:ui].info(I18n.t("vagrant_cloudstack.creating_port_forwarding_rule"))
|
168
|
+
|
169
|
+
begin
|
170
|
+
response = env[:cloudstack_compute].list_public_ip_addresses({:id => pf_ip_address_id})
|
171
|
+
rescue Fog::Compute::Cloudstack::Error => e
|
172
|
+
raise Errors::FogError, :message => e.message
|
173
|
+
end
|
174
|
+
|
175
|
+
if response["listpublicipaddressesresponse"]["count"] == 0
|
176
|
+
@logger.info("IP address #{pf_ip_address_id} not exists. Skip creating port forwarding rule.")
|
177
|
+
env[:ui].info(I18n.t("IP address #{pf_ip_address_id} not exists. Skip creating port forwarding rule."))
|
178
|
+
return
|
179
|
+
end
|
180
|
+
|
181
|
+
pf_ip_address = response["listpublicipaddressesresponse"]["publicipaddress"][0]["ipaddress"]
|
182
|
+
|
183
|
+
env[:ui].info(" -- IP address ID: #{pf_ip_address_id}")
|
184
|
+
env[:ui].info(" -- IP address: #{pf_ip_address}")
|
185
|
+
env[:ui].info(" -- Public port: #{pf_public_port}")
|
186
|
+
env[:ui].info(" -- Private port: #{pf_private_port}")
|
187
|
+
|
188
|
+
options = {
|
189
|
+
:ipaddressid => pf_ip_address_id,
|
190
|
+
:publicport => pf_public_port,
|
191
|
+
:privateport => pf_private_port,
|
192
|
+
:protocol => "tcp",
|
193
|
+
:virtualmachineid => env[:machine].id,
|
194
|
+
:openfirewall => "true"
|
195
|
+
}
|
196
|
+
|
197
|
+
begin
|
198
|
+
job_id = env[:cloudstack_compute].create_port_forwarding_rule(options)["createportforwardingruleresponse"]["jobid"]
|
199
|
+
while true
|
200
|
+
response = env[:cloudstack_compute].query_async_job_result({:jobid => job_id})
|
201
|
+
if response["queryasyncjobresultresponse"]["jobstatus"] != 0
|
202
|
+
port_forwarding_rule = response["queryasyncjobresultresponse"]["jobresult"]["portforwardingrule"]
|
203
|
+
break
|
204
|
+
else
|
205
|
+
sleep 2
|
206
|
+
end
|
207
|
+
end
|
208
|
+
rescue Fog::Compute::Cloudstack::Error => e
|
209
|
+
raise Errors::FogError, :message => e.message
|
210
|
+
end
|
211
|
+
|
212
|
+
# Save port forwarding rule id to the data dir so it can be released when the instance is destroyed
|
213
|
+
port_forwarding_file = env[:machine].data_dir.join('port_forwarding')
|
214
|
+
port_forwarding_file.open('w+') do |f|
|
215
|
+
f.write(port_forwarding_rule["id"])
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
138
219
|
def terminate(env)
|
139
220
|
destroy_env = env.dup
|
140
221
|
destroy_env.delete(:interrupted)
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require "log4r"
|
2
|
+
|
3
|
+
require 'vagrant/util/retryable'
|
4
|
+
|
5
|
+
require 'vagrant-cloudstack/util/timer'
|
6
|
+
|
7
|
+
module VagrantPlugins
|
8
|
+
module Cloudstack
|
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_cloudstack::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[:cloudstack_compute].servers.get(env[:machine].id)
|
24
|
+
|
25
|
+
env[:ui].info(I18n.t("vagrant_cloudstack.starting"))
|
26
|
+
|
27
|
+
begin
|
28
|
+
server.start
|
29
|
+
|
30
|
+
domain = env[:machine].provider_config.domain
|
31
|
+
domain_config = env[:machine].provider_config.get_domain_config(domain)
|
32
|
+
|
33
|
+
# Wait for the instance to be ready first
|
34
|
+
env[:metrics]["instance_ready_time"] = Util::Timer.time do
|
35
|
+
tries = domain_config.instance_ready_timeout / 2
|
36
|
+
|
37
|
+
env[:ui].info(I18n.t("vagrant_cloudstack.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: domain_config.instance_ready_timeout
|
50
|
+
end
|
51
|
+
end
|
52
|
+
rescue Fog::Compute::Cloudstack::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_cloudstack.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_cloudstack.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 Cloudstack
|
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_cloudstack::action::stop_instance")
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(env)
|
14
|
+
server = env[:cloudstack_compute].servers.get(env[:machine].id)
|
15
|
+
|
16
|
+
if env[:machine].state.id == :stopped
|
17
|
+
env[:ui].info(I18n.t("vagrant_cloudstack.already_status", :status => env[:machine].state.id))
|
18
|
+
else
|
19
|
+
env[:ui].info(I18n.t("vagrant_cloudstack.stopping"))
|
20
|
+
server.stop(!!env[:force_halt])
|
21
|
+
end
|
22
|
+
|
23
|
+
@app.call(env)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -11,9 +11,29 @@ module VagrantPlugins
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def call(env)
|
14
|
-
|
14
|
+
# Delete the Port forwarding rule
|
15
|
+
env[:ui].info(I18n.t("vagrant_cloudstack.deleting_port_forwarding_rule"))
|
16
|
+
port_forwarding_file = env[:machine].data_dir.join("port_forwarding")
|
17
|
+
if port_forwarding_file.file?
|
18
|
+
rule_id = port_forwarding_file.read
|
19
|
+
begin
|
20
|
+
job_id = env[:cloudstack_compute].delete_port_forwarding_rule({:id => rule_id})["deleteportforwardingruleresponse"]["jobid"]
|
21
|
+
while true
|
22
|
+
response = env[:cloudstack_compute].query_async_job_result({:jobid => job_id})
|
23
|
+
if response["queryasyncjobresultresponse"]["jobstatus"] != 0
|
24
|
+
break
|
25
|
+
else
|
26
|
+
sleep 2
|
27
|
+
end
|
28
|
+
end
|
29
|
+
rescue Fog::Compute::Cloudstack::Error => e
|
30
|
+
raise Errors::FogError, :message => e.message
|
31
|
+
end
|
32
|
+
port_forwarding_file.delete
|
33
|
+
end
|
15
34
|
|
16
35
|
# Destroy the server and remove the tracking ID
|
36
|
+
server = env[:cloudstack_compute].servers.get(env[:machine].id)
|
17
37
|
env[:ui].info(I18n.t("vagrant_cloudstack.terminating"))
|
18
38
|
server.destroy
|
19
39
|
env[:machine].id = nil
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "log4r"
|
2
|
+
require "timeout"
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module Cloudstack
|
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_cloudstack::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_cloudstack.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
|
@@ -8,12 +8,40 @@ module VagrantPlugins
|
|
8
8
|
# Include the built-in modules so we can use them as top-level things.
|
9
9
|
include Vagrant::Action::Builtin
|
10
10
|
|
11
|
+
# This action is called to halt the remote machine.
|
12
|
+
def self.action_halt
|
13
|
+
Vagrant::Action::Builder.new.tap do |b|
|
14
|
+
b.use ConfigValidate
|
15
|
+
b.use Call, IsCreated do |env, b2|
|
16
|
+
if !env[:result]
|
17
|
+
b2.use MessageNotCreated
|
18
|
+
next
|
19
|
+
end
|
20
|
+
|
21
|
+
b2.use ConnectCloudstack
|
22
|
+
b2.use StopInstance
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
11
27
|
# This action is called to terminate the remote machine.
|
12
28
|
def self.action_destroy
|
13
29
|
Vagrant::Action::Builder.new.tap do |b|
|
14
|
-
b.use
|
15
|
-
|
16
|
-
|
30
|
+
b.use Call, DestroyConfirm do |env, b2|
|
31
|
+
if env[:result]
|
32
|
+
b2.use ConfigValidate
|
33
|
+
b.use Call, IsCreated do |env2, b3|
|
34
|
+
if !env2[:result]
|
35
|
+
b3.use MessageNotCreated
|
36
|
+
next
|
37
|
+
end
|
38
|
+
end
|
39
|
+
b2.use ConnectCloudstack
|
40
|
+
b2.use TerminateInstance
|
41
|
+
else
|
42
|
+
b2.use MessageWillNotDestroy
|
43
|
+
end
|
44
|
+
end
|
17
45
|
end
|
18
46
|
end
|
19
47
|
|
@@ -84,21 +112,55 @@ module VagrantPlugins
|
|
84
112
|
end
|
85
113
|
end
|
86
114
|
|
115
|
+
def self.action_prepare_boot
|
116
|
+
Vagrant::Action::Builder.new.tap do |b|
|
117
|
+
b.use Provision
|
118
|
+
b.use SyncFolders
|
119
|
+
b.use WarnNetworks
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
87
123
|
# This action is called to bring the box up from nothing.
|
88
124
|
def self.action_up
|
125
|
+
Vagrant::Action::Builder.new.tap do |b|
|
126
|
+
b.use ConfigValidate
|
127
|
+
b.use ConnectCloudstack
|
128
|
+
b.use Call, IsCreated do |env1, b1|
|
129
|
+
if env1[:result]
|
130
|
+
b1.use Call, IsStopped do |env2, b2|
|
131
|
+
if env2[:result]
|
132
|
+
b2.use action_prepare_boot
|
133
|
+
b2.use StartInstance # restart this instance
|
134
|
+
else
|
135
|
+
b2.use MessageAlreadyCreated # TODO write a better message
|
136
|
+
end
|
137
|
+
end
|
138
|
+
else
|
139
|
+
b1.use action_prepare_boot
|
140
|
+
b1.use RunInstance # launch a new instance
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def self.action_reload
|
89
147
|
Vagrant::Action::Builder.new.tap do |b|
|
90
148
|
b.use ConfigValidate
|
91
149
|
b.use ConnectCloudstack
|
92
150
|
b.use Call, IsCreated do |env, b2|
|
93
|
-
if env[:result]
|
94
|
-
b2.use
|
151
|
+
if !env[:result]
|
152
|
+
b2.use MessageNotCreated
|
95
153
|
next
|
96
154
|
end
|
97
155
|
|
98
|
-
b2.use
|
99
|
-
b2.use
|
100
|
-
|
101
|
-
|
156
|
+
b2.use action_halt
|
157
|
+
b2.use Call, WaitForState, :stopped, 120 do |env2, b3|
|
158
|
+
if env2[:result]
|
159
|
+
b3.use action_up
|
160
|
+
else
|
161
|
+
# TODO we couldn't reach :stopped, what now?
|
162
|
+
end
|
163
|
+
end
|
102
164
|
end
|
103
165
|
end
|
104
166
|
end
|
@@ -107,13 +169,18 @@ module VagrantPlugins
|
|
107
169
|
action_root = Pathname.new(File.expand_path("../action", __FILE__))
|
108
170
|
autoload :ConnectCloudstack, action_root.join("connect_cloudstack")
|
109
171
|
autoload :IsCreated, action_root.join("is_created")
|
172
|
+
autoload :IsStopped, action_root.join("is_stopped")
|
110
173
|
autoload :MessageAlreadyCreated, action_root.join("message_already_created")
|
111
174
|
autoload :MessageNotCreated, action_root.join("message_not_created")
|
175
|
+
autoload :MessageWillNotDestroy, action_root.join("message_will_not_destroy")
|
112
176
|
autoload :ReadSSHInfo, action_root.join("read_ssh_info")
|
113
177
|
autoload :ReadState, action_root.join("read_state")
|
114
178
|
autoload :RunInstance, action_root.join("run_instance")
|
179
|
+
autoload :StartInstance, action_root.join("start_instance")
|
180
|
+
autoload :StopInstance, action_root.join("stop_instance")
|
115
181
|
autoload :SyncFolders, action_root.join("sync_folders")
|
116
182
|
autoload :TimedProvision, action_root.join("timed_provision")
|
183
|
+
autoload :WaitForState, action_root.join("wait_for_state")
|
117
184
|
autoload :WarnNetworks, action_root.join("warn_networks")
|
118
185
|
autoload :TerminateInstance, action_root.join("terminate_instance")
|
119
186
|
end
|
@@ -48,6 +48,11 @@ module VagrantPlugins
|
|
48
48
|
# @return [String]
|
49
49
|
attr_accessor :network_id
|
50
50
|
|
51
|
+
# Network Type
|
52
|
+
#
|
53
|
+
# @return [String]
|
54
|
+
attr_accessor :network_type
|
55
|
+
|
51
56
|
# Project uuid that the instance should belong to
|
52
57
|
#
|
53
58
|
# @return [String]
|
@@ -69,6 +74,26 @@ module VagrantPlugins
|
|
69
74
|
# @return [String]
|
70
75
|
attr_accessor :zone_id
|
71
76
|
|
77
|
+
# The name of the keypair to use.
|
78
|
+
#
|
79
|
+
# @return [String]
|
80
|
+
attr_accessor :keypair
|
81
|
+
|
82
|
+
# IP address id to use for port forwarding rule
|
83
|
+
#
|
84
|
+
# @return [String]
|
85
|
+
attr_accessor :pf_ip_address_id
|
86
|
+
|
87
|
+
# public port to use for port forwarding rule
|
88
|
+
#
|
89
|
+
# @return [String]
|
90
|
+
attr_accessor :pf_public_port
|
91
|
+
|
92
|
+
# private port to use for port forwarding rule
|
93
|
+
#
|
94
|
+
# @return [String]
|
95
|
+
attr_accessor :pf_private_port
|
96
|
+
|
72
97
|
def initialize(domain_specific=false)
|
73
98
|
@host = UNSET_VALUE
|
74
99
|
@path = UNSET_VALUE
|
@@ -79,10 +104,15 @@ module VagrantPlugins
|
|
79
104
|
@instance_ready_timeout = UNSET_VALUE
|
80
105
|
@domain_id = UNSET_VALUE
|
81
106
|
@network_id = UNSET_VALUE
|
107
|
+
@network_type = UNSET_VALUE
|
82
108
|
@project_id = UNSET_VALUE
|
83
109
|
@service_offering_id = UNSET_VALUE
|
84
110
|
@template_id = UNSET_VALUE
|
85
111
|
@zone_id = UNSET_VALUE
|
112
|
+
@keypair = UNSET_VALUE
|
113
|
+
@pf_ip_address_id = UNSET_VALUE
|
114
|
+
@pf_public_port = UNSET_VALUE
|
115
|
+
@pf_private_port = UNSET_VALUE
|
86
116
|
|
87
117
|
# Internal state (prefix with __ so they aren't automatically
|
88
118
|
# merged)
|
@@ -180,6 +210,9 @@ module VagrantPlugins
|
|
180
210
|
# Network uuid must be nil, since we can't default that
|
181
211
|
@network_id = nil if @network_id == UNSET_VALUE
|
182
212
|
|
213
|
+
# NetworkType is 'Advanced' by default
|
214
|
+
@network_type = "Advanced" if @network_type == UNSET_VALUE
|
215
|
+
|
183
216
|
# Project uuid must be nil, since we can't default that
|
184
217
|
@project_id = nil if @project_id == UNSET_VALUE
|
185
218
|
|
@@ -192,6 +225,18 @@ module VagrantPlugins
|
|
192
225
|
# Zone uuid must be nil, since we can't default that
|
193
226
|
@zone_id = nil if @zone_id == UNSET_VALUE
|
194
227
|
|
228
|
+
# Keypair defaults to nil
|
229
|
+
@keypair = nil if @keypair == UNSET_VALUE
|
230
|
+
|
231
|
+
# IP address id must be nil, since we can't default that
|
232
|
+
@pf_ip_address_id = nil if @pf_ip_address_id == UNSET_VALUE
|
233
|
+
|
234
|
+
# Public port must be nil, since we can't default that
|
235
|
+
@pf_public_port = nil if @pf_public_port == UNSET_VALUE
|
236
|
+
|
237
|
+
# Private port must be nil, since we can't default that
|
238
|
+
@pf_private_port = nil if @pf_private_port == UNSET_VALUE
|
239
|
+
|
195
240
|
# Compile our domain specific configurations only within
|
196
241
|
# NON-DOMAIN-SPECIFIC configurations.
|
197
242
|
if !@__domain_specific
|
data/locales/en.yml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
en:
|
2
2
|
vagrant_cloudstack:
|
3
|
-
|
4
|
-
The machine is already
|
3
|
+
already_status: |-
|
4
|
+
The machine is already %{status}.
|
5
5
|
launching_instance: |-
|
6
6
|
Launching an instance with the following settings...
|
7
7
|
launch_no_keypair: |-
|
@@ -21,16 +21,27 @@ en:
|
|
21
21
|
Make sure rsync is installed and the binary can be found in the PATH.
|
22
22
|
rsync_folder: |-
|
23
23
|
Rsyncing folder: %{hostpath} => %{guestpath}
|
24
|
+
starting: |-
|
25
|
+
Starting the instance...
|
26
|
+
stopping: |-
|
27
|
+
Stopping the instance...
|
24
28
|
terminating: |-
|
25
29
|
Terminating the instance...
|
26
30
|
waiting_for_ready: |-
|
27
31
|
Waiting for instance to become "ready"...
|
28
32
|
waiting_for_ssh: |-
|
29
33
|
Waiting for SSH to become available...
|
34
|
+
creating_port_forwarding_rule: |-
|
35
|
+
Creating a port forwarding rule for this instance ...
|
36
|
+
deleting_port_forwarding_rule: |-
|
37
|
+
Deleting the port forwarding rule ...
|
30
38
|
warn_networks: |-
|
31
39
|
Warning! The Cloudstack provider doesn't support any of the Vagrant
|
32
40
|
high-level network configurations (`config.vm.network`). They
|
33
41
|
will be silently ignored.
|
42
|
+
will_not_destroy: |-
|
43
|
+
The instance '%{name}' will not be destroyed, since the confirmation
|
44
|
+
was declined.
|
34
45
|
|
35
46
|
config:
|
36
47
|
api_key_required: |-
|
@@ -64,9 +75,19 @@ en:
|
|
64
75
|
not created
|
65
76
|
long_not_created: |-
|
66
77
|
The instance is not created. Run `vagrant up` to create it.
|
78
|
+
short_stopped: |-
|
79
|
+
stopped
|
80
|
+
long_stopped: |-
|
81
|
+
The instance is stopped. Run `vagrant up` to start it.
|
67
82
|
|
68
|
-
|
83
|
+
short_stopping: |-
|
84
|
+
stopping
|
85
|
+
long_stopping: |-
|
86
|
+
The instance is stopping. Wait until is completely stopped to
|
87
|
+
run `vagrant up` and start it.
|
88
|
+
|
89
|
+
short_running: |-
|
69
90
|
running
|
70
|
-
|
91
|
+
long_running: |-
|
71
92
|
The instance is running. To stop this machine, you can run
|
72
93
|
`vagrant halt`. To destroy the machine, you can run `vagrant destroy`.
|
@@ -28,6 +28,10 @@ describe VagrantPlugins::Cloudstack::Config do
|
|
28
28
|
its("service_offering_id") { should be_nil }
|
29
29
|
its("template_id") { should be_nil }
|
30
30
|
its("zone_id") { should be_nil }
|
31
|
+
its("keypair") { should be_nil }
|
32
|
+
its("pf_ip_address_id") { should be_nil }
|
33
|
+
its("pf_public_port") { should be_nil }
|
34
|
+
its("pf_private_port") { should be_nil }
|
31
35
|
end
|
32
36
|
|
33
37
|
describe "overriding defaults" do
|
@@ -75,6 +79,10 @@ describe VagrantPlugins::Cloudstack::Config do
|
|
75
79
|
let(:config_service_offering_id) { "foo" }
|
76
80
|
let(:config_template_id) { "foo" }
|
77
81
|
let(:config_zone_id) { "foo" }
|
82
|
+
let(:config_keypair) { "foo" }
|
83
|
+
let(:config_pf_ip_address_id) { "foo" }
|
84
|
+
let(:config_pf_public_port) { "foo" }
|
85
|
+
let(:config_pf_private_port) { "foo" }
|
78
86
|
|
79
87
|
def set_test_values(instance)
|
80
88
|
instance.host = config_host
|
@@ -90,6 +98,10 @@ describe VagrantPlugins::Cloudstack::Config do
|
|
90
98
|
instance.service_offering_id = config_service_offering_id
|
91
99
|
instance.template_id = config_template_id
|
92
100
|
instance.zone_id = config_zone_id
|
101
|
+
instance.keypair = config_keypair
|
102
|
+
instance.pf_ip_address_id = config_pf_ip_address_id
|
103
|
+
instance.pf_public_port = config_pf_public_port
|
104
|
+
instance.pf_private_port = config_pf_private_port
|
93
105
|
end
|
94
106
|
|
95
107
|
it "should raise an exception if not finalized" do
|
@@ -122,6 +134,10 @@ describe VagrantPlugins::Cloudstack::Config do
|
|
122
134
|
its("service_offering_id") { should == config_service_offering_id }
|
123
135
|
its("template_id") { should == config_template_id }
|
124
136
|
its("zone_id") { should == config_zone_id }
|
137
|
+
its("keypair") { should == config_keypair }
|
138
|
+
its("pf_ip_address_id") { should == config_pf_ip_address_id }
|
139
|
+
its("pf_public_port") { should == config_pf_public_port }
|
140
|
+
its("pf_private_port") { should == config_pf_private_port }
|
125
141
|
end
|
126
142
|
|
127
143
|
context "with a specific config set" do
|
@@ -153,6 +169,10 @@ describe VagrantPlugins::Cloudstack::Config do
|
|
153
169
|
its("service_offering_id") { should == config_service_offering_id }
|
154
170
|
its("template_id") { should == config_template_id }
|
155
171
|
its("zone_id") { should == config_zone_id }
|
172
|
+
its("keypair") { should == config_keypair }
|
173
|
+
its("pf_ip_address_id") { should == config_pf_ip_address_id }
|
174
|
+
its("pf_public_port") { should == config_pf_public_port }
|
175
|
+
its("pf_private_port") { should == config_pf_private_port }
|
156
176
|
end
|
157
177
|
|
158
178
|
describe "inheritance of parent config" do
|
data/vagrant-cloudstack.gemspec
CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.version = VagrantPlugins::Cloudstack::VERSION
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
8
|
s.license = "MIT"
|
9
|
-
s.authors = ["Mitchell Hashimoto", "Carl Loa Odin", "Tor-Åke Fransson", "Roeland Kuipers", "atsaki"]
|
9
|
+
s.authors = ["Mitchell Hashimoto", "Carl Loa Odin", "Tor-Åke Fransson", "Olle Lundberg", "Roeland Kuipers", "u-ichi", "atsaki"]
|
10
10
|
s.email = "carlodin@gmail.com"
|
11
11
|
s.homepage = "https://github.com/klarna/vagrant-cloudstack/"
|
12
12
|
s.summary = "Enables Vagrant to manage machines in Cloudstack."
|
metadata
CHANGED
@@ -1,18 +1,20 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vagrant-cloudstack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mitchell Hashimoto
|
8
8
|
- Carl Loa Odin
|
9
9
|
- Tor-Åke Fransson
|
10
|
+
- Olle Lundberg
|
10
11
|
- Roeland Kuipers
|
12
|
+
- u-ichi
|
11
13
|
- atsaki
|
12
14
|
autorequire:
|
13
15
|
bindir: bin
|
14
16
|
cert_chain: []
|
15
|
-
date: 2013-
|
17
|
+
date: 2013-12-03 00:00:00.000000000 Z
|
16
18
|
dependencies:
|
17
19
|
- !ruby/object:Gem::Dependency
|
18
20
|
name: fog
|
@@ -97,14 +99,19 @@ files:
|
|
97
99
|
- Gemfile
|
98
100
|
- lib/vagrant-cloudstack/action/connect_cloudstack.rb
|
99
101
|
- lib/vagrant-cloudstack/action/is_created.rb
|
102
|
+
- lib/vagrant-cloudstack/action/is_stopped.rb
|
100
103
|
- lib/vagrant-cloudstack/action/message_already_created.rb
|
101
104
|
- lib/vagrant-cloudstack/action/message_not_created.rb
|
105
|
+
- lib/vagrant-cloudstack/action/message_will_not_destroy.rb
|
102
106
|
- lib/vagrant-cloudstack/action/read_ssh_info.rb
|
103
107
|
- lib/vagrant-cloudstack/action/read_state.rb
|
104
108
|
- lib/vagrant-cloudstack/action/run_instance.rb
|
109
|
+
- lib/vagrant-cloudstack/action/start_instance.rb
|
110
|
+
- lib/vagrant-cloudstack/action/stop_instance.rb
|
105
111
|
- lib/vagrant-cloudstack/action/sync_folders.rb
|
106
112
|
- lib/vagrant-cloudstack/action/terminate_instance.rb
|
107
113
|
- lib/vagrant-cloudstack/action/timed_provision.rb
|
114
|
+
- lib/vagrant-cloudstack/action/wait_for_state.rb
|
108
115
|
- lib/vagrant-cloudstack/action/warn_networks.rb
|
109
116
|
- lib/vagrant-cloudstack/action.rb
|
110
117
|
- lib/vagrant-cloudstack/config.rb
|