testlab 1.13.0 → 1.14.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -209,3 +209,20 @@ command :status do |status|
209
209
  commands[:container].commands[:status].execute({}, {}, [])
210
210
  end
211
211
  end
212
+
213
+
214
+ # LAB DOCTOR
215
+ #############
216
+ desc 'Check the health of the lab'
217
+ long_desc <<-EOF
218
+ Attempts to analyze the health of the lab and report any issues.
219
+ EOF
220
+ command :doctor do |doctor|
221
+ doctor.action do |global_options, options, args|
222
+ if @testlab.doctor == true
223
+ @testlab.ui.stdout.puts("Everything is OK".green.bold)
224
+ else
225
+ @testlab.ui.stdout.puts(format_message("OH NOES! SOMETHING IS SCREWED UP!".red.bold))
226
+ end
227
+ end
228
+ end
data/lib/testlab.rb CHANGED
@@ -159,6 +159,14 @@ class TestLab
159
159
  #
160
160
  # @return [Boolean] True if successful.
161
161
  def boot
162
+
163
+ # Raise how many files we can have open to the hard limit.
164
+ rlimit_nofile = Process.getrlimit(Process::RLIMIT_NOFILE)
165
+ if rlimit_nofile[0] != rlimit_nofile[1]
166
+ self.ui.logger.info { "Changing maximum open file descriptors from #{rlimit_nofile[0].inspect} to #{rlimit_nofile[1].inspect}" }
167
+ Process.setrlimit(Process::RLIMIT_NOFILE, rlimit_nofile[1])
168
+ end
169
+
162
170
  @labfile = TestLab::Labfile.load(labfile_path)
163
171
  @labfile.testlab = self
164
172
 
@@ -351,6 +359,26 @@ class TestLab
351
359
  true
352
360
  end
353
361
 
362
+ # Test Lab Doctor
363
+ #
364
+ # Attempts to analyze the lab for issues.
365
+ #
366
+ # @return [Boolean] True if everything is OK; false otherwise.
367
+ def doctor
368
+ results = Array.new
369
+
370
+ if ((rlimit_nofile = Process.getrlimit(Process::RLIMIT_NOFILE)[0]) < 1024)
371
+ @ui.stderr.puts(format_message("The maximum number of file handles is set to #{rlimit_nofile}! Please raise it to 1024 or higher!".red.bold))
372
+ results << false
373
+ end
374
+
375
+ results << nodes.all? do |node|
376
+ node.doctor
377
+ end
378
+
379
+ results.flatten.compact.all?
380
+ end
381
+
354
382
  # Node Method Proxy
355
383
  #
356
384
  # Iterates all of the lab nodes, sending the supplied method name and arguments
@@ -13,7 +13,6 @@ class TestLab
13
13
  @ui.logger.debug { "Container Create: #{self.id}" }
14
14
 
15
15
  self.node.alive? or return false
16
- self.node.ok?
17
16
 
18
17
  persistent_operation_check(:create)
19
18
 
@@ -37,7 +36,6 @@ class TestLab
37
36
  @ui.logger.debug { "Container Destroy: #{self.id}" }
38
37
 
39
38
  self.node.alive? or return false
40
- self.node.ok?
41
39
 
42
40
  please_wait(:ui => @ui, :message => format_object_action(self, 'Destroy', :red)) do
43
41
  self.lxc.destroy(%(-f))
@@ -58,7 +56,6 @@ class TestLab
58
56
  @ui.logger.debug { "Container Up: #{self.id}" }
59
57
 
60
58
  self.node.alive? or return false
61
- self.node.ok?
62
59
 
63
60
  please_wait(:ui => @ui, :message => format_object_action(self, 'Up', :green)) do
64
61
  configure
@@ -104,7 +101,6 @@ class TestLab
104
101
  @ui.logger.debug { "Container Down: #{self.id}" }
105
102
 
106
103
  self.node.alive? or return false
107
- self.node.ok?
108
104
 
109
105
  please_wait(:ui => @ui, :message => format_object_action(self, 'Down', :red)) do
110
106
 
@@ -60,7 +60,6 @@ class TestLab
60
60
  @ui.logger.debug { "Container Export: #{self.id} " }
61
61
 
62
62
  self.node.alive? or return false
63
- self.node.ok?
64
63
 
65
64
  (self.state == :not_created) and raise ContainerError, 'You must create a container before you can export it!'
66
65
 
@@ -115,7 +114,6 @@ EOF
115
114
  @ui.logger.debug { "Container Import: #{self.id}" }
116
115
 
117
116
  self.node.alive? or return false
118
- self.node.ok?
119
117
 
120
118
  import_tempfile = Tempfile.new('import')
121
119
  remote_filename = File.basename(import_tempfile.path.dup)
@@ -13,7 +13,6 @@ class TestLab
13
13
  @ui.logger.debug { "Container Provision: #{self.id} " }
14
14
 
15
15
  self.node.alive? or return false
16
- self.node.ok?
17
16
 
18
17
  please_wait(:ui => @ui, :message => format_object_action(self, :provision, :green)) do
19
18
  do_provisioner_callbacks(self, :provision, @ui)
@@ -32,7 +31,6 @@ class TestLab
32
31
  @ui.logger.debug { "Container Deprovision: #{self.id} " }
33
32
 
34
33
  self.node.alive? or return false
35
- self.node.ok?
36
34
 
37
35
  persistent_operation_check(:deprovision)
38
36
 
data/lib/testlab/node.rb CHANGED
@@ -12,6 +12,7 @@ class TestLab
12
12
  # Sub-Modules
13
13
  autoload :Actions, 'testlab/node/actions'
14
14
  autoload :ClassMethods, 'testlab/node/class_methods'
15
+ autoload :Doctor, 'testlab/node/doctor'
15
16
  autoload :LXC, 'testlab/node/lxc'
16
17
  autoload :MethodMissing, 'testlab/node/method_missing'
17
18
  autoload :Provision, 'testlab/node/provision'
@@ -19,6 +20,7 @@ class TestLab
19
20
  autoload :Status, 'testlab/node/status'
20
21
 
21
22
  include TestLab::Node::Actions
23
+ include TestLab::Node::Doctor
22
24
  include TestLab::Node::LXC
23
25
  include TestLab::Node::MethodMissing
24
26
  include TestLab::Node::Provision
@@ -0,0 +1,62 @@
1
+ class TestLab
2
+ class Node
3
+
4
+ module Doctor
5
+
6
+ # Node Doctor
7
+ #
8
+ # Attempts to analyze the current node and report any issues.
9
+ #
10
+ # @result [Boolean] True if everything is OK; false otherwise.
11
+ def doctor
12
+ if self.dead?
13
+ @ui.stderr.puts(format_message("The node #{self.id.inspect} is dead! (Did you forget to up or build the node?)".red.bold))
14
+ return false
15
+ end
16
+
17
+ if !self.lxc.installed?
18
+ @ui.stderr.puts(format_message("LXC does not appear to be installed on your TestLab node! (Did you forget to provision or build the node?)".red.bold))
19
+ return false
20
+ end
21
+
22
+ result = true
23
+
24
+ # make sure the node has some free space
25
+ free_space_percent = (self.exec(%(df -P /), :ignore_exit_status => true).output.split("\n")[1].split[-2].to_i rescue nil)
26
+ if free_space_percent.nil?
27
+ @ui.stderr.puts(format_message("ERROR: We could not determine how much free space node #{self.id.inspect} has!".red.bold))
28
+ result = false
29
+ elsif (free_space_percent >= 90)
30
+ @ui.stderr.puts(format_message("WARNING: Your TestLab node #{self.id.inspect} is using #{free_space_percent}% of its available disk space!".red.bold))
31
+ result = false
32
+ end
33
+
34
+ # get the names of all of the defined containers
35
+ my_container_names = self.containers.map(&:id)
36
+
37
+ # ephemeral containers parent containers have a "-master" suffix; we need to remove these from the results or we will complain about them
38
+ node_container_names = self.lxc.containers.map(&:name).delete_if do |node_container_name|
39
+ my_container_names.any?{ |my_container_name| "#{my_container_name}-master" == node_container_name }
40
+ end
41
+
42
+ unknown_container_names = (node_container_names - my_container_names)
43
+ unknown_running_container_names = self.lxc.containers.select{ |c| (unknown_container_names.include?(c.name) && (c.state == :running)) }.map(&:name)
44
+
45
+ if unknown_container_names.count > 0
46
+ if unknown_running_container_names.count > 0
47
+ @ui.stderr.puts(format_message("WARNING: You have *running* containers on your TestLab node #{self.id.inspect} which are not defined in your Labfile!".red.bold))
48
+ @ui.stderr.puts(format_message(">>> You may need to manually stop the following containers: #{unknown_running_container_names.join(', ')}".red.bold))
49
+ result = false
50
+ end
51
+
52
+ @ui.stderr.puts(format_message("WARNING: You have containers on your TestLab node #{self.id.inspect} which are not defined in your Labfile!".red.bold))
53
+ @ui.stderr.puts(format_message(">>> You may need to manually remove the following containers: #{unknown_container_names.join(', ')}".red.bold))
54
+ end
55
+
56
+ result
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+ end
@@ -8,7 +8,7 @@ class TestLab
8
8
  # @return [Hash] A hash detailing the status of the node.
9
9
  def status
10
10
  {
11
- :ok => self.ok?.inspect,
11
+ :ok => self.doctor.inspect,
12
12
  :id => self.id,
13
13
  :instance_id => @provider.instance_id,
14
14
  :state => @provider.state,
@@ -21,52 +21,6 @@ class TestLab
21
21
  }
22
22
  end
23
23
 
24
- def ok?
25
- self.dead? and return false
26
-
27
- result = true
28
-
29
- if !self.lxc.installed?
30
- # @ui.stderr.puts(format_message("ERROR: "))
31
- raise NodeError, "LXC does not appear to be installed on your TestLab node! (Did you forget to provision or build the node?)"
32
- # result = false
33
- end
34
-
35
- # make sure the node has some free space
36
- free_space_percent = (self.exec(%(df -P /), :ignore_exit_status => true).output.split("\n")[1].split[-2].to_i rescue nil)
37
- if free_space_percent.nil?
38
- @ui.stderr.puts(format_message("ERROR: We could not determine how much free space node #{self.id.inspect} has!".red.bold))
39
- result = false
40
- elsif (free_space_percent >= 90)
41
- @ui.stderr.puts(format_message("WARNING: Your TestLab node #{self.id.inspect} is using #{free_space_percent}% of its available disk space!".red.bold))
42
- result = false
43
- end
44
-
45
- # get the names of all of the defined containers
46
- my_container_names = self.containers.map(&:id)
47
-
48
- # ephemeral containers parent containers have a "-master" suffix; we need to remove these from the results or we will complain about them
49
- node_container_names = self.lxc.containers.map(&:name).delete_if do |node_container_name|
50
- my_container_names.any?{ |my_container_name| "#{my_container_name}-master" == node_container_name }
51
- end
52
-
53
- unknown_container_names = (node_container_names - my_container_names)
54
- unknown_running_container_names = self.lxc.containers.select{ |c| (unknown_container_names.include?(c.name) && (c.state == :running)) }.map(&:name)
55
-
56
- if unknown_container_names.count > 0
57
- if unknown_running_container_names.count > 0
58
- @ui.stderr.puts(format_message("WARNING: You have *running* containers on your TestLab node #{self.id.inspect} which are not defined in your Labfile!".red.bold))
59
- @ui.stderr.puts(format_message(">>> You may need to manually stop the following containers: #{unknown_running_container_names.join(', ')}".red.bold))
60
- result = false
61
- end
62
-
63
- @ui.stderr.puts(format_message("WARNING: You have containers on your TestLab node #{self.id.inspect} which are not defined in your Labfile!".red.bold))
64
- @ui.stderr.puts(format_message(">>> You may need to manually remove the following containers: #{unknown_container_names.join(', ')}".red.bold))
65
- end
66
-
67
- result
68
- end
69
-
70
24
  end
71
25
 
72
26
  end
@@ -1,6 +1,6 @@
1
1
  class TestLab
2
2
  unless const_defined?(:VERSION)
3
3
  # TestLab Gem Version
4
- VERSION = "1.13.0"
4
+ VERSION = "1.14.0"
5
5
  end
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: testlab
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.13.0
4
+ version: 1.14.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-12-13 00:00:00.000000000 Z
12
+ date: 2013-12-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: gli
@@ -266,6 +266,7 @@ files:
266
266
  - lib/testlab/node.rb
267
267
  - lib/testlab/node/actions.rb
268
268
  - lib/testlab/node/class_methods.rb
269
+ - lib/testlab/node/doctor.rb
269
270
  - lib/testlab/node/lxc.rb
270
271
  - lib/testlab/node/method_missing.rb
271
272
  - lib/testlab/node/provision.rb
@@ -350,7 +351,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
350
351
  version: '0'
351
352
  segments:
352
353
  - 0
353
- hash: -3460081152239272666
354
+ hash: -2303575706409532818
354
355
  required_rubygems_version: !ruby/object:Gem::Requirement
355
356
  none: false
356
357
  requirements:
@@ -359,7 +360,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
359
360
  version: '0'
360
361
  segments:
361
362
  - 0
362
- hash: -3460081152239272666
363
+ hash: -2303575706409532818
363
364
  requirements: []
364
365
  rubyforge_project:
365
366
  rubygems_version: 1.8.25