knife-solo 0.0.15 → 0.1.0.pre1
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.
- data/CHANGELOG.md +216 -0
- data/LICENSE +7 -0
- data/README.rdoc +127 -0
- data/Rakefile +31 -0
- data/lib/chef/knife/cook.rb +4 -131
- data/lib/chef/knife/kitchen.rb +4 -49
- data/lib/chef/knife/prepare.rb +4 -50
- data/lib/chef/knife/solo_bootstrap.rb +51 -0
- data/lib/chef/knife/solo_clean.rb +25 -0
- data/lib/chef/knife/solo_cook.rb +137 -0
- data/lib/chef/knife/solo_init.rb +59 -0
- data/lib/chef/knife/solo_prepare.rb +56 -0
- data/lib/chef/knife/wash_up.rb +4 -15
- data/lib/knife-solo/bootstraps.rb +1 -1
- data/lib/knife-solo/bootstraps/linux.rb +6 -4
- data/lib/knife-solo/bootstraps/sun_os.rb +9 -0
- data/lib/knife-solo/deprecated_command.rb +19 -0
- data/lib/knife-solo/info.rb +1 -1
- data/lib/knife-solo/kitchen_command.rb +5 -10
- data/lib/knife-solo/node_config_command.rb +17 -3
- data/lib/knife-solo/ssh_command.rb +3 -3
- data/test/bootstraps_test.rb +90 -0
- data/test/deprecated_command_test.rb +46 -0
- data/test/integration/cases/apache2_bootstrap.rb +15 -0
- data/test/integration/cases/apache2_cook.rb +28 -0
- data/test/integration/cases/empty_cook.rb +8 -0
- data/test/integration/cases/encrypted_data_bag.rb +27 -0
- data/test/integration/centos5_6_test.rb +19 -0
- data/test/integration/gentoo2011_test.rb +18 -0
- data/test/integration/omnios_r151004_test.rb +14 -0
- data/test/integration/scientific_linux_63_test.rb +15 -0
- data/test/integration/sles_11_test.rb +14 -0
- data/test/integration/ubuntu10_04_test.rb +15 -0
- data/test/integration/ubuntu12_04_bootstrap_test.rb +17 -0
- data/test/integration/ubuntu12_04_test.rb +15 -0
- data/test/integration_helper.rb +16 -0
- data/test/kitchen_command_test.rb +31 -0
- data/test/minitest/parallel.rb +41 -0
- data/test/node_config_command_test.rb +101 -0
- data/test/solo_bootstrap_test.rb +32 -0
- data/test/solo_clean_test.rb +12 -0
- data/test/solo_cook_test.rb +67 -0
- data/test/solo_init_test.rb +40 -0
- data/test/solo_prepare_test.rb +50 -0
- data/test/ssh_command_test.rb +100 -0
- data/test/support/config.yml.example +4 -0
- data/test/support/data_bag_key +1 -0
- data/test/support/ec2_runner.rb +122 -0
- data/test/support/integration_test.rb +94 -0
- data/test/support/issue_files/gentoo2011 +3 -0
- data/test/support/issue_files/sles11-sp1 +4 -0
- data/test/support/issue_files/ubuntu +2 -0
- data/test/support/kitchen_helper.rb +22 -0
- data/test/support/loggable.rb +18 -0
- data/test/support/secret_cookbook/metadata.rb +5 -0
- data/test/support/secret_cookbook/recipes/default.rb +8 -0
- data/test/support/ssh_config +3 -0
- data/test/support/test_case.rb +24 -0
- data/test/support/validation_helper.rb +39 -0
- data/test/test_helper.rb +7 -0
- metadata +99 -11
- data/lib/knife-solo/knife_solo_error.rb +0 -3
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'integration_helper'
|
2
|
+
|
3
|
+
class Ubuntu12_04BootstrapTest < IntegrationTest
|
4
|
+
def user
|
5
|
+
"ubuntu"
|
6
|
+
end
|
7
|
+
|
8
|
+
def image_id
|
9
|
+
"ami-9a873ff3"
|
10
|
+
end
|
11
|
+
|
12
|
+
def prepare_server
|
13
|
+
# Do nothing as `solo bootstrap` will do everything
|
14
|
+
end
|
15
|
+
|
16
|
+
include Apache2Bootstrap
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
|
4
|
+
Bundler.require
|
5
|
+
require 'minitest/parallel'
|
6
|
+
Bundler.require(:test)
|
7
|
+
|
8
|
+
require 'pathname'
|
9
|
+
$base_dir = Pathname.new(__FILE__).dirname
|
10
|
+
|
11
|
+
require 'support/loggable'
|
12
|
+
require 'support/ec2_runner'
|
13
|
+
require 'support/integration_test'
|
14
|
+
|
15
|
+
MiniTest::Parallel.processor_count = 5
|
16
|
+
MiniTest::Unit.runner = EC2Runner.new
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'support/kitchen_helper'
|
3
|
+
|
4
|
+
require 'chef/knife'
|
5
|
+
require 'knife-solo/kitchen_command'
|
6
|
+
|
7
|
+
class DummyKitchenCommand < Chef::Knife
|
8
|
+
include KnifeSolo::KitchenCommand
|
9
|
+
end
|
10
|
+
|
11
|
+
class KitchenCommandTest < TestCase
|
12
|
+
include KitchenHelper
|
13
|
+
|
14
|
+
def test_barks_outside_of_the_kitchen
|
15
|
+
cmd = command
|
16
|
+
cmd.ui.expects(:err).with(regexp_matches(/must be run inside .* kitchen/))
|
17
|
+
outside_kitchen do
|
18
|
+
assert_exits { cmd.validate_kitchen! }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_runs_when_in_a_kitchen
|
23
|
+
in_kitchen do
|
24
|
+
command.validate_kitchen!
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def command(*args)
|
29
|
+
knife_command(DummyKitchenCommand, *args)
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# https://github.com/ngauthier/minitest-parallel
|
2
|
+
if defined?(MiniTest)
|
3
|
+
raise "Do not require minitest before minitest/parallel\n"
|
4
|
+
end
|
5
|
+
require 'parallel'
|
6
|
+
require 'minitest/unit'
|
7
|
+
|
8
|
+
module MiniTest::Parallel
|
9
|
+
def self.included(base)
|
10
|
+
base.class_eval do
|
11
|
+
alias_method :_run_suites_in_series, :_run_suites
|
12
|
+
alias_method :_run_suites, :_run_suites_in_parallel
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.processor_count=(procs)
|
17
|
+
@processor_count = procs
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.processor_count
|
21
|
+
@processor_count ||= Parallel.processor_count
|
22
|
+
end
|
23
|
+
|
24
|
+
def _run_suites_in_parallel(suites, type)
|
25
|
+
result = Parallel.map(suites, :in_processes => MiniTest::Parallel.processor_count) do |suite|
|
26
|
+
ret = _run_suite(suite, type)
|
27
|
+
{
|
28
|
+
:failures => failures,
|
29
|
+
:errors => errors,
|
30
|
+
:report => report,
|
31
|
+
:run_suite_return => ret
|
32
|
+
}
|
33
|
+
end
|
34
|
+
self.failures = result.inject(0) {|sum, x| sum + x[:failures] }
|
35
|
+
self.errors = result.inject(0) {|sum, x| sum + x[:errors] }
|
36
|
+
self.report = result.inject([]) {|sum, x| sum + x[:report] }
|
37
|
+
result.map {|x| x[:run_suite_return] }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
MiniTest::Unit.send(:include, MiniTest::Parallel)
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'support/kitchen_helper'
|
3
|
+
|
4
|
+
require 'chef/knife'
|
5
|
+
require 'knife-solo/node_config_command'
|
6
|
+
|
7
|
+
class DummyNodeConfigCommand < Chef::Knife
|
8
|
+
include KnifeSolo::NodeConfigCommand
|
9
|
+
|
10
|
+
# This is normally declared in KnifeSolo::SshCommand
|
11
|
+
def host
|
12
|
+
@name_args.first
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class NodeConfigCommandTest < TestCase
|
17
|
+
include KitchenHelper
|
18
|
+
|
19
|
+
def setup
|
20
|
+
@host = "defaulthost"
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_node_config_defaults_to_host_name
|
24
|
+
cmd = command(@host)
|
25
|
+
assert_equal "nodes/#{@host}.json", cmd.node_config.to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_takes_node_config_as_second_arg
|
29
|
+
cmd = command(@host, "nodes/myhost.json")
|
30
|
+
assert_equal "nodes/myhost.json", cmd.node_config.to_s
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_takes_node_config_from_option
|
34
|
+
cmd = command(@host, "--node-name=mynode")
|
35
|
+
assert_equal "nodes/mynode.json", cmd.node_config.to_s
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_takes_node_config_as_second_arg_even_with_name_option
|
39
|
+
cmd = command(@host, "nodes/myhost.json", "--node-name=mynode")
|
40
|
+
assert_equal "nodes/myhost.json", cmd.node_config.to_s
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_generates_a_node_config
|
44
|
+
in_kitchen do
|
45
|
+
cmd = command(@host)
|
46
|
+
cmd.generate_node_config
|
47
|
+
assert cmd.node_config.exist?
|
48
|
+
assert_match '{"run_list":[]}', cmd.node_config.read
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_wont_overwrite_node_config
|
53
|
+
in_kitchen do
|
54
|
+
cmd = command(@host, "--run-list=role[myrole]")
|
55
|
+
File.open(cmd.node_config, "w") do |f|
|
56
|
+
f << "testdata"
|
57
|
+
end
|
58
|
+
cmd.generate_node_config
|
59
|
+
assert_match "testdata", cmd.node_config.read
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_generates_a_node_config_from_name_option
|
64
|
+
in_kitchen do
|
65
|
+
cmd = command(@host, "--node-name=mynode")
|
66
|
+
cmd.generate_node_config
|
67
|
+
assert cmd.node_config.exist?
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_generates_a_node_config_with_specified_run_list
|
72
|
+
in_kitchen do
|
73
|
+
cmd = command(@host, "--run-list=role[base],recipe[foo]")
|
74
|
+
cmd.generate_node_config
|
75
|
+
assert_match '{"run_list":["role[base]","recipe[foo]"]}', cmd.node_config.read
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_generates_a_node_config_with_specified_attributes
|
80
|
+
in_kitchen do
|
81
|
+
foo_json = '"foo":{"bar":[1,2],"baz":"x"}'
|
82
|
+
cmd = command(@host, "--json-attributes={#{foo_json}}")
|
83
|
+
cmd.generate_node_config
|
84
|
+
assert_match "{#{foo_json},\"run_list\":[]}", cmd.node_config.read
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_generates_a_node_config_with_specified_run_list_and_attributes
|
89
|
+
in_kitchen do
|
90
|
+
foo_json = '"foo":"bar"'
|
91
|
+
run_list = 'recipe[baz]'
|
92
|
+
cmd = command(@host, "--run-list=#{run_list}", "--json-attributes={#{foo_json}}")
|
93
|
+
cmd.generate_node_config
|
94
|
+
assert_match "{#{foo_json},\"run_list\":[\"#{run_list}\"]}", cmd.node_config.read
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def command(*args)
|
99
|
+
knife_command(DummyNodeConfigCommand, *args)
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'support/kitchen_helper'
|
3
|
+
require 'support/validation_helper'
|
4
|
+
|
5
|
+
require 'chef/knife/solo_bootstrap'
|
6
|
+
require 'chef/knife/solo_cook'
|
7
|
+
require 'chef/knife/solo_prepare'
|
8
|
+
|
9
|
+
class SoloBootstrapTest < TestCase
|
10
|
+
include KitchenHelper
|
11
|
+
include ValidationHelper::ValidationTests
|
12
|
+
|
13
|
+
def test_includes_all_prepare_options
|
14
|
+
bootstrap_options = Chef::Knife::SoloBootstrap.options
|
15
|
+
Chef::Knife::SoloPrepare.new.options.keys.each do |opt_key|
|
16
|
+
assert bootstrap_options.include?(opt_key), "Should support option :#{opt_key}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_runs_prepare_and_cook
|
21
|
+
Chef::Knife::SoloPrepare.any_instance.expects(:run)
|
22
|
+
Chef::Knife::SoloCook.any_instance.expects(:run)
|
23
|
+
|
24
|
+
in_kitchen do
|
25
|
+
command("somehost").run
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def command(*args)
|
30
|
+
knife_command(Chef::Knife::SoloBootstrap, *args)
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'support/validation_helper'
|
3
|
+
|
4
|
+
require 'chef/knife/solo_clean'
|
5
|
+
|
6
|
+
class SoloCleanTest < TestCase
|
7
|
+
include ValidationHelper::ValidationTests
|
8
|
+
|
9
|
+
def command(*args)
|
10
|
+
knife_command(Chef::Knife::SoloClean, *args)
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'support/kitchen_helper'
|
3
|
+
require 'support/validation_helper'
|
4
|
+
|
5
|
+
require 'chef/cookbook/chefignore'
|
6
|
+
require 'chef/knife/solo_cook'
|
7
|
+
|
8
|
+
class SuccessfulResult
|
9
|
+
def success?
|
10
|
+
true
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class SoloCookTest < TestCase
|
15
|
+
include KitchenHelper
|
16
|
+
include ValidationHelper::ValidationTests
|
17
|
+
|
18
|
+
def test_gets_destination_path_from_chef_config
|
19
|
+
Chef::Config.file_cache_path "/tmp/chef-solo"
|
20
|
+
assert_equal "/tmp/chef-solo", command.chef_path
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_gets_patch_path_from_chef_config
|
24
|
+
Chef::Config.cookbook_path ["/tmp/chef-solo/cookbooks"]
|
25
|
+
assert_equal "/tmp/chef-solo/cookbooks/chef_solo_patches/libraries", command.patch_path
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_chefignore_is_valid_object
|
29
|
+
assert_instance_of Chef::Cookbook::Chefignore, command.chefignore
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_rsync_exclude_sources_chefignore
|
33
|
+
in_kitchen do
|
34
|
+
file_to_ignore = "dummy.txt"
|
35
|
+
File.open(file_to_ignore, 'w') {|f| f.puts "This file should be ignored"}
|
36
|
+
File.open("chefignore", 'w') {|f| f.puts file_to_ignore}
|
37
|
+
assert command.rsync_exclude.include?(file_to_ignore), "#{file_to_ignore} should have been excluded"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_passes_node_name_to_chef_solo
|
42
|
+
assert_chef_solo_option "--node-name=mynode", "-N mynode"
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_passes_whyrun_mode_to_chef_solo
|
46
|
+
assert_chef_solo_option "--why-run", "-W"
|
47
|
+
end
|
48
|
+
|
49
|
+
# Asserts that the chef_solo_option is passed to chef-solo iff cook_option
|
50
|
+
# is specified for the cook command
|
51
|
+
def assert_chef_solo_option(cook_option, chef_solo_option)
|
52
|
+
matcher = regexp_matches(/\s#{Regexp.quote(chef_solo_option)}(\s|$)/)
|
53
|
+
in_kitchen do
|
54
|
+
cmd = command("somehost", cook_option)
|
55
|
+
cmd.expects(:stream_command).with(matcher).returns(SuccessfulResult.new)
|
56
|
+
cmd.cook
|
57
|
+
|
58
|
+
cmd = command("somehost")
|
59
|
+
cmd.expects(:stream_command).with(Not(matcher)).returns(SuccessfulResult.new)
|
60
|
+
cmd.cook
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def command(*args)
|
65
|
+
knife_command(Chef::Knife::SoloCook, *args)
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'support/kitchen_helper'
|
3
|
+
|
4
|
+
require 'chef/knife/solo_init'
|
5
|
+
|
6
|
+
class SoloInitTest < TestCase
|
7
|
+
include KitchenHelper
|
8
|
+
|
9
|
+
def test_produces_folders
|
10
|
+
in_kitchen do
|
11
|
+
assert File.exist?("nodes")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_produces_gitkeep_in_folders
|
16
|
+
in_kitchen do
|
17
|
+
assert File.exist?("nodes/.gitkeep")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_barks_without_directory_arg
|
22
|
+
cmd = command
|
23
|
+
cmd.ui.expects(:err).with(regexp_matches(/You must specify a directory/))
|
24
|
+
$stdout.stubs(:puts)
|
25
|
+
outside_kitchen do
|
26
|
+
assert_exits cmd
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_takes_directory_as_arg
|
31
|
+
outside_kitchen do
|
32
|
+
command("new_kitchen").run
|
33
|
+
assert File.exist?("new_kitchen/nodes")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def command(*args)
|
38
|
+
knife_command(Chef::Knife::SoloInit, *args)
|
39
|
+
end
|
40
|
+
end
|