test-kitchen 0.6.0 → 0.7.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- data/config/Cheffile +0 -7
- data/lib/test-kitchen/cli/destroy.rb +0 -6
- data/lib/test-kitchen/cli.rb +15 -1
- data/lib/test-kitchen/dsl.rb +5 -1
- data/lib/test-kitchen/environment.rb +2 -0
- data/lib/test-kitchen/platform.rb +16 -0
- data/lib/test-kitchen/project/base.rb +1 -1
- data/lib/test-kitchen/runner/base.rb +2 -0
- data/lib/test-kitchen/runner/openstack/dsl.rb +39 -0
- data/lib/test-kitchen/runner/openstack/environment.rb +141 -0
- data/lib/test-kitchen/runner/openstack.rb +147 -0
- data/lib/test-kitchen/runner.rb +1 -0
- data/lib/test-kitchen/scaffold.rb +1 -1
- data/lib/test-kitchen/version.rb +1 -1
- metadata +28 -9
data/config/Cheffile
CHANGED
@@ -21,13 +21,6 @@ require 'test-kitchen'
|
|
21
21
|
site 'http://community.opscode.com/api/v1'
|
22
22
|
|
23
23
|
# base test-kitchen cookbooks
|
24
|
-
cookbook 'apt', '1.4.6'
|
25
|
-
cookbook 'yum', '0.8.0'
|
26
|
-
cookbook 'build-essential', '1.1.0'
|
27
|
-
cookbook 'git', '1.0.0'
|
28
|
-
cookbook 'rvm',
|
29
|
-
:git => 'https://github.com/fnichol/chef-rvm.git',
|
30
|
-
:ref => 'c27a8942ed311ccce2c63c2e863201b049c70a0d'
|
31
24
|
cookbook 'test-kitchen',
|
32
25
|
:path => TestKitchen.source_root.join('cookbooks', 'test-kitchen').to_s
|
33
26
|
|
@@ -27,12 +27,6 @@ module TestKitchen
|
|
27
27
|
banner "kitchen destroy (options)"
|
28
28
|
|
29
29
|
def run
|
30
|
-
options = {
|
31
|
-
:platform => config[:platform],
|
32
|
-
:configuration => config[:configuration]
|
33
|
-
}
|
34
|
-
|
35
|
-
runner = TestKitchen::Runner.targets['vagrant'].new(env, options)
|
36
30
|
runner.destroy
|
37
31
|
end
|
38
32
|
|
data/lib/test-kitchen/cli.rb
CHANGED
@@ -54,6 +54,14 @@ module TestKitchen
|
|
54
54
|
:show_options => true,
|
55
55
|
:exit => 0
|
56
56
|
|
57
|
+
option :version,
|
58
|
+
:short => "-v",
|
59
|
+
:long => "--version",
|
60
|
+
:description => "Show Test Kitchen version",
|
61
|
+
:boolean => true,
|
62
|
+
:proc => lambda {|v| puts "test-kitchen: #{::TestKitchen::VERSION}"},
|
63
|
+
:exit => 0
|
64
|
+
|
57
65
|
attr_accessor :runner
|
58
66
|
attr_accessor :env
|
59
67
|
attr_accessor :ui
|
@@ -91,7 +99,7 @@ module TestKitchen
|
|
91
99
|
def runner
|
92
100
|
@runner ||= begin
|
93
101
|
# CLI option takes precedence, then project
|
94
|
-
runner_name = config[:runner] || env.project.runner ||
|
102
|
+
runner_name = config[:runner] || env.project.runner || env.default_runner
|
95
103
|
runner_class = TestKitchen::Runner.targets[runner_name]
|
96
104
|
runner = runner_class.new(env, config)
|
97
105
|
end
|
@@ -257,6 +265,12 @@ module TestKitchen
|
|
257
265
|
|
258
266
|
def print_help_and_exit(exitcode=1, fatal_message=nil)
|
259
267
|
$stderr.puts(fatal_message) if fatal_message
|
268
|
+
|
269
|
+
begin
|
270
|
+
self.parse_options
|
271
|
+
rescue OptionParser::InvalidOption => e
|
272
|
+
puts "#{e}\n"
|
273
|
+
end
|
260
274
|
puts self.opt_parser
|
261
275
|
puts
|
262
276
|
TestKitchen::CLI::Kitchen.list_commands
|
data/lib/test-kitchen/dsl.rb
CHANGED
@@ -15,10 +15,10 @@
|
|
15
15
|
# See the License for the specific language governing permissions and
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
|
-
|
19
18
|
require 'hashr'
|
20
19
|
require 'test-kitchen/project'
|
21
20
|
require 'test-kitchen/platform'
|
21
|
+
require 'test-kitchen/runner/openstack/dsl'
|
22
22
|
|
23
23
|
module TestKitchen
|
24
24
|
module DSL
|
@@ -31,6 +31,10 @@ module TestKitchen
|
|
31
31
|
def platform(name, &block)
|
32
32
|
env.platforms[name.to_s] = Platform.new(name, &block)
|
33
33
|
end
|
34
|
+
|
35
|
+
def default_runner(name)
|
36
|
+
env.default_runner = name
|
37
|
+
end
|
34
38
|
end
|
35
39
|
module CookbookDSL
|
36
40
|
def cookbook(name, &block)
|
@@ -32,6 +32,7 @@ module TestKitchen
|
|
32
32
|
attr_reader :ui
|
33
33
|
attr_reader :kitchenfile_name
|
34
34
|
attr_accessor :project
|
35
|
+
attr_accessor :default_runner
|
35
36
|
|
36
37
|
KITCHEN_SUBDIRS = [".", "kitchen", "test/kitchen"]
|
37
38
|
|
@@ -47,6 +48,7 @@ module TestKitchen
|
|
47
48
|
@project = Project::Cookbook.new(File.basename(Dir.pwd))
|
48
49
|
end
|
49
50
|
|
51
|
+
@default_runner = "vagrant"
|
50
52
|
@tmp_path = root_path.join('.kitchen')
|
51
53
|
@cache_path = tmp_path.join('.cache')
|
52
54
|
@ui = options[:ui]
|
@@ -41,6 +41,8 @@ module TestKitchen
|
|
41
41
|
include Chef::Mixin::ParamsValidate
|
42
42
|
|
43
43
|
attr_reader :name
|
44
|
+
|
45
|
+
# Virtual Box Specific Attributes
|
44
46
|
attr_writer :box, :box_url
|
45
47
|
|
46
48
|
def initialize(name, &block)
|
@@ -49,6 +51,20 @@ module TestKitchen
|
|
49
51
|
instance_eval(&block) if block_given?
|
50
52
|
end
|
51
53
|
|
54
|
+
OPENSTACK_OPTIONS = {
|
55
|
+
:image_id => nil, :flavor_id => nil, :install_chef => false,
|
56
|
+
:install_chef_cmd => "curl -L http://www.opscode.com/chef/install.sh | sudo bash",
|
57
|
+
:keyname => nil, :instance_name => nil, :ssh_user => "root", :ssh_key => nil}
|
58
|
+
|
59
|
+
OPENSTACK_OPTIONS.each do |option, default|
|
60
|
+
attr_writer option
|
61
|
+
define_method(option) do |*args|
|
62
|
+
arg = args.first
|
63
|
+
set_or_return(option, arg, default.nil? ? {} : {:default => default})
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
|
52
68
|
def box(arg=nil)
|
53
69
|
set_or_return(:box, arg, {})
|
54
70
|
end
|
@@ -143,6 +143,8 @@ module TestKitchen
|
|
143
143
|
desired_platform = env.all_platforms[options[:platform]]
|
144
144
|
if desired_platform.box_url
|
145
145
|
TestKitchen::Runner.targets['vagrant'].new(env, options)
|
146
|
+
elsif desired_platform.image_id
|
147
|
+
TestKitchen::Runner.targets['openstack'].new(env, options)
|
146
148
|
else
|
147
149
|
raise ArgumentError,
|
148
150
|
"No runner available for platform: #{desired_platform.name}"
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'test-kitchen/runner/openstack/environment'
|
2
|
+
|
3
|
+
module TestKitchen
|
4
|
+
class Openstack
|
5
|
+
include Chef::Mixin::ParamsValidate
|
6
|
+
|
7
|
+
attr_writer :username, :password, :tenant, :auth_url
|
8
|
+
|
9
|
+
def initialize(&block)
|
10
|
+
instance_eval(&block) if block_given?
|
11
|
+
end
|
12
|
+
|
13
|
+
def username(arg=nil)
|
14
|
+
set_or_return(:username, arg, {})
|
15
|
+
end
|
16
|
+
|
17
|
+
def password(arg=nil)
|
18
|
+
set_or_return(:password, arg, {})
|
19
|
+
end
|
20
|
+
|
21
|
+
def tenant(arg=nil)
|
22
|
+
set_or_return(:tenant, arg, {})
|
23
|
+
end
|
24
|
+
|
25
|
+
def auth_url(arg=nil)
|
26
|
+
set_or_return(:auth_url, arg, {})
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
module TestKitchen
|
32
|
+
module DSL
|
33
|
+
module BasicDSL
|
34
|
+
def openstack(&block)
|
35
|
+
TestKitchen::Environment::Openstack.config = TestKitchen::Openstack.new(&block)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'test-kitchen/environment'
|
2
|
+
require 'json'
|
3
|
+
require 'fog'
|
4
|
+
|
5
|
+
module TestKitchen
|
6
|
+
class Environment
|
7
|
+
class Openstack < TestKitchen::Environment
|
8
|
+
attr_reader :username, :password, :tenant, :auth_url
|
9
|
+
attr_reader :servers
|
10
|
+
|
11
|
+
def initialize(conf={})
|
12
|
+
super
|
13
|
+
@username = conf[:username] || config.username
|
14
|
+
@password = conf[:password] || config.password
|
15
|
+
@tenant = conf[:tenant] || config.tenant
|
16
|
+
@auth_url = conf[:auth_url] || config.auth_url
|
17
|
+
@servers = {}
|
18
|
+
load
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_server(platform_name, server_def)
|
22
|
+
@servers[platform_name] ||=
|
23
|
+
begin
|
24
|
+
server = connection.servers.create({ :name => server_def[:instance_name],
|
25
|
+
:image_ref => server_def[:image_id],
|
26
|
+
:flavor_ref => server_def[:flavor_id],
|
27
|
+
:key_name => server_def[:keyname]})
|
28
|
+
server.wait_for { ready? }
|
29
|
+
sleep(2) until tcp_test_ssh(server.public_ip_address['addr'])
|
30
|
+
save
|
31
|
+
server
|
32
|
+
end
|
33
|
+
|
34
|
+
# These won't persist on the fog objectso we have to set them every
|
35
|
+
# time. :(
|
36
|
+
@servers[platform_name].username = server_def[:ssh_user]
|
37
|
+
if server_def[:ssh_key]
|
38
|
+
@servers[platform_name].private_key_path = File.expand_path(server_def[:ssh_key])
|
39
|
+
end
|
40
|
+
@servers[platform_name]
|
41
|
+
end
|
42
|
+
|
43
|
+
def tcp_test_ssh(hostname)
|
44
|
+
tcp_socket = TCPSocket.new(hostname, '22')
|
45
|
+
IO.select([tcp_socket], nil, nil, 5)
|
46
|
+
rescue SocketError, Errno::ETIMEDOUT, Errno::EPERM,
|
47
|
+
Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ENETUNREACH
|
48
|
+
false
|
49
|
+
ensure
|
50
|
+
tcp_socket && tcp_socket.close
|
51
|
+
end
|
52
|
+
|
53
|
+
def connection
|
54
|
+
@connection ||= Fog::Compute.new(:provider => 'OpenStack',
|
55
|
+
:openstack_username => username,
|
56
|
+
:openstack_api_key => password,
|
57
|
+
:openstack_auth_url => auth_url,
|
58
|
+
:openstack_tenant => tenant)
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
# The following functions all take a name of
|
63
|
+
# of a VM in our enironment
|
64
|
+
|
65
|
+
def status(name)
|
66
|
+
if @servers.has_key?(name)
|
67
|
+
@servers[name].state.to_s.downcase
|
68
|
+
else
|
69
|
+
"not created"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def destroy(name)
|
74
|
+
@servers[name].destroy if @servers.has_key?(name)
|
75
|
+
@servers.delete(name)
|
76
|
+
save
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
# Ideally we could use the #ssh and #scp functions on Fog's server '
|
81
|
+
# object. But these seem to be broken in the case of Openstack
|
82
|
+
|
83
|
+
def ssh_options(name)
|
84
|
+
if key = @servers[name].private_key_path
|
85
|
+
{:keys => [key]}
|
86
|
+
else
|
87
|
+
{}
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def ssh(name)
|
92
|
+
server = @servers[name]
|
93
|
+
Fog::SSH.new(server.public_ip_address['addr'], server.username, ssh_options(name))
|
94
|
+
end
|
95
|
+
|
96
|
+
def scp(name)
|
97
|
+
server = @servers[name]
|
98
|
+
Fog::SCP.new(server.public_ip_address['addr'], server.username, ssh_options(name))
|
99
|
+
end
|
100
|
+
|
101
|
+
# GROSS: Global config as a class variable
|
102
|
+
def config
|
103
|
+
@@config
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.config
|
107
|
+
@@config
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.config=(config)
|
111
|
+
@@config = config
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
# Store state in .openstack_state file,
|
117
|
+
# allowing us to re-use already created VMs
|
118
|
+
|
119
|
+
def state_file
|
120
|
+
File.join(root_path, ".openstack_state")
|
121
|
+
end
|
122
|
+
|
123
|
+
def load
|
124
|
+
if File.exists?(state_file)
|
125
|
+
state = JSON.parse(File.read(state_file))
|
126
|
+
state.each do |platform, id|
|
127
|
+
@servers[platform] = connection.servers.get(id)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def save
|
133
|
+
state = {}
|
134
|
+
@servers.each {|k,s| state[k] = s.id}
|
135
|
+
File.open(state_file, 'w') do |f|
|
136
|
+
f.write(state.to_json)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Steven Danna (<steve@opscode.com>)
|
3
|
+
# Copyright:: Copyright (c) 2012 Opscode, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'fog'
|
20
|
+
require 'test-kitchen/runner/openstack/environment'
|
21
|
+
|
22
|
+
module TestKitchen
|
23
|
+
module Runner
|
24
|
+
class Openstack < Base
|
25
|
+
|
26
|
+
|
27
|
+
# @vm: The TestKitchen::Platform::Version object
|
28
|
+
#
|
29
|
+
# @platform: From the parent constructor, contains the full name
|
30
|
+
# of the relevant platform if we were created by #for_platform
|
31
|
+
|
32
|
+
attr_accessor :vm
|
33
|
+
|
34
|
+
def initialize(env, options={})
|
35
|
+
super
|
36
|
+
|
37
|
+
if @platform
|
38
|
+
@vm = env.all_platforms[@platform]
|
39
|
+
end
|
40
|
+
|
41
|
+
@os_env = TestKitchen::Environment::Openstack.new()
|
42
|
+
end
|
43
|
+
|
44
|
+
def create
|
45
|
+
env.ui.msg "[#{platform}] Provisioning guest on Openstack", :green
|
46
|
+
@os_env.create_server(@platform,
|
47
|
+
{ :instance_name => (vm.instance_name || "cookbook-tester-#{platform}"),
|
48
|
+
:image_id => vm.image_id,
|
49
|
+
:flavor_id => vm.flavor_id,
|
50
|
+
:keyname => vm.keyname,
|
51
|
+
:ssh_key => vm.ssh_key,
|
52
|
+
:ssh_user => vm.ssh_user})
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
def converge
|
57
|
+
install_chef if vm.install_chef
|
58
|
+
move_repo
|
59
|
+
move_cookbooks
|
60
|
+
run_chef_solo
|
61
|
+
end
|
62
|
+
|
63
|
+
# status and destroy are expected to operate on all
|
64
|
+
# vm's in an environment
|
65
|
+
def status
|
66
|
+
env.all_platforms.each do |name, ver|
|
67
|
+
env.ui.msg "#{name}\t#{@os_env.status(name)}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def destroy
|
72
|
+
env.all_platforms.each do |name, platform|
|
73
|
+
env.ui.msg "[#{name}] Terminating openstack server", :yellow
|
74
|
+
@os_env.destroy name
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def execute_remote_command(platform_name, command, message=nil)
|
79
|
+
env.ui.msg("[#{platform_name}] #{message}", :green) if message
|
80
|
+
results = @os_env.ssh(platform_name).run(command) do |data|
|
81
|
+
stdout, stderr = data.map {|s| s.rstrip}
|
82
|
+
stdout.lines.each do |line|
|
83
|
+
env.ui.msg "[#{platform_name}] #{line}", :green
|
84
|
+
end
|
85
|
+
stderr.lines.each do |line|
|
86
|
+
env.ui.msg "[#{platform_name}] #{line}", :red
|
87
|
+
end
|
88
|
+
end
|
89
|
+
if results.first.status != 0
|
90
|
+
msg = message || "Remote command"
|
91
|
+
env.ui.msg "[#{platform_name}] #{msg} failed!", :red
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
def install_chef(name=platform)
|
98
|
+
execute_remote_command(name, vm.install_chef_cmd, "Installing Chef")
|
99
|
+
end
|
100
|
+
|
101
|
+
def run_chef_solo(name=platform)
|
102
|
+
execute_remote_command(name, "echo '#{json_for_node}' > node.json",
|
103
|
+
"Creating node configuration JSON")
|
104
|
+
execute_remote_command(name, "echo 'cookbook_path [ \"#{remote_cookbook_dir}\" ]' > solo.rb",
|
105
|
+
"Creating chef-solo configuration")
|
106
|
+
execute_remote_command(name, "sudo chef-solo -j node.json -c solo.rb",
|
107
|
+
"Running chef-solo on host")
|
108
|
+
end
|
109
|
+
|
110
|
+
def move_cookbooks(name=platform)
|
111
|
+
env.ui.msg("[#{name}] Moving cookbooks via SCP", :green)
|
112
|
+
@os_env.scp(name).upload(File.join(env.tmp_path, "cookbooks"),
|
113
|
+
remote_cookbook_dir, :recursive => true)
|
114
|
+
end
|
115
|
+
|
116
|
+
def move_repo(name=platform)
|
117
|
+
env.ui.msg("[#{name}] Moving repo via SCP", :green)
|
118
|
+
execute_remote_command(name, "sudo mkdir -p #{remote_root_dir}")
|
119
|
+
execute_remote_command(name, "sudo chown #{vm.ssh_user} #{remote_root_dir}")
|
120
|
+
@os_env.scp(name).upload(File.join(env.tmp_path, "cookbook_under_test"),
|
121
|
+
configuration.guest_source_root,
|
122
|
+
{:recursive => true})
|
123
|
+
end
|
124
|
+
|
125
|
+
def json_for_node
|
126
|
+
{
|
127
|
+
'test-kitchen' => {
|
128
|
+
'project' => configuration.to_hash.merge('source_root' => configuration.guest_source_root,
|
129
|
+
'test_root' => configuration.guest_test_root)},
|
130
|
+
'run_list' => run_list
|
131
|
+
}.to_json
|
132
|
+
end
|
133
|
+
|
134
|
+
def run_list
|
135
|
+
configuration.run_list + [test_recipe_name]
|
136
|
+
end
|
137
|
+
|
138
|
+
def remote_root_dir
|
139
|
+
File.dirname(configuration.guest_source_root)
|
140
|
+
end
|
141
|
+
|
142
|
+
def remote_cookbook_dir
|
143
|
+
File.join(remote_root_dir, 'cookbooks')
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
data/lib/test-kitchen/runner.rb
CHANGED
data/lib/test-kitchen/version.rb
CHANGED
metadata
CHANGED
@@ -1,32 +1,48 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: test-kitchen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.7.0.beta.1
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Seth Chisamore
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-11-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: fog
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
14
30
|
- !ruby/object:Gem::Dependency
|
15
31
|
name: foodcritic
|
16
32
|
requirement: !ruby/object:Gem::Requirement
|
17
33
|
none: false
|
18
34
|
requirements:
|
19
|
-
- -
|
35
|
+
- - ! '>='
|
20
36
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
37
|
+
version: 1.4.0
|
22
38
|
type: :runtime
|
23
39
|
prerelease: false
|
24
40
|
version_requirements: !ruby/object:Gem::Requirement
|
25
41
|
none: false
|
26
42
|
requirements:
|
27
|
-
- -
|
43
|
+
- - ! '>='
|
28
44
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
45
|
+
version: 1.4.0
|
30
46
|
- !ruby/object:Gem::Dependency
|
31
47
|
name: hashr
|
32
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -161,6 +177,9 @@ files:
|
|
161
177
|
- lib/test-kitchen/project/supported_platforms.rb
|
162
178
|
- lib/test-kitchen/project.rb
|
163
179
|
- lib/test-kitchen/runner/base.rb
|
180
|
+
- lib/test-kitchen/runner/openstack/dsl.rb
|
181
|
+
- lib/test-kitchen/runner/openstack/environment.rb
|
182
|
+
- lib/test-kitchen/runner/openstack.rb
|
164
183
|
- lib/test-kitchen/runner/vagrant.rb
|
165
184
|
- lib/test-kitchen/runner.rb
|
166
185
|
- lib/test-kitchen/scaffold.rb
|
@@ -183,9 +202,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
183
202
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
184
203
|
none: false
|
185
204
|
requirements:
|
186
|
-
- - ! '
|
205
|
+
- - ! '>'
|
187
206
|
- !ruby/object:Gem::Version
|
188
|
-
version:
|
207
|
+
version: 1.3.1
|
189
208
|
requirements: []
|
190
209
|
rubyforge_project:
|
191
210
|
rubygems_version: 1.8.23
|