knife-solo 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.coveralls.yml +2 -0
- data/CHANGELOG.md +51 -1
- data/README.rdoc +21 -1
- data/Rakefile +5 -1
- data/lib/chef/knife/solo_cook.rb +44 -16
- data/lib/chef/knife/solo_init.rb +1 -1
- data/lib/knife-solo/berkshelf.rb +10 -1
- data/lib/knife-solo/bootstraps/linux.rb +3 -1
- data/lib/knife-solo/info.rb +1 -1
- data/lib/knife-solo/node_config_command.rb +13 -1
- data/lib/knife-solo/resources/knife.rb +5 -4
- data/lib/knife-solo/resources/solo.rb.erb +2 -0
- data/lib/knife-solo/ssh_command.rb +22 -57
- data/lib/knife-solo/ssh_connection.rb +78 -0
- data/lib/knife-solo/tools.rb +2 -2
- data/test/integration/cases/environment.rb +25 -0
- data/test/integration/debian7_knife_bootstrap_test.rb +1 -1
- data/test/integration/ubuntu12_04_test.rb +1 -0
- data/test/performance/ssh_performance_test.rb +38 -0
- data/test/solo_cook_test.rb +26 -12
- data/test/ssh_command_test.rb +18 -2
- data/test/support/environment_cookbook/attributes/default.rb +1 -0
- data/test/support/environment_cookbook/metadata.rb +6 -0
- data/test/support/environment_cookbook/recipes/default.rb +4 -0
- data/test/support/test_environment.json +11 -0
- data/test/test_helper.rb +3 -0
- metadata +46 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e6a9075b35d746ef773b48fab2a4058b9b10b007
|
4
|
+
data.tar.gz: 2a4a78e808b7052a9775fb8da0018abfdb07bd33
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a2020e3b7d7971c882e29a4fe1391f96231d10de8643e5a045d612b45181df2f2e95e78728af0ee10be4c5513f2a2df127e5c928620a6988077d8e1e7bb6cacd
|
7
|
+
data.tar.gz: b6c1d721762e00bcfbc5cc25626094184c91d5feae3c882947cbf2772a62bd952c47eb5675af38ab07c4f7952cbd8f1012035ddca2b11b9e546e62435ceda8ce
|
data/.coveralls.yml
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,49 @@
|
|
1
|
+
# 0.4.0 / 2013-10-30
|
2
|
+
|
3
|
+
## Changes and new features
|
4
|
+
|
5
|
+
* Add SSH option --[no-]host-key-verify ([274])
|
6
|
+
* Add --no-sync option to skip syncing and only run Chef ([284])
|
7
|
+
* Use Omnibus installer for Debian 7 ([287])
|
8
|
+
* Support Raspbian ([295])
|
9
|
+
* Support environments (from Chef 11.6.0 on) ([285])
|
10
|
+
|
11
|
+
## Fixes
|
12
|
+
|
13
|
+
* Cache SSH connections ([265])
|
14
|
+
* Support Berkshelf 3.0 ([268])
|
15
|
+
* Follow symlinks when uploading kitchen ([279], [289])
|
16
|
+
* Quote rsync paths to avoid problems with spaces in directory names ([281], [286])
|
17
|
+
* Fix precedence of automatic cookbook_path components ([296], [298])
|
18
|
+
* Print an error message if a `*_path` configuration value is not a String ([278], [300])
|
19
|
+
* Mention knife-solo_data_bag gem in the docs ([83])
|
20
|
+
* Pin to ffi 1.9.1 due to issues with newer versions
|
21
|
+
* Docs around berkshelf and librarian-chef integrations
|
22
|
+
|
23
|
+
## Thanks to our contributors!
|
24
|
+
|
25
|
+
* [Andreas Josephson][teyrow]
|
26
|
+
* [Markus Kern][makern]
|
27
|
+
* [Michael Glass][michaelglass]
|
28
|
+
* [Mathieu Allaire][allaire]
|
29
|
+
|
30
|
+
[83]: https://github.com/matschaffer/knife-solo/issues/83
|
31
|
+
[265]: https://github.com/matschaffer/knife-solo/issues/265
|
32
|
+
[268]: https://github.com/matschaffer/knife-solo/issues/268
|
33
|
+
[274]: https://github.com/matschaffer/knife-solo/issues/274
|
34
|
+
[278]: https://github.com/matschaffer/knife-solo/issues/278
|
35
|
+
[279]: https://github.com/matschaffer/knife-solo/issues/279
|
36
|
+
[281]: https://github.com/matschaffer/knife-solo/issues/281
|
37
|
+
[284]: https://github.com/matschaffer/knife-solo/issues/284
|
38
|
+
[285]: https://github.com/matschaffer/knife-solo/issues/285
|
39
|
+
[286]: https://github.com/matschaffer/knife-solo/issues/286
|
40
|
+
[287]: https://github.com/matschaffer/knife-solo/issues/287
|
41
|
+
[289]: https://github.com/matschaffer/knife-solo/issues/289
|
42
|
+
[295]: https://github.com/matschaffer/knife-solo/issues/295
|
43
|
+
[296]: https://github.com/matschaffer/knife-solo/issues/296
|
44
|
+
[298]: https://github.com/matschaffer/knife-solo/issues/298
|
45
|
+
[300]: https://github.com/matschaffer/knife-solo/issues/300
|
46
|
+
|
1
47
|
# 0.3.0 / 2013-08-01
|
2
48
|
|
3
49
|
**NOTE**: This release includes breaking changes. See [upgrade instructions](https://github.com/matschaffer/knife-solo/wiki/Upgrading-to-0.3.0) for more information.
|
@@ -358,6 +404,8 @@ And a special thanks to [Teemu Matilainen][tmatilai] who is now on the list of d
|
|
358
404
|
[jgarber]: https://github.com/jgarber
|
359
405
|
[jgrevich]: https://github.com/jgrevich
|
360
406
|
[kmdsbng]: https://github.com/kmdsbng
|
407
|
+
[makern]: https://github.com/makern
|
408
|
+
[michaelglass]: https://github.com/michaelglass
|
361
409
|
[naoya]: https://github.com/naoya
|
362
410
|
[natlownes]: https://github.com/natlownes
|
363
411
|
[patatepartie]: https://github.com/patatepartie
|
@@ -373,8 +421,10 @@ And a special thanks to [Teemu Matilainen][tmatilai] who is now on the list of d
|
|
373
421
|
[searlm]: https://github.com/searlm
|
374
422
|
[skyeagle]: https://github.com/skyeagle
|
375
423
|
[smdern]: https://github.com/smdern
|
424
|
+
[teyrow]: https://github.com/teyrow
|
376
425
|
[tknerr]: https://github.com/tknerr
|
377
426
|
[tmatilai]: https://github.com/tmatilai
|
378
|
-
[tocky]:
|
427
|
+
[tocky]: https://github.com/tocky
|
379
428
|
[vjpr]: https://github.com/vjpr
|
380
429
|
[zeph]: https://github.com/zeph
|
430
|
+
[allaire]: https://github.com/allaire
|
data/README.rdoc
CHANGED
@@ -26,6 +26,26 @@ If you need to install from git run:
|
|
26
26
|
|
27
27
|
bundle && bundle exec rake install
|
28
28
|
|
29
|
+
== Integration with Berkshelf & Librarian
|
30
|
+
|
31
|
+
knife-solo also integrates with {Berkshelf}[http://berkshelf.com/] and {Librarian-Chef}[https://github.com/applicationsonline/librarian-chef] for managing your cookbooks out of the box.
|
32
|
+
|
33
|
+
We try to do this somewhat automatically by first checking if you have either of the two gems installed. If you have both, we will default to Berkshelf.
|
34
|
+
|
35
|
+
During <tt>knife solo init</tt> we'll generate the appropriate configuration file for either gem. Then during <tt>knife solo cook</tt> we'll run the installation step for whichever configuration file is in your kitchen.
|
36
|
+
|
37
|
+
Both commands accept option flags to disable this feature if needed (<tt>--no-berkshelf</tt> or <tt>--no-librarian</tt>). The init command also offers enable flags to generate configuration files regardless of whether or not you have the supporting gem installed.
|
38
|
+
|
39
|
+
More detailed logic for this integration is available in the {Berkshelf & Librarian-Chef integration}[https://github.com/matschaffer/knife-solo/wiki/Berkshelf-&-Librarian-Chef-integration] wiki page.
|
40
|
+
|
41
|
+
=== A note about the "cookbooks" directory
|
42
|
+
|
43
|
+
One common "gotcha" is that you may have Berkshelf or Librarian-Chef installed without knowing it. This will generate a kitchen that is configured to use them which might not have been your intention. Once the configuration file is available, the <tt>cookbooks</tt> directory will be reserved for cookbooks that are resolved via one of those tools. Any cookbooks that you create there will be removed when you run <tt>knife solo cook</tt>.
|
44
|
+
|
45
|
+
Please use <tt>site-cookbooks</tt> for custom cookbooks or (better yet) give them their own git repositories which are then included using Berkshelf or Librarian-Chef.
|
46
|
+
|
47
|
+
== knife-solo commands
|
48
|
+
|
29
49
|
=== Init command
|
30
50
|
|
31
51
|
The init command simply takes a name of the directory to store the kitchen structure. Use "." to initialize the current directory.
|
@@ -74,7 +94,7 @@ This uploads all of your cookbooks in addition to a patch that allows you to use
|
|
74
94
|
|
75
95
|
This also supports encrypted data bags. To use them, set the path to your key with +encrypted_data_bag_secret+ in .chef/knife.rb.
|
76
96
|
|
77
|
-
The knife
|
97
|
+
The built-in knife commands for working with data bags don't work well without a Chef server so we recommend using the {knife-solo_data_bag}[https://github.com/thbishop/knife-solo_data_bag] gem. This will provide "solo" versions of all the typical data bag commands. The default kitchen structure generated by <tt>knife solo init</tt> should be compatible with all the operations listed in the documentation for that gem.
|
78
98
|
|
79
99
|
=== Bootstrap command
|
80
100
|
|
data/Rakefile
CHANGED
@@ -15,7 +15,6 @@ MANIFEST_IGNORES = %w[
|
|
15
15
|
script/test
|
16
16
|
]
|
17
17
|
|
18
|
-
|
19
18
|
namespace :manifest do
|
20
19
|
desc 'Checks for outstanding changes to the manifest'
|
21
20
|
task :verify => :update do
|
@@ -72,6 +71,11 @@ task 'gh-pages' do
|
|
72
71
|
end
|
73
72
|
|
74
73
|
namespace :test do
|
74
|
+
Rake::TestTask.new(:performance) do |t|
|
75
|
+
t.libs << "test"
|
76
|
+
t.test_files = FileList['test/performance/*_test.rb']
|
77
|
+
end
|
78
|
+
|
75
79
|
Rake::TestTask.new(:integration) do |t|
|
76
80
|
t.libs << "test"
|
77
81
|
t.test_files = FileList['test/integration/*_test.rb']
|
data/lib/chef/knife/solo_cook.rb
CHANGED
@@ -41,6 +41,10 @@ class Chef
|
|
41
41
|
:long => '--sync-only',
|
42
42
|
:description => 'Only sync the cookbook - do not run Chef'
|
43
43
|
|
44
|
+
option :sync,
|
45
|
+
:long => '--no-sync',
|
46
|
+
:description => 'Do not sync kitchen - only run Chef'
|
47
|
+
|
44
48
|
option :berkshelf,
|
45
49
|
:long => '--no-berkshelf',
|
46
50
|
:description => 'Skip berks install'
|
@@ -76,11 +80,14 @@ class Chef
|
|
76
80
|
ui.msg "Running Chef on #{host}..."
|
77
81
|
|
78
82
|
check_chef_version if config[:chef_check]
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
83
|
+
if config_value(:sync, true)
|
84
|
+
generate_node_config
|
85
|
+
berkshelf_install if config_value(:berkshelf, true)
|
86
|
+
librarian_install if config_value(:librarian, true)
|
87
|
+
patch_cookbooks_install
|
88
|
+
sync_kitchen
|
89
|
+
generate_solorb
|
90
|
+
end
|
84
91
|
cook unless config[:sync_only]
|
85
92
|
end
|
86
93
|
end
|
@@ -104,13 +111,14 @@ class Chef
|
|
104
111
|
run_portable_mkdir_p(provisioning_path, '0700')
|
105
112
|
|
106
113
|
cookbook_paths.each_with_index do |path, i|
|
107
|
-
upload_to_provision_path(path, "/cookbooks-#{i + 1}", 'cookbook_path')
|
114
|
+
upload_to_provision_path(path.to_s, "/cookbooks-#{i + 1}", 'cookbook_path')
|
108
115
|
end
|
109
|
-
upload_to_provision_path(node_config, 'dna.json')
|
116
|
+
upload_to_provision_path(node_config.to_s, 'dna.json')
|
110
117
|
upload_to_provision_path(nodes_path, 'nodes')
|
111
118
|
upload_to_provision_path(:role_path, 'roles')
|
112
119
|
upload_to_provision_path(:data_bag_path, 'data_bags')
|
113
120
|
upload_to_provision_path(:encrypted_data_bag_secret, 'data_bag_key')
|
121
|
+
upload_to_provision_path(:environment_path, 'environments')
|
114
122
|
end
|
115
123
|
|
116
124
|
def expand_path(path)
|
@@ -122,7 +130,7 @@ class Chef
|
|
122
130
|
end
|
123
131
|
|
124
132
|
def cookbook_paths
|
125
|
-
@cookbook_paths ||= expanded_config_paths(:cookbook_path)
|
133
|
+
@cookbook_paths ||= expanded_config_paths(:cookbook_path)
|
126
134
|
end
|
127
135
|
|
128
136
|
def proxy_setting_keys
|
@@ -219,6 +227,8 @@ class Chef
|
|
219
227
|
|
220
228
|
if src.nil?
|
221
229
|
Chef::Log.debug "'#{key_name}' not set"
|
230
|
+
elsif !src.is_a?(String)
|
231
|
+
ui.error "#{key_name} is not a String: #{src.inspect}"
|
222
232
|
elsif !File.exist?(src)
|
223
233
|
ui.warn "Local #{key_name} '#{src}' does not exist"
|
224
234
|
else
|
@@ -237,24 +247,36 @@ class Chef
|
|
237
247
|
end
|
238
248
|
|
239
249
|
def rsync(source_path, target_path, extra_opts = '--delete')
|
240
|
-
cmd =
|
241
|
-
cmd
|
242
|
-
cmd <<
|
243
|
-
|
244
|
-
|
250
|
+
cmd = ['rsync', '-rL', rsync_debug, rsync_permissions, %Q{--rsh=ssh #{ssh_args}}, extra_opts]
|
251
|
+
cmd += rsync_excludes.map { |ignore| "--exclude=#{ignore}" }
|
252
|
+
cmd << adjust_rsync_path_on_client(source_path)
|
253
|
+
cmd << %Q{:#{adjust_rsync_path_on_node(target_path)}}
|
254
|
+
cmd = cmd.flatten.compact
|
255
|
+
Chef::Log.debug cmd.inspect
|
256
|
+
system!(*cmd)
|
245
257
|
end
|
246
258
|
|
247
259
|
def check_chef_version
|
248
260
|
ui.msg "Checking Chef version..."
|
249
|
-
unless
|
261
|
+
unless chef_version_satisfies? CHEF_VERSION_CONSTRAINT
|
250
262
|
raise "Couldn't find Chef #{CHEF_VERSION_CONSTRAINT} on #{host}. Please run `knife solo prepare #{ssh_args}` to ensure Chef is installed and up to date."
|
251
263
|
end
|
264
|
+
if node_environment != '_default' && chef_version_satisfies?('<11.6.0')
|
265
|
+
ui.warn "Chef version #{chef_version} does not support environments. Environment '#{node_environment}' will be ignored."
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
def chef_version_satisfies?(requirement)
|
270
|
+
Gem::Requirement.new(requirement).satisfied_by? Gem::Version.new(chef_version)
|
252
271
|
end
|
253
272
|
|
254
273
|
# Parses "Chef: x.y.z" from the chef-solo version output
|
255
274
|
def chef_version
|
256
|
-
|
257
|
-
|
275
|
+
# Memoize the version to avoid multiple SSH calls
|
276
|
+
@chef_version ||= lambda do
|
277
|
+
cmd = %q{sudo chef-solo --version 2>/dev/null | awk '$1 == "Chef:" {print $2}'}
|
278
|
+
run_command(cmd).stdout.strip
|
279
|
+
end.call
|
258
280
|
end
|
259
281
|
|
260
282
|
def cook
|
@@ -268,6 +290,12 @@ class Chef
|
|
268
290
|
result = stream_command cmd
|
269
291
|
raise "chef-solo failed. See output above." unless result.success?
|
270
292
|
end
|
293
|
+
|
294
|
+
protected
|
295
|
+
|
296
|
+
def patch_cookbooks_install
|
297
|
+
add_cookbook_path(patch_cookbooks_path)
|
298
|
+
end
|
271
299
|
end
|
272
300
|
end
|
273
301
|
end
|
data/lib/chef/knife/solo_init.rb
CHANGED
@@ -32,7 +32,7 @@ class Chef
|
|
32
32
|
validate!
|
33
33
|
create_kitchen
|
34
34
|
create_config
|
35
|
-
create_cupboards %w[nodes roles data_bags site-cookbooks cookbooks]
|
35
|
+
create_cupboards %w[nodes roles data_bags environments site-cookbooks cookbooks]
|
36
36
|
gitignore %w[/cookbooks/]
|
37
37
|
if (cm = cookbook_manager)
|
38
38
|
cm.bootstrap(@base)
|
data/lib/knife-solo/berkshelf.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'digest/sha1'
|
2
|
+
require 'fileutils'
|
2
3
|
require 'knife-solo/cookbook_manager'
|
3
4
|
require 'knife-solo/tools'
|
4
5
|
|
@@ -17,7 +18,15 @@ module KnifeSolo
|
|
17
18
|
def install!
|
18
19
|
path = berkshelf_path
|
19
20
|
ui.msg "Installing Berkshelf cookbooks to '#{path}'..."
|
20
|
-
|
21
|
+
|
22
|
+
berksfile = ::Berkshelf::Berksfile.from_file('Berksfile')
|
23
|
+
if berksfile.respond_to?(:vendor)
|
24
|
+
FileUtils.rm_rf(path)
|
25
|
+
berksfile.vendor(path)
|
26
|
+
else
|
27
|
+
berksfile.install(:path => path)
|
28
|
+
end
|
29
|
+
|
21
30
|
path
|
22
31
|
end
|
23
32
|
|
@@ -63,10 +63,12 @@ module KnifeSolo::Bootstraps
|
|
63
63
|
def distro
|
64
64
|
return @distro if @distro
|
65
65
|
@distro = case issue
|
66
|
-
when %r{Debian GNU/Linux
|
66
|
+
when %r{Debian GNU/Linux [67]}
|
67
67
|
{:type => (x86? ? "debianoid_omnibus" : "debianoid_gem")}
|
68
68
|
when %r{Debian}
|
69
69
|
{:type => "debianoid_gem"}
|
70
|
+
when %r{Raspbian}
|
71
|
+
{:type => "debianoid_gem"}
|
70
72
|
when %r{Ubuntu}i
|
71
73
|
{:type => (x86? ? "debianoid_omnibus" : "debianoid_gem")}
|
72
74
|
when %r{Linaro}
|
data/lib/knife-solo/info.rb
CHANGED
@@ -30,6 +30,12 @@ module KnifeSolo
|
|
30
30
|
:description => 'A JSON string to be added to node config (if it does not exist)',
|
31
31
|
:proc => lambda { |o| JSON.parse(o) },
|
32
32
|
:default => nil
|
33
|
+
|
34
|
+
option :environment,
|
35
|
+
:short => '-E ENVIRONMENT',
|
36
|
+
:long => '--environment ENVIRONMENT',
|
37
|
+
:description => 'The Chef environment for your node'
|
38
|
+
|
33
39
|
end
|
34
40
|
end
|
35
41
|
|
@@ -47,6 +53,11 @@ module KnifeSolo
|
|
47
53
|
config[:chef_node_name] || host
|
48
54
|
end
|
49
55
|
|
56
|
+
def node_environment
|
57
|
+
node = node_config.exist? ? JSON.parse(IO.read(node_config)) : {}
|
58
|
+
config[:environment] || node['environment'] || '_default'
|
59
|
+
end
|
60
|
+
|
50
61
|
def generate_node_config
|
51
62
|
if node_config.exist?
|
52
63
|
Chef::Log.debug "Node config '#{node_config}' already exists"
|
@@ -56,7 +67,8 @@ module KnifeSolo
|
|
56
67
|
File.open(node_config, 'w') do |f|
|
57
68
|
attributes = config[:json_attributes] || config[:first_boot_attributes] || {}
|
58
69
|
run_list = { :run_list => config[:run_list] || [] }
|
59
|
-
|
70
|
+
environment = config[:environment] ? { :environment => config[:environment] } : {}
|
71
|
+
f.print attributes.merge(run_list).merge(environment).to_json
|
60
72
|
end
|
61
73
|
end
|
62
74
|
end
|
@@ -1,7 +1,8 @@
|
|
1
|
-
cookbook_path
|
2
|
-
node_path
|
3
|
-
role_path
|
4
|
-
|
1
|
+
cookbook_path ["cookbooks", "site-cookbooks"]
|
2
|
+
node_path "nodes"
|
3
|
+
role_path "roles"
|
4
|
+
environment_path "environments"
|
5
|
+
data_bag_path "data_bags"
|
5
6
|
#encrypted_data_bag_secret "data_bag_key"
|
6
7
|
|
7
8
|
knife[:berkshelf_path] = "cookbooks"
|
@@ -4,6 +4,8 @@ nodes_path File.join(base, 'nodes')
|
|
4
4
|
role_path File.join(base, 'roles')
|
5
5
|
data_bag_path File.join(base, 'data_bags')
|
6
6
|
encrypted_data_bag_secret File.join(base, 'data_bag_key')
|
7
|
+
environment_path File.join(base, 'environments')
|
8
|
+
environment <%= node_environment.inspect %>
|
7
9
|
|
8
10
|
cookbook_path []
|
9
11
|
<% cookbook_paths.each_with_index do |path, i| -%>
|
@@ -1,7 +1,9 @@
|
|
1
|
+
|
1
2
|
module KnifeSolo
|
2
3
|
module SshCommand
|
3
4
|
|
4
5
|
def self.load_deps
|
6
|
+
require 'knife-solo/ssh_connection'
|
5
7
|
require 'net/ssh'
|
6
8
|
end
|
7
9
|
|
@@ -59,6 +61,12 @@ module KnifeSolo
|
|
59
61
|
:long => '--sudo-command SUDO_COMMAND',
|
60
62
|
:description => 'The command to use instead of sudo for admin privileges'
|
61
63
|
|
64
|
+
option :host_key_verify,
|
65
|
+
:long => "--[no-]host-key-verify",
|
66
|
+
:description => "Verify host key, enabled by default.",
|
67
|
+
:boolean => true,
|
68
|
+
:default => true
|
69
|
+
|
62
70
|
end
|
63
71
|
end
|
64
72
|
|
@@ -124,6 +132,10 @@ module KnifeSolo
|
|
124
132
|
options[:port] = config[:ssh_port] if config[:ssh_port]
|
125
133
|
options[:password] = config[:ssh_password] if config[:ssh_password]
|
126
134
|
options[:keys] = [config[:identity_file]] if config[:identity_file]
|
135
|
+
if !config[:host_key_verify]
|
136
|
+
options[:paranoid] = false
|
137
|
+
options[:user_known_hosts_file] = "/dev/null"
|
138
|
+
end
|
127
139
|
options
|
128
140
|
end
|
129
141
|
|
@@ -148,9 +160,12 @@ module KnifeSolo
|
|
148
160
|
host_arg = [user, host].compact.join('@')
|
149
161
|
config_arg = "-F #{config[:ssh_config]}" if config[:ssh_config]
|
150
162
|
ident_arg = "-i #{config[:identity_file]}" if config[:identity_file]
|
151
|
-
port_arg = "-p #{config[:ssh_port]}" if config[:ssh_port]
|
163
|
+
port_arg = "-p #{config[:ssh_port]}" if config[:ssh_port]
|
164
|
+
knownhosts_arg = "-o UserKnownHostsFile=#{connection_options[:user_known_hosts_file]}" if config[:host_key_verify] == false
|
165
|
+
stricthosts_arg = "-o StrictHostKeyChecking=no" if config[:host_key_verify] == false
|
166
|
+
|
152
167
|
|
153
|
-
[host_arg, config_arg, ident_arg, port_arg].compact.join(' ')
|
168
|
+
[host_arg, config_arg, ident_arg, port_arg, knownhosts_arg, stricthosts_arg].compact.join(' ')
|
154
169
|
end
|
155
170
|
|
156
171
|
def sudo_command
|
@@ -161,27 +176,6 @@ module KnifeSolo
|
|
161
176
|
config[:startup_script]
|
162
177
|
end
|
163
178
|
|
164
|
-
class ExecResult
|
165
|
-
attr_accessor :stdout, :stderr, :exit_code
|
166
|
-
|
167
|
-
def initialize(exit_code = nil)
|
168
|
-
@exit_code = exit_code
|
169
|
-
@stdout = ""
|
170
|
-
@stderr = ""
|
171
|
-
end
|
172
|
-
|
173
|
-
def success?
|
174
|
-
exit_code == 0
|
175
|
-
end
|
176
|
-
|
177
|
-
# Helper to use when raising exceptions since some operations
|
178
|
-
# (e.g., command not found) error on stdout
|
179
|
-
def stderr_or_stdout
|
180
|
-
return stderr unless stderr.empty?
|
181
|
-
stdout
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
179
|
def windows_node?
|
186
180
|
return @windows_node unless @windows_node.nil?
|
187
181
|
@windows_node = run_command('ver', :process_sudo => false).stdout =~ /Windows/i
|
@@ -229,43 +223,14 @@ module KnifeSolo
|
|
229
223
|
detect_authentication_method
|
230
224
|
|
231
225
|
Chef::Log.debug("Initial command #{command}")
|
232
|
-
result = ExecResult.new
|
233
226
|
|
234
227
|
command = processed_command(command, options)
|
235
228
|
Chef::Log.debug("Running processed command #{command}")
|
236
229
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
raise "ssh.channel.exec failure" unless success
|
242
|
-
|
243
|
-
channel.on_data do |ch, data| # stdout
|
244
|
-
if data =~ /^knife sudo password: /
|
245
|
-
ch.send_data("#{password}\n")
|
246
|
-
else
|
247
|
-
Chef::Log.debug("#{command} stdout: #{data}")
|
248
|
-
ui.stdout << data if options[:streaming]
|
249
|
-
result.stdout << data
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
channel.on_extended_data do |ch, type, data|
|
254
|
-
next unless type == 1
|
255
|
-
Chef::Log.debug("#{command} stderr: #{data}")
|
256
|
-
ui.stderr << data if options[:streaming]
|
257
|
-
result.stderr << data
|
258
|
-
end
|
259
|
-
|
260
|
-
channel.on_request("exit-status") do |ch, data|
|
261
|
-
result.exit_code = data.read_long
|
262
|
-
end
|
263
|
-
|
264
|
-
end
|
265
|
-
ssh.loop
|
266
|
-
end
|
267
|
-
end
|
268
|
-
result
|
230
|
+
output = ui.stdout if options[:streaming]
|
231
|
+
|
232
|
+
@connection ||= SshConnection.new(host, user, connection_options, method(:password))
|
233
|
+
@connection.run_command(command, output)
|
269
234
|
end
|
270
235
|
|
271
236
|
# Runs commands from the specified array until successful.
|
@@ -276,7 +241,7 @@ module KnifeSolo
|
|
276
241
|
result = run_command(command, options)
|
277
242
|
return result if result.success?
|
278
243
|
end
|
279
|
-
ExecResult.new(1)
|
244
|
+
SshConnection::ExecResult.new(1)
|
280
245
|
end
|
281
246
|
|
282
247
|
# TODO:
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'net/ssh'
|
2
|
+
|
3
|
+
module KnifeSolo
|
4
|
+
class SshConnection
|
5
|
+
class ExecResult
|
6
|
+
attr_accessor :stdout, :stderr, :exit_code
|
7
|
+
|
8
|
+
def initialize(exit_code = nil)
|
9
|
+
@exit_code = exit_code
|
10
|
+
@stdout = ""
|
11
|
+
@stderr = ""
|
12
|
+
end
|
13
|
+
|
14
|
+
def success?
|
15
|
+
exit_code == 0
|
16
|
+
end
|
17
|
+
|
18
|
+
# Helper to use when raising exceptions since some operations
|
19
|
+
# (e.g., command not found) error on stdout
|
20
|
+
def stderr_or_stdout
|
21
|
+
return stderr unless stderr.empty?
|
22
|
+
stdout
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize(host, user, connection_options, sudo_password_hook)
|
27
|
+
@host = host
|
28
|
+
@user = user
|
29
|
+
@connection_options = connection_options
|
30
|
+
@password_hook = sudo_password_hook
|
31
|
+
end
|
32
|
+
|
33
|
+
attr_reader :host, :user, :connection_options
|
34
|
+
|
35
|
+
def session
|
36
|
+
@session ||= Net::SSH.start(host, user, connection_options)
|
37
|
+
end
|
38
|
+
|
39
|
+
def password
|
40
|
+
@password ||= @password_hook.call
|
41
|
+
end
|
42
|
+
|
43
|
+
def run_command(command, output = nil)
|
44
|
+
result = ExecResult.new
|
45
|
+
|
46
|
+
session.open_channel do |channel|
|
47
|
+
channel.request_pty
|
48
|
+
channel.exec(command) do |ch, success|
|
49
|
+
raise "ssh.channel.exec failure" unless success
|
50
|
+
|
51
|
+
channel.on_data do |ch, data| # stdout
|
52
|
+
if data =~ /^knife sudo password: /
|
53
|
+
ch.send_data("#{password}\n")
|
54
|
+
else
|
55
|
+
Chef::Log.debug("#{command} stdout: #{data}")
|
56
|
+
output << data if output
|
57
|
+
result.stdout << data
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
channel.on_extended_data do |ch, type, data|
|
62
|
+
next unless type == 1
|
63
|
+
Chef::Log.debug("#{command} stderr: #{data}")
|
64
|
+
output << data if output
|
65
|
+
result.stderr << data
|
66
|
+
end
|
67
|
+
|
68
|
+
channel.on_request("exit-status") do |ch, data|
|
69
|
+
result.exit_code = data.read_long
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end.wait
|
74
|
+
|
75
|
+
result
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/lib/knife-solo/tools.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
module Environment
|
2
|
+
def setup
|
3
|
+
super
|
4
|
+
FileUtils.cp_r $base_dir.join('support', 'environment_cookbook'), 'site-cookbooks/environment_cookbook'
|
5
|
+
FileUtils.cp $base_dir.join('support', 'test_environment.json'), 'environments/test_environment.json'
|
6
|
+
end
|
7
|
+
|
8
|
+
def cook_environment(node)
|
9
|
+
write_nodefile(node)
|
10
|
+
assert_subcommand "cook"
|
11
|
+
`ssh #{connection_string} cat /etc/chef_environment`
|
12
|
+
end
|
13
|
+
|
14
|
+
# Test that chef picks up environments properly
|
15
|
+
# NOTE: This shells out to ssh, so may not be windows-compatible
|
16
|
+
def test_chef_environment
|
17
|
+
# If no environment is specified chef needs to use "_default" and attribute from cookbook
|
18
|
+
actual = cook_environment(run_list: ["recipe[environment_cookbook]"])
|
19
|
+
assert_equal "_default/untouched", actual
|
20
|
+
|
21
|
+
# If one is specified chef needs to pick it up and get override attibute
|
22
|
+
actual = cook_environment(run_list: ["recipe[environment_cookbook]"], environment: 'test_environment')
|
23
|
+
assert_equal "test_environment/test_env_was_here", actual
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'support/kitchen_helper'
|
3
|
+
require 'chef/knife/solo_prepare'
|
4
|
+
|
5
|
+
require 'knife-solo/bootstraps'
|
6
|
+
require 'knife-solo/bootstraps/linux'
|
7
|
+
|
8
|
+
require 'knife-solo/ssh_connection'
|
9
|
+
|
10
|
+
require 'benchmark'
|
11
|
+
|
12
|
+
class KnifeSolo::Bootstraps::Linux
|
13
|
+
def debianoid_omnibus_install
|
14
|
+
run_command("echo apt-get update")
|
15
|
+
run_command("echo apt-get install")
|
16
|
+
run_command("echo curl omnibus")
|
17
|
+
run_command("echo run omnibus")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class SshPerformanceTest < TestCase
|
22
|
+
include KitchenHelper
|
23
|
+
|
24
|
+
def do_it
|
25
|
+
# NOTE: Assumes user & host on @matschaffer's machine. Modify or paramaterize if needed.
|
26
|
+
10.times { knife_command(Chef::Knife::SoloPrepare, "ubuntu@172.16.20.133").run }
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_ssh_performance_of_prepare
|
30
|
+
in_kitchen do
|
31
|
+
Benchmark.bmbm do |b|
|
32
|
+
b.report("cached attributes: ") do
|
33
|
+
do_it
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/test/solo_cook_test.rb
CHANGED
@@ -56,11 +56,6 @@ class SoloCookTest < TestCase
|
|
56
56
|
assert Dir.exist?(path), "patch_cookbooks_path is not a directory"
|
57
57
|
end
|
58
58
|
|
59
|
-
def test_cookbook_paths_includes_patch_cookbooks
|
60
|
-
cmd = command
|
61
|
-
assert_equal cmd.patch_cookbooks_path, cmd.cookbook_paths.last, "patch_cookbooks is not included"
|
62
|
-
end
|
63
|
-
|
64
59
|
def test_cookbook_paths_expands_paths
|
65
60
|
cmd = command
|
66
61
|
Chef::Config.cookbook_path = ["mycookbooks", "/some/other/path"]
|
@@ -84,9 +79,18 @@ class SoloCookTest < TestCase
|
|
84
79
|
assert_equal({ :http_proxy => "http://proxy:3128" }, conf)
|
85
80
|
end
|
86
81
|
|
82
|
+
def test_adds_patch_cookboks_with_lowest_precedence
|
83
|
+
in_kitchen do
|
84
|
+
cmd = command("somehost")
|
85
|
+
cmd.run
|
86
|
+
#note: cookbook_paths are in order of precedence (low->high)
|
87
|
+
assert_equal cmd.patch_cookbooks_path, cmd.cookbook_paths[0]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
87
91
|
def test_does_not_run_berkshelf_if_no_berkfile
|
88
92
|
in_kitchen do
|
89
|
-
Berkshelf::Berksfile.any_instance.expects(:
|
93
|
+
Berkshelf::Berksfile.any_instance.expects(:vendor).never
|
90
94
|
command("somehost").run
|
91
95
|
end
|
92
96
|
end
|
@@ -94,7 +98,7 @@ class SoloCookTest < TestCase
|
|
94
98
|
def test_runs_berkshelf_if_berkfile_found
|
95
99
|
in_kitchen do
|
96
100
|
FileUtils.touch "Berksfile"
|
97
|
-
Berkshelf::Berksfile.any_instance.expects(:
|
101
|
+
Berkshelf::Berksfile.any_instance.expects(:vendor)
|
98
102
|
command("somehost").run
|
99
103
|
end
|
100
104
|
end
|
@@ -102,7 +106,7 @@ class SoloCookTest < TestCase
|
|
102
106
|
def test_does_not_run_berkshelf_if_denied_by_option
|
103
107
|
in_kitchen do
|
104
108
|
FileUtils.touch "Berksfile"
|
105
|
-
Berkshelf::Berksfile.any_instance.expects(:
|
109
|
+
Berkshelf::Berksfile.any_instance.expects(:vendor).never
|
106
110
|
command("somehost", "--no-berkshelf").run
|
107
111
|
end
|
108
112
|
end
|
@@ -113,7 +117,7 @@ class SoloCookTest < TestCase
|
|
113
117
|
cmd = command("somehost")
|
114
118
|
cmd.ui.expects(:err).with(regexp_matches(/berkshelf gem/))
|
115
119
|
KnifeSolo::Berkshelf.expects(:load_gem).returns(false)
|
116
|
-
Berkshelf::Berksfile.any_instance.expects(:
|
120
|
+
Berkshelf::Berksfile.any_instance.expects(:vendor).never
|
117
121
|
cmd.run
|
118
122
|
end
|
119
123
|
end
|
@@ -123,7 +127,7 @@ class SoloCookTest < TestCase
|
|
123
127
|
cmd = command("somehost")
|
124
128
|
cmd.ui.expects(:err).never
|
125
129
|
KnifeSolo::Berkshelf.expects(:load_gem).never
|
126
|
-
Berkshelf::Berksfile.any_instance.expects(:
|
130
|
+
Berkshelf::Berksfile.any_instance.expects(:vendor).never
|
127
131
|
cmd.run
|
128
132
|
end
|
129
133
|
end
|
@@ -132,9 +136,10 @@ class SoloCookTest < TestCase
|
|
132
136
|
in_kitchen do
|
133
137
|
FileUtils.touch "Berksfile"
|
134
138
|
KnifeSolo::Berkshelf.any_instance.stubs(:berkshelf_path).returns("berkshelf/path")
|
139
|
+
Berkshelf::Berksfile.any_instance.stubs(:vendor)
|
135
140
|
cmd = command("somehost")
|
136
141
|
cmd.run
|
137
|
-
assert_equal File.join(Dir.pwd, "berkshelf/path"), cmd.cookbook_paths[
|
142
|
+
assert_equal File.join(Dir.pwd, "berkshelf/path"), cmd.cookbook_paths[1].to_s
|
138
143
|
end
|
139
144
|
end
|
140
145
|
|
@@ -186,9 +191,10 @@ class SoloCookTest < TestCase
|
|
186
191
|
ENV['LIBRARIAN_CHEF_PATH'] = "librarian/path"
|
187
192
|
in_kitchen do
|
188
193
|
FileUtils.touch "Cheffile"
|
194
|
+
Librarian::Action::Install.any_instance.stubs(:run)
|
189
195
|
cmd = command("somehost")
|
190
196
|
cmd.run
|
191
|
-
assert_equal File.join(Dir.pwd, "librarian/path"), cmd.cookbook_paths[
|
197
|
+
assert_equal File.join(Dir.pwd, "librarian/path"), cmd.cookbook_paths[1].to_s
|
192
198
|
end
|
193
199
|
end
|
194
200
|
|
@@ -247,6 +253,14 @@ class SoloCookTest < TestCase
|
|
247
253
|
end
|
248
254
|
end
|
249
255
|
|
256
|
+
def test_does_not_sync_if_no_sync_specified
|
257
|
+
in_kitchen do
|
258
|
+
cmd = command("somehost", "--no-sync")
|
259
|
+
cmd.expects(:sync_kitchen).never
|
260
|
+
cmd.run
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
250
264
|
def test_passes_node_name_to_chef_solo
|
251
265
|
assert_chef_solo_option "--node-name=mynode", "-N mynode"
|
252
266
|
end
|
data/test/ssh_command_test.rb
CHANGED
@@ -82,6 +82,18 @@ class SshCommandTest < TestCase
|
|
82
82
|
assert_equal "source ~/.bashrc && echo $TEST_PROP", cmd.processed_command("echo $TEST_PROP")
|
83
83
|
end
|
84
84
|
|
85
|
+
def test_handle_no_host_key_verify
|
86
|
+
cmd = command("10.0.0.1", "--no-host-key-verify")
|
87
|
+
assert_equal false, cmd.connection_options[:paranoid]
|
88
|
+
assert_equal "/dev/null", cmd.connection_options[:user_known_hosts_file]
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_handle_default_host_key_verify_is_paranoid
|
92
|
+
cmd = command("10.0.0.1")
|
93
|
+
assert_nil(cmd.connection_options[:paranoid]) # Net:SSH default is :paranoid => true
|
94
|
+
assert_nil(cmd.connection_options[:user_known_hosts_file])
|
95
|
+
end
|
96
|
+
|
85
97
|
def test_builds_cli_ssh_args
|
86
98
|
DummySshCommand.any_instance.stubs(:try_connection)
|
87
99
|
|
@@ -103,6 +115,10 @@ class SshCommandTest < TestCase
|
|
103
115
|
cmd = command("usertest@10.0.0.1", "--ssh-port=222")
|
104
116
|
cmd.validate_ssh_options!
|
105
117
|
assert_equal "usertest@10.0.0.1 -p 222", cmd.ssh_args
|
118
|
+
|
119
|
+
cmd = command("usertest@10.0.0.1", "--no-host-key-verify")
|
120
|
+
cmd.validate_ssh_options!
|
121
|
+
assert_equal "usertest@10.0.0.1 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no", cmd.ssh_args
|
106
122
|
end
|
107
123
|
|
108
124
|
def test_barks_without_atleast_a_hostname
|
@@ -127,14 +143,14 @@ class SshCommandTest < TestCase
|
|
127
143
|
def test_run_with_fallbacks_returns_error_if_all_fail
|
128
144
|
cmd = command
|
129
145
|
cmd.expects(:run_command).twice.returns(result(64, "fail"))
|
130
|
-
|
146
|
+
|
131
147
|
res = cmd.run_with_fallbacks(["foo", "bar"])
|
132
148
|
assert_equal "", res.stdout
|
133
149
|
assert_equal 1, res.exit_code
|
134
150
|
end
|
135
151
|
|
136
152
|
def result(code, stdout = "")
|
137
|
-
res = KnifeSolo::
|
153
|
+
res = KnifeSolo::SshConnection::ExecResult.new(code)
|
138
154
|
res.stdout = stdout
|
139
155
|
res
|
140
156
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
default['environment']['test_attribute'] = "untouched"
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-solo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mat Schaffer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-10-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: berkshelf
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 3.0.0.beta.2
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 3.0.0.beta.2
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: ffi
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - <
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.9.1
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - <
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.9.1
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: fog
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -136,6 +150,20 @@ dependencies:
|
|
136
150
|
- - ~>
|
137
151
|
- !ruby/object:Gem::Version
|
138
152
|
version: '3.12'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: coveralls
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - '>='
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - '>='
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
139
167
|
- !ruby/object:Gem::Dependency
|
140
168
|
name: chef
|
141
169
|
requirement: !ruby/object:Gem::Requirement
|
@@ -190,6 +218,7 @@ executables: []
|
|
190
218
|
extensions: []
|
191
219
|
extra_rdoc_files: []
|
192
220
|
files:
|
221
|
+
- .coveralls.yml
|
193
222
|
- CHANGELOG.md
|
194
223
|
- LICENSE
|
195
224
|
- README.rdoc
|
@@ -221,6 +250,7 @@ files:
|
|
221
250
|
- lib/knife-solo/resources/knife.rb
|
222
251
|
- lib/knife-solo/resources/solo.rb.erb
|
223
252
|
- lib/knife-solo/ssh_command.rb
|
253
|
+
- lib/knife-solo/ssh_connection.rb
|
224
254
|
- lib/knife-solo/tools.rb
|
225
255
|
- test/bootstraps_test.rb
|
226
256
|
- test/deprecated_command_test.rb
|
@@ -233,6 +263,7 @@ files:
|
|
233
263
|
- test/integration/cases/cache_path_usage.rb
|
234
264
|
- test/integration/cases/empty_cook.rb
|
235
265
|
- test/integration/cases/encrypted_data_bag.rb
|
266
|
+
- test/integration/cases/environment.rb
|
236
267
|
- test/integration/cases/knife_bootstrap.rb
|
237
268
|
- test/integration/centos5_8_test.rb
|
238
269
|
- test/integration/centos6_3_test.rb
|
@@ -249,6 +280,7 @@ files:
|
|
249
280
|
- test/knife_bootstrap_test.rb
|
250
281
|
- test/minitest/parallel.rb
|
251
282
|
- test/node_config_command_test.rb
|
283
|
+
- test/performance/ssh_performance_test.rb
|
252
284
|
- test/solo_bootstrap_test.rb
|
253
285
|
- test/solo_clean_test.rb
|
254
286
|
- test/solo_cook_test.rb
|
@@ -260,6 +292,9 @@ files:
|
|
260
292
|
- test/support/config.yml.example
|
261
293
|
- test/support/data_bag_key
|
262
294
|
- test/support/ec2_runner.rb
|
295
|
+
- test/support/environment_cookbook/attributes/default.rb
|
296
|
+
- test/support/environment_cookbook/metadata.rb
|
297
|
+
- test/support/environment_cookbook/recipes/default.rb
|
263
298
|
- test/support/integration_test.rb
|
264
299
|
- test/support/issue_files/gentoo2011
|
265
300
|
- test/support/issue_files/sles11-sp1
|
@@ -270,6 +305,7 @@ files:
|
|
270
305
|
- test/support/secret_cookbook/recipes/default.rb
|
271
306
|
- test/support/ssh_config
|
272
307
|
- test/support/test_case.rb
|
308
|
+
- test/support/test_environment.json
|
273
309
|
- test/support/validation_helper.rb
|
274
310
|
- test/test_helper.rb
|
275
311
|
- test/tools_test.rb
|
@@ -341,6 +377,7 @@ test_files:
|
|
341
377
|
- test/integration/cases/cache_path_usage.rb
|
342
378
|
- test/integration/cases/empty_cook.rb
|
343
379
|
- test/integration/cases/encrypted_data_bag.rb
|
380
|
+
- test/integration/cases/environment.rb
|
344
381
|
- test/integration/cases/knife_bootstrap.rb
|
345
382
|
- test/integration/centos5_8_test.rb
|
346
383
|
- test/integration/centos6_3_test.rb
|
@@ -357,6 +394,7 @@ test_files:
|
|
357
394
|
- test/knife_bootstrap_test.rb
|
358
395
|
- test/minitest/parallel.rb
|
359
396
|
- test/node_config_command_test.rb
|
397
|
+
- test/performance/ssh_performance_test.rb
|
360
398
|
- test/solo_bootstrap_test.rb
|
361
399
|
- test/solo_clean_test.rb
|
362
400
|
- test/solo_cook_test.rb
|
@@ -368,6 +406,9 @@ test_files:
|
|
368
406
|
- test/support/config.yml.example
|
369
407
|
- test/support/data_bag_key
|
370
408
|
- test/support/ec2_runner.rb
|
409
|
+
- test/support/environment_cookbook/attributes/default.rb
|
410
|
+
- test/support/environment_cookbook/metadata.rb
|
411
|
+
- test/support/environment_cookbook/recipes/default.rb
|
371
412
|
- test/support/integration_test.rb
|
372
413
|
- test/support/issue_files/gentoo2011
|
373
414
|
- test/support/issue_files/sles11-sp1
|
@@ -378,6 +419,7 @@ test_files:
|
|
378
419
|
- test/support/secret_cookbook/recipes/default.rb
|
379
420
|
- test/support/ssh_config
|
380
421
|
- test/support/test_case.rb
|
422
|
+
- test/support/test_environment.json
|
381
423
|
- test/support/validation_helper.rb
|
382
424
|
- test/test_helper.rb
|
383
425
|
- test/tools_test.rb
|