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.
Files changed (62) hide show
  1. data/CHANGELOG.md +216 -0
  2. data/LICENSE +7 -0
  3. data/README.rdoc +127 -0
  4. data/Rakefile +31 -0
  5. data/lib/chef/knife/cook.rb +4 -131
  6. data/lib/chef/knife/kitchen.rb +4 -49
  7. data/lib/chef/knife/prepare.rb +4 -50
  8. data/lib/chef/knife/solo_bootstrap.rb +51 -0
  9. data/lib/chef/knife/solo_clean.rb +25 -0
  10. data/lib/chef/knife/solo_cook.rb +137 -0
  11. data/lib/chef/knife/solo_init.rb +59 -0
  12. data/lib/chef/knife/solo_prepare.rb +56 -0
  13. data/lib/chef/knife/wash_up.rb +4 -15
  14. data/lib/knife-solo/bootstraps.rb +1 -1
  15. data/lib/knife-solo/bootstraps/linux.rb +6 -4
  16. data/lib/knife-solo/bootstraps/sun_os.rb +9 -0
  17. data/lib/knife-solo/deprecated_command.rb +19 -0
  18. data/lib/knife-solo/info.rb +1 -1
  19. data/lib/knife-solo/kitchen_command.rb +5 -10
  20. data/lib/knife-solo/node_config_command.rb +17 -3
  21. data/lib/knife-solo/ssh_command.rb +3 -3
  22. data/test/bootstraps_test.rb +90 -0
  23. data/test/deprecated_command_test.rb +46 -0
  24. data/test/integration/cases/apache2_bootstrap.rb +15 -0
  25. data/test/integration/cases/apache2_cook.rb +28 -0
  26. data/test/integration/cases/empty_cook.rb +8 -0
  27. data/test/integration/cases/encrypted_data_bag.rb +27 -0
  28. data/test/integration/centos5_6_test.rb +19 -0
  29. data/test/integration/gentoo2011_test.rb +18 -0
  30. data/test/integration/omnios_r151004_test.rb +14 -0
  31. data/test/integration/scientific_linux_63_test.rb +15 -0
  32. data/test/integration/sles_11_test.rb +14 -0
  33. data/test/integration/ubuntu10_04_test.rb +15 -0
  34. data/test/integration/ubuntu12_04_bootstrap_test.rb +17 -0
  35. data/test/integration/ubuntu12_04_test.rb +15 -0
  36. data/test/integration_helper.rb +16 -0
  37. data/test/kitchen_command_test.rb +31 -0
  38. data/test/minitest/parallel.rb +41 -0
  39. data/test/node_config_command_test.rb +101 -0
  40. data/test/solo_bootstrap_test.rb +32 -0
  41. data/test/solo_clean_test.rb +12 -0
  42. data/test/solo_cook_test.rb +67 -0
  43. data/test/solo_init_test.rb +40 -0
  44. data/test/solo_prepare_test.rb +50 -0
  45. data/test/ssh_command_test.rb +100 -0
  46. data/test/support/config.yml.example +4 -0
  47. data/test/support/data_bag_key +1 -0
  48. data/test/support/ec2_runner.rb +122 -0
  49. data/test/support/integration_test.rb +94 -0
  50. data/test/support/issue_files/gentoo2011 +3 -0
  51. data/test/support/issue_files/sles11-sp1 +4 -0
  52. data/test/support/issue_files/ubuntu +2 -0
  53. data/test/support/kitchen_helper.rb +22 -0
  54. data/test/support/loggable.rb +18 -0
  55. data/test/support/secret_cookbook/metadata.rb +5 -0
  56. data/test/support/secret_cookbook/recipes/default.rb +8 -0
  57. data/test/support/ssh_config +3 -0
  58. data/test/support/test_case.rb +24 -0
  59. data/test/support/validation_helper.rb +39 -0
  60. data/test/test_helper.rb +7 -0
  61. metadata +99 -11
  62. data/lib/knife-solo/knife_solo_error.rb +0 -3
@@ -0,0 +1,14 @@
1
+ require 'integration_helper'
2
+
3
+ class OmniOSr151004Test < IntegrationTest
4
+ def user
5
+ "root"
6
+ end
7
+
8
+ def image_id
9
+ "ami-4e2c9727"
10
+ end
11
+
12
+ include EmptyCook
13
+ include EncryptedDataBag
14
+ end
@@ -0,0 +1,15 @@
1
+ require 'integration_helper'
2
+
3
+ class ScientificLinux63Test < IntegrationTest
4
+ def user
5
+ "root"
6
+ end
7
+
8
+ def image_id
9
+ "ami-313b8e58"
10
+ end
11
+
12
+ include EmptyCook
13
+ #include Apache2Cook
14
+ include EncryptedDataBag
15
+ end
@@ -0,0 +1,14 @@
1
+ require 'integration_helper'
2
+
3
+ class Sles11_Test < IntegrationTest
4
+ def user
5
+ "root"
6
+ end
7
+
8
+ def image_id
9
+ "ami-ca32efa3"
10
+ end
11
+
12
+ include EmptyCook
13
+ include EncryptedDataBag
14
+ end
@@ -0,0 +1,15 @@
1
+ require 'integration_helper'
2
+
3
+ class Ubuntu10_04Test < IntegrationTest
4
+ def user
5
+ "ubuntu"
6
+ end
7
+
8
+ def image_id
9
+ "ami-6936fb00"
10
+ end
11
+
12
+ include EmptyCook
13
+ include Apache2Cook
14
+ include EncryptedDataBag
15
+ end
@@ -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,15 @@
1
+ require 'integration_helper'
2
+
3
+ class Ubuntu12_04Test < IntegrationTest
4
+ def user
5
+ "ubuntu"
6
+ end
7
+
8
+ def image_id
9
+ "ami-9a873ff3"
10
+ end
11
+
12
+ include EmptyCook
13
+ include Apache2Cook
14
+ include EncryptedDataBag
15
+ 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