pantry-chef 0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.travis.yml +16 -0
- data/Gemfile +15 -0
- data/LICENSE +20 -0
- data/README.md +49 -0
- data/Rakefile +18 -0
- data/lib/pantry/chef.rb +47 -0
- data/lib/pantry/chef/configure_chef.rb +59 -0
- data/lib/pantry/chef/list_cookbooks.rb +31 -0
- data/lib/pantry/chef/run.rb +30 -0
- data/lib/pantry/chef/run_chef_solo.rb +21 -0
- data/lib/pantry/chef/send_cookbooks.rb +23 -0
- data/lib/pantry/chef/sync_cookbooks.rb +84 -0
- data/lib/pantry/chef/sync_data_bags.rb +19 -0
- data/lib/pantry/chef/sync_environments.rb +19 -0
- data/lib/pantry/chef/sync_roles.rb +19 -0
- data/lib/pantry/chef/upload_cookbook.rb +110 -0
- data/lib/pantry/chef/upload_data_bag.rb +37 -0
- data/lib/pantry/chef/upload_environment.rb +28 -0
- data/lib/pantry/chef/upload_role.rb +28 -0
- data/lib/pantry/chef/version.rb +5 -0
- data/lib/pantry/init.rb +1 -0
- data/pantry-chef.gemspec +27 -0
- data/test/acceptance/chef/run_test.rb +69 -0
- data/test/acceptance/chef/upload_cookbook_test.rb +26 -0
- data/test/acceptance/chef/upload_data_bag_test.rb +36 -0
- data/test/acceptance/chef/upload_environment_test.rb +22 -0
- data/test/acceptance/chef/upload_role_test.rb +21 -0
- data/test/acceptance/test_helper.rb +25 -0
- data/test/fixtures/cookbooks/bad/recipes/default.rb +1 -0
- data/test/fixtures/cookbooks/mini/metadata.rb +5 -0
- data/test/fixtures/cookbooks/mini/recipes/default.rb +1 -0
- data/test/fixtures/data_bags/settings/test.json +0 -0
- data/test/fixtures/environments/test.rb +2 -0
- data/test/fixtures/roles/app.rb +2 -0
- data/test/fixtures/roles/app1.rb +2 -0
- data/test/root_dir/applications/pantry/chef/roles/app.rb +2 -0
- data/test/unit/chef/configure_chef_test.rb +64 -0
- data/test/unit/chef/list_cookbooks_test.rb +49 -0
- data/test/unit/chef/run_chef_solo_test.rb +29 -0
- data/test/unit/chef/run_test.rb +5 -0
- data/test/unit/chef/send_cookbooks_test.rb +44 -0
- data/test/unit/chef/sync_cookbooks_test.rb +40 -0
- data/test/unit/chef/sync_data_bags_test.rb +21 -0
- data/test/unit/chef/sync_environments_test.rb +21 -0
- data/test/unit/chef/sync_roles_test.rb +21 -0
- data/test/unit/chef/upload_cookbook_test.rb +132 -0
- data/test/unit/chef/upload_data_bag_test.rb +24 -0
- data/test/unit/chef/upload_environment_test.rb +11 -0
- data/test/unit/chef/upload_role_test.rb +11 -0
- data/test/unit/test_helper.rb +26 -0
- metadata +166 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'pantry/test/acceptance'
|
2
|
+
require 'pantry/chef'
|
3
|
+
|
4
|
+
Pantry.logger.disable!
|
5
|
+
#Pantry.config.log_level = :debug
|
6
|
+
|
7
|
+
class Minitest::Test
|
8
|
+
|
9
|
+
def setup
|
10
|
+
Pantry.config.root_dir = File.expand_path("../../root_dir", __FILE__)
|
11
|
+
clean_up_pantry_root
|
12
|
+
end
|
13
|
+
|
14
|
+
# Ensure Pantry.root is always clean for each test.
|
15
|
+
def clean_up_pantry_root
|
16
|
+
Dir["#{Pantry.root}/**/*"].each do |file|
|
17
|
+
FileUtils.rm_rf file
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def fixture_path(file_path)
|
22
|
+
File.join(File.dirname(__FILE__), "..", "fixtures", file_path)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
# Do nothing
|
@@ -0,0 +1 @@
|
|
1
|
+
# Do nothing
|
File without changes
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'unit/test_helper'
|
2
|
+
|
3
|
+
describe Pantry::Chef::ConfigureChef do
|
4
|
+
|
5
|
+
fake_fs!
|
6
|
+
|
7
|
+
it "creates expected directory structure for chef file storage" do
|
8
|
+
command = Pantry::Chef::ConfigureChef.new
|
9
|
+
command.perform(Pantry::Message.new)
|
10
|
+
|
11
|
+
%w(cache cookbooks environments).each do |dir|
|
12
|
+
assert File.directory?(Pantry.root.join("chef", dir)),
|
13
|
+
"Did not create the chef #{dir} directory"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it "writes out chef/solo.rb pointing chef to the right locations" do
|
18
|
+
command = Pantry::Chef::ConfigureChef.new
|
19
|
+
command.perform(Pantry::Message.new)
|
20
|
+
|
21
|
+
solo_rb = Pantry.root.join("etc", "chef", "solo.rb")
|
22
|
+
assert File.exists?(solo_rb), "Did not write out a solo.rb file"
|
23
|
+
|
24
|
+
solo_contents = File.read(solo_rb)
|
25
|
+
|
26
|
+
assert_match %r|cookbook_path\s*"#{Pantry.root.join("chef", "cookbooks")}|,
|
27
|
+
solo_contents
|
28
|
+
assert_match %r|file_cache_path\s*"#{Pantry.root.join("chef", "cache")}|,
|
29
|
+
solo_contents
|
30
|
+
assert_match %r|role_path\s*"#{Pantry.root.join("chef", "roles")}|,
|
31
|
+
solo_contents
|
32
|
+
assert_match %r|environment_path\s*"#{Pantry.root.join("chef", "environments")}|,
|
33
|
+
solo_contents
|
34
|
+
assert_match %r|json_attribs\s*"#{Pantry.root.join("etc", "chef", "node.json")}"|,
|
35
|
+
solo_contents
|
36
|
+
end
|
37
|
+
|
38
|
+
it "writes out the node.json file with run list based on client roles" do
|
39
|
+
client = Pantry::Client.new(roles: %w(app db))
|
40
|
+
|
41
|
+
command = Pantry::Chef::ConfigureChef.new
|
42
|
+
command.client = client
|
43
|
+
command.perform(Pantry::Message.new)
|
44
|
+
|
45
|
+
node_json = File.read(Pantry.root.join("etc", "chef", "node.json"))
|
46
|
+
|
47
|
+
assert_match "role[app]", node_json
|
48
|
+
assert_match "role[db]", node_json
|
49
|
+
end
|
50
|
+
|
51
|
+
it "writes out the current environment of the Client if one exists" do
|
52
|
+
client = Pantry::Client.new(environment: "staging")
|
53
|
+
|
54
|
+
command = Pantry::Chef::ConfigureChef.new
|
55
|
+
command.client = client
|
56
|
+
command.perform(Pantry::Message.new)
|
57
|
+
|
58
|
+
solo_rb = Pantry.root.join("etc/chef/solo.rb")
|
59
|
+
solo_contents = File.read(solo_rb)
|
60
|
+
|
61
|
+
assert_match %|environment "staging"|, solo_contents
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'unit/test_helper'
|
2
|
+
|
3
|
+
describe Pantry::Chef::ListCookbooks do
|
4
|
+
|
5
|
+
describe "#perform" do
|
6
|
+
fake_fs!
|
7
|
+
|
8
|
+
it "returns the list of cookbooks and latest version known" do
|
9
|
+
cookbooks = [
|
10
|
+
Pantry.root.join("chef", "cookbook-cache", "mini.tgz"),
|
11
|
+
Pantry.root.join("chef", "cookbook-cache", "ruby.tgz"),
|
12
|
+
Pantry.root.join("chef", "cookbook-cache", "pantry.tgz")
|
13
|
+
]
|
14
|
+
|
15
|
+
cookbooks.each do|c|
|
16
|
+
FileUtils.mkdir_p(File.dirname(c))
|
17
|
+
FileUtils.touch(c)
|
18
|
+
end
|
19
|
+
|
20
|
+
Pantry.stubs(:file_checksum).returns("deadbeef")
|
21
|
+
|
22
|
+
command = Pantry::Chef::ListCookbooks.new
|
23
|
+
cookbook_list = command.perform(Pantry::Message.new)
|
24
|
+
|
25
|
+
assert_equal [
|
26
|
+
["mini", 0, "deadbeef"],
|
27
|
+
["pantry", 0, "deadbeef"],
|
28
|
+
["ruby", 0, "deadbeef"]
|
29
|
+
], cookbook_list
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#receive_server_response" do
|
34
|
+
mock_ui!
|
35
|
+
|
36
|
+
it "displays the list alphabetical order" do
|
37
|
+
message = Pantry::Message.new
|
38
|
+
message << ["pantry", 0, "deadbeef"]
|
39
|
+
message << ["ruby", 0, "deadbeef"]
|
40
|
+
message << ["mini", 0, "deadbeef"]
|
41
|
+
|
42
|
+
command = Pantry::Chef::ListCookbooks.new
|
43
|
+
command.receive_server_response(message)
|
44
|
+
|
45
|
+
assert_equal "mini\npantry\nruby\n", stdout
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'unit/test_helper'
|
2
|
+
|
3
|
+
describe Pantry::Chef::RunChefSolo do
|
4
|
+
|
5
|
+
it "executes the chef-solo command, returning outputs" do
|
6
|
+
config_file = Pantry.root.join(*%w(etc chef solo.rb))
|
7
|
+
Open3.expects(:capture3).with("chef-solo --config #{config_file}").
|
8
|
+
returns(["chef ran", "error", 0])
|
9
|
+
|
10
|
+
command = Pantry::Chef::RunChefSolo.new
|
11
|
+
stdout, stderr, status = command.perform(Pantry::Message.new)
|
12
|
+
|
13
|
+
assert_equal "chef ran", stdout
|
14
|
+
assert_equal "error", stderr
|
15
|
+
assert_equal 0, status
|
16
|
+
end
|
17
|
+
|
18
|
+
it "returns error message if chef-solo not found on the system" do
|
19
|
+
Open3.expects(:capture3).raises(Errno::ENOENT, "Can't find LOLZ")
|
20
|
+
|
21
|
+
command = Pantry::Chef::RunChefSolo.new
|
22
|
+
stdout, stderr, status = command.perform(Pantry::Message.new)
|
23
|
+
|
24
|
+
assert_equal "", stdout
|
25
|
+
assert_equal "No such file or directory - Can't find LOLZ", stderr
|
26
|
+
assert_equal 1, status
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'unit/test_helper'
|
2
|
+
|
3
|
+
describe Pantry::Chef::SendCookbooks do
|
4
|
+
|
5
|
+
fake_fs!
|
6
|
+
|
7
|
+
describe "#perform" do
|
8
|
+
|
9
|
+
it "takes the list of receivers and builds senders, passing in the proper cookbook file" do
|
10
|
+
message = Pantry::Message.new
|
11
|
+
message << ["mini", "receiver_ident", "file_uuid"]
|
12
|
+
message << ["pantry", "receiver_ident2", "file_uuid2"]
|
13
|
+
|
14
|
+
cookbooks = [
|
15
|
+
Pantry.root.join("chef", "cookbook-cache", "mini.tgz"),
|
16
|
+
Pantry.root.join("chef", "cookbook-cache", "pantry.tgz")
|
17
|
+
]
|
18
|
+
|
19
|
+
cookbooks.each do|c|
|
20
|
+
FileUtils.mkdir_p(File.dirname(c))
|
21
|
+
FileUtils.touch(c)
|
22
|
+
end
|
23
|
+
|
24
|
+
server = mock
|
25
|
+
server.expects(:send_file).with(
|
26
|
+
Pantry.root.join("chef", "cookbook-cache", "mini.tgz"),
|
27
|
+
"receiver_ident",
|
28
|
+
"file_uuid"
|
29
|
+
)
|
30
|
+
|
31
|
+
server.expects(:send_file).with(
|
32
|
+
Pantry.root.join("chef", "cookbook-cache", "pantry.tgz"),
|
33
|
+
"receiver_ident2",
|
34
|
+
"file_uuid2"
|
35
|
+
)
|
36
|
+
|
37
|
+
command = Pantry::Chef::SendCookbooks.new
|
38
|
+
command.server = server
|
39
|
+
command.perform(message)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'unit/test_helper'
|
2
|
+
|
3
|
+
describe Pantry::Chef::SyncCookbooks do
|
4
|
+
|
5
|
+
describe "#perform" do
|
6
|
+
|
7
|
+
it "requests to the server a list of cookbooks it should have" do
|
8
|
+
client = stub_everything
|
9
|
+
client.expects(:send_request).with do |message|
|
10
|
+
assert_equal "Chef::ListCookbooks", message.type
|
11
|
+
end.returns(mock(:value => Pantry::Message.new))
|
12
|
+
|
13
|
+
command = Pantry::Chef::SyncCookbooks.new
|
14
|
+
command.client = client
|
15
|
+
command.perform(Pantry::Message.new)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "fires off receivers for each cookbook in the list and waits for downloads to finish" do
|
19
|
+
client = stub_everything
|
20
|
+
message = Pantry::Message.new
|
21
|
+
message << ["cookbook1", 0, "checksum1"]
|
22
|
+
|
23
|
+
client.stubs(:send_request).returns(stub(:value => message)).times(2)
|
24
|
+
|
25
|
+
client.expects(:receive_file).with(0, "checksum1").returns(
|
26
|
+
receive_info = Pantry::Communication::FileService::ReceivingFile.new(0, "checksum1", 1, 1)
|
27
|
+
)
|
28
|
+
|
29
|
+
receive_info.expects(:wait_for_finish)
|
30
|
+
|
31
|
+
command = Pantry::Chef::SyncCookbooks.new
|
32
|
+
command.client = client
|
33
|
+
command.perform(Pantry::Message.new)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "deletes cookbooks stored locally not in the list (?)"
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'unit/test_helper'
|
2
|
+
|
3
|
+
describe Pantry::Chef::SyncDataBags do
|
4
|
+
|
5
|
+
it "reads from the server directory for chef" do
|
6
|
+
cmd = Pantry::Chef::SyncDataBags.new
|
7
|
+
cmd.client = Pantry::ClientInfo.new(application: "pantry")
|
8
|
+
|
9
|
+
dir = cmd.server_directory(Pathname.new(""))
|
10
|
+
assert_equal "applications/pantry/chef/data_bags", dir.to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
it "writes to the client's local chef dir" do
|
14
|
+
cmd = Pantry::Chef::SyncDataBags.new
|
15
|
+
|
16
|
+
dir = cmd.client_directory(Pathname.new(""))
|
17
|
+
assert_equal "chef/data_bags", dir.to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'unit/test_helper'
|
2
|
+
|
3
|
+
describe Pantry::Chef::SyncEnvironments do
|
4
|
+
|
5
|
+
it "reads from the server directory for chef" do
|
6
|
+
cmd = Pantry::Chef::SyncEnvironments.new
|
7
|
+
cmd.client = Pantry::ClientInfo.new(application: "pantry")
|
8
|
+
|
9
|
+
dir = cmd.server_directory(Pathname.new(""))
|
10
|
+
assert_equal "applications/pantry/chef/environments", dir.to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
it "writes to the client's local chef dir" do
|
14
|
+
cmd = Pantry::Chef::SyncEnvironments.new
|
15
|
+
|
16
|
+
dir = cmd.client_directory(Pathname.new(""))
|
17
|
+
assert_equal "chef/environments", dir.to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'unit/test_helper'
|
2
|
+
|
3
|
+
describe Pantry::Chef::SyncRoles do
|
4
|
+
|
5
|
+
it "reads from the server directory for chef" do
|
6
|
+
cmd = Pantry::Chef::SyncRoles.new
|
7
|
+
cmd.client = Pantry::ClientInfo.new(application: "pantry")
|
8
|
+
|
9
|
+
dir = cmd.server_directory(Pathname.new(""))
|
10
|
+
assert_equal "applications/pantry/chef/roles", dir.to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
it "writes to the client's local chef dir" do
|
14
|
+
cmd = Pantry::Chef::SyncRoles.new
|
15
|
+
|
16
|
+
dir = cmd.client_directory(Pathname.new(""))
|
17
|
+
assert_equal "chef/roles", dir.to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'unit/test_helper'
|
2
|
+
|
3
|
+
describe Pantry::Chef::UploadCookbook do
|
4
|
+
|
5
|
+
mock_ui!
|
6
|
+
|
7
|
+
def build_command(cookbook_name)
|
8
|
+
@command ||=
|
9
|
+
Pantry::Chef::UploadCookbook.new(fixture_path("cookbooks/#{cookbook_name}"))
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#prepare_message" do
|
13
|
+
|
14
|
+
after do
|
15
|
+
File.unlink(@command.cookbook_tarball) if @command && @command.cookbook_tarball
|
16
|
+
end
|
17
|
+
|
18
|
+
it "figures out name of the requested cookbook" do
|
19
|
+
command = build_command("mini")
|
20
|
+
message = command.prepare_message({})
|
21
|
+
|
22
|
+
assert_not_nil message, "Did not return a message"
|
23
|
+
assert_equal "mini", message[:cookbook_name]
|
24
|
+
end
|
25
|
+
|
26
|
+
it "tars up the cookbook, noting the size and a checksum of the file" do
|
27
|
+
command = build_command("mini")
|
28
|
+
message = command.prepare_message({})
|
29
|
+
|
30
|
+
assert message[:cookbook_size] > 0, "Did not calculate a size of the tarball"
|
31
|
+
assert_not_nil message[:cookbook_checksum], "Did not calculate a checksum"
|
32
|
+
|
33
|
+
assert_not_nil command.cookbook_tarball, "Did not save a pointer to the tarball"
|
34
|
+
assert File.exists?(command.cookbook_tarball), "No tarball found on the file system"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "errors out if no metadata file" do
|
38
|
+
assert_raises Pantry::Chef::MissingMetadata do
|
39
|
+
command = build_command("bad")
|
40
|
+
command.prepare_message({})
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it "errors if it can't find the cookbook" do
|
45
|
+
assert_raises Pantry::Chef::UnknownCookbook do
|
46
|
+
command = build_command("nonexist")
|
47
|
+
command.prepare_message({})
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#perform" do
|
53
|
+
|
54
|
+
let(:incoming_message) do
|
55
|
+
m = command.to_message
|
56
|
+
m[:cookbook_name] = "testing"
|
57
|
+
m[:cookbook_size] = 100
|
58
|
+
m[:cookbook_checksum] = "123abc"
|
59
|
+
m
|
60
|
+
end
|
61
|
+
|
62
|
+
let(:command) { build_command("mini") }
|
63
|
+
|
64
|
+
let(:receiver_info) {
|
65
|
+
stub(
|
66
|
+
:file_uuid => "abc123",
|
67
|
+
:receiver_uuid => "receiver",
|
68
|
+
:on_complete => nil
|
69
|
+
)
|
70
|
+
}
|
71
|
+
|
72
|
+
it "ensures a place exists for the uploaded cookbook to go" do
|
73
|
+
command.server_or_client = stub(:receive_file => receiver_info)
|
74
|
+
response = command.perform(incoming_message)
|
75
|
+
|
76
|
+
assert File.directory?(Pantry.root.join("chef", "cookbooks")),
|
77
|
+
"Did not create directory for the testing cookbook"
|
78
|
+
end
|
79
|
+
|
80
|
+
it "responds successfully and fires off a file upload receiver" do
|
81
|
+
server_mock = mock
|
82
|
+
server_mock.expects(:receive_file).with(100, "123abc").returns(receiver_info)
|
83
|
+
|
84
|
+
command.server_or_client = server_mock
|
85
|
+
|
86
|
+
response = command.perform(incoming_message)
|
87
|
+
|
88
|
+
assert_equal [true, "receiver", "abc123"], response
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "#receive_server_response" do
|
94
|
+
|
95
|
+
let(:command) { build_command("mini") }
|
96
|
+
|
97
|
+
it "triggers a file upload actor with the cookbook tarball and message UUID" do
|
98
|
+
client = mock
|
99
|
+
client.expects(:send_file).with do |file, receiver_uuid|
|
100
|
+
assert File.exists?(file), "Did not find the file"
|
101
|
+
assert_equal "abc123", receiver_uuid
|
102
|
+
end.returns(mock(:wait_for_finish))
|
103
|
+
|
104
|
+
command.server_or_client = client
|
105
|
+
command.prepare_message({})
|
106
|
+
|
107
|
+
response_message = Pantry::Message.new
|
108
|
+
response_message.body << "true"
|
109
|
+
response_message.body << "abc123"
|
110
|
+
|
111
|
+
command.receive_server_response(response_message)
|
112
|
+
end
|
113
|
+
|
114
|
+
it "fails out with a message and cleans up if the server response with an error" do
|
115
|
+
client = mock
|
116
|
+
client.expects(:send_file).never
|
117
|
+
|
118
|
+
command.server_or_client = client
|
119
|
+
command.prepare_message({})
|
120
|
+
|
121
|
+
response_message = Pantry::Message.new
|
122
|
+
response_message << "false"
|
123
|
+
response_message << "Unable to Upload Reason"
|
124
|
+
|
125
|
+
command.receive_server_response(response_message)
|
126
|
+
|
127
|
+
assert_match /ERROR: Unable to Upload Reason/, stdout
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|