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 +2 -1
- data/bin/tl +8 -4
- data/features/step_definitions/testlab_steps.rb +5 -1
- data/features/support/Labfile.local +46 -0
- data/features/support/Labfile.vagrant +58 -0
- data/features/support/env.rb +8 -0
- data/features/testlab.feature +4 -8
- data/lib/commands/container.rb +28 -240
- data/lib/commands/network.rb +27 -193
- data/lib/commands/node.rb +9 -160
- data/lib/commands/testlab.rb +72 -10
- data/lib/testlab/container/actions.rb +2 -2
- data/lib/testlab/container/io.rb +21 -12
- data/lib/testlab/container/lifecycle.rb +13 -0
- data/lib/testlab/container/ssh.rb +2 -2
- data/lib/testlab/container.rb +3 -1
- data/lib/testlab/interface.rb +2 -0
- data/lib/testlab/network/actions.rb +2 -2
- data/lib/testlab/network/lifecycle.rb +15 -0
- data/lib/testlab/network/status.rb +1 -1
- data/lib/testlab/network.rb +3 -1
- data/lib/testlab/node/lifecycle.rb +9 -0
- data/lib/testlab/node.rb +2 -0
- data/lib/testlab/user.rb +2 -0
- data/lib/testlab/utility/gli.rb +83 -0
- data/lib/testlab/utility/logger.rb +35 -30
- data/lib/testlab/utility.rb +2 -0
- data/lib/testlab/version.rb +1 -1
- data/lib/testlab.rb +111 -38
- data/spec/container_spec.rb +4 -0
- data/spec/network_spec.rb +4 -0
- metadata +9 -6
- data/features/support/Labfile +0 -85
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.
|
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
|
data/features/support/env.rb
CHANGED
@@ -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
|
data/features/testlab.feature
CHANGED
@@ -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
|
61
|
-
When I
|
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
|
data/lib/commands/container.rb
CHANGED
@@ -20,193 +20,17 @@
|
|
20
20
|
|
21
21
|
# CONTAINERS
|
22
22
|
#############
|
23
|
-
|
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
|
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 =
|
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 '
|
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 '
|
74
|
+
c.desc 'Container SSH configuration'
|
252
75
|
c.long_desc <<-EOF
|
253
|
-
Displays
|
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
|
-
|
259
|
-
|
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 '
|
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
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
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
|
113
|
+
c.desc 'Clone containers'
|
307
114
|
c.long_desc <<-EOF
|
308
|
-
An ephemeral copy of the container is started.
|
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
|
-
|
313
|
-
|
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
|
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
|
-
|
343
|
-
|
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
|
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
|
-
|
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
|