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