testlab 0.7.6 → 0.8.0

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