testlab 1.15.1 → 1.16.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.
- checksums.yaml +15 -0
- data/.travis.yml +0 -1
- data/bin/tl +11 -14
- data/lib/commands/node.rb +26 -0
- data/lib/testlab.rb +17 -10
- data/lib/testlab/container/actions.rb +2 -2
- data/lib/testlab/container/io.rb +2 -0
- data/lib/testlab/provider.rb +1 -1
- data/lib/testlab/providers/vagrant.rb +86 -2
- data/lib/testlab/provisioners/bind.rb +10 -4
- data/lib/testlab/user/lifecycle.rb +1 -1
- data/lib/testlab/utility/logger.rb +5 -2
- data/lib/testlab/utility/misc.rb +13 -6
- data/lib/testlab/version.rb +1 -1
- metadata +5 -37
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NmQ5ZmI1ZmRjYTJhNjJjOGNkOWRiYjE1ODQ3ZDM4OGVjODAxNjRlNw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NzU1NDg1NDc0MjM4MWZjZmQwZThhYjQyNWY2NjQ4YjNjMzRjODEwMw==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YjRmYTkzZWM3ZTEwOWI5MjMwY2U1NjY1MjI4YTdmYWVmYWY4OWYyOTNmNzUx
|
10
|
+
ZTY4NDkxODdiZWMwNzI2MjY1Mzc1MjQwZmI0ZjUyYmIzY2FhY2U2ZjhjYzM3
|
11
|
+
M2Y1MGIwMjcxOTk2YTU2NDkzZGIzYThlOThiNWQxNjQ4YmQ5YjQ=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NDkzMTBjZTI2ODUzZDI3OGQyZjc0OWI3YzMxMWVjMDNhZTRjYTA4MzE4Zjg0
|
14
|
+
MDQxZmRjMWVkZjFmYTk3MmZhOTA4MzdkOTMxMTgyOGFiYmQ5NjRmOWFjOTk2
|
15
|
+
MGJlZTFmMjQ3OTQxMjNlNDk1ZWNhMTNhZWMzMDk4M2MyMzc5ZGM=
|
data/.travis.yml
CHANGED
data/bin/tl
CHANGED
@@ -82,31 +82,30 @@ desc 'Quiet mode'
|
|
82
82
|
default_value false
|
83
83
|
switch [:q, :quiet]
|
84
84
|
|
85
|
-
desc 'Path to Labfile
|
85
|
+
desc 'Path to Labfile'
|
86
86
|
arg_name 'path/to/file'
|
87
|
-
# default_value File.join(Dir.pwd, 'Labfile')
|
88
87
|
flag [:l, :labfile]
|
89
88
|
|
90
|
-
desc 'Path to Repository directory
|
89
|
+
desc 'Path to Repository directory'
|
91
90
|
arg_name 'path/to/directory'
|
92
|
-
default_value Dir.pwd
|
93
91
|
flag [:r, :repo]
|
94
92
|
|
95
|
-
desc 'Path to Configuration directory
|
93
|
+
desc 'Path to Configuration directory'
|
96
94
|
arg_name 'path/to/directory'
|
97
|
-
# default_value File.join(Dir.pwd, ".testlab-#{TestLab.hostname}")
|
98
95
|
flag [:c, :config]
|
99
96
|
|
97
|
+
desc 'Path to Log file'
|
98
|
+
default_value STDOUT
|
99
|
+
arg_name 'path/to/log_file'
|
100
|
+
flag [:L, :log_file]
|
101
|
+
|
100
102
|
pre do |global,command,options,args|
|
101
103
|
@testlab_start_time = Time.now.utc
|
102
104
|
|
103
105
|
(global[:verbose] == true) and (ENV['LOG_LEVEL'] = 'DEBUG')
|
104
106
|
|
105
|
-
log_file = File.join(global[:repo], "testlab-#{TestLab.hostname}.log")
|
106
|
-
@logger = ZTK::Logger.new(log_file)
|
107
|
-
|
108
107
|
@ui = ZTK::UI.new(
|
109
|
-
:logger =>
|
108
|
+
:logger => ZTK::Logger.new(global[:log_file]),
|
110
109
|
:verbose => global[:verbose],
|
111
110
|
:quiet => global[:quiet]
|
112
111
|
)
|
@@ -122,8 +121,6 @@ pre do |global,command,options,args|
|
|
122
121
|
:repo_dir => global[:repo]
|
123
122
|
)
|
124
123
|
|
125
|
-
TestLab::Utility.log_header(@testlab).each { |line| @logger.info { line } }
|
126
|
-
|
127
124
|
@testlab.boot
|
128
125
|
|
129
126
|
if !@ui.quiet?
|
@@ -162,9 +159,9 @@ on_error do |exception|
|
|
162
159
|
else
|
163
160
|
testlab_run_time = (Time.now.utc - @testlab_start_time)
|
164
161
|
|
165
|
-
@logger.fatal { exception.inspect }
|
162
|
+
@ui.logger.fatal { exception.inspect }
|
166
163
|
exception.backtrace.each do |line|
|
167
|
-
@logger.logdev.write("#{line}\n")
|
164
|
+
@ui.logger.logdev.write("#{line}\n")
|
168
165
|
end
|
169
166
|
|
170
167
|
message = format_message("TestLab v#{TestLab::VERSION} Aborted (%0.4f seconds)".black.bold % testlab_run_time)
|
data/lib/commands/node.rb
CHANGED
@@ -51,4 +51,30 @@ build_lab_commands(:node, TestLab::Node) do |c|
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
+
# NODE IMPORT
|
55
|
+
##############
|
56
|
+
c.desc 'Node Import (only if provider supported)'
|
57
|
+
c.command :import do |import|
|
58
|
+
import.desc 'Specify the node image file to import.'
|
59
|
+
import.arg_name 'filename'
|
60
|
+
import.flag [:input]
|
61
|
+
|
62
|
+
import.action do |global_options,options,args|
|
63
|
+
node = iterate_objects_by_name(options[:name], TestLab::Node).first
|
64
|
+
|
65
|
+
node.import(options[:input])
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# NODE EXPORT
|
70
|
+
##############
|
71
|
+
c.desc 'Node Export (only if provider supported)'
|
72
|
+
c.command :export do |export|
|
73
|
+
export.action do |global_options,options,args|
|
74
|
+
node = iterate_objects_by_name(options[:name], TestLab::Node).first
|
75
|
+
|
76
|
+
node.export
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
54
80
|
end
|
data/lib/testlab.rb
CHANGED
@@ -141,16 +141,19 @@ class TestLab
|
|
141
141
|
attr_accessor :labfile_path
|
142
142
|
|
143
143
|
def initialize(options={})
|
144
|
-
self.ui
|
145
|
-
self.class.ui
|
144
|
+
self.ui = (options[:ui] || ZTK::UI.new)
|
145
|
+
self.class.ui = self.ui
|
146
146
|
|
147
|
-
|
147
|
+
_labfile_path = (options[:labfile_path] || ENV['LABFILE'] || 'Labfile')
|
148
|
+
@labfile_path = ZTK::Locator.find(_labfile_path)
|
148
149
|
|
149
|
-
@
|
150
|
+
@repo_dir = (options[:repo_dir] || File.dirname(@labfile_path))
|
151
|
+
|
152
|
+
@config_dir = (options[:config_dir] || File.join(@repo_dir, ".testlab-#{TestLab.hostname}"))
|
150
153
|
File.exists?(@config_dir) or FileUtils.mkdir_p(@config_dir)
|
151
154
|
|
152
|
-
|
153
|
-
|
155
|
+
# @log_file = (options[:log_file] || File.join(@repo_dir, "testlab-#{TestLab.hostname}.log") || STDOUT)
|
156
|
+
# self.ui.logger = ZTK::Logger.new(@log_file)
|
154
157
|
end
|
155
158
|
|
156
159
|
# Boot TestLab
|
@@ -159,15 +162,19 @@ class TestLab
|
|
159
162
|
#
|
160
163
|
# @return [Boolean] True if successful.
|
161
164
|
def boot
|
165
|
+
TestLab::Utility.log_header(self).each { |line| self.ui.logger.info { line } }
|
162
166
|
|
163
167
|
# Raise how many files we can have open to the hard limit.
|
164
168
|
nofile_cur, nofile_max = Process.getrlimit(Process::RLIMIT_NOFILE)
|
165
169
|
if nofile_cur != nofile_max
|
166
170
|
|
167
|
-
# OSX likes to indicate we can set the infinity value here
|
168
|
-
#
|
169
|
-
#
|
170
|
-
#
|
171
|
+
# OSX likes to indicate we can set the infinity value here.
|
172
|
+
#
|
173
|
+
# Doing so causes the following exception to throw:
|
174
|
+
# Errno::EINVAL: Invalid argument - setrlimit
|
175
|
+
#
|
176
|
+
# In the event infinity is returned as the max value, use 4096 as the max
|
177
|
+
# value.
|
171
178
|
if (nofile_max == Process::RLIM_INFINITY)
|
172
179
|
nofile_max = 4096
|
173
180
|
end
|
@@ -71,7 +71,7 @@ class TestLab
|
|
71
71
|
self.lxc.start(start_args)
|
72
72
|
end
|
73
73
|
|
74
|
-
(self.state != :running) and raise ContainerError, "The container failed to online! (did you create it? Check status with 'tl status')"
|
74
|
+
(self.state != :running) and raise ContainerError, "The container #{self.id.inspect} failed to online! (did you create it? Check status with 'tl status')"
|
75
75
|
|
76
76
|
ZTK::TCPSocketCheck.new(:ui => @ui, :host => self.primary_interface.ip, :port => 22).wait
|
77
77
|
|
@@ -119,7 +119,7 @@ class TestLab
|
|
119
119
|
self.persist and self.lxc.destroy(%(-f))
|
120
120
|
end
|
121
121
|
|
122
|
-
(self.state == :running) and raise ContainerError, "The container failed to offline!"
|
122
|
+
(self.state == :running) and raise ContainerError, "The container #{self.id.inspect} failed to offline!"
|
123
123
|
|
124
124
|
do_provisioner_callbacks(self, :down, @ui)
|
125
125
|
end
|
data/lib/testlab/container/io.rb
CHANGED
@@ -73,6 +73,8 @@ class TestLab
|
|
73
73
|
# Ensure the container is stopped before we attempt to export it.
|
74
74
|
self.down
|
75
75
|
|
76
|
+
self.lxc.attach(%(-- /bin/bash -c 'apt-get clean'))
|
77
|
+
|
76
78
|
export_tempfile = Tempfile.new('export')
|
77
79
|
remote_filename = File.basename(export_tempfile.path.dup)
|
78
80
|
export_tempfile.close!
|
data/lib/testlab/provider.rb
CHANGED
@@ -7,7 +7,7 @@ class TestLab
|
|
7
7
|
#
|
8
8
|
# @author Zachary Patten <zachary AT jovelabs DOT com>
|
9
9
|
class Provider
|
10
|
-
PROXY_METHODS = %w(instance_id state user identity ip port create destroy up down reload status alive? dead? exists?).map(&:to_sym)
|
10
|
+
PROXY_METHODS = %w(instance_id state user identity ip port create destroy up down export import reload status alive? dead? exists?).map(&:to_sym)
|
11
11
|
|
12
12
|
autoload :AWS, 'testlab/providers/aws'
|
13
13
|
autoload :BareMetal, 'testlab/providers/bare_metal'
|
@@ -36,6 +36,8 @@ class TestLab
|
|
36
36
|
|
37
37
|
# ensure our vagrant key is there
|
38
38
|
@config[:vagrant] ||= Hash.new
|
39
|
+
|
40
|
+
@command = ZTK::Command.new(:ui => @ui, :silence => true, :ignore_exit_status => true, :timeout => 3600)
|
39
41
|
end
|
40
42
|
|
41
43
|
################################################################################
|
@@ -73,6 +75,68 @@ class TestLab
|
|
73
75
|
true
|
74
76
|
end
|
75
77
|
|
78
|
+
################################################################################
|
79
|
+
|
80
|
+
# Export the Vagrant-controlled VM
|
81
|
+
def export(filename=nil)
|
82
|
+
tempfile = Tempfile.new('export')
|
83
|
+
temppath = tempfile.path.dup
|
84
|
+
tempfile.unlink
|
85
|
+
File.exists?(temppath) or FileUtils.mkdir_p(temppath)
|
86
|
+
|
87
|
+
labfile_source = File.join(@config[:vagrant][:file], 'Labfile')
|
88
|
+
labfile_destination = File.join(temppath, 'Labfile')
|
89
|
+
|
90
|
+
image_name = "lab.ova"
|
91
|
+
image_location = File.join(temppath, image_name)
|
92
|
+
|
93
|
+
export_destination = File.join(@config[:vagrant][:file], "#{self.instance_id}.lab")
|
94
|
+
|
95
|
+
self.down
|
96
|
+
self.vboxmanage_cli(%W(export #{self.instance_id} --output #{image_location}))
|
97
|
+
FileUtils.cp(labfile_source, labfile_destination)
|
98
|
+
|
99
|
+
Dir.chdir(temppath) do
|
100
|
+
@command.exec(%(tar cvf #{export_destination} *))
|
101
|
+
end
|
102
|
+
|
103
|
+
FileUtils.rm_rf(temppath)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Import the Vagrant-controlled VM
|
107
|
+
def import(filename=nil)
|
108
|
+
filename = (filename || "#{self.instance_id}.lab")
|
109
|
+
|
110
|
+
tempfile = Tempfile.new('export')
|
111
|
+
temppath = tempfile.path.dup
|
112
|
+
tempfile.unlink
|
113
|
+
File.exists?(temppath) or FileUtils.mkdir_p(temppath)
|
114
|
+
|
115
|
+
id_filename = File.join(@config[:vagrant][:file], ".vagrant", "machines", self.instance_id, "virtualbox", "id")
|
116
|
+
FileUtils.mkdir_p(File.dirname(id_filename))
|
117
|
+
|
118
|
+
labfile_source = File.join(temppath, 'Labfile')
|
119
|
+
labfile_destination = File.join(@config[:vagrant][:file], 'Labfile')
|
120
|
+
|
121
|
+
image_name = "lab.ova"
|
122
|
+
image_location = File.join(temppath, image_name)
|
123
|
+
|
124
|
+
FileUtils.cp(filename, temppath)
|
125
|
+
Dir.chdir(temppath) do
|
126
|
+
@command.exec(%(tar xvf #{filename}))
|
127
|
+
end
|
128
|
+
|
129
|
+
self.destroy
|
130
|
+
self.vboxmanage_cli(%W(import #{image_location} --vsys 0 --vmname #{self.instance_id} --vsys 0 --cpus #{self.cpus} --vsys 0 --memory #{self.memory}))
|
131
|
+
uuid = self.vboxmanage_cli(%W(showvminfo #{self.instance_id} | grep UUID | head -1 | cut -f 2 -d ':')).output.strip
|
132
|
+
|
133
|
+
@command.exec(%(echo '#{uuid}' > #{id_filename}))
|
134
|
+
|
135
|
+
FileUtils.cp(labfile_source, labfile_destination)
|
136
|
+
|
137
|
+
FileUtils.rm_rf(temppath)
|
138
|
+
end
|
139
|
+
|
76
140
|
################################################################################
|
77
141
|
|
78
142
|
# Reload Vagrant-controlled VM
|
@@ -119,7 +183,7 @@ class TestLab
|
|
119
183
|
####################
|
120
184
|
|
121
185
|
def instance_id
|
122
|
-
(@config[:vagrant][:id] || "
|
186
|
+
(@config[:vagrant][:id] || "#{File.basename(@config[:vagrant][:file])}-#{TestLab.hostname}".downcase)
|
123
187
|
end
|
124
188
|
|
125
189
|
def user
|
@@ -183,7 +247,7 @@ class TestLab
|
|
183
247
|
@ui.logger.debug { "command == #{command.inspect}" }
|
184
248
|
|
185
249
|
render_vagrantfile
|
186
|
-
result =
|
250
|
+
result = @command.exec(command)
|
187
251
|
|
188
252
|
if result.exit_code != 0
|
189
253
|
@ui.stderr.puts
|
@@ -196,6 +260,26 @@ class TestLab
|
|
196
260
|
result
|
197
261
|
end
|
198
262
|
|
263
|
+
def vboxmanage_cli(*args)
|
264
|
+
@ui.logger.debug { "args == #{args.inspect}" }
|
265
|
+
|
266
|
+
command = TestLab.build_command_line("VBoxManage", *args)
|
267
|
+
@ui.logger.debug { "command == #{command.inspect}" }
|
268
|
+
|
269
|
+
render_vagrantfile
|
270
|
+
result = @command.exec(command)
|
271
|
+
|
272
|
+
if result.exit_code != 0
|
273
|
+
@ui.stderr.puts
|
274
|
+
@ui.stderr.puts
|
275
|
+
@ui.stderr.puts(result.output)
|
276
|
+
|
277
|
+
raise VagrantError, "VBoxManage failed to execute!"
|
278
|
+
end
|
279
|
+
|
280
|
+
result
|
281
|
+
end
|
282
|
+
|
199
283
|
def render_vagrantfile
|
200
284
|
context = {
|
201
285
|
:id => self.instance_id,
|
@@ -138,13 +138,19 @@ class TestLab
|
|
138
138
|
end
|
139
139
|
|
140
140
|
def bind_install(node)
|
141
|
-
node.
|
142
|
-
|
141
|
+
node.bootstrap(<<-EOSHELL)
|
142
|
+
export DEBIAN_FRONTEND="noninteractive"
|
143
|
+
|
144
|
+
(dpkg --status bind9 &> /dev/null || apt-get -qy install bind9)
|
145
|
+
rm -fv /etc/bind/{*.arpa,*.zone,*.conf*}
|
146
|
+
EOSHELL
|
143
147
|
end
|
144
148
|
|
145
149
|
def bind_reload(node)
|
146
|
-
node.
|
147
|
-
|
150
|
+
node.bootstrap(<<-EOSHELL)
|
151
|
+
chown -Rv bind:bind /etc/bind
|
152
|
+
rndc reload
|
153
|
+
EOSHELL
|
148
154
|
end
|
149
155
|
|
150
156
|
def bind_provision(node)
|
@@ -82,7 +82,7 @@ class TestLab
|
|
82
82
|
|
83
83
|
# ensure the container user home directory is owned by them
|
84
84
|
home_dir = self.container.lxc.attach(%(-- /bin/bash -c 'grep #{self.username} /etc/passwd | cut -d ":" -f6')).strip
|
85
|
-
self.container.lxc.attach(%(-- /bin/bash -c 'sudo chown -
|
85
|
+
self.container.lxc.attach(%(-- /bin/bash -c 'sudo chown -R $(id -u #{self.username}):$(id -g #{self.username}) #{home_dir}'))
|
86
86
|
|
87
87
|
# ensure the sudo user group can do passwordless sudo
|
88
88
|
self.container.lxc.attach(%(-- /bin/bash -c 'grep "sudo\tALL=\(ALL:ALL\) ALL" /etc/sudoers && sed -i "s/sudo\tALL=\(ALL:ALL\) ALL/sudo\tALL=\(ALL:ALL\) NOPASSWD: ALL/" /etc/sudoers'))
|
@@ -54,12 +54,15 @@ class TestLab
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def log_gem_dependencies(testlab)
|
57
|
-
{
|
58
|
-
"gli_version" => ::GLI::VERSION.inspect,
|
57
|
+
dependencies = {
|
59
58
|
"lxc_version" => ::LXC::VERSION.inspect,
|
60
59
|
"ztk_version" => ::ZTK::VERSION.inspect,
|
61
60
|
"activesupport_version" => ::ActiveSupport::VERSION::STRING.inspect
|
62
61
|
}
|
62
|
+
|
63
|
+
defined?(::GLI) and dependencies.merge!("gli_version" => ::GLI::VERSION.inspect)
|
64
|
+
|
65
|
+
dependencies
|
63
66
|
end
|
64
67
|
|
65
68
|
def log_external_dependencies(testlab)
|
data/lib/testlab/utility/misc.rb
CHANGED
@@ -28,18 +28,25 @@ class TestLab
|
|
28
28
|
def please_wait(options={}, &block)
|
29
29
|
ui = options[:ui]
|
30
30
|
message = options[:message]
|
31
|
-
mark = (options[:mark] || "
|
31
|
+
mark = (options[:mark] || "Completed in %0.4f seconds!")
|
32
32
|
|
33
33
|
!block_given? and raise MiscError, "You must supply a block!"
|
34
34
|
ui.nil? and raise MiscError, "You must supply a ZTK::UI object!"
|
35
35
|
message.nil? and raise MiscError, "You must supply a message!"
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
if (ui.logger.logdev == STDOUT)
|
38
|
+
mark = format_message("#{message} / #{mark.black.bold}")
|
39
|
+
message = format_message(message)
|
40
|
+
else
|
41
|
+
message = format_message(message)
|
42
|
+
length = message.uncolor.length
|
43
|
+
max = (length >= 60 ? (length+1) : (60 - length))
|
44
|
+
mark = ((' ' * max) + "# #{mark}".black.bold)
|
45
|
+
end
|
46
|
+
use_spinner = ((ui.logger.logdev == STDOUT) ? false : true)
|
41
47
|
|
42
|
-
ZTK::Benchmark.bench(:ui => ui, :message => message, :mark => mark) do
|
48
|
+
ZTK::Benchmark.bench(:ui => ui, :message => message, :mark => mark, :use_spinner => use_spinner) do
|
49
|
+
(ui.logger.logdev == STDOUT) and STDOUT.puts
|
43
50
|
yield
|
44
51
|
end
|
45
52
|
end
|
data/lib/testlab/version.rb
CHANGED
metadata
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: testlab
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
5
|
-
prerelease:
|
4
|
+
version: 1.16.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Zachary Patten
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-01-11 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: gli
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - ! '>='
|
20
18
|
- !ruby/object:Gem::Version
|
@@ -22,7 +20,6 @@ dependencies:
|
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
24
|
- - ! '>='
|
28
25
|
- !ruby/object:Gem::Version
|
@@ -30,7 +27,6 @@ dependencies:
|
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: lxc
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
31
|
- - ! '>='
|
36
32
|
- !ruby/object:Gem::Version
|
@@ -38,7 +34,6 @@ dependencies:
|
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
38
|
- - ! '>='
|
44
39
|
- !ruby/object:Gem::Version
|
@@ -46,7 +41,6 @@ dependencies:
|
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: ztk
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
45
|
- - ! '>='
|
52
46
|
- !ruby/object:Gem::Version
|
@@ -54,7 +48,6 @@ dependencies:
|
|
54
48
|
type: :runtime
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
52
|
- - ! '>='
|
60
53
|
- !ruby/object:Gem::Version
|
@@ -62,7 +55,6 @@ dependencies:
|
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: activesupport
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
59
|
- - ! '>='
|
68
60
|
- !ruby/object:Gem::Version
|
@@ -70,7 +62,6 @@ dependencies:
|
|
70
62
|
type: :runtime
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
66
|
- - ! '>='
|
76
67
|
- !ruby/object:Gem::Version
|
@@ -78,7 +69,6 @@ dependencies:
|
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: bundler
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
73
|
- - ! '>='
|
84
74
|
- !ruby/object:Gem::Version
|
@@ -86,7 +76,6 @@ dependencies:
|
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
80
|
- - ! '>='
|
92
81
|
- !ruby/object:Gem::Version
|
@@ -94,7 +83,6 @@ dependencies:
|
|
94
83
|
- !ruby/object:Gem::Dependency
|
95
84
|
name: pry
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
86
|
requirements:
|
99
87
|
- - ! '>='
|
100
88
|
- !ruby/object:Gem::Version
|
@@ -102,7 +90,6 @@ dependencies:
|
|
102
90
|
type: :development
|
103
91
|
prerelease: false
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
93
|
requirements:
|
107
94
|
- - ! '>='
|
108
95
|
- !ruby/object:Gem::Version
|
@@ -110,7 +97,6 @@ dependencies:
|
|
110
97
|
- !ruby/object:Gem::Dependency
|
111
98
|
name: rake
|
112
99
|
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
100
|
requirements:
|
115
101
|
- - ! '>='
|
116
102
|
- !ruby/object:Gem::Version
|
@@ -118,7 +104,6 @@ dependencies:
|
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
107
|
requirements:
|
123
108
|
- - ! '>='
|
124
109
|
- !ruby/object:Gem::Version
|
@@ -126,7 +111,6 @@ dependencies:
|
|
126
111
|
- !ruby/object:Gem::Dependency
|
127
112
|
name: redcarpet
|
128
113
|
requirement: !ruby/object:Gem::Requirement
|
129
|
-
none: false
|
130
114
|
requirements:
|
131
115
|
- - ! '>='
|
132
116
|
- !ruby/object:Gem::Version
|
@@ -134,7 +118,6 @@ dependencies:
|
|
134
118
|
type: :development
|
135
119
|
prerelease: false
|
136
120
|
version_requirements: !ruby/object:Gem::Requirement
|
137
|
-
none: false
|
138
121
|
requirements:
|
139
122
|
- - ! '>='
|
140
123
|
- !ruby/object:Gem::Version
|
@@ -142,7 +125,6 @@ dependencies:
|
|
142
125
|
- !ruby/object:Gem::Dependency
|
143
126
|
name: aruba
|
144
127
|
requirement: !ruby/object:Gem::Requirement
|
145
|
-
none: false
|
146
128
|
requirements:
|
147
129
|
- - ! '>='
|
148
130
|
- !ruby/object:Gem::Version
|
@@ -150,7 +132,6 @@ dependencies:
|
|
150
132
|
type: :development
|
151
133
|
prerelease: false
|
152
134
|
version_requirements: !ruby/object:Gem::Requirement
|
153
|
-
none: false
|
154
135
|
requirements:
|
155
136
|
- - ! '>='
|
156
137
|
- !ruby/object:Gem::Version
|
@@ -158,7 +139,6 @@ dependencies:
|
|
158
139
|
- !ruby/object:Gem::Dependency
|
159
140
|
name: rspec
|
160
141
|
requirement: !ruby/object:Gem::Requirement
|
161
|
-
none: false
|
162
142
|
requirements:
|
163
143
|
- - ! '>='
|
164
144
|
- !ruby/object:Gem::Version
|
@@ -166,7 +146,6 @@ dependencies:
|
|
166
146
|
type: :development
|
167
147
|
prerelease: false
|
168
148
|
version_requirements: !ruby/object:Gem::Requirement
|
169
|
-
none: false
|
170
149
|
requirements:
|
171
150
|
- - ! '>='
|
172
151
|
- !ruby/object:Gem::Version
|
@@ -174,7 +153,6 @@ dependencies:
|
|
174
153
|
- !ruby/object:Gem::Dependency
|
175
154
|
name: yard
|
176
155
|
requirement: !ruby/object:Gem::Requirement
|
177
|
-
none: false
|
178
156
|
requirements:
|
179
157
|
- - ! '>='
|
180
158
|
- !ruby/object:Gem::Version
|
@@ -182,7 +160,6 @@ dependencies:
|
|
182
160
|
type: :development
|
183
161
|
prerelease: false
|
184
162
|
version_requirements: !ruby/object:Gem::Requirement
|
185
|
-
none: false
|
186
163
|
requirements:
|
187
164
|
- - ! '>='
|
188
165
|
- !ruby/object:Gem::Version
|
@@ -190,7 +167,6 @@ dependencies:
|
|
190
167
|
- !ruby/object:Gem::Dependency
|
191
168
|
name: coveralls
|
192
169
|
requirement: !ruby/object:Gem::Requirement
|
193
|
-
none: false
|
194
170
|
requirements:
|
195
171
|
- - ! '>='
|
196
172
|
- !ruby/object:Gem::Version
|
@@ -198,7 +174,6 @@ dependencies:
|
|
198
174
|
type: :development
|
199
175
|
prerelease: false
|
200
176
|
version_requirements: !ruby/object:Gem::Requirement
|
201
|
-
none: false
|
202
177
|
requirements:
|
203
178
|
- - ! '>='
|
204
179
|
- !ruby/object:Gem::Version
|
@@ -339,33 +314,26 @@ files:
|
|
339
314
|
homepage: http://hackers.lookout.com/testlab/
|
340
315
|
licenses:
|
341
316
|
- Apache 2.0
|
317
|
+
metadata: {}
|
342
318
|
post_install_message:
|
343
319
|
rdoc_options: []
|
344
320
|
require_paths:
|
345
321
|
- lib
|
346
322
|
required_ruby_version: !ruby/object:Gem::Requirement
|
347
|
-
none: false
|
348
323
|
requirements:
|
349
324
|
- - ! '>='
|
350
325
|
- !ruby/object:Gem::Version
|
351
326
|
version: '0'
|
352
|
-
segments:
|
353
|
-
- 0
|
354
|
-
hash: -3524242101058471505
|
355
327
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
356
|
-
none: false
|
357
328
|
requirements:
|
358
329
|
- - ! '>='
|
359
330
|
- !ruby/object:Gem::Version
|
360
331
|
version: '0'
|
361
|
-
segments:
|
362
|
-
- 0
|
363
|
-
hash: -3524242101058471505
|
364
332
|
requirements: []
|
365
333
|
rubyforge_project:
|
366
|
-
rubygems_version: 1.
|
334
|
+
rubygems_version: 2.1.11
|
367
335
|
signing_key:
|
368
|
-
specification_version:
|
336
|
+
specification_version: 4
|
369
337
|
summary: A toolkit for building virtual computer labs
|
370
338
|
test_files:
|
371
339
|
- features/step_definitions/container_steps.rb
|