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
data/lib/chef/knife/wash_up.rb
CHANGED
@@ -1,21 +1,10 @@
|
|
1
|
-
require 'chef/knife'
|
2
|
-
require 'knife-solo/
|
3
|
-
require 'knife-solo/kitchen_command'
|
1
|
+
require 'chef/knife/solo_clean'
|
2
|
+
require 'knife-solo/deprecated_command'
|
4
3
|
|
5
4
|
class Chef
|
6
5
|
class Knife
|
7
|
-
class WashUp <
|
8
|
-
include KnifeSolo::
|
9
|
-
include KnifeSolo::KitchenCommand
|
10
|
-
|
11
|
-
banner "knife wash_up [user@]hostname"
|
12
|
-
|
13
|
-
def run
|
14
|
-
validate_first_cli_arg_is_a_hostname!
|
15
|
-
super
|
16
|
-
Chef::Config.from_file('solo.rb')
|
17
|
-
run_command "rm -rf #{Chef::Config.file_cache_path}"
|
18
|
-
end
|
6
|
+
class WashUp < SoloClean
|
7
|
+
include KnifeSolo::DeprecatedCommand
|
19
8
|
end
|
20
9
|
end
|
21
10
|
end
|
@@ -96,14 +96,16 @@ module KnifeSolo::Bootstraps
|
|
96
96
|
{:type => "omnibus", :version => "FC15"}
|
97
97
|
when %r{Fedora release.*? 16}
|
98
98
|
{:type => "omnibus", :version => "FC16"}
|
99
|
+
when %r{Fedora release.*? 17}
|
100
|
+
{:type => "omnibus", :version => "FC17"}
|
99
101
|
when %r{Scientific Linux.*? 5}
|
100
102
|
{:type => "omnibus", :version => "RHEL5"}
|
101
103
|
when %r{Scientific Linux.*? 6}
|
102
104
|
{:type => "yum_omnibus", :version => "RHEL6"}
|
103
|
-
when %r{SUSE Linux Enterprise Server
|
104
|
-
{:type => "
|
105
|
-
when %r{openSUSE
|
106
|
-
{:type => "
|
105
|
+
when %r{SUSE Linux Enterprise Server 1[12]}
|
106
|
+
{:type => "omnibus", :version => "SLES11"}
|
107
|
+
when %r{openSUSE 1[12]}
|
108
|
+
{:type => "omnibus", :version => "openSUSE"}
|
107
109
|
when %r{This is \\n\.\\O \(\\s \\m \\r\) \\t}
|
108
110
|
{:type => "emerge_gem", :version => "Gentoo"}
|
109
111
|
else
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module KnifeSolo
|
2
|
+
module DeprecatedCommand
|
3
|
+
|
4
|
+
def self.included(other)
|
5
|
+
other.class_eval do
|
6
|
+
def self.deprecated
|
7
|
+
"`knife #{common_name}` is deprecated! Please use:\n #{superclass.banner}"
|
8
|
+
end
|
9
|
+
|
10
|
+
banner deprecated
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def run
|
15
|
+
ui.warn self.class.deprecated
|
16
|
+
super
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/knife-solo/info.rb
CHANGED
@@ -1,19 +1,14 @@
|
|
1
|
-
require 'knife-solo/knife_solo_error'
|
2
|
-
|
3
1
|
module KnifeSolo
|
4
2
|
module KitchenCommand
|
5
|
-
class OutOfKitchenError < KnifeSoloError
|
6
|
-
def message
|
7
|
-
"This command must be run inside a Chef solo kitchen."
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
3
|
def self.required_files
|
12
4
|
%w(solo.rb)
|
13
5
|
end
|
14
6
|
|
15
|
-
def
|
16
|
-
|
7
|
+
def validate_kitchen!
|
8
|
+
unless required_files_present?
|
9
|
+
ui.fatal "This command must be run inside a Chef solo kitchen."
|
10
|
+
exit 1
|
11
|
+
end
|
17
12
|
end
|
18
13
|
|
19
14
|
def required_files_present?
|
@@ -15,6 +15,20 @@ module KnifeSolo
|
|
15
15
|
:short => "-N NAME",
|
16
16
|
:long => "--node-name NAME",
|
17
17
|
:description => "The Chef node name for your new node"
|
18
|
+
|
19
|
+
option :run_list,
|
20
|
+
:short => "-r RUN_LIST",
|
21
|
+
:long => "--run-list RUN_LIST",
|
22
|
+
:description => "Comma separated list of roles/recipes to put to node config (if it does not exist)",
|
23
|
+
:proc => lambda { |o| o.split(/[\s,]+/) },
|
24
|
+
:default => []
|
25
|
+
|
26
|
+
option :first_boot_attributes,
|
27
|
+
:short => "-j JSON_ATTRIBS",
|
28
|
+
:long => "--json-attributes",
|
29
|
+
:description => "A JSON string to be added to node config (if it does not exist)",
|
30
|
+
:proc => lambda { |o| JSON.parse(o) },
|
31
|
+
:default => {}
|
18
32
|
end
|
19
33
|
end
|
20
34
|
|
@@ -29,9 +43,9 @@ module KnifeSolo
|
|
29
43
|
else
|
30
44
|
ui.msg "Generating node config '#{node_config}'..."
|
31
45
|
File.open(node_config, 'w') do |f|
|
32
|
-
|
33
|
-
|
34
|
-
|
46
|
+
attributes = config[:first_boot_attributes] || {}
|
47
|
+
run_list = { :run_list => config[:run_list] || [] }
|
48
|
+
f.print attributes.merge(run_list).to_json
|
35
49
|
end
|
36
50
|
end
|
37
51
|
end
|
@@ -2,7 +2,6 @@ module KnifeSolo
|
|
2
2
|
module SshCommand
|
3
3
|
|
4
4
|
def self.load_deps
|
5
|
-
require 'knife-solo/knife_solo_error'
|
6
5
|
require 'net/ssh'
|
7
6
|
end
|
8
7
|
|
@@ -55,8 +54,9 @@ module KnifeSolo
|
|
55
54
|
|
56
55
|
def validate_first_cli_arg_is_a_hostname!
|
57
56
|
unless first_cli_arg_is_a_hostname?
|
58
|
-
|
59
|
-
|
57
|
+
show_usage
|
58
|
+
ui.fatal "You must specify [<user>@]<hostname> as the first argument"
|
59
|
+
exit 1
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'knife-solo/bootstraps'
|
4
|
+
|
5
|
+
class KnifeSolo::Bootstraps::StubOS < KnifeSolo::Bootstraps::Base
|
6
|
+
end
|
7
|
+
|
8
|
+
class KnifeSolo::Bootstraps::StubOS2 < KnifeSolo::Bootstraps::Base
|
9
|
+
def gem_packages ; ['chef'] ; end
|
10
|
+
def distro ; {:type => 'gem', :version => 'Fanny Faker'} ; end
|
11
|
+
def gem_install
|
12
|
+
# dont' actually install anything
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class BootstrapsTest < TestCase
|
17
|
+
def test_bootstrap_class_exists_for
|
18
|
+
assert_equal true, KnifeSolo::Bootstraps.class_exists_for?('Stub OS')
|
19
|
+
|
20
|
+
assert_equal false, KnifeSolo::Bootstraps.class_exists_for?('Mythical OS')
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_distro_raises_if_not_implemented
|
24
|
+
bootstrap = bootstrap_instance()
|
25
|
+
|
26
|
+
assert_raises RuntimeError do
|
27
|
+
bootstrap.distro()
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_gem_packages_raises_if_not_implemented
|
32
|
+
bootstrap = bootstrap_instance()
|
33
|
+
|
34
|
+
assert_raises RuntimeError do
|
35
|
+
bootstrap.gem_packages()
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_bootstrap_calls_appropriate_install_method
|
40
|
+
bootstrap = KnifeSolo::Bootstraps::StubOS2.new(mock)
|
41
|
+
bootstrap.stubs(:distro).returns({:type => 'disco_gem'})
|
42
|
+
|
43
|
+
bootstrap.expects(:disco_gem_install)
|
44
|
+
|
45
|
+
bootstrap.bootstrap!
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_bootstrap_calls_pre_bootstrap_checks
|
49
|
+
bootstrap = KnifeSolo::Bootstraps::StubOS2.new(mock)
|
50
|
+
|
51
|
+
bootstrap.expects(:run_pre_bootstrap_checks)
|
52
|
+
|
53
|
+
bootstrap.bootstrap!
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_bootstrap_delegates_to_knife_prepare
|
57
|
+
prepare = mock('chef::knife::prepare')
|
58
|
+
bootstrap = KnifeSolo::Bootstraps::StubOS2.new(prepare)
|
59
|
+
|
60
|
+
assert prepare == bootstrap.prepare
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_darwin_checks_for_xcode_install_and_barfs_if_missing
|
64
|
+
bootstrap = KnifeSolo::Bootstraps::Darwin.new(mock)
|
65
|
+
# don't want to actually run anything
|
66
|
+
bootstrap.stubs(:gem_install)
|
67
|
+
|
68
|
+
bootstrap.expects(:has_xcode_installed?).returns(false)
|
69
|
+
|
70
|
+
assert_raises RuntimeError do
|
71
|
+
bootstrap.bootstrap!
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_omnibus_install_methdod
|
76
|
+
bootstrap = KnifeSolo::Bootstraps::StubOS2.new(mock)
|
77
|
+
bootstrap.stubs(:distro).returns({:type => "omnibus"})
|
78
|
+
|
79
|
+
bootstrap.expects(:omnibus_install)
|
80
|
+
|
81
|
+
bootstrap.bootstrap!
|
82
|
+
end
|
83
|
+
|
84
|
+
# ***
|
85
|
+
|
86
|
+
def bootstrap_instance
|
87
|
+
@prepare = mock('Knife::Chef::SoloPrepare')
|
88
|
+
KnifeSolo::Bootstraps::StubOS.new(@prepare)
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'chef/knife'
|
4
|
+
require 'knife-solo/deprecated_command'
|
5
|
+
|
6
|
+
class DummyNewCommand < Chef::Knife
|
7
|
+
banner "knife dummy_new_command"
|
8
|
+
|
9
|
+
def run
|
10
|
+
# calls #new_run so we can be sure this gets called
|
11
|
+
new_run
|
12
|
+
end
|
13
|
+
|
14
|
+
def new_run
|
15
|
+
# dummy
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class DummyDeprecatedCommand < DummyNewCommand
|
20
|
+
include KnifeSolo::DeprecatedCommand
|
21
|
+
end
|
22
|
+
|
23
|
+
class DeprecatedCommandTest < TestCase
|
24
|
+
def test_help_warns_about_deprecation
|
25
|
+
$stdout.expects(:puts).with(regexp_matches(/deprecated!/))
|
26
|
+
assert_exits { command("--help") }
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_warns_about_deprecation
|
30
|
+
cmd = command
|
31
|
+
cmd.ui.expects(:err).with(regexp_matches(/deprecated!/))
|
32
|
+
cmd.run
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_runs_original_command
|
36
|
+
cmd = command
|
37
|
+
cmd.ui.stubs(:err)
|
38
|
+
cmd.expects(:new_run)
|
39
|
+
cmd.run
|
40
|
+
end
|
41
|
+
|
42
|
+
def command(*args)
|
43
|
+
DummyDeprecatedCommand.load_deps
|
44
|
+
DummyDeprecatedCommand.new(args)
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# Tries to bootstrap with apache2 cookbook and
|
2
|
+
# verifies the "It Works!" page is present.
|
3
|
+
|
4
|
+
require $base_dir.join('integration', 'cases', 'apache2_cook')
|
5
|
+
|
6
|
+
module Apache2Bootstrap
|
7
|
+
include Apache2Cook
|
8
|
+
|
9
|
+
def test_apache2
|
10
|
+
write_cheffile
|
11
|
+
system "librarian-chef install >> #{log_file}"
|
12
|
+
assert_subcommand "bootstrap --run-list=recipe[apache2]"
|
13
|
+
assert_match default_apache_message, http_response
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Tries to cook with apache2 cookbook and
|
2
|
+
# verifies the "It Works!" page is present.
|
3
|
+
module Apache2Cook
|
4
|
+
def write_cheffile
|
5
|
+
File.open('Cheffile', 'w') do |f|
|
6
|
+
f.print <<-CHEF
|
7
|
+
site 'http://community.opscode.com/api/v1'
|
8
|
+
cookbook 'apache2'
|
9
|
+
CHEF
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def http_response
|
14
|
+
Net::HTTP.get(URI.parse("http://"+server.public_ip_address))
|
15
|
+
end
|
16
|
+
|
17
|
+
def default_apache_message
|
18
|
+
/It works!/
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_apache2
|
22
|
+
write_cheffile
|
23
|
+
system "librarian-chef install >> #{log_file}"
|
24
|
+
write_nodefile(run_list: ["recipe[apache2]"])
|
25
|
+
assert_subcommand "cook"
|
26
|
+
assert_match default_apache_message, http_response
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'chef/encrypted_data_bag_item'
|
2
|
+
|
3
|
+
module EncryptedDataBag
|
4
|
+
def setup
|
5
|
+
super
|
6
|
+
FileUtils.cp $base_dir.join('support', 'data_bag_key'), 'data_bag_key'
|
7
|
+
FileUtils.cp_r $base_dir.join('support', 'secret_cookbook'), 'cookbooks/secret_cookbook'
|
8
|
+
@password = "essential particles busy loud"
|
9
|
+
create_data_bag
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_data_bag
|
13
|
+
secret = Chef::EncryptedDataBagItem.load_secret('data_bag_key')
|
14
|
+
data = {"id" => "passwords", "admin" => @password}
|
15
|
+
encrypted_data = Chef::EncryptedDataBagItem.encrypt_data_bag_item(data, secret)
|
16
|
+
write_json_file('data_bags/dev/passwords.json', encrypted_data)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Test that we can read an encrypted data bag value
|
20
|
+
# NOTE: This shells out to ssh, so may not be windows-compatible
|
21
|
+
def test_reading_encrypted_data_bag
|
22
|
+
write_nodefile(run_list: ["recipe[secret_cookbook]"])
|
23
|
+
assert_subcommand "cook"
|
24
|
+
actual = `ssh #{connection_string} cat /etc/admin_password`
|
25
|
+
assert_equal @password, actual
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'integration_helper'
|
2
|
+
|
3
|
+
class Centos5_6Test < IntegrationTest
|
4
|
+
def user
|
5
|
+
"root"
|
6
|
+
end
|
7
|
+
|
8
|
+
def image_id
|
9
|
+
"ami-3fe42456"
|
10
|
+
end
|
11
|
+
|
12
|
+
def default_apache_message
|
13
|
+
/Apache 2 Test Page/
|
14
|
+
end
|
15
|
+
|
16
|
+
include EmptyCook
|
17
|
+
include Apache2Cook
|
18
|
+
include EncryptedDataBag
|
19
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'integration_helper'
|
2
|
+
|
3
|
+
class Gentoo2011Test < IntegrationTest
|
4
|
+
def user
|
5
|
+
"root"
|
6
|
+
end
|
7
|
+
|
8
|
+
def image_id
|
9
|
+
"ami-ae49b7c7"
|
10
|
+
end
|
11
|
+
|
12
|
+
# `emerge chef` takes a very long time (~ 50 minutes) on an m1.small
|
13
|
+
# Uncoment this if you need to verify Gentoo operation
|
14
|
+
|
15
|
+
# include EmptyCook
|
16
|
+
# include Apache2Cook
|
17
|
+
# include EncryptedDataBag
|
18
|
+
end
|