testlab 0.6.5 → 0.6.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/README.md +35 -32
  2. data/bin/tl +13 -640
  3. data/lib/commands/container.rb +292 -0
  4. data/lib/commands/network.rb +233 -0
  5. data/lib/commands/node.rb +182 -0
  6. data/lib/commands/testlab.rb +98 -0
  7. data/lib/testlab/container/actions.rb +15 -5
  8. data/lib/testlab/container/io.rb +69 -0
  9. data/lib/testlab/container/lifecycle.rb +6 -10
  10. data/lib/testlab/container/status.rb +1 -1
  11. data/lib/testlab/container.rb +2 -0
  12. data/lib/testlab/network/actions.rb +16 -0
  13. data/lib/testlab/network/lifecycle.rb +14 -20
  14. data/lib/testlab/network/status.rb +11 -5
  15. data/lib/testlab/network.rb +6 -6
  16. data/lib/testlab/node/actions.rb +16 -0
  17. data/lib/testlab/node/lifecycle.rb +15 -11
  18. data/lib/testlab/node/status.rb +1 -2
  19. data/lib/testlab/node.rb +1 -1
  20. data/lib/testlab/provisioner.rb +2 -1
  21. data/lib/testlab/provisioners/apt.rb +1 -1
  22. data/lib/testlab/provisioners/apt_cacher_ng.rb +2 -2
  23. data/lib/testlab/provisioners/bind.rb +1 -1
  24. data/lib/testlab/provisioners/chef_gem.rb +2 -2
  25. data/lib/testlab/provisioners/omnibus.rb +2 -2
  26. data/lib/testlab/provisioners/omnitruck.rb +2 -2
  27. data/lib/testlab/provisioners/raring.rb +1 -1
  28. data/lib/testlab/provisioners/resolv.rb +2 -2
  29. data/lib/testlab/provisioners/route.rb +51 -0
  30. data/lib/testlab/provisioners/shell.rb +1 -1
  31. data/lib/testlab/provisioners/templates/apt/bootstrap.erb +6 -1
  32. data/lib/testlab/provisioners/templates/apt_cacher_ng/bootstrap.erb +4 -1
  33. data/lib/testlab/provisioners/templates/raring/bootstrap.erb +9 -4
  34. data/lib/testlab/utility/logger.rb +87 -0
  35. data/lib/testlab/utility.rb +4 -2
  36. data/lib/testlab/version.rb +1 -1
  37. data/lib/testlab.rb +28 -0
  38. data/spec/container_spec.rb +18 -12
  39. data/spec/network_spec.rb +4 -0
  40. data/spec/node_spec.rb +6 -19
  41. data/spec/provisioners/shell_spec.rb +2 -2
  42. data/spec/support/Labfile +3 -3
  43. data/testlab.gemspec +2 -2
  44. metadata +13 -6
data/bin/tl CHANGED
@@ -26,657 +26,30 @@ include TestLab::Utility::Misc
26
26
 
27
27
  version TestLab::VERSION
28
28
 
29
- program_desc %(A framework for building lightweight virtual infrastructure using LXC)
29
+ program_desc %(TestLab - A toolkit for building virtual computer labs)
30
30
  # program_long_desc %(Program Long Description)
31
31
 
32
32
  sort_help :manually
33
33
  default_command :help
34
34
 
35
- # LAB CREATE
36
- #############
37
- desc 'Create the test lab'
38
- command :create do |create|
39
- create.action do |global_options,options,args|
40
- @testlab.create
41
- end
42
- end
43
-
44
- # LAB DESTROY
45
- ##############
46
- desc 'Destroy the test lab'
47
- command :destroy do |destroy|
48
- destroy.action do |global_options,options,args|
49
- @testlab.destroy
50
- end
51
- end
52
-
53
- # LAB ONLINE
54
- #############
55
- desc 'Online the test lab'
56
- command :up do |up|
57
- up.action do |global_options,options,args|
58
- @testlab.up
59
- end
60
- end
61
-
62
- # LAB OFFLINE
63
- ##############
64
- desc 'Offline the test lab'
65
- command :down do |down|
66
- down.action do |global_options,options,args|
67
- @testlab.down
68
- end
69
- end
70
-
71
- # LAB SETUP
72
- ############
73
- desc 'Setup the test lab infrastructure'
74
- command :setup do |setup|
75
- setup.action do |global_options,options,args|
76
- @testlab.setup
77
- end
78
- end
79
-
80
- # LAB TEARDOWN
81
- ###############
82
- desc 'Teardown the test lab infrastructure'
83
- command :teardown do |teardown|
84
- teardown.action do |global_options,options,args|
85
- @testlab.teardown
86
- end
87
- end
88
-
89
- # LAB STATUS
90
- #############
91
- desc 'Display information on the status of the test lab'
92
- command :status do |status|
93
- status.action do |global_options,options,args|
94
- @testlab.ui.stdout.puts("\nNODES:".green.bold)
95
- commands[:node].commands[:status].execute({}, {}, [])
96
-
97
- @testlab.ui.stdout.puts("\nNETWORKS:".green.bold)
98
- commands[:network].commands[:status].execute({}, {}, [])
99
-
100
- @testlab.ui.stdout.puts("\nCONTAINERS:".green.bold)
101
- commands[:container].commands[:status].execute({}, {}, [])
102
- end
103
- end
104
-
105
- # NODES
106
- ########
107
- desc 'Manage nodes'
108
- arg_name 'Describe arguments to node here'
109
- command :node do |c|
110
-
111
- c.desc 'Node ID or Name'
112
- c.arg_name 'node'
113
- c.flag [:n, :name]
114
-
115
- # NODE SSH
116
- ###########
117
- c.desc 'Open an SSH console to a node'
118
- c.command :ssh do |ssh|
119
- ssh.action do |global_options,options,args|
120
- help_now!('name is required') if options[:name].nil?
121
-
122
- node = @testlab.nodes.select{ |n| n.id.to_sym == options[:name].to_sym }.first
123
- node.nil? and raise TestLab::TestLabError, "We could not find the node you supplied!"
124
-
125
- node.ssh.console
126
- end
127
- end
128
-
129
- # NODE STATUS
130
- ##############
131
- c.desc 'Display the status of node(s)'
132
- c.long_desc 'Displays the status of all nodes or a single node if supplied via the ID parameter.'
133
- c.command :status do |status|
134
- status.action do |global_options, options, args|
135
- if options[:name].nil?
136
- # No ID supplied; show everything
137
- ZTK::Report.new(:ui => @testlab.ui).spreadsheet(@testlab.nodes, TestLab::Node::STATUS_KEYS) do |node|
138
- OpenStruct.new(node.status)
139
- end
140
- else
141
- # ID supplied; show just that item
142
- node = @testlab.nodes.select{ |c| c.id.to_sym == options[:name].to_sym }.first
143
- node.nil? and raise TestLab::TestLabError, "We could not find the node you supplied!"
144
-
145
- ZTK::Report.new(:ui => @testlab.ui).list(node, TestLab::Node::STATUS_KEYS) do |node|
146
- OpenStruct.new(node.status)
147
- end
148
- end
149
- end
150
- end
151
-
152
- # NODE UP
153
- ##########
154
- c.desc 'Up a node'
155
- c.long_desc <<-EOF
156
- Up a node. The node is started and brought online.
157
- EOF
158
- c.command :up do |up|
159
- up.action do |global_options, options, args|
160
- if options[:name].nil?
161
- help_now!('name is required') if options[:name].nil?
162
- else
163
- node = @testlab.nodes.select{ |c| c.id.to_sym == options[:name].to_sym }.first
164
- node.nil? and raise TestLab::TestLabError, "We could not find the node you supplied!"
165
-
166
- node.up
167
- end
168
- end
169
- end
170
-
171
- # NODE DOWN
172
- ############
173
- c.desc 'Down a node'
174
- c.long_desc <<-EOF
175
- Down a node. The node is stopped taking it offline.
176
- EOF
177
- c.command :down do |down|
178
- down.action do |global_options, options, args|
179
- if options[:name].nil?
180
- help_now!('name is required') if options[:name].nil?
181
- else
182
- node = @testlab.nodes.select{ |c| c.id.to_sym == options[:name].to_sym }.first
183
- node.nil? and raise TestLab::TestLabError, "We could not find the node you supplied!"
184
-
185
- node.down
186
- end
187
- end
188
- end
189
-
190
- # NODE CREATE
191
- ##############
192
- c.desc 'Create a node'
193
- c.long_desc <<-EOF
194
- Create a node. The node is created.
195
- EOF
196
- c.command :create do |create|
197
- create.action do |global_options, options, args|
198
- if options[:name].nil?
199
- help_now!('name is required') if options[:name].nil?
200
- else
201
- node = @testlab.nodes.select{ |c| c.id.to_sym == options[:name].to_sym }.first
202
- node.nil? and raise TestLab::TestLabError, "We could not find the node you screateplied!"
203
-
204
- node.create
205
- end
206
- end
207
- end
208
-
209
- # NODE DESTROY
210
- ############
211
- c.desc 'Destroy a node'
212
- c.long_desc <<-EOF
213
- Destroy a node. The node is stopped and destroyed.
214
- EOF
215
- c.command :destroy do |destroy|
216
- destroy.action do |global_options, options, args|
217
- if options[:name].nil?
218
- help_now!('name is required') if options[:name].nil?
219
- else
220
- node = @testlab.nodes.select{ |c| c.id.to_sym == options[:name].to_sym }.first
221
- node.nil? and raise TestLab::TestLabError, "We could not find the node you supplied!"
222
-
223
- node.destroy
224
- end
225
- end
226
- end
227
-
228
- # NODE SETUP
229
- #############
230
- c.desc 'Setup a node'
231
- c.long_desc <<-EOF
232
- Setup a node. The node is created, started and provisioned.
233
- EOF
234
- c.command :setup do |setup|
235
- setup.action do |global_options, options, args|
236
- if options[:name].nil?
237
- help_now!('name is required') if options[:name].nil?
238
- else
239
- node = @testlab.nodes.select{ |c| c.id.to_sym == options[:name].to_sym }.first
240
- node.nil? and raise TestLab::TestLabError, "We could not find the node you supplied!"
241
-
242
- node.setup
243
- end
244
- end
245
- end
246
-
247
- # NODE TEARDOWN
248
- ################
249
- c.desc 'Teardown a node'
250
- c.long_desc <<-EOF
251
- Teardown a node. The node is offlined and destroyed.
252
- EOF
253
- c.command :teardown do |teardown|
254
- teardown.action do |global_options, options, args|
255
- if options[:name].nil?
256
- help_now!('name is required') if options[:name].nil?
257
- else
258
- node = @testlab.nodes.select{ |c| c.id.to_sym == options[:name].to_sym }.first
259
- node.nil? and raise TestLab::TestLabError, "We could not find the node you supplied!"
260
-
261
- node.teardown
262
- end
263
- end
264
- end
265
-
266
- end
267
-
268
- # NETWORKS
269
- ###########
270
- desc 'Manage networks'
271
- arg_name 'Describe arguments to network here'
272
- command :network do |c|
273
-
274
- c.desc 'Network ID or Name'
275
- c.arg_name 'network'
276
- c.flag [:n, :name]
277
-
278
-
279
- # ROUTES
280
- #########
281
- c.desc 'Manage routes'
282
- c.command :route do |route|
283
-
284
- # ROUTE ADD
285
- ############
286
- route.desc 'Add routes to lab networks'
287
- route.command :add do |add|
288
- add.action do |global_options,options,args|
289
- help_now!('name is required') if options[:name].nil?
290
-
291
- network = @testlab.networks.select{ |c| c.id.to_sym == options[:name].to_sym }.first
292
- network.nil? and raise TestLab::TestLabError, "We could not find the network you supplied!"
293
-
294
- network.manage_route(:add)
295
- @testlab.ui.stdout.puts("Added routes successfully!".green.bold)
296
- @testlab.ui.stdout.puts %x(netstat -nr | grep '#{network.node.ip}').strip
297
- end
298
- end
299
-
300
- # ROUTE DEL
301
- ############
302
- route.desc 'Delete routes to lab networks'
303
- route.command :del do |del|
304
- del.action do |global_options,options,args|
305
- help_now!('name is required') if options[:name].nil?
306
-
307
- network = @testlab.networks.select{ |c| c.id.to_sym == options[:name].to_sym }.first
308
- network.nil? and raise TestLab::TestLabError, "We could not find the network you supplied!"
309
-
310
- network.manage_route(:del)
311
- @testlab.ui.stdout.puts("Deleted routes successfully!".red.bold)
312
- @testlab.ui.stdout.puts %x(netstat -nr | grep '#{network.node.ip}').strip
313
- end
314
- end
315
-
316
- # ROUTE SHOW
317
- #############
318
- route.desc 'Show routes to lab networks'
319
- route.command :show do |show|
320
- show.action do |global_options,options,args|
321
- help_now!('name is required') if options[:name].nil?
322
-
323
- network = @testlab.networks.select{ |c| c.id.to_sym == options[:name].to_sym }.first
324
- network.nil? and raise TestLab::TestLabError, "We could not find the network you supplied!"
325
-
326
- @testlab.ui.stdout.puts("TestLab routes:".green.bold)
327
- case RUBY_PLATFORM
328
- when /darwin/ then
329
- @testlab.ui.stdout.puts %x(netstat -nrf inet | grep '#{network.node.ip}').strip
330
- when /linux/ then
331
- @testlab.ui.stdout.puts %x(netstat -nr | grep '#{network.node.ip}').strip
332
- end
333
- end
334
- end
335
- end
35
+ commands_from 'commands'
336
36
 
337
- # NETWORK STATUS
338
- #################
339
- c.desc 'Display the status of network(s)'
340
- c.long_desc 'Displays the status of all networks or a single network if supplied via the ID parameter.'
341
- c.command :status do |status|
342
- status.action do |global_options, options, args|
343
- if options[:name].nil?
344
- # No ID supplied; show everything
345
- networks = @testlab.networks.delete_if{|n| n.node.dead? }
346
- if networks.count == 0
347
- @testlab.ui.stderr.puts("You either have no networks defined or dead nodes!".yellow)
348
- else
349
- ZTK::Report.new(:ui => @testlab.ui).spreadsheet(networks, TestLab::Network::STATUS_KEYS) do |network|
350
- OpenStruct.new(network.status)
351
- end
352
- end
353
- else
354
- # ID supplied; show just that item
355
- network = @testlab.networks.select{ |c| c.id.to_sym == options[:name].to_sym }.first
356
- network.nil? and raise TestLab::TestLabError, "We could not find the network you supplied!"
357
-
358
- ZTK::Report.new(:ui => @testlab.ui).list(network, TestLab::Network::STATUS_KEYS) do |network|
359
- OpenStruct.new(network.status)
360
- end
361
- end
362
- end
363
- end
364
-
365
- # NETWORK UP
366
- ###############
367
- c.desc 'Up a network'
368
- c.long_desc <<-EOF
369
- Up a network. The network is started and brought online.
370
- EOF
371
- c.command :up do |up|
372
- up.action do |global_options, options, args|
373
- if options[:name].nil?
374
- help_now!('name is required') if options[:name].nil?
375
- else
376
- network = @testlab.networks.select{ |c| c.id.to_sym == options[:name].to_sym }.first
377
- network.nil? and raise TestLab::TestLabError, "We could not find the network you supplied!"
378
-
379
- network.up
380
- end
381
- end
382
- end
383
-
384
- # NETWORK DOWN
385
- #################
386
- c.desc 'Down a network'
387
- c.long_desc <<-EOF
388
- Down a network. The network is stopped taking it offline.
389
- EOF
390
- c.command :down do |down|
391
- down.action do |global_options, options, args|
392
- if options[:name].nil?
393
- help_now!('name is required') if options[:name].nil?
394
- else
395
- network = @testlab.networks.select{ |c| c.id.to_sym == options[:name].to_sym }.first
396
- network.nil? and raise TestLab::TestLabError, "We could not find the network you supplied!"
397
-
398
- network.down
399
- end
400
- end
401
- end
402
-
403
- # NETWORK SETUP
404
- ####################
405
- c.desc 'Setup a network'
406
- c.long_desc <<-EOF
407
- Setup a network. The network is created, started and provisioned.
408
- EOF
409
- c.command :setup do |setup|
410
- setup.action do |global_options, options, args|
411
- if options[:name].nil?
412
- help_now!('name is required') if options[:name].nil?
413
- else
414
- network = @testlab.networks.select{ |c| c.id.to_sym == options[:name].to_sym }.first
415
- network.nil? and raise TestLab::TestLabError, "We could not find the network you supplied!"
416
-
417
- network.setup
418
- end
419
- end
420
- end
421
-
422
- # NETWORK TEARDOWN
423
- ####################
424
- c.desc 'Teardown a network'
425
- c.long_desc <<-EOF
426
- Teardown a network. The network is offlined and destroyed.
427
- EOF
428
- c.command :teardown do |teardown|
429
- teardown.action do |global_options, options, args|
430
- if options[:name].nil?
431
- help_now!('name is required') if options[:name].nil?
432
- else
433
- network = @testlab.networks.select{ |c| c.id.to_sym == options[:name].to_sym }.first
434
- network.nil? and raise TestLab::TestLabError, "We could not find the network you supplied!"
435
-
436
- network.teardown
437
- end
438
- end
439
- end
440
-
441
- end
442
-
443
- # CONTAINERS
444
- #############
445
- desc 'Manage containers'
446
- arg_name 'Describe arguments to container here'
447
- command :container do |c|
448
-
449
- c.desc 'Container ID or Name'
450
- c.arg_name 'container'
451
- c.flag [:n, :name]
452
-
453
- # CONTAINER SSH
454
- ################
455
- c.desc 'Open an SSH console to a container'
456
- c.command :ssh do |ssh|
457
-
458
- ssh.desc 'Specify an SSH Username to use'
459
- ssh.arg_name 'username'
460
- ssh.flag [:u, :user]
461
-
462
- ssh.desc 'Specify an SSH Identity Key to use'
463
- ssh.arg_name 'key'
464
- ssh.flag [:i, :identity]
465
-
466
- ssh.action do |global_options, options, args|
467
- help_now!('name is required') if options[:name].nil?
468
-
469
- container = @testlab.containers.select{ |n| n.id.to_sym == options[:name].to_sym }.first
470
- container.nil? and raise TestLab::TestLabError, "We could not find the container you supplied!"
471
-
472
- ssh_options = Hash.new
473
- ssh_options[:user] = options[:user]
474
- ssh_options[:keys] = options[:identity]
475
-
476
- container.ssh(ssh_options).console
477
- end
478
- end
479
-
480
- # CONTAINER STATUS
481
- ###################
482
- c.desc 'Display the status of container(s)'
483
- c.long_desc <<-EOF
484
- Displays the status of all containers or a single container if supplied via the ID parameter.
485
- EOF
486
- c.command :status do |status|
487
- status.action do |global_options, options, args|
488
- if options[:name].nil?
489
- # No ID supplied; show everything
490
- containers = @testlab.containers.delete_if{ |c| c.node.dead? }
491
- if containers.count == 0
492
- @testlab.ui.stderr.puts("You either have no containers defined or dead nodes!".yellow)
493
- else
494
- # ZTK::Report.new(:ui => @testlab.ui).spreadsheet(containers, TestLab::Container::STATUS_KEYS.reject{|k| k == :fqdn}) do |container|
495
- ZTK::Report.new(:ui => @testlab.ui).list(containers, TestLab::Container::STATUS_KEYS) do |container|
496
- # OpenStruct.new(container.status.reject{|k,v| k == :fqdn})
497
- OpenStruct.new(container.status)
498
- end
499
- end
500
- else
501
- # ID supplied; show just that item
502
- container = @testlab.containers.select{ |c| c.id.to_sym == options[:name].to_sym }.first
503
- container.nil? and raise TestLab::TestLabError, "We could not find the container you supplied!"
504
-
505
- ZTK::Report.new(:ui => @testlab.ui).list(container, TestLab::Container::STATUS_KEYS) do |container|
506
- OpenStruct.new(container.status)
507
- end
508
- end
509
- end
510
- end
511
-
512
- # CONTAINER RECYCLE
513
- ####################
514
- c.desc 'Recycles a container'
515
- c.long_desc <<-EOF
516
- Recycles a container. The container is taken through a series of state changes to ensure it is pristine.
517
-
518
- The containers is cycled in this order:
519
-
520
- Down -> Destroy -> Create -> Up
521
- EOF
522
- c.command :recycle do |recycle|
523
- recycle.action do |global_options, options, args|
524
- if options[:name].nil?
525
- help_now!('name is required') if options[:name].nil?
526
- else
527
- container = @testlab.containers.select{ |c| c.id.to_sym == options[:name].to_sym }.first
528
- container.nil? and raise TestLab::TestLabError, "We could not find the container you supplied!"
529
-
530
- container.teardown
531
- container.setup
532
- end
533
- end
534
- end
535
-
536
- # CONTAINER UP
537
- ###############
538
- c.desc 'Up a container'
539
- c.long_desc <<-EOF
540
- Up a container. The container is started and brought online.
541
- EOF
542
- c.command :up do |up|
543
- up.action do |global_options, options, args|
544
- if options[:name].nil?
545
- help_now!('name is required') if options[:name].nil?
546
- else
547
- container = @testlab.containers.select{ |c| c.id.to_sym == options[:name].to_sym }.first
548
- container.nil? and raise TestLab::TestLabError, "We could not find the container you supplied!"
549
-
550
- container.up
551
- end
552
- end
553
- end
554
-
555
- # CONTAINER DOWN
556
- #################
557
- c.desc 'Down a container'
558
- c.long_desc <<-EOF
559
- Down a container. The container is stopped taking it offline.
560
- EOF
561
- c.command :down do |down|
562
- down.action do |global_options, options, args|
563
- if options[:name].nil?
564
- help_now!('name is required') if options[:name].nil?
565
- else
566
- container = @testlab.containers.select{ |c| c.id.to_sym == options[:name].to_sym }.first
567
- container.nil? and raise TestLab::TestLabError, "We could not find the container you supplied!"
568
-
569
- container.down
570
- end
571
- end
572
- end
573
-
574
- # CONTAINER CREATE
575
- ###################
576
- c.desc 'Create a container'
577
- c.long_desc <<-EOF
578
- Create a container. The container is created.
579
- EOF
580
- c.command :create do |create|
581
- create.action do |global_options, options, args|
582
- if options[:name].nil?
583
- help_now!('name is required') if options[:name].nil?
584
- else
585
- container = @testlab.containers.select{ |c| c.id.to_sym == options[:name].to_sym }.first
586
- container.nil? and raise TestLab::TestLabError, "We could not find the container you screateplied!"
587
-
588
- container.create
589
- end
590
- end
591
- end
592
-
593
- # CONTAINER DESTROY
594
- ####################
595
- c.desc 'Destroy a container'
596
- c.long_desc <<-EOF
597
- Destroy a container. The container is stopped and destroyed.
598
- EOF
599
- c.command :destroy do |destroy|
600
- destroy.action do |global_options, options, args|
601
- if options[:name].nil?
602
- help_now!('name is required') if options[:name].nil?
603
- else
604
- container = @testlab.containers.select{ |c| c.id.to_sym == options[:name].to_sym }.first
605
- container.nil? and raise TestLab::TestLabError, "We could not find the container you supplied!"
606
-
607
- container.destroy
608
- end
609
- end
610
- end
611
-
612
- # CONTAINER SETUP
613
- ####################
614
- c.desc 'Setup a container'
615
- c.long_desc <<-EOF
616
- Setup a container. The container is created, started and provisioned.
617
- EOF
618
- c.command :setup do |setup|
619
- setup.action do |global_options, options, args|
620
- if options[:name].nil?
621
- help_now!('name is required') if options[:name].nil?
622
- else
623
- container = @testlab.containers.select{ |c| c.id.to_sym == options[:name].to_sym }.first
624
- container.nil? and raise TestLab::TestLabError, "We could not find the container you supplied!"
625
-
626
- container.setup
627
- end
628
- end
629
- end
630
-
631
- # CONTAINER TEARDOWN
632
- ####################
633
- c.desc 'Teardown a container'
634
- c.long_desc <<-EOF
635
- Teardown a container. The container is offlined and destroyed.
636
- EOF
637
- c.command :teardown do |teardown|
638
- teardown.action do |global_options, options, args|
639
- if options[:name].nil?
640
- help_now!('name is required') if options[:name].nil?
641
- else
642
- container = @testlab.containers.select{ |c| c.id.to_sym == options[:name].to_sym }.first
643
- container.nil? and raise TestLab::TestLabError, "We could not find the container you supplied!"
644
-
645
- container.teardown
646
- end
647
- end
648
- end
649
-
650
- # CONTAINER CLONE
651
- ##################
652
- c.desc 'Clone a container'
653
- c.long_desc <<-EOF
654
- Clone a container. The container is offlined and an ephemeral copy of it is started.
655
- EOF
656
- c.command :clone do |clone|
657
- clone.action do |global_options, options, args|
658
- if options[:name].nil?
659
- help_now!('name is required') if options[:name].nil?
660
- else
661
- container = @testlab.containers.select{ |c| c.id.to_sym == options[:name].to_sym }.first
662
- container.nil? and raise TestLab::TestLabError, "We could not find the container you supplied!"
663
-
664
- container.clone
665
- end
666
- end
667
- end
668
-
669
- end
37
+ desc 'Show verbose output'
38
+ default_value false
39
+ switch [:v, :verbose]
670
40
 
671
41
  pre do |global,command,options,args|
672
- # Pre logic here
673
- # Return true to proceed; false to abort and not call the
674
- # chosen command
675
- # Use skips_pre before a command to skip this block
676
- # on that command only
42
+ global[:v].nil? or (global[:v] == true) and ENV['LOG_LEVEL'] = 'DEBUG'
677
43
 
678
44
  log_file = File.join(Dir.pwd, "testlab.log")
679
45
  @logger = ZTK::Logger.new(log_file)
46
+
47
+ TestLab::Utility.log_header.each { |line| @logger.info { line } }
48
+
49
+ @logger.debug { "global(#{global.inspect})" }
50
+ @logger.debug { "options(#{options.inspect})" }
51
+ @logger.debug { "args(#{args.inspect})" }
52
+
680
53
  @ui = ZTK::UI.new(:logger => @logger)
681
54
  @testlab = TestLab.new(:ui => @ui)
682
55