knife-solo 0.0.15 → 0.1.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
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