knife-solo 0.3.0 → 0.4.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 +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
|