test-kitchen 1.0.0.alpha.7 → 1.0.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.travis.yml +3 -0
- data/CHANGELOG.md +70 -2
- data/README.md +2 -2
- data/Rakefile +14 -11
- data/lib/kitchen.rb +7 -2
- data/lib/kitchen/busser.rb +19 -7
- data/lib/kitchen/cli.rb +29 -7
- data/lib/kitchen/color.rb +5 -5
- data/lib/kitchen/config.rb +49 -10
- data/lib/kitchen/driver.rb +4 -0
- data/lib/kitchen/driver/base.rb +42 -25
- data/lib/kitchen/driver/ssh_base.rb +45 -139
- data/lib/kitchen/errors.rb +3 -0
- data/lib/kitchen/generator/init.rb +41 -31
- data/lib/kitchen/instance.rb +34 -20
- data/lib/kitchen/login_command.rb +34 -0
- data/lib/kitchen/platform.rb +22 -12
- data/lib/kitchen/provisioner.rb +50 -0
- data/lib/kitchen/provisioner/base.rb +63 -0
- data/lib/kitchen/provisioner/chef_base.rb +290 -0
- data/lib/kitchen/provisioner/chef_solo.rb +69 -0
- data/lib/kitchen/provisioner/chef_zero.rb +92 -0
- data/lib/kitchen/ssh.rb +160 -0
- data/lib/kitchen/suite.rb +53 -33
- data/lib/kitchen/version.rb +1 -1
- data/spec/kitchen/config_spec.rb +40 -8
- data/spec/kitchen/driver/base_spec.rb +123 -0
- data/spec/kitchen/instance_spec.rb +61 -54
- data/spec/kitchen/platform_spec.rb +20 -13
- data/spec/kitchen/suite_spec.rb +34 -28
- data/support/chef-client-zero.rb +59 -0
- data/templates/init/kitchen.yml.erb +4 -4
- data/test-kitchen.gemspec +1 -1
- metadata +55 -90
- data/lib/kitchen/chef_data_uploader.rb +0 -177
@@ -1,177 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
#
|
3
|
-
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
4
|
-
#
|
5
|
-
# Copyright (C) 2012, Fletcher Nichol
|
6
|
-
#
|
7
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
-
# you may not use this file except in compliance with the License.
|
9
|
-
# You may obtain a copy of the License at
|
10
|
-
#
|
11
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
-
#
|
13
|
-
# Unless required by applicable law or agreed to in writing, software
|
14
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
-
# See the License for the specific language governing permissions and
|
17
|
-
# limitations under the License.
|
18
|
-
|
19
|
-
require 'fileutils'
|
20
|
-
require 'json'
|
21
|
-
require 'net/scp'
|
22
|
-
require 'stringio'
|
23
|
-
|
24
|
-
module Kitchen
|
25
|
-
|
26
|
-
# Uploads Chef asset files such as dna.json, data bags, and cookbooks to an
|
27
|
-
# instance over SSH.
|
28
|
-
#
|
29
|
-
# @author Fletcher Nichol <fnichol@nichol.ca>
|
30
|
-
class ChefDataUploader
|
31
|
-
|
32
|
-
include ShellOut
|
33
|
-
include Logging
|
34
|
-
|
35
|
-
def initialize(instance, ssh_args, kitchen_root, chef_home)
|
36
|
-
@instance = instance
|
37
|
-
@ssh_args = ssh_args
|
38
|
-
@kitchen_root = kitchen_root
|
39
|
-
@chef_home = chef_home
|
40
|
-
end
|
41
|
-
|
42
|
-
def upload
|
43
|
-
Net::SCP.start(*ssh_args) do |scp|
|
44
|
-
upload_json scp
|
45
|
-
upload_solo_rb scp
|
46
|
-
upload_cookbooks scp
|
47
|
-
upload_data_bags scp if instance.suite.data_bags_path
|
48
|
-
upload_roles scp if instance.suite.roles_path
|
49
|
-
upload_secret scp if instance.suite.encrypted_data_bag_secret_key_path
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
private
|
54
|
-
|
55
|
-
attr_reader :instance, :ssh_args, :kitchen_root, :chef_home
|
56
|
-
|
57
|
-
def logger
|
58
|
-
instance.logger
|
59
|
-
end
|
60
|
-
|
61
|
-
def upload_json(scp)
|
62
|
-
json_file = StringIO.new(instance.dna.to_json)
|
63
|
-
scp.upload!(json_file, "#{chef_home}/dna.json")
|
64
|
-
end
|
65
|
-
|
66
|
-
def upload_solo_rb(scp)
|
67
|
-
solo_rb_file = StringIO.new(solo_rb_contents)
|
68
|
-
scp.upload!(solo_rb_file, "#{chef_home}/solo.rb")
|
69
|
-
end
|
70
|
-
|
71
|
-
def upload_cookbooks(scp)
|
72
|
-
cookbooks_dir = local_cookbooks
|
73
|
-
upload_path(scp, cookbooks_dir, "cookbooks")
|
74
|
-
ensure
|
75
|
-
FileUtils.rmtree(cookbooks_dir) unless cookbooks_dir.nil?
|
76
|
-
end
|
77
|
-
|
78
|
-
def upload_data_bags(scp)
|
79
|
-
upload_path(scp, instance.suite.data_bags_path)
|
80
|
-
end
|
81
|
-
|
82
|
-
def upload_roles(scp)
|
83
|
-
upload_path(scp, instance.suite.roles_path)
|
84
|
-
end
|
85
|
-
|
86
|
-
def upload_secret(scp)
|
87
|
-
scp.upload!(instance.suite.encrypted_data_bag_secret_key_path,
|
88
|
-
"#{chef_home}/encrypted_data_bag_secret")
|
89
|
-
end
|
90
|
-
|
91
|
-
def upload_path(scp, path, dir = File.basename(path))
|
92
|
-
dest = "#{chef_home}/#{dir}"
|
93
|
-
|
94
|
-
scp.upload!(path, dest, :recursive => true) do |ch, name, sent, total|
|
95
|
-
if sent == total
|
96
|
-
info("Uploaded #{name.sub(%r{^#{path}/}, '')} (#{total} bytes)")
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
def solo_rb_contents
|
102
|
-
solo = []
|
103
|
-
solo << %{node_name "#{instance.name}"}
|
104
|
-
solo << %{file_cache_path "#{chef_home}/cache"}
|
105
|
-
solo << %{cookbook_path "#{chef_home}/cookbooks"}
|
106
|
-
solo << %{role_path "#{chef_home}/roles"}
|
107
|
-
if instance.suite.data_bags_path
|
108
|
-
solo << %{data_bag_path "#{chef_home}/data_bags"}
|
109
|
-
end
|
110
|
-
if instance.suite.encrypted_data_bag_secret_key_path
|
111
|
-
secret = "#{chef_home}/encrypted_data_bag_secret"
|
112
|
-
solo << %{encrypted_data_bag_secret "#{secret}"}
|
113
|
-
end
|
114
|
-
solo.join("\n")
|
115
|
-
end
|
116
|
-
|
117
|
-
def local_cookbooks
|
118
|
-
tmpdir = Dir.mktmpdir("#{instance.name}-cookbooks")
|
119
|
-
prepare_tmpdir(tmpdir)
|
120
|
-
tmpdir
|
121
|
-
end
|
122
|
-
|
123
|
-
def prepare_tmpdir(tmpdir)
|
124
|
-
if File.exists?(File.join(kitchen_root, "Berksfile"))
|
125
|
-
run_resolver("Berkshelf", "berks", tmpdir)
|
126
|
-
elsif File.exists?(File.join(kitchen_root, "Cheffile"))
|
127
|
-
run_resolver("Librarian", "librarian-chef", tmpdir)
|
128
|
-
elsif File.directory?(File.join(kitchen_root, "cookbooks"))
|
129
|
-
cp_cookbooks(tmpdir)
|
130
|
-
elsif File.exists?(File.join(kitchen_root, "metadata.rb"))
|
131
|
-
cp_this_cookbook(tmpdir)
|
132
|
-
else
|
133
|
-
FileUtils.rmtree(tmpdir)
|
134
|
-
fatal("Berksfile, Cheffile, cookbooks/, or metadata.rb" +
|
135
|
-
" must exist in #{kitchen_root}")
|
136
|
-
raise UserError, "Cookbooks could not be found"
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
def run_resolver(name, bin, tmpdir)
|
141
|
-
# Just going to have to take your chances on Windows - no way to
|
142
|
-
# check for a command without running it, and looking for an
|
143
|
-
# exit code. Good times.
|
144
|
-
if RUBY_PLATFORM !~ /mswin|mingw/
|
145
|
-
begin
|
146
|
-
run_command "if ! command -v #{bin} >/dev/null; then exit 1; fi"
|
147
|
-
rescue Kitchen::ShellOut::ShellCommandFailed
|
148
|
-
fatal("#{name} must be installed, add it to your Gemfile.")
|
149
|
-
raise UserError, "#{bin} command not found"
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
Kitchen.mutex.synchronize do
|
154
|
-
run_command "#{bin} install --path #{tmpdir}"
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
def cp_cookbooks(tmpdir)
|
159
|
-
FileUtils.cp_r(File.join(kitchen_root, "cookbooks", "."), tmpdir)
|
160
|
-
cp_this_cookbook(tmpdir) if File.exists?(File.expand_path('metadata.rb'))
|
161
|
-
end
|
162
|
-
|
163
|
-
def cp_this_cookbook(tmpdir)
|
164
|
-
metadata_rb = File.join(kitchen_root, "metadata.rb")
|
165
|
-
cb_name = MetadataChopper.extract(metadata_rb).first or raise(UserError,
|
166
|
-
"The metadata.rb does not define the 'name' key." +
|
167
|
-
" Please add: `name '<cookbook_name>'` to metadata.rb and try again")
|
168
|
-
|
169
|
-
cb_path = File.join(tmpdir, cb_name)
|
170
|
-
glob = Dir.glob("#{kitchen_root}/{metadata.rb,README.*," +
|
171
|
-
"attributes,files,libraries,providers,recipes,resources,templates}")
|
172
|
-
|
173
|
-
FileUtils.mkdir_p(cb_path)
|
174
|
-
FileUtils.cp_r(glob, cb_path)
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|