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 +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
|