kytoon 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,10 @@
1
+ * Wed Sep 19 2012 Dan Prince <dprince@redhat.com> - 1.2.0
2
+ - Add provider for OpenStack.
3
+ - Add bin/kytoon with commands corresponding to rake tasks.
4
+ - Move rake tasks under 'kytoon' namespace (previously used 'group').
5
+ - Updates to raise KytoonException instead of just raise.
6
+ - Rename gateway_ip task to just ip.
7
+
1
8
  * Thu Aug 23 2012 Dan Prince <dprince@redhat.com> - 1.1.1
2
9
  - Add 'libvirt_use_sudo' option to config file.
3
10
  - Move config parameter checks into specific providers.
data/Gemfile CHANGED
@@ -10,6 +10,7 @@ group :development do
10
10
  gem "bundler", "~> 1.1.4"
11
11
  gem "builder", "~> 3.0.0"
12
12
  gem "jeweler", "~> 1.8.3"
13
+ gem "thor", "~> 0.14"
13
14
  gem "uuidtools", "~> 2.1.2"
14
15
  gem "mocha", "~> 0.12.1"
15
16
  end
data/Gemfile.lock CHANGED
@@ -15,6 +15,7 @@ GEM
15
15
  rake (0.9.2.2)
16
16
  rdoc (3.12)
17
17
  json (~> 1.4)
18
+ thor (0.16.0)
18
19
  uuidtools (2.1.2)
19
20
 
20
21
  PLATFORMS
@@ -26,4 +27,5 @@ DEPENDENCIES
26
27
  jeweler (~> 1.8.3)
27
28
  mocha (~> 0.12.1)
28
29
  rdoc (~> 3.12)
30
+ thor (~> 0.14)
29
31
  uuidtools (~> 2.1.2)
data/README.md ADDED
@@ -0,0 +1,214 @@
1
+ # Kytoon
2
+
3
+ Create small virtual server groups
4
+
5
+ ## Description
6
+
7
+ Provides both a CLI (bin/kytoon) and set of rake tasks to help automate the creation and configuration of virtual server groups. Kytoon provides the ability to create projects that can be used by team members and continuous integration systems to create similar (if not identical) groups of servers for development and/or testing. Configuration information is stored in JSON and YAML formats which can be easily parsed, edited, and version controlled.
8
+
9
+ Inspired by and based on the Chef VPC Toolkit.
10
+
11
+ ## Features
12
+
13
+ * Multiple providers (see below)
14
+ * A CLI with matching set of rake tasks.
15
+ * Create server groups with multiple nodes.
16
+ * Automatically injects your ssh into each server group.
17
+ * Configures hostnames (host files) on nodes within each group. Once you ssh
18
+ into the group use preconfigured hostnames to access all the nodes.
19
+
20
+ ## Provider support
21
+
22
+ - Libvirt: manage instances on local machine w/ libvirt, virt-clone, and libguestfs
23
+ - XenServer: manage instances on a remote XenServer box (via ssh)
24
+ - OpenStack: create instances in the cloud.
25
+
26
+ ## Installation
27
+
28
+ Gem install kytoon.
29
+
30
+ gem install kytoon
31
+
32
+ Create a .kytoon.conf file in your $HOME directory.
33
+
34
+ # The default group type.
35
+ # Set to one of: openstack, libvirt, xenserver
36
+ group_type: openstack
37
+
38
+ # Openstack Settings
39
+ openstack_url: <auth_url>
40
+ openstack_username: <username>
41
+ openstack_password: <password>
42
+ openstack_network_name: public # Optional: defaults to public
43
+ openstack_keypair_name: < keyname > # Optional: file injection via personalities is the default
44
+ openstack_ip_type: 4 # IP type (4 or 6): defaults to 4
45
+ openstack_build_timeout: 480 # Server build timeout. Defaults to: 480
46
+ openstack_ping_timeout: 60 # Server build timeout. Defaults to: 60
47
+
48
+ # Libvirt settings
49
+ # Whether commands to create local group should use sudo
50
+ libvirt_use_sudo: False
51
+
52
+ ## Defining server groups
53
+
54
+ Server group config files are used to define how Kytoon configures
55
+ each server group. These files typically live inside of project are
56
+ provider specific. The config files control things like memory, hostname,
57
+ flavor, etc. Each group should define identify one instance as the 'gateway' host which marks it as the primary access point for SSH access into the group.
58
+
59
+ By default Kytoon looks for config/server_group.json in the current directory.
60
+ You can override this with Rake using GROUP_CONFIG or bin/kytoon using --group-config.
61
+
62
+ Below are example server_group.json config files for each provider.
63
+
64
+ For Openstack:
65
+
66
+ ```bash
67
+
68
+ cat > config/server_group.json <<-"EOF_CAT"
69
+ {
70
+ "name": "Fedora",
71
+ "servers": [
72
+ {
73
+ "hostname": "nova1",
74
+ "image_ref": "1234",
75
+ "flavor_ref": "5678",
76
+ "gateway": "true"
77
+ },
78
+ {
79
+ "hostname": "compute1",
80
+ "image_ref": "1234",
81
+ "flavor_ref": "5678"
82
+ }
83
+ ]
84
+ }
85
+ EOF_CAT
86
+ ```
87
+
88
+ For Libvirt (uses libvirt DHCP server for instance IP configuration):
89
+
90
+ ```bash
91
+
92
+ cat > config/server_group.json <<-"EOF_CAT"
93
+ {
94
+ "name": "Fedora",
95
+ "servers": [
96
+ {
97
+ "hostname": "nova1",
98
+ "memory": "1",
99
+ "gateway": "true",
100
+ "original_xml": "/home/dprince/f17.xml",
101
+ "create_cow": "true"
102
+ }
103
+ ]
104
+ }
105
+ EOF_CAT
106
+ ```
107
+
108
+ For XenServer (uses Openstack Guest agent for instance configuration):
109
+ ```bash
110
+
111
+ cat > config/server_group.json <<-"EOF_CAT"
112
+ {
113
+ "name": "Fedora",
114
+ "netmask": "255.255.255.0",
115
+ "gateway": "192.168.0.1",
116
+ "broadcast": "192.168.0.127",
117
+ "dns_nameserver": "8.8.8.8",
118
+ "network_type": "static",
119
+ "public_ip_bridge": "xenbr0",
120
+ "bridge": "xenbr1",
121
+ "servers": [
122
+ {
123
+ "hostname": "login",
124
+ "image_path": "/images/fedora-agent2.xva",
125
+ "ip_address": "192.168.0.2",
126
+ "mac": "e2:6d:71:67:7e:66"
127
+ },
128
+ {
129
+ "hostname": "nova1",
130
+ "image_path": "/images/fedora-agent2.xva",
131
+ "ip_address": "192.168.0.3",
132
+ "mac": "e2:ad:a1:a7:ae:67"
133
+ }
134
+ ]
135
+ }
136
+ EOF_CAT
137
+ ```
138
+
139
+ ## Command line
140
+
141
+ The following options are supported on the command line:
142
+
143
+ kytoon create # Create a new server group.
144
+ kytoon delete # Delete a server group.
145
+ kytoon help [TASK] # Describe available tasks or one specific task
146
+ kytoon ip # Print the IP address of the gateway server
147
+ kytoon list # List existing server groups.
148
+ kytoon show # Print information for a server group.
149
+ kytoon ssh # SSH into a group.
150
+
151
+ ## Rakefile configuration
152
+
153
+ To include Kytoon rake tasks in your own project add the following to your
154
+ Rakefile:
155
+
156
+ KYTOON_PROJECT = "#{File.dirname(__FILE__)}" unless defined?(KYTOON_PROJECT)
157
+ require 'rubygems'
158
+ require 'kytoon'
159
+ include Kytoon
160
+ Dir[File.join("#{Kytoon::Version::KYTOON_ROOT}/rake", '*.rake')].each do |rakefile|
161
+ import(rakefile)
162
+ end
163
+
164
+ ## Rake Tasks
165
+
166
+ Example commands:
167
+
168
+ * Create a new server group.
169
+
170
+ $ rake kytoon:create
171
+
172
+ * List your currently running server groups.
173
+
174
+ $ rake kytoon:list
175
+
176
+ * SSH into the current (most recently created) server group
177
+
178
+ $ rake kytoon:ssh
179
+
180
+ * SSH into a server group with an ID of 3
181
+
182
+ $ rake kytoon:ssh GROUP_ID=3
183
+
184
+ * Delete the server group with an ID of 3
185
+
186
+ $ rake kytoon:delete GROUP_ID=3
187
+
188
+
189
+ ## Bash Automation Script
190
+
191
+ The following is an example bash script to spin up a group and run commands via SSH.
192
+
193
+ ```bash
194
+ #!/bin/bash
195
+ # override the group type specified in .kytoon.conf
196
+ export GROUP_TYPE=libvirt
197
+
198
+ trap "rake kytoon:delete" INT TERM EXIT # cleanup the group on exit
199
+
200
+ # create a server group (uses config/server_group.json)
201
+ rake kytoon:create
202
+
203
+ # create a server group with alternate json file
204
+ rake kytoon:create GROUP_CONFIG=config/my_group.json
205
+
206
+ # Run some scripts on the login server
207
+ rake kytoon:ssh bash <<-EOF_BASH
208
+ echo 'It works!'
209
+ EOF_BASH
210
+ ```
211
+
212
+ ## Copyright
213
+
214
+ Copyright (c) 2012 Red Hat Inc. See LICENSE.txt for further details.
data/Rakefile CHANGED
@@ -18,17 +18,19 @@ Rake::Task['test'].comment = "Unit"
18
18
 
19
19
  begin
20
20
  require 'jeweler'
21
- Jeweler::Tasks.new do |gemspec|
22
- gemspec.name = "kytoon"
23
- gemspec.summary = "Create & configure ephemeral virtual private clouds."
24
- gemspec.description = "A set of Rake tasks that provide a framework to help automate the creation and configuration of VPC server groups."
25
- gemspec.email = "dprince@redhat.com"
26
- gemspec.homepage = "http://github.com/dprince/kytoon"
27
- gemspec.authors = ["Dan Prince"]
28
- gemspec.add_dependency 'rake'
29
- gemspec.add_dependency 'builder'
30
- gemspec.add_dependency 'json'
31
- gemspec.add_dependency 'uuidtools'
21
+ Jeweler::Tasks.new do |gem|
22
+ gem.name = "kytoon"
23
+ gem.summary = "Create & configure ephemeral virtual private clouds."
24
+ gem.description = "A set of Rake tasks that provide a framework to help automate the creation and configuration of VPC server groups."
25
+ gem.email = "dprince@redhat.com"
26
+ gem.homepage = "http://github.com/dprince/kytoon"
27
+ gem.authors = ["Dan Prince"]
28
+ gem.add_dependency 'rake'
29
+ gem.add_dependency 'builder'
30
+ gem.add_dependency 'json'
31
+ gem.add_dependency 'openstack-compute'
32
+ gem.add_dependency 'thor'
33
+ gem.add_dependency 'uuidtools'
32
34
  end
33
35
  rescue LoadError
34
36
  puts "Jeweler not available. Install it with: sudo gem install jeweler"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.1
1
+ 1.2.0
data/bin/kytoon ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ require "rubygems"
3
+ require "kytoon"
4
+
5
+ KYTOON_PROJECT = ENV['PWD']
6
+
7
+ Kytoon::ThorTasks.start
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "Fedora",
3
+ "servers": [
4
+ {
5
+ "hostname": "nova1",
6
+ "image_ref": "1234",
7
+ "flavor_ref": "5678",
8
+ "gateway": "true",
9
+ "keypair": "test"
10
+ }
11
+ ]
12
+ }
data/lib/kytoon.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require 'kytoon/util'
2
2
  require 'kytoon/ssh_util'
3
+ require 'kytoon/thor_tasks'
4
+ require 'kytoon/exception'
3
5
  require 'kytoon/version'
4
6
  require 'kytoon/xml_util'
5
7
  require 'kytoon/server_group'
@@ -0,0 +1,8 @@
1
+ class KytoonException < StandardError
2
+ end
3
+
4
+ class ConfigException < KytoonException
5
+ end
6
+
7
+ class NoServerGroupExists < KytoonException
8
+ end
@@ -170,7 +170,7 @@ fi
170
170
  }, server['ip_address']) do |ok, out|
171
171
  if not ok
172
172
  puts out
173
- raise "Failed to copy host file to instance #{server['hostname']}."
173
+ raise KytoonException, "Failed to copy host file to instance #{server['hostname']}."
174
174
  end
175
175
  end
176
176
  end
@@ -182,12 +182,12 @@ fi
182
182
  id = options[:id]
183
183
  if id.nil? then
184
184
  group=ServerGroup.most_recent
185
- raise "No server group files exist." if group.nil?
185
+ raise NoServerGroupExists, "No server group files exist." if group.nil?
186
186
  id=group.id
187
187
  end
188
188
 
189
189
  out_file=File.join(@@data_dir, "#{id}.json")
190
- raise "No server group files exist." if not File.exists?(out_file)
190
+ raise NoServerGroupExists, "No server group files exist." if not File.exists?(out_file)
191
191
  ServerGroup.from_json(IO.read(out_file))
192
192
  end
193
193
 
@@ -223,7 +223,7 @@ fi
223
223
  REXML::XPath.each(dom, "//disk[1]/source") do |source_xml|
224
224
  return source_xml.attributes['file']
225
225
  end
226
- raise "Unable to find disk path for instance."
226
+ raise KytoonException, "Unable to find disk path for instance."
227
227
  end
228
228
 
229
229
  def self.create_instance(group_id, inst_name, memory_gigs, original, original_xml, disk_path, create_cow, ssh_public_key, sudo)
@@ -288,7 +288,7 @@ fi
288
288
  retval=$?
289
289
  if not retval.success?
290
290
  puts out
291
- raise "Failed to create instance #{inst_name}."
291
+ raise KytoonException, "Failed to create instance #{inst_name}."
292
292
  end
293
293
 
294
294
  # lookup server IP here...
@@ -298,7 +298,7 @@ fi
298
298
  REXML::XPath.each(dom, "//interface/mac") do |interface_xml|
299
299
  mac_addr = interface_xml.attributes['address']
300
300
  end
301
- raise "Failed to lookup mac address for #{inst_name}" if mac_addr.nil?
301
+ raise KytoonException, "Failed to lookup mac address for #{inst_name}" if mac_addr.nil?
302
302
 
303
303
  instance_ip = %x{grep -i #{mac_addr} /var/lib/libvirt/dnsmasq/default.leases | cut -d " " -f 3}.chomp
304
304
  count = 0
@@ -307,7 +307,7 @@ fi
307
307
  sleep 1
308
308
  count += 1
309
309
  if count >= 60 then
310
- raise "Failed to lookup ip address for #{inst_name}"
310
+ raise KytoonException, "Failed to lookup ip address for #{inst_name}"
311
311
  end
312
312
  end
313
313
  return instance_ip
@@ -335,7 +335,7 @@ fi
335
335
  retval=$?
336
336
  if not retval.success?
337
337
  puts out
338
- raise "Failed to cleanup instances."
338
+ raise KytoonException, "Failed to cleanup instances."
339
339
  end
340
340
  end
341
341
 
@@ -0,0 +1,5 @@
1
+ require 'kytoon/providers/openstack/server_group'
2
+
3
+ Kytoon::Util.check_config_param('openstack_url')
4
+ Kytoon::Util.check_config_param('openstack_username')
5
+ Kytoon::Util.check_config_param('openstack_password')
@@ -0,0 +1,317 @@
1
+ require 'json'
2
+ require 'kytoon/util'
3
+ require 'openstack/compute'
4
+
5
+ module Kytoon
6
+
7
+ module Providers
8
+
9
+ module Openstack
10
+
11
+ # Openstack server group provider.
12
+ class ServerGroup
13
+
14
+ @@connection=nil
15
+ @@data_dir=File.join(KYTOON_PROJECT, "tmp", "openstack")
16
+
17
+ def self.data_dir
18
+ @@data_dir
19
+ end
20
+
21
+ def self.data_dir=(dir)
22
+ @@data_dir=dir
23
+ end
24
+
25
+ CONFIG_FILE = KYTOON_PROJECT + File::SEPARATOR + "config" + File::SEPARATOR + "server_group.json"
26
+
27
+ attr_accessor :id
28
+ attr_accessor :name
29
+
30
+ def initialize(options={})
31
+ @id = options[:id] || Time.now.to_i
32
+ @name = options[:name]
33
+ @servers=[]
34
+ end
35
+
36
+ def server(name)
37
+ @servers.select {|s| s['hostname'] == name}[0] if @servers.size > 0
38
+ end
39
+
40
+ def servers
41
+ @servers
42
+ end
43
+
44
+ def gateway_ip
45
+ @servers.select {|s| s['gateway'] == 'true' }[0]['ip_address'] if @servers.size > 0
46
+ end
47
+
48
+ # generate a Server Group XML from server_group.json
49
+ def self.from_json(json)
50
+
51
+ json_hash=JSON.parse(json)
52
+
53
+ sg=ServerGroup.new(
54
+ :id => json_hash["id"],
55
+ :name => json_hash["name"]
56
+ )
57
+ json_hash["servers"].each do |server_hash|
58
+
59
+ sg.servers << {
60
+ 'id' => server_hash['id'],
61
+ 'hostname' => server_hash['hostname'],
62
+ 'image_ref' => server_hash['image_ref'],
63
+ 'flavor_ref' => server_hash['flavor_ref'],
64
+ 'keypair_name' => server_hash['keypair_name'],
65
+ 'gateway' => server_hash['gateway'] || "false",
66
+ 'ip_address' => server_hash['ip_address']
67
+ }
68
+ end
69
+ return sg
70
+ end
71
+
72
+ def pretty_print
73
+
74
+ puts "Group ID: #{@id}"
75
+ puts "name: #{@name}"
76
+ puts "gateway IP: #{self.gateway_ip}"
77
+ puts "Servers:"
78
+ servers.each do |server|
79
+ puts "\tname: #{server['hostname']}"
80
+ puts "\t--"
81
+ end
82
+
83
+ end
84
+
85
+ def server_names
86
+
87
+ names=[]
88
+
89
+ servers.each do |server|
90
+ if block_given? then
91
+ yield server['hostname']
92
+ else
93
+ names << server['hostname']
94
+ end
95
+ end
96
+
97
+ names
98
+
99
+ end
100
+
101
+ def cache_to_disk
102
+
103
+ sg_hash = {
104
+ 'id' => @id,
105
+ 'name' => @name,
106
+ 'servers' => []
107
+ }
108
+ @servers.each do |server|
109
+ sg_hash['servers'] << {'id' => server['id'], 'hostname' => server['hostname'], 'image_ref' => server['image_ref'], 'gateway' => server['gateway'], 'flavor_ref' => server['flavor_ref'], 'ip_address' => server['ip_address']}
110
+ end
111
+
112
+ FileUtils.mkdir_p(@@data_dir)
113
+ File.open(File.join(@@data_dir, "#{@id}.json"), 'w') do |f|
114
+ f.chmod(0600)
115
+ f.write(sg_hash.to_json)
116
+ end
117
+ end
118
+
119
+ def delete
120
+ servers.each do |server|
121
+ ServerGroup.destroy_instance(server['id'])
122
+ end
123
+ out_file=File.join(@@data_dir, "#{@id}.json")
124
+ File.delete(out_file) if File.exists?(out_file)
125
+ end
126
+
127
+
128
+ def self.create(sg)
129
+
130
+ hosts_file_data = "127.0.0.1\tlocalhost localhost.localdomain\n"
131
+
132
+ build_timeout = (Util.load_configs['openstack_build_timeout'] || 60).to_i
133
+
134
+ sg.servers.each do |server|
135
+ server_id = create_instance(sg.id, server['hostname'], server['image_ref'], server['flavor_ref'], server['keypair_name']).id
136
+
137
+ server['id'] = server_id
138
+ sg.cache_to_disk
139
+ end
140
+
141
+ begin
142
+ Timeout::timeout(build_timeout) do
143
+ ips = get_server_ips
144
+ sg.servers.each do |server|
145
+ server_ip = ips[server['id']]
146
+ server['ip_address'] = server_ip
147
+ sg.cache_to_disk
148
+ hosts_file_data += "#{server_ip}\t#{server['hostname']}\n"
149
+ end
150
+ end
151
+ rescue Timeout::Error => te
152
+ raise KytoonException, "Timeout building server group."
153
+ end
154
+
155
+
156
+ puts "Copying hosts files..."
157
+ #now that we have IP info copy hosts files into the servers
158
+ sg.servers.each do |server|
159
+ ping_test(server['ip_address'])
160
+ Kytoon::Util.remote_exec(%{
161
+ cat > /etc/hosts <<-EOF_CAT
162
+ #{hosts_file_data}
163
+ EOF_CAT
164
+ hostname "#{server['hostname']}"
165
+ if [ -f /etc/sysconfig/network ]; then
166
+ sed -e "s|^HOSTNAME.*|HOSTNAME=#{server['hostname']}|" -i /etc/sysconfig/network
167
+ fi
168
+ }, server['ip_address']) do |ok, out|
169
+ if not ok
170
+ puts out
171
+ raise KytoonException, "Failed to copy host file to instance #{server['hostname']}."
172
+ end
173
+ end
174
+ end
175
+
176
+ sg
177
+
178
+ end
179
+
180
+ def self.get(options={})
181
+ id = options[:id]
182
+ if id.nil? then
183
+ group=ServerGroup.most_recent
184
+ raise NoServerGroupExists, "No server group files exist." if group.nil?
185
+ id=group.id
186
+ end
187
+
188
+ out_file=File.join(@@data_dir, "#{id}.json")
189
+ raise NoServerGroupExists, "No server group files exist." if not File.exists?(out_file)
190
+ ServerGroup.from_json(IO.read(out_file))
191
+ end
192
+
193
+ def self.index(options={})
194
+
195
+ server_groups=[]
196
+ Dir[File.join(ServerGroup.data_dir, '*.json')].each do |file|
197
+ server_groups << ServerGroup.from_json(IO.read(file))
198
+ end
199
+ server_groups
200
+
201
+ end
202
+
203
+ def self.most_recent
204
+ server_groups=[]
205
+ Dir[File.join(@@data_dir, "*.json")].each do |file|
206
+ server_groups << ServerGroup.from_json(IO.read(file))
207
+ end
208
+ if server_groups.size > 0 then
209
+ server_groups.sort { |a,b| b.id <=> a.id }[0]
210
+ else
211
+ nil
212
+ end
213
+ end
214
+
215
+ def self.init_connection
216
+ configs = Util.load_configs
217
+ if @@connection.nil? then
218
+ @@connection = OpenStack::Compute::Connection.new(
219
+ :username => configs['openstack_username'].to_s,
220
+ :api_key => configs['openstack_password'].to_s,
221
+ :auth_url => configs['openstack_url'],
222
+ :retry_auth => false)
223
+ else
224
+ @@connection
225
+ end
226
+ end
227
+
228
+ def self.create_instance(group_id, hostname, image_ref, flavor_ref, keypair_name)
229
+
230
+ ssh_public_key = Util.public_key_path
231
+ configs = Util.load_configs
232
+
233
+ conn = self.init_connection
234
+
235
+ options = {
236
+ :name => "#{group_id}_#{hostname}",
237
+ :imageRef => image_ref,
238
+ :flavorRef => flavor_ref,
239
+ :personality => {ssh_public_key => "/root/.ssh/authorized_keys"},
240
+ :is_debug => true}
241
+
242
+ keypair_name = configs['openstack_keypair_name'] if keypair_name.nil?
243
+ if not keypair_name.nil? and not keypair_name.empty? then
244
+ options.store(:key_name, keypair_name)
245
+ end
246
+
247
+ conn.create_server(options)
248
+
249
+ end
250
+
251
+ def self.default_ip_type()
252
+ ip_type = Util.load_configs['openstack_ip_type'] || 4
253
+ ip_type.to_i
254
+ end
255
+
256
+ def self.get_server_ips()
257
+
258
+ ips = {}
259
+ configs = Util.load_configs
260
+
261
+ network_name = configs['openstack_network_name'] || 'public'
262
+
263
+ conn = self.init_connection
264
+ all_active = false
265
+ until all_active do
266
+ all_active = true
267
+ conn.servers.each do |server|
268
+ server = conn.server(server[:id])
269
+ if server.status == 'ACTIVE' and ips[server.id].nil? then
270
+ addresses = server.addresses[network_name.to_sym].select {|a| a.version == self.default_ip_type}
271
+ ips[server.id] = addresses[0].address
272
+ else
273
+ all_active = false
274
+ end
275
+ end
276
+ end
277
+
278
+ ips
279
+
280
+ end
281
+
282
+ def self.ping_test(ip_addr)
283
+
284
+ ping_timeout = (Util.load_configs['openstack_ping_timeout'] || 60).to_i
285
+
286
+ begin
287
+ ping = self.default_ip_type == 6 ? 'ping6' : 'ping'
288
+ ping_command = "#{ping} -c 1 #{ip_addr} > /dev/null 2>&1"
289
+ Timeout::timeout(ping_timeout) do
290
+ while(1) do
291
+ return true if system(ping_command)
292
+ end
293
+ end
294
+ rescue Timeout::Error => te
295
+ raise KytoonException, "Timeout pinging server: #{ping_command}"
296
+ end
297
+
298
+ return false
299
+
300
+ end
301
+
302
+ def self.destroy_instance(uuid)
303
+ begin
304
+ conn = self.init_connection
305
+ conn.server(uuid).delete!
306
+ rescue Exception => e
307
+ puts "Error deleting server: #{e.message}"
308
+ end
309
+ end
310
+
311
+ end
312
+
313
+ end
314
+
315
+ end
316
+
317
+ end