vagrant-openstack-plugin-tom 0.12.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.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/.travis.yml +11 -0
- data/Authors.txt +11 -0
- data/CHANGELOG.md +185 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +23 -0
- data/README.md +278 -0
- data/Rakefile +21 -0
- data/dummy.box +0 -0
- data/example_box/README.md +13 -0
- data/example_box/metadata.json +3 -0
- data/example_vagrant_file +24 -0
- data/lib/vagrant-openstack-plugin.rb +53 -0
- data/lib/vagrant-openstack-plugin/action.rb +268 -0
- data/lib/vagrant-openstack-plugin/action/connect_openstack.rb +90 -0
- data/lib/vagrant-openstack-plugin/action/create_network_interfaces.rb +52 -0
- data/lib/vagrant-openstack-plugin/action/create_orchestration_stack.rb +97 -0
- data/lib/vagrant-openstack-plugin/action/create_server.rb +263 -0
- data/lib/vagrant-openstack-plugin/action/delete_orchestration_stack.rb +78 -0
- data/lib/vagrant-openstack-plugin/action/delete_server.rb +84 -0
- data/lib/vagrant-openstack-plugin/action/hard_reboot_server.rb +27 -0
- data/lib/vagrant-openstack-plugin/action/is_created.rb +16 -0
- data/lib/vagrant-openstack-plugin/action/is_paused.rb +16 -0
- data/lib/vagrant-openstack-plugin/action/is_snapshoting.rb +24 -0
- data/lib/vagrant-openstack-plugin/action/is_suspended.rb +16 -0
- data/lib/vagrant-openstack-plugin/action/message_already_created.rb +16 -0
- data/lib/vagrant-openstack-plugin/action/message_already_paused.rb +16 -0
- data/lib/vagrant-openstack-plugin/action/message_already_suspended.rb +16 -0
- data/lib/vagrant-openstack-plugin/action/message_not_created.rb +16 -0
- data/lib/vagrant-openstack-plugin/action/message_server_running.rb +16 -0
- data/lib/vagrant-openstack-plugin/action/message_snapshot_done.rb +16 -0
- data/lib/vagrant-openstack-plugin/action/message_snapshot_in_progress.rb +16 -0
- data/lib/vagrant-openstack-plugin/action/message_will_not_destroy.rb +16 -0
- data/lib/vagrant-openstack-plugin/action/pause_server.rb +27 -0
- data/lib/vagrant-openstack-plugin/action/read_ssh_info.rb +103 -0
- data/lib/vagrant-openstack-plugin/action/read_state.rb +39 -0
- data/lib/vagrant-openstack-plugin/action/reboot_server.rb +27 -0
- data/lib/vagrant-openstack-plugin/action/resume_server.rb +31 -0
- data/lib/vagrant-openstack-plugin/action/suspend_server.rb +27 -0
- data/lib/vagrant-openstack-plugin/action/sync_folders.rb +104 -0
- data/lib/vagrant-openstack-plugin/action/take_snapshot.rb +26 -0
- data/lib/vagrant-openstack-plugin/action/wait_for_state.rb +39 -0
- data/lib/vagrant-openstack-plugin/action/wait_for_task.rb +44 -0
- data/lib/vagrant-openstack-plugin/action/warn_networks.rb +19 -0
- data/lib/vagrant-openstack-plugin/command.rb +70 -0
- data/lib/vagrant-openstack-plugin/command/command_snapshot.rb +43 -0
- data/lib/vagrant-openstack-plugin/config.rb +246 -0
- data/lib/vagrant-openstack-plugin/errors.rb +71 -0
- data/lib/vagrant-openstack-plugin/plugin.rb +45 -0
- data/lib/vagrant-openstack-plugin/provider.rb +50 -0
- data/lib/vagrant-openstack-plugin/version.rb +5 -0
- data/locales/en.yml +154 -0
- data/spec/vagrant-openstack-plugin/config_spec.rb +152 -0
- data/vagrant-openstack-plugin.gemspec +24 -0
- metadata +142 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
require "log4r"
|
2
|
+
|
3
|
+
require 'vagrant/util/scoped_hash_override'
|
4
|
+
|
5
|
+
module VagrantPlugins
|
6
|
+
module OpenStack
|
7
|
+
module Action
|
8
|
+
class CreateNetworkInterfaces
|
9
|
+
include Vagrant::Util::ScopedHashOverride
|
10
|
+
|
11
|
+
def initialize(app, env)
|
12
|
+
@app = app
|
13
|
+
@logger = Log4r::Logger.new("vagrant_openstack::action::create_network_interfaces")
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
networks_to_configure = []
|
18
|
+
env[:machine].config.vm.networks.each_with_index do |network, slot_number|
|
19
|
+
type = network[0]
|
20
|
+
original_options = network[1]
|
21
|
+
next if type != :private_network
|
22
|
+
next if original_options[:auto_config] === false
|
23
|
+
next if slot_number == 0
|
24
|
+
|
25
|
+
options = scoped_hash_override(original_options, :openstack)
|
26
|
+
|
27
|
+
@logger.info "Configuring interface slot_number #{slot_number} options #{options}"
|
28
|
+
|
29
|
+
network_to_configure = {
|
30
|
+
:interface => slot_number,
|
31
|
+
}
|
32
|
+
|
33
|
+
if options[:ip]
|
34
|
+
network_to_configure = {
|
35
|
+
:type => :static,
|
36
|
+
:ip => options[:ip],
|
37
|
+
:netmask => "255.255.255.0",
|
38
|
+
}.merge(network_to_configure)
|
39
|
+
else
|
40
|
+
network_to_configure[:type] = :dhcp
|
41
|
+
end
|
42
|
+
|
43
|
+
networks_to_configure.push(network_to_configure)
|
44
|
+
end
|
45
|
+
env[:ui].info I18n.t('vagrant.actions.vm.network.configuring')
|
46
|
+
env[:machine].guest.capability(:configure_networks, networks_to_configure)
|
47
|
+
@app.call(env)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require "fog"
|
2
|
+
require "log4r"
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module OpenStack
|
6
|
+
module Action
|
7
|
+
class CreateOrchestrationStack
|
8
|
+
|
9
|
+
def initialize(app, env)
|
10
|
+
@app = app
|
11
|
+
@logger = Log4r::Logger.new(
|
12
|
+
"vagrant_openstack::action::create_orchestration_stack")
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
# Get the config.
|
17
|
+
config = env[:machine].provider_config
|
18
|
+
|
19
|
+
# Are we going to handle orchestration stacks?
|
20
|
+
if not config.orchestration_stack_name
|
21
|
+
return @app.call(env)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Create new fog orchestration service.
|
25
|
+
env[:openstack_orchestration] = Fog::Orchestration.new(
|
26
|
+
env[:fog_openstack_params])
|
27
|
+
|
28
|
+
# Check if stack is already created.
|
29
|
+
env[:openstack_orchestration].list_stacks.body['stacks'].each do |stack|
|
30
|
+
if config.orchestration_stack_name == stack['stack_name']
|
31
|
+
return @app.call(env)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# To avoid confusion, only one source for orchestration template
|
36
|
+
# should be set.
|
37
|
+
if [config.orchestration_cfn_template,
|
38
|
+
config.orchestration_cfn_template_file,
|
39
|
+
config.orchestration_cfn_template_url].count(nil) != 2
|
40
|
+
raise Errors::OrchestrationTemplateError,
|
41
|
+
:err => 'One source for orchestration template should be specified.'
|
42
|
+
end
|
43
|
+
|
44
|
+
# Prepare parameters for new orchestration stack.
|
45
|
+
# TODO: configurable parameters
|
46
|
+
stack_params = {
|
47
|
+
:disable_rollback => false,
|
48
|
+
:timeout_in_minutes => 5,
|
49
|
+
}
|
50
|
+
|
51
|
+
# Set template source.
|
52
|
+
if config.orchestration_cfn_template
|
53
|
+
stack_params[:template] = config.orchestration_cfn_template
|
54
|
+
elsif config.orchestration_cfn_template_file
|
55
|
+
if not File.exist?(config.orchestration_cfn_template_file)
|
56
|
+
raise Errors::OrchestrationNoTemplateFileError,
|
57
|
+
:fname => config.orchestration_cfn_template_file
|
58
|
+
end
|
59
|
+
|
60
|
+
# Load template file content. Newlines can cause parse error of
|
61
|
+
# input JSON string.
|
62
|
+
stack_params[:template] = ''
|
63
|
+
File.open(config.orchestration_cfn_template_file) { |file|
|
64
|
+
file.each_line do |line|
|
65
|
+
stack_params[:template] << line
|
66
|
+
end
|
67
|
+
}
|
68
|
+
else
|
69
|
+
stack_params[:template_url] = config.orchestration_cfn_template_url
|
70
|
+
end
|
71
|
+
|
72
|
+
# Set template parameters.
|
73
|
+
stack_params[:parameters] = config.orchestration_cfn_template_parameters
|
74
|
+
|
75
|
+
# Create new stack.
|
76
|
+
env[:ui].info(I18n.t("vagrant_openstack.creating_orchestration_stack"))
|
77
|
+
stack = env[:openstack_orchestration].create_stack(
|
78
|
+
config.orchestration_stack_name, stack_params)
|
79
|
+
|
80
|
+
# Write UUID of newly created stack into file for later use (stack removal).
|
81
|
+
created_stacks_fname = env[:machine].data_dir + 'orchestration_stacks'
|
82
|
+
message = 'Saving information about created orchestration stack '
|
83
|
+
message << "#{config.orchestration_stack_name}, "
|
84
|
+
message << "UUID=#{stack.body['stack']['id']} "
|
85
|
+
message << "to file #{created_stacks_fname}."
|
86
|
+
@logger.info(message)
|
87
|
+
|
88
|
+
File.open(created_stacks_fname, 'a') do |file|
|
89
|
+
file.puts stack.body['stack']['id']
|
90
|
+
end
|
91
|
+
|
92
|
+
@app.call(env)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,263 @@
|
|
1
|
+
require "fog"
|
2
|
+
require "log4r"
|
3
|
+
|
4
|
+
require 'vagrant/util/retryable'
|
5
|
+
|
6
|
+
module VagrantPlugins
|
7
|
+
module OpenStack
|
8
|
+
module Action
|
9
|
+
# This creates the OpenStack server.
|
10
|
+
class CreateServer
|
11
|
+
include Vagrant::Util::Retryable
|
12
|
+
|
13
|
+
def initialize(app, env)
|
14
|
+
@app = app
|
15
|
+
@logger = Log4r::Logger.new("vagrant_openstack::action::create_server")
|
16
|
+
end
|
17
|
+
|
18
|
+
def call(env)
|
19
|
+
# Get the configs
|
20
|
+
config = env[:machine].provider_config
|
21
|
+
|
22
|
+
# Find the flavor
|
23
|
+
env[:ui].info(I18n.t("vagrant_openstack.finding_flavor"))
|
24
|
+
flavor = find_matching(env[:openstack_compute].flavors.all, config.flavor)
|
25
|
+
raise Errors::NoMatchingFlavor if !flavor
|
26
|
+
|
27
|
+
# Find the image
|
28
|
+
env[:ui].info(I18n.t("vagrant_openstack.finding_image"))
|
29
|
+
image = find_matching(env[:openstack_compute].images, config.image)
|
30
|
+
raise Errors::NoMatchingImage if !image
|
31
|
+
|
32
|
+
# Figure out the name for the server
|
33
|
+
server_name = config.server_name || env[:machine].name
|
34
|
+
|
35
|
+
# Build the options for launching...
|
36
|
+
options = {
|
37
|
+
:flavor_ref => flavor.id,
|
38
|
+
:image_ref => image.id,
|
39
|
+
:name => server_name,
|
40
|
+
:key_name => config.keypair_name,
|
41
|
+
:metadata => config.metadata,
|
42
|
+
:user_data => config.user_data,
|
43
|
+
:security_groups => config.security_groups,
|
44
|
+
:os_scheduler_hints => config.scheduler_hints,
|
45
|
+
:availability_zone => config.availability_zone
|
46
|
+
}
|
47
|
+
|
48
|
+
# Fallback to only one network, otherwise `config.networks` overrides
|
49
|
+
unless config.networks
|
50
|
+
if config.network
|
51
|
+
config.networks = [ config.network ]
|
52
|
+
else
|
53
|
+
config.networks = []
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Find networks if provided
|
58
|
+
unless config.networks.empty?
|
59
|
+
env[:ui].info(I18n.t("vagrant_openstack.finding_network"))
|
60
|
+
options[:nics] = Array.new
|
61
|
+
config.networks.each_with_index do |os_network_name, i|
|
62
|
+
|
63
|
+
# Use the configured OpenStack network, if it exists.
|
64
|
+
os_network = find_matching(env[:openstack_network].networks, os_network_name)
|
65
|
+
if os_network
|
66
|
+
current = { :net_id => os_network.id }
|
67
|
+
|
68
|
+
# Match the OpenStack network to a corresponding
|
69
|
+
# config.vm.network option. If there is one, use that for its
|
70
|
+
# IP address.
|
71
|
+
config_network = env[:machine].config.vm.networks[i]
|
72
|
+
if config_network
|
73
|
+
ip_address = config_network[1][:ip]
|
74
|
+
current[:v4_fixed_ip] = ip_address if ip_address
|
75
|
+
end
|
76
|
+
|
77
|
+
options[:nics] << current
|
78
|
+
end
|
79
|
+
end
|
80
|
+
env[:ui].info("options[:nics]: #{options[:nics]}")
|
81
|
+
end
|
82
|
+
|
83
|
+
# Output the settings we're going to use to the user
|
84
|
+
env[:ui].info(I18n.t("vagrant_openstack.launching_server"))
|
85
|
+
env[:ui].info(" -- Flavor: #{flavor.name}")
|
86
|
+
env[:ui].info(" -- Image: #{image.name}")
|
87
|
+
env[:ui].info(" -- Name: #{server_name}")
|
88
|
+
config.networks.each do |n|
|
89
|
+
env[:ui].info(" -- Network: #{n}")
|
90
|
+
end
|
91
|
+
if config.security_groups
|
92
|
+
env[:ui].info(" -- Security Groups: #{config.security_groups}")
|
93
|
+
end
|
94
|
+
|
95
|
+
# Create the server
|
96
|
+
server = env[:openstack_compute].servers.create(options)
|
97
|
+
|
98
|
+
# Store the ID right away so we can track it
|
99
|
+
env[:machine].id = server.id
|
100
|
+
|
101
|
+
# Wait for the server to finish building
|
102
|
+
env[:ui].info(I18n.t("vagrant_openstack.waiting_for_build"))
|
103
|
+
retryable(:on => Fog::Errors::TimeoutError, :tries => 200) do
|
104
|
+
# If we're interrupted don't worry about waiting
|
105
|
+
next if env[:interrupted]
|
106
|
+
|
107
|
+
# Set the progress
|
108
|
+
env[:ui].clear_line
|
109
|
+
env[:ui].report_progress(server.progress, 100, false)
|
110
|
+
|
111
|
+
# Wait for the server to be ready
|
112
|
+
begin
|
113
|
+
server.wait_for(5) { ready? }
|
114
|
+
# Once the server is up and running assign a floating IP if we have one
|
115
|
+
floating_ip = config.floating_ip
|
116
|
+
# try to automatically allocate and associate a floating IP
|
117
|
+
if floating_ip && floating_ip.to_sym == :auto
|
118
|
+
if config.floating_ip_pool
|
119
|
+
env[:ui].info("Allocating floating IP address from pool: #{config.floating_ip_pool}")
|
120
|
+
address = env[:openstack_compute].allocate_address(config.floating_ip_pool).body["floating_ip"]
|
121
|
+
if address["ip"].nil?
|
122
|
+
raise Errors::FloatingIPNotAllocated
|
123
|
+
else
|
124
|
+
floating_ip = address["ip"]
|
125
|
+
end
|
126
|
+
else
|
127
|
+
addresses = env[:openstack_compute].addresses
|
128
|
+
free_floating = addresses.find_index {|a| a.fixed_ip.nil?}
|
129
|
+
if free_floating.nil?
|
130
|
+
raise Errors::FloatingIPNotFound
|
131
|
+
else
|
132
|
+
floating_ip = addresses[free_floating].ip
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# try to automatically associate the next available unassigned ip in the given pool
|
138
|
+
if floating_ip && floating_ip.to_sym == :associate_unassigned
|
139
|
+
if config.floating_ip_pool
|
140
|
+
env[:ui].info("Associating floating IP address from pool: #{config.floating_ip_pool}")
|
141
|
+
addresses = env[:openstack_compute].addresses
|
142
|
+
|
143
|
+
# grab the next available IP in this pool which is not currently allocated:
|
144
|
+
address = env[:openstack_compute].addresses.find { |thisone|
|
145
|
+
(thisone.attributes[:pool].eql? config.floating_ip_pool and thisone.attributes[:instance_id].nil?)
|
146
|
+
}
|
147
|
+
|
148
|
+
if address.nil?
|
149
|
+
raise Errors::FloatingUnassignedIPNotFound
|
150
|
+
else
|
151
|
+
floating_ip = address.attributes[:ip]
|
152
|
+
end
|
153
|
+
result = env[:openstack_compute].associate_address(server.id,floating_ip)
|
154
|
+
if result[:status] != 202
|
155
|
+
raise Errors::FloatingIPFailedAssociate
|
156
|
+
else
|
157
|
+
env[:ui].info("Found and Associated floating IP address #{address.attributes[:ip]} from pool #{config.floating_ip_pool}")
|
158
|
+
end
|
159
|
+
else
|
160
|
+
raise Errors::FloatingUnassignedRequiresPool
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
if floating_ip
|
165
|
+
floater = env[:openstack_compute].addresses.find { |thisone| thisone.ip.eql? floating_ip }
|
166
|
+
floater.server = server
|
167
|
+
end
|
168
|
+
|
169
|
+
# Process disks if provided
|
170
|
+
volumes = Array.new
|
171
|
+
if config.disks && !config.disks.empty?
|
172
|
+
env[:ui].info(I18n.t("vagrant_openstack.creating_disks"))
|
173
|
+
config.disks.each do |disk|
|
174
|
+
volume = env[:openstack_compute].volumes.all.find{|v| v.name ==
|
175
|
+
disk["name"] and
|
176
|
+
v.description ==
|
177
|
+
disk["description"] and
|
178
|
+
v.size ==
|
179
|
+
disk["size"] and
|
180
|
+
v.ready? }
|
181
|
+
if volume
|
182
|
+
env[:ui].info("re-using volume: #{disk["name"]}")
|
183
|
+
disk["volume_id"] = volume.id
|
184
|
+
else
|
185
|
+
env[:ui].info("creating volume: #{disk["name"]}")
|
186
|
+
disk["volume_id"] = env[:openstack_compute].create_volume(
|
187
|
+
disk["name"], disk["description"], disk["size"]).\
|
188
|
+
data[:body]["volume"]["id"]
|
189
|
+
volumes << { :id => disk["volume_id"] }
|
190
|
+
end
|
191
|
+
|
192
|
+
# mount points are not expected to be meaningful
|
193
|
+
# add useful support if your cloud respects them
|
194
|
+
begin
|
195
|
+
# Assume instance has only one disk
|
196
|
+
nova_offset = 1
|
197
|
+
# Increase counter in case we have swap or ephemeral disks.
|
198
|
+
if flavor.swap != 0
|
199
|
+
nova_offset += 1
|
200
|
+
end
|
201
|
+
if flavor.ephemeral != 0
|
202
|
+
nova_offset += 1
|
203
|
+
end
|
204
|
+
server.attach_volume(disk["volume_id"], "/dev/vd#{("c".."z").to_a[server.volume_attachments.length + nova_offset]}")
|
205
|
+
server.wait_for{ volume_attachments.any?{|vol| vol["id"]==disk["volume_id"]} }
|
206
|
+
rescue Excon::Errors::Error => e
|
207
|
+
raise Errors::VolumeBadState, :volume => disk["name"], :state => e.message
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
# store this so we can use it later
|
213
|
+
env[:floating_ip] = floating_ip
|
214
|
+
|
215
|
+
rescue RuntimeError => e
|
216
|
+
# If we don't have an error about a state transition, then
|
217
|
+
# we just move on.
|
218
|
+
raise if e.message !~ /should have transitioned/
|
219
|
+
raise Errors::CreateBadState, :state => server.state.downcase
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
if !env[:interrupted]
|
224
|
+
# Clear the line one more time so the progress is removed
|
225
|
+
env[:ui].clear_line
|
226
|
+
|
227
|
+
# Wait for SSH to become available
|
228
|
+
env[:ui].info(I18n.t("vagrant_openstack.waiting_for_ssh"))
|
229
|
+
while true
|
230
|
+
begin
|
231
|
+
# If we're interrupted then just back out
|
232
|
+
break if env[:interrupted]
|
233
|
+
break if env[:machine].communicate.ready?
|
234
|
+
rescue Errno::ENETUNREACH, Errno::EHOSTUNREACH
|
235
|
+
end
|
236
|
+
sleep 2
|
237
|
+
end
|
238
|
+
|
239
|
+
env[:ui].info(I18n.t("vagrant_openstack.ready"))
|
240
|
+
end
|
241
|
+
|
242
|
+
@app.call(env)
|
243
|
+
end
|
244
|
+
|
245
|
+
protected
|
246
|
+
|
247
|
+
# This method finds a matching _thing_ in a collection of
|
248
|
+
# _things_. This works matching if the ID or NAME equals to
|
249
|
+
# `name`. Or, if `name` is a regexp, a partial match is chosen
|
250
|
+
# as well.
|
251
|
+
def find_matching(collection, name)
|
252
|
+
collection.each do |single|
|
253
|
+
return single if single.id == name
|
254
|
+
return single if single.name == name
|
255
|
+
return single if name.is_a?(Regexp) && name =~ single.name
|
256
|
+
end
|
257
|
+
|
258
|
+
nil
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require "fog"
|
2
|
+
require "log4r"
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module OpenStack
|
6
|
+
module Action
|
7
|
+
class DeleteOrchestrationStack
|
8
|
+
|
9
|
+
def initialize(app, env)
|
10
|
+
@app = app
|
11
|
+
@logger = Log4r::Logger.new(
|
12
|
+
"vagrant_openstack::action::delete_orchestration_stack")
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
# Get the config.
|
17
|
+
config = env[:machine].provider_config
|
18
|
+
|
19
|
+
# Load IDs for orchestration stacks created by vagrant and this
|
20
|
+
# project.
|
21
|
+
created_stacks_fname = env[:machine].data_dir + 'orchestration_stacks'
|
22
|
+
|
23
|
+
# Return if no action is needed.
|
24
|
+
if not config.orchestration_stack_destroy or not File.exist?(created_stacks_fname)
|
25
|
+
env[:machine].id = nil
|
26
|
+
return @app.call(env)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Create new fog orchestration service.
|
30
|
+
env[:openstack_orchestration] = Fog::Orchestration.new(
|
31
|
+
env[:fog_openstack_params])
|
32
|
+
|
33
|
+
# Load IDs of stacks to be deleted.
|
34
|
+
available_stacks = env[:openstack_orchestration].list_stacks.body['stacks']
|
35
|
+
stacks_to_delete = []
|
36
|
+
File.open(created_stacks_fname) { |file|
|
37
|
+
file.each_line do |stack_id|
|
38
|
+
stack = find_stack(available_stacks, stack_id.chomp!)
|
39
|
+
next if not stack
|
40
|
+
stacks_to_delete << stack
|
41
|
+
end
|
42
|
+
}
|
43
|
+
|
44
|
+
# Delete stacks.
|
45
|
+
if stacks_to_delete.length > 0
|
46
|
+
env[:ui].info(I18n.t("vagrant_openstack.deleting_orchestration_stacks"))
|
47
|
+
end
|
48
|
+
|
49
|
+
stacks_to_delete.each do |stack|
|
50
|
+
@logger.info("Removing orchestration stack #{stack['stack_name']} (#{stack['id']}).")
|
51
|
+
env[:openstack_orchestration].delete_stack(
|
52
|
+
stack['stack_name'], stack['id'])
|
53
|
+
|
54
|
+
stacks_from_file.delete(stack)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Delete file holding created stack IDs.
|
58
|
+
@logger.info("Deleting file #{created_stacks_fname}.")
|
59
|
+
File.delete(created_stacks_fname)
|
60
|
+
|
61
|
+
env[:machine].id = nil
|
62
|
+
@app.call(env)
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def find_stack(available_stacks, stack_id)
|
68
|
+
available_stacks.each do |stack|
|
69
|
+
if stack['id'] == stack_id
|
70
|
+
return stack
|
71
|
+
end
|
72
|
+
end
|
73
|
+
false
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|