testlab 0.7.6 → 0.8.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.
data/README.md CHANGED
@@ -26,7 +26,7 @@ The TestLab command-line program `tl` follows in the style of git:
26
26
  tl [global options] command [command options] [arguments...]
27
27
 
28
28
  VERSION
29
- 0.7.5
29
+ 0.7.6
30
30
 
31
31
  GLOBAL OPTIONS
32
32
  -l, --labfile=path/to/file - Path to Labfile: ${REPO}/Labfile (default: none)
@@ -49,6 +49,7 @@ The TestLab command-line program `tl` follows in the style of git:
49
49
  setup - Setup the test lab infrastructure
50
50
  teardown - Teardown the test lab infrastructure
51
51
  build - Build the test lab infrastructure
52
+ demolish - Demolish the test lab infrastructure
52
53
  status - Display information on the status of the test lab
53
54
 
54
55
  You stand up your lab with the following command:
data/bin/tl CHANGED
@@ -22,6 +22,7 @@ require 'gli'
22
22
  require 'testlab'
23
23
 
24
24
  include GLI::App
25
+ include TestLab::Utility::GLI
25
26
  include TestLab::Utility::Misc
26
27
 
27
28
  version TestLab::VERSION
@@ -71,6 +72,10 @@ pre do |global,command,options,args|
71
72
  :quiet => global[:quiet]
72
73
  )
73
74
 
75
+ @ui.logger.debug { "global(#{global.inspect})" }
76
+ @ui.logger.debug { "options(#{options.inspect})" }
77
+ @ui.logger.debug { "args(#{args.inspect})" }
78
+
74
79
  @testlab = TestLab.new(
75
80
  :ui => @ui,
76
81
  :labfile_path => global[:labfile],
@@ -78,15 +83,14 @@ pre do |global,command,options,args|
78
83
  :repo_dir => global[:repo]
79
84
  )
80
85
 
81
- @ui.logger.debug { "global(#{global.inspect})" }
82
- @ui.logger.debug { "options(#{options.inspect})" }
83
- @ui.logger.debug { "args(#{args.inspect})" }
84
-
85
86
  TestLab::Utility.log_header(@testlab).each { |line| @logger.info { line } }
86
87
 
88
+ @testlab.boot
89
+
87
90
  if !@ui.quiet?
88
91
  message = format_message("TestLab v#{TestLab::VERSION} Loaded".black.bold)
89
92
  @testlab.ui.stdout.puts(message)
93
+ @testlab.ui.logger.info { message.uncolor }
90
94
  end
91
95
 
92
96
  true
@@ -10,6 +10,10 @@ When /^I build the lab with "([^"]*)"$/ do |app_name|
10
10
  testlab_cmd(app_name, %W(build))
11
11
  end
12
12
 
13
+ When /^I demolish the lab with "([^"]*)"$/ do |app_name|
14
+ testlab_cmd(app_name, %W(demolish))
15
+ end
16
+
13
17
  When /^I up the lab with "([^"]*)"$/ do |app_name|
14
18
  testlab_cmd(app_name, %W(up))
15
19
  end
@@ -24,5 +28,5 @@ end
24
28
 
25
29
  def testlab_cmd(app_name, *args)
26
30
  args = args.join(' ')
27
- step %(I run `#{app_name} --repo=#{TEST_REPO} #{args}`)
31
+ step %(I run `#{app_name} --repo=#{TEST_REPO} --labfile=#{TEST_LABFILE} #{args}`)
28
32
  end
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env ruby
2
+ #^syntax detection
3
+
4
+ node 'vagrant' do
5
+
6
+ provider TestLab::Provider::Local
7
+
8
+ provisioners [TestLab::Provisioner::Raring]
9
+
10
+ config ({
11
+ :bind => {
12
+ :domain => "default.zone"
13
+ }
14
+ })
15
+
16
+ network 'labnet' do
17
+ address '10.128.0.1/16'
18
+ bridge :br_test
19
+ end
20
+
21
+ container "test-server" do
22
+ distro "ubuntu"
23
+ release "precise"
24
+
25
+ provisioners [
26
+ TestLab::Provisioner::AptCacherNG,
27
+ TestLab::Provisioner::Apt
28
+ ]
29
+
30
+ user 'deployer' do
31
+ password 'deployer'
32
+ identity File.join(ENV['HOME'], '.ssh', 'id_rsa')
33
+ public_identity File.join(ENV['HOME'], '.ssh', 'id_rsa.pub')
34
+ uid 2600
35
+ gid 2600
36
+ end
37
+
38
+ interface do
39
+ network_id 'labnet'
40
+ name :eth0
41
+ address '10.128.0.254/16'
42
+ mac '00:00:5e:63:b5:9f'
43
+ end
44
+ end
45
+
46
+ end
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env ruby
2
+ #^syntax detection
3
+
4
+ node 'vagrant' do
5
+
6
+ provider TestLab::Provider::Vagrant
7
+
8
+ provisioners [
9
+ TestLab::Provisioner::Raring,
10
+ TestLab::Provisioner::Bind
11
+ ]
12
+
13
+ config ({
14
+ :vagrant => {
15
+ :id => "test-cucumber-#{TestLab.hostname}".downcase,
16
+ :cpus => ZTK::Parallel::MAX_FORKS.div(2), # use half of the available processors
17
+ :memory => ZTK::Parallel::MAX_MEMORY.div(3).div(1024 * 1024), # use a third of available RAM
18
+ :box => 'raring64',
19
+ :box_url => 'https://dl.dropboxusercontent.com/u/22904185/boxes/raring64.box',
20
+ :file => File.dirname(__FILE__)
21
+ },
22
+ :bind => {
23
+ :domain => "default.zone"
24
+ }
25
+ })
26
+
27
+ network 'labnet' do
28
+ address '10.128.0.1/16'
29
+ bridge :br0
30
+ end
31
+
32
+ container "test-server" do
33
+ distro "ubuntu"
34
+ release "precise"
35
+
36
+ provisioners [
37
+ TestLab::Provisioner::Resolv,
38
+ TestLab::Provisioner::AptCacherNG,
39
+ TestLab::Provisioner::Apt
40
+ ]
41
+
42
+ user 'deployer' do
43
+ password 'deployer'
44
+ identity File.join(ENV['HOME'], '.ssh', 'id_rsa')
45
+ public_identity File.join(ENV['HOME'], '.ssh', 'id_rsa.pub')
46
+ uid 2600
47
+ gid 2600
48
+ end
49
+
50
+ interface do
51
+ network_id 'labnet'
52
+ name :eth0
53
+ address '10.128.0.254/16'
54
+ mac '00:00:5e:63:b5:9f'
55
+ end
56
+ end
57
+
58
+ end
@@ -2,8 +2,16 @@ require 'aruba/cucumber'
2
2
 
3
3
  ENV['PATH'] = "#{File.expand_path(File.dirname(__FILE__) + '/../../bin')}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
4
4
  LIB_DIR = File.join(File.expand_path(File.dirname(__FILE__)),'..','..','lib')
5
+
5
6
  TEST_REPO = File.dirname(__FILE__)
6
7
 
8
+ if ENV['USER'] == 'vagrant'
9
+ TEST_LABFILE = File.join(TEST_REPO, 'Labfile.local')
10
+ else
11
+ TEST_LABFILE = File.join(TEST_REPO, 'Labfile.vagrant')
12
+ end
13
+
14
+
7
15
  Before do
8
16
  # Using "announce" causes massive warnings on 1.9.2
9
17
  @aruba_timeout_seconds = 3600
@@ -11,6 +11,8 @@ Feature: TestLab command-line
11
11
  Then the exit status should be 0
12
12
  When I get the containers ssh-config with "tl"
13
13
  Then the exit status should be 0
14
+ When I demolish the lab with "tl"
15
+ Then the exit status should be 0
14
16
 
15
17
 
16
18
  Scenario: TestLab help
@@ -26,8 +28,6 @@ Feature: TestLab command-line
26
28
 
27
29
 
28
30
  Scenario: TestLab import
29
- When I down the lab with "tl"
30
- Then the exit status should be 0
31
31
  When I build the nodes with "tl"
32
32
  Then the exit status should be 0
33
33
  When I import the containers with "tl"
@@ -37,8 +37,6 @@ Feature: TestLab command-line
37
37
 
38
38
 
39
39
  Scenario: TestLab clone
40
- When I down the lab with "tl"
41
- Then the exit status should be 0
42
40
  When I build the lab with "tl"
43
41
  Then the exit status should be 0
44
42
  When I clone the containers with "tl"
@@ -57,8 +55,6 @@ Feature: TestLab command-line
57
55
  Then the exit status should be 0
58
56
 
59
57
 
60
- Scenario: TestLab destroy
61
- When I down the lab with "tl"
62
- Then the exit status should be 0
63
- When I destroy the lab with "tl"
58
+ Scenario: TestLab Demolish
59
+ When I demolish the lab with "tl"
64
60
  Then the exit status should be 0
@@ -20,193 +20,17 @@
20
20
 
21
21
  # CONTAINERS
22
22
  #############
23
- desc 'Manage containers'
24
- arg_name 'Describe arguments to container here'
25
- command :container do |c|
26
-
27
- c.desc 'Single or comma separated list of container IDs'
28
- c.arg_name 'container[,container,...]'
29
- c.flag [:n, :name]
30
-
31
- # CONTAINER CREATE
32
- ###################
33
- c.desc 'Create a container'
34
- c.long_desc <<-EOF
35
- Creates a container on the node the container belongs to.
36
- EOF
37
- c.command :create do |create|
38
- create.action do |global_options, options, args|
39
- if options[:name].nil?
40
- help_now!('a name is required') if options[:name].nil?
41
- else
42
- names = options[:name].split(',')
43
- containers = TestLab::Container.find(names)
44
- (containers.nil? || (containers.count == 0)) and raise TestLab::TestLabError, "We could not find any of the containers you supplied!"
45
-
46
- containers.each do |container|
47
- container.create
48
- end
49
- end
50
- end
51
- end
52
-
53
- # CONTAINER DESTROY
54
- ####################
55
- c.desc 'Destroy a container'
56
- c.long_desc <<-EOF
57
- Destroys the container, force stopping it if necessary. The containers file system is purged from disk. This is a destructive operation, there is no way to recover from it.
58
- EOF
59
- c.command :destroy do |destroy|
60
- destroy.action do |global_options, options, args|
61
- if options[:name].nil?
62
- help_now!('a name is required') if options[:name].nil?
63
- else
64
- names = options[:name].split(',')
65
- containers = TestLab::Container.find(names)
66
- (containers.nil? || (containers.count == 0)) and raise TestLab::TestLabError, "We could not find any of the containers you supplied!"
67
-
68
- containers.each do |container|
69
- container.destroy
70
- end
71
- end
72
- end
73
- end
74
-
75
- # CONTAINER UP
76
- ###############
77
- c.desc 'Up a container'
78
- c.long_desc <<-EOF
79
- The container is started and brought online.
80
- EOF
81
- c.command :up do |up|
82
- up.action do |global_options, options, args|
83
- if options[:name].nil?
84
- help_now!('a name is required') if options[:name].nil?
85
- else
86
- names = options[:name].split(',')
87
- containers = TestLab::Container.find(names)
88
- (containers.nil? || (containers.count == 0)) and raise TestLab::TestLabError, "We could not find any of the containers you supplied!"
89
-
90
- containers.each do |container|
91
- container.up
92
- end
93
- end
94
- end
95
- end
96
-
97
- # CONTAINER DOWN
98
- #################
99
- c.desc 'Down a container'
100
- c.long_desc <<-EOF
101
- The container is stopped taking it offline.
102
- EOF
103
- c.command :down do |down|
104
- down.action do |global_options, options, args|
105
- if options[:name].nil?
106
- help_now!('a name is required') if options[:name].nil?
107
- else
108
- names = options[:name].split(',')
109
- containers = TestLab::Container.find(names)
110
- (containers.nil? || (containers.count == 0)) and raise TestLab::TestLabError, "We could not find any of the containers you supplied!"
111
-
112
- containers.each do |container|
113
- container.down
114
- end
115
- end
116
- end
117
- end
118
-
119
- # CONTAINER SETUP
120
- ####################
121
- c.desc 'Setup a container'
122
- c.long_desc <<-EOF
123
- The container is provisioned.
124
- EOF
125
- c.command :setup do |setup|
126
- setup.action do |global_options, options, args|
127
- if options[:name].nil?
128
- help_now!('a name is required') if options[:name].nil?
129
- else
130
- names = options[:name].split(',')
131
- containers = TestLab::Container.find(names)
132
- (containers.nil? || (containers.count == 0)) and raise TestLab::TestLabError, "We could not find any of the containers you supplied!"
133
-
134
- containers.each do |container|
135
- container.setup
136
- end
137
- end
138
- end
139
- end
140
-
141
- # CONTAINER TEARDOWN
142
- ####################
143
- c.desc 'Teardown a container'
144
- c.long_desc <<-EOF
145
- The container is deprovisioned.
146
- EOF
147
- c.command :teardown do |teardown|
148
- teardown.action do |global_options, options, args|
149
- if options[:name].nil?
150
- help_now!('a name is required') if options[:name].nil?
151
- else
152
- names = options[:name].split(',')
153
- containers = TestLab::Container.find(names)
154
- (containers.nil? || (containers.count == 0)) and raise TestLab::TestLabError, "We could not find any of the containers you supplied!"
155
-
156
- containers.each do |container|
157
- container.teardown
158
- end
159
- end
160
- end
161
- end
162
-
163
- # CONTAINER BUILD
164
- ##################
165
- c.desc 'Build a container'
166
- c.long_desc <<-EOF
167
- Attempts to build up the container. TestLab will attempt to create, online and provision the container.
168
-
169
- The container is taken through the following phases:
170
-
171
- Create -> Up -> Setup
172
- EOF
173
- c.command :build do |build|
174
- build.action do |global_options, options, args|
175
- if options[:name].nil?
176
- help_now!('a name is required') if options[:name].nil?
177
- else
178
- names = options[:name].split(',')
179
- containers = TestLab::Container.find(names)
180
- (containers.nil? || (containers.count == 0)) and raise TestLab::TestLabError, "We could not find any of the containers you supplied!"
181
-
182
- containers.each do |container|
183
- container.build
184
- end
185
- end
186
- end
187
- end
23
+ build_lab_commands(:container, TestLab::Container) do |c|
188
24
 
189
25
  # CONTAINER STATUS
190
26
  ###################
191
- c.desc 'Display the status of containers'
27
+ c.desc 'Display containers status'
192
28
  c.long_desc <<-EOF
193
29
  Displays the status of all containers or single/multiple containers if supplied via the ID parameter.
194
30
  EOF
195
31
  c.command :status do |status|
196
32
  status.action do |global_options, options, args|
197
- containers = Array.new
198
-
199
- if options[:name].nil?
200
- # No ID supplied; show everything
201
- containers = TestLab::Container.all
202
- else
203
- # ID supplied; show just those items
204
- names = options[:name].split(',')
205
- containers = TestLab::Container.find(names)
206
- (containers.nil? || (containers.count == 0)) and raise TestLab::TestLabError, "We could not find any of the containers you supplied!"
207
- end
208
-
209
- containers = containers.delete_if{ |container| container.node.dead? }
33
+ containers = iterate_objects_by_name(options[:name], TestLab::Container).delete_if{ |container| container.node.dead? }
210
34
 
211
35
  if (containers.count == 0)
212
36
  @testlab.ui.stderr.puts("You either have no containers defined or dead nodes!".yellow)
@@ -215,13 +39,12 @@ EOF
215
39
  OpenStruct.new(container.status)
216
40
  end
217
41
  end
218
-
219
42
  end
220
43
  end
221
44
 
222
45
  # CONTAINER SSH
223
46
  ################
224
- c.desc 'Open an SSH console to a container'
47
+ c.desc 'Container SSH console'
225
48
  c.command :ssh do |ssh|
226
49
 
227
50
  ssh.desc 'Specify an SSH Username to use'
@@ -248,30 +71,22 @@ EOF
248
71
 
249
72
  # CONTAINER SSH-CONFIG
250
73
  #######################
251
- c.desc 'Display the SSH configuration for a container'
74
+ c.desc 'Container SSH configuration'
252
75
  c.long_desc <<-EOF
253
- Displays the SSH configuration for the supplied container name.
76
+ Displays a containers SSH configuration.
254
77
  EOF
255
78
  c.command :'ssh-config' do |ssh_config|
256
79
 
257
80
  ssh_config.action do |global_options, options, args|
258
- if options[:name].nil?
259
- help_now!('a name is required') if options[:name].nil?
260
- else
261
- names = options[:name].split(',')
262
- containers = TestLab::Container.find(names)
263
- (containers.nil? || (containers.count == 0)) and raise TestLab::TestLabError, "We could not find any of the containers you supplied!"
264
-
265
- containers.each do |container|
266
- puts(container.ssh_config)
267
- end
81
+ iterate_objects_by_name(options[:name], TestLab::Container) do |container|
82
+ puts(container.ssh_config)
268
83
  end
269
84
  end
270
85
  end
271
86
 
272
87
  # CONTAINER RECYCLE
273
88
  ####################
274
- c.desc 'Recycles a container'
89
+ c.desc 'Recycle containers'
275
90
  c.long_desc <<-EOF
276
91
  Recycles a container. The container is taken through a series of state changes to ensure it is pristine.
277
92
 
@@ -281,51 +96,37 @@ Teardown -> Down -> Destroy -> Create -> Up -> Setup
281
96
  EOF
282
97
  c.command :recycle do |recycle|
283
98
  recycle.action do |global_options, options, args|
284
- if options[:name].nil?
285
- help_now!('a name is required') if options[:name].nil?
286
- else
287
- names = options[:name].split(',')
288
- containers = TestLab::Container.find(names)
289
- (containers.nil? || (containers.count == 0)) and raise TestLab::TestLabError, "We could not find any of the containers you supplied!"
290
-
291
- containers.each do |container|
292
- container.teardown
293
- container.down
294
- container.destroy
295
-
296
- container.create
297
- container.up
298
- container.setup
299
- end
99
+ iterate_objects_by_name(options[:name], TestLab::Container) do |container|
100
+ container.teardown
101
+ container.down
102
+ container.destroy
103
+
104
+ container.create
105
+ container.up
106
+ container.setup
300
107
  end
301
108
  end
302
109
  end
303
110
 
304
111
  # CONTAINER CLONE
305
112
  ##################
306
- c.desc 'Clone a container'
113
+ c.desc 'Clone containers'
307
114
  c.long_desc <<-EOF
308
- An ephemeral copy of the container is started. There is a small delay incured during the first clone operation.
115
+ An ephemeral copy of the container is started.
116
+
117
+ NOTE: There is a small delay incured during the first clone operation.
309
118
  EOF
310
119
  c.command :clone do |clone|
311
120
  clone.action do |global_options, options, args|
312
- if options[:name].nil?
313
- help_now!('a name is required') if options[:name].nil?
314
- else
315
- names = options[:name].split(',')
316
- containers = TestLab::Container.find(names)
317
- (containers.nil? || (containers.count == 0)) and raise TestLab::TestLabError, "We could not find any of the containers you supplied!"
318
-
319
- containers.each do |container|
320
- container.clone
321
- end
121
+ iterate_objects_by_name(options[:name], TestLab::Container) do |container|
122
+ container.clone
322
123
  end
323
124
  end
324
125
  end
325
126
 
326
127
  # CONTAINER EXPORT
327
128
  ###################
328
- c.desc 'Export a container to a shipping container (file)'
129
+ c.desc 'Export containers'
329
130
  c.command :export do |export|
330
131
 
331
132
  export.desc 'Specify the level of bzip2 compression to use (1-9)'
@@ -334,28 +135,19 @@ EOF
334
135
  export.flag [:c, :compression]
335
136
 
336
137
  export.desc 'Specify the shipping container file to export to.'
337
- # export.default_value nil
338
138
  export.arg_name 'filename'
339
139
  export.flag [:output]
340
140
 
341
141
  export.action do |global_options, options, args|
342
- if options[:name].nil?
343
- help_now!('a name is required') if options[:name].nil?
344
- else
345
- names = options[:name].split(',')
346
- containers = TestLab::Container.find(names)
347
- (containers.nil? || (containers.count == 0)) and raise TestLab::TestLabError, "We could not find any of the containers you supplied!"
348
-
349
- containers.each do |container|
350
- container.export(options[:compression], options[:output])
351
- end
142
+ iterate_objects_by_name(options[:name], TestLab::Container) do |container|
143
+ container.export(options[:compression], options[:output])
352
144
  end
353
145
  end
354
146
  end
355
147
 
356
148
  # CONTAINER IMPORT
357
149
  ###################
358
- c.desc 'Import a shipping container (file)'
150
+ c.desc 'Import containers'
359
151
  c.command :import do |import|
360
152
 
361
153
  import.desc 'Specify the shipping container file to import from.'
@@ -367,11 +159,7 @@ EOF
367
159
  help_now!('a name is required') if options[:name].nil?
368
160
  help_now!('a filename is required') if options[:input].nil?
369
161
  else
370
- names = options[:name].split(',')
371
- containers = TestLab::Container.find(names)
372
- (containers.nil? || (containers.count == 0)) and raise TestLab::TestLabError, "We could not find any of the containers you supplied!"
373
-
374
- containers.each do |container|
162
+ iterate_objects_by_name(options[:name], TestLab::Container) do |container|
375
163
  container.import(options[:input])
376
164
  end
377
165
  end