pantry-chef 0.1
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.
- 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
|