chef 12.2.1-x86-mingw32 → 12.3.0.rc.0-x86-mingw32
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 +4 -4
- data/ext/win32-eventlog/Rakefile +10 -6
- data/lib/chef.rb +1 -0
- data/lib/chef/application/apply.rb +5 -0
- data/lib/chef/application/client.rb +10 -0
- data/lib/chef/application/knife.rb +5 -1
- data/lib/chef/application/solo.rb +5 -0
- data/lib/chef/chef_class.rb +130 -0
- data/lib/chef/client.rb +15 -7
- data/lib/chef/config.rb +13 -0
- data/lib/chef/event_loggers/windows_eventlog.rb +11 -5
- data/lib/chef/http.rb +13 -3
- data/lib/chef/http/basic_client.rb +21 -4
- data/lib/chef/http/socketless_chef_zero_client.rb +207 -0
- data/lib/chef/knife.rb +3 -0
- data/lib/chef/knife/bootstrap.rb +1 -1
- data/lib/chef/knife/core/status_presenter.rb +12 -11
- data/lib/chef/knife/ssh.rb +3 -1
- data/lib/chef/knife/status.rb +32 -7
- data/lib/chef/local_mode.rb +13 -3
- data/lib/chef/mixin/provides.rb +32 -0
- data/lib/chef/platform/provider_priority_map.rb +16 -7
- data/lib/chef/platform/resource_priority_map.rb +37 -0
- data/lib/chef/policy_builder/expand_node_object.rb +14 -0
- data/lib/chef/policy_builder/policyfile.rb +0 -1
- data/lib/chef/provider.rb +5 -20
- data/lib/chef/provider/package/rubygems.rb +4 -1
- data/lib/chef/provider/service/macosx.rb +66 -30
- data/lib/chef/provider_resolver.rb +10 -5
- data/lib/chef/resource.rb +5 -39
- data/lib/chef/resource/gem_package.rb +5 -0
- data/lib/chef/resource/link.rb +1 -1
- data/lib/chef/resource/macosx_service.rb +59 -0
- data/lib/chef/resource/remote_file.rb +0 -4
- data/lib/chef/resource_resolver.rb +101 -0
- data/lib/chef/rest.rb +4 -5
- data/lib/chef/search/query.rb +1 -1
- data/lib/chef/server_api.rb +1 -0
- data/lib/chef/version.rb +1 -1
- data/spec/data/lwrp/providers/buck_passer.rb +2 -1
- data/spec/data/lwrp/resources/bar.rb +1 -1
- data/spec/data/{big_json.json → nested.json} +2 -2
- data/spec/functional/event_loggers/windows_eventlog_spec.rb +14 -0
- data/spec/functional/resource/execute_spec.rb +1 -1
- data/spec/integration/client/client_spec.rb +12 -1
- data/spec/integration/client/ipv6_spec.rb +1 -1
- data/spec/integration/knife/common_options_spec.rb +3 -3
- data/spec/integration/recipes/lwrp_inline_resources_spec.rb +1 -1
- data/spec/integration/solo/solo_spec.rb +7 -5
- data/spec/unit/application/client_spec.rb +10 -0
- data/spec/unit/chef_class_spec.rb +91 -0
- data/spec/unit/client_spec.rb +13 -0
- data/spec/unit/http/basic_client_spec.rb +43 -6
- data/spec/unit/http/socketless_chef_zero_client_spec.rb +174 -0
- data/spec/unit/http_spec.rb +14 -0
- data/spec/unit/json_compat_spec.rb +7 -20
- data/spec/unit/knife/ssh_spec.rb +18 -0
- data/spec/unit/knife/status_spec.rb +69 -3
- data/spec/unit/knife_spec.rb +5 -0
- data/spec/unit/provider/package/rubygems_spec.rb +19 -0
- data/spec/unit/provider/service/macosx_spec.rb +230 -203
- data/spec/unit/provider_resolver_spec.rb +1 -0
- data/spec/unit/recipe_spec.rb +48 -0
- data/spec/unit/resource/link_spec.rb +15 -0
- data/spec/unit/resource_spec.rb +6 -6
- data/spec/unit/rest_spec.rb +9 -0
- data/spec/unit/search/query_spec.rb +24 -0
- data/spec/unit/shell_spec.rb +3 -1
- metadata +16 -9
- data/spec/data/big_json_plus_one.json +0 -2
data/spec/unit/http_spec.rb
CHANGED
@@ -20,6 +20,7 @@ require 'spec_helper'
|
|
20
20
|
|
21
21
|
require 'chef/http'
|
22
22
|
require 'chef/http/basic_client'
|
23
|
+
require 'chef/http/socketless_chef_zero_client'
|
23
24
|
|
24
25
|
class Chef::HTTP
|
25
26
|
public :create_url
|
@@ -27,6 +28,19 @@ end
|
|
27
28
|
|
28
29
|
describe Chef::HTTP do
|
29
30
|
|
31
|
+
context "when given a chefzero:// URL" do
|
32
|
+
|
33
|
+
let(:uri) { URI("chefzero://localhost:1") }
|
34
|
+
|
35
|
+
subject(:http) { Chef::HTTP.new(uri) }
|
36
|
+
|
37
|
+
it "uses the SocketlessChefZeroClient to handle requests" do
|
38
|
+
expect(http.http_client).to be_a_kind_of(Chef::HTTP::SocketlessChefZeroClient)
|
39
|
+
expect(http.http_client.url).to eq(uri)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
30
44
|
describe "create_url" do
|
31
45
|
|
32
46
|
it 'should return a correctly formatted url 1/3 CHEF-5261' do
|
@@ -72,32 +72,19 @@ describe Chef::JSONCompat do
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
-
|
76
|
-
|
75
|
+
# On FreeBSD 10.1 i386 rspec fails with a SystemStackError loading the expect line with more that 252 entries
|
76
|
+
# https://github.com/chef/chef/issues/3101
|
77
|
+
describe "with the file with 252 or less nested entries" do
|
78
|
+
let(:json) { IO.read(File.join(CHEF_SPEC_DATA, 'nested.json')) }
|
77
79
|
let(:hash) { Chef::JSONCompat.from_json(json) }
|
78
80
|
|
79
|
-
describe "when
|
81
|
+
describe "when the 252 json file is loaded" do
|
80
82
|
it "should create a Hash from the file" do
|
81
83
|
expect(hash).to be_kind_of(Hash)
|
82
84
|
end
|
83
85
|
|
84
|
-
it "should has 'test' as a
|
85
|
-
expect(hash['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
describe "with a file with more than 300 nested entries" do
|
91
|
-
let(:json) { IO.read(File.join(CHEF_SPEC_DATA, 'big_json_plus_one.json')) }
|
92
|
-
let(:hash) { Chef::JSONCompat.from_json(json, {:max_nesting => 301}) }
|
93
|
-
|
94
|
-
describe "when a big json file is loaded" do
|
95
|
-
it "should create a Hash from the file" do
|
96
|
-
expect(hash).to be_kind_of(Hash)
|
97
|
-
end
|
98
|
-
|
99
|
-
it "should has 'test' as a 301st nested value" do
|
100
|
-
expect(hash['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']).to eq('test')
|
86
|
+
it "should has 'test' as a 252 nested value" do
|
87
|
+
expect(hash['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']['key']).to eq('test')
|
101
88
|
end
|
102
89
|
end
|
103
90
|
end
|
data/spec/unit/knife/ssh_spec.rb
CHANGED
@@ -96,6 +96,24 @@ describe Chef::Knife::Ssh do
|
|
96
96
|
should_return_specified_attributes
|
97
97
|
end
|
98
98
|
|
99
|
+
context "when cloud hostnames are available but empty" do
|
100
|
+
before do
|
101
|
+
@node_foo.automatic_attrs[:cloud][:public_hostname] = ''
|
102
|
+
@node_bar.automatic_attrs[:cloud][:public_hostname] = ''
|
103
|
+
end
|
104
|
+
|
105
|
+
it "returns an array of fqdns" do
|
106
|
+
configure_query([@node_foo, @node_bar])
|
107
|
+
expect(@knife).to receive(:session_from_list).with([
|
108
|
+
['foo.example.org', nil],
|
109
|
+
['bar.example.org', nil]
|
110
|
+
])
|
111
|
+
@knife.configure_session
|
112
|
+
end
|
113
|
+
|
114
|
+
should_return_specified_attributes
|
115
|
+
end
|
116
|
+
|
99
117
|
it "should raise an error if no host are found" do
|
100
118
|
configure_query([ ])
|
101
119
|
expect(@knife.ui).to receive(:fatal)
|
@@ -24,15 +24,81 @@ describe Chef::Knife::Status do
|
|
24
24
|
n.automatic_attrs["fqdn"] = "foobar"
|
25
25
|
n.automatic_attrs["ohai_time"] = 1343845969
|
26
26
|
end
|
27
|
-
|
28
|
-
|
29
|
-
allow(
|
27
|
+
allow(Time).to receive(:now).and_return(Time.at(1428573420))
|
28
|
+
@query = double("Chef::Search::Query")
|
29
|
+
allow(@query).to receive(:search).and_yield(node)
|
30
|
+
allow(Chef::Search::Query).to receive(:new).and_return(@query)
|
30
31
|
@knife = Chef::Knife::Status.new
|
31
32
|
@stdout = StringIO.new
|
32
33
|
allow(@knife.ui).to receive(:stdout).and_return(@stdout)
|
33
34
|
end
|
34
35
|
|
35
36
|
describe "run" do
|
37
|
+
let(:opts) {{filter_result:
|
38
|
+
{ name: ["name"], ipaddress: ["ipaddress"], ohai_time: ["ohai_time"],
|
39
|
+
ec2: ["ec2"], run_list: ["run_list"], platform: ["platform"],
|
40
|
+
platform_version: ["platform_version"], chef_environment: ["chef_environment"]}}}
|
41
|
+
|
42
|
+
it "should default to searching for everything" do
|
43
|
+
expect(@query).to receive(:search).with(:node, "*:*", opts)
|
44
|
+
@knife.run
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should filter healthy nodes" do
|
48
|
+
@knife.config[:hide_healthy] = true
|
49
|
+
expect(@query).to receive(:search).with(:node, "NOT ohai_time:[1428569820 TO 1428573420]", opts)
|
50
|
+
@knife.run
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should filter by environment" do
|
54
|
+
@knife.config[:environment] = "production"
|
55
|
+
expect(@query).to receive(:search).with(:node, "chef_environment:production", opts)
|
56
|
+
@knife.run
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should filter by environment and health" do
|
60
|
+
@knife.config[:environment] = "production"
|
61
|
+
@knife.config[:hide_healthy] = true
|
62
|
+
expect(@query).to receive(:search).with(:node, "chef_environment:production NOT ohai_time:[1428569820 TO 1428573420]", opts)
|
63
|
+
@knife.run
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should not use partial search with long output" do
|
67
|
+
@knife.config[:long_output] = true
|
68
|
+
expect(@query).to receive(:search).with(:node, "*:*", {})
|
69
|
+
@knife.run
|
70
|
+
end
|
71
|
+
|
72
|
+
context "with a custom query" do
|
73
|
+
before :each do
|
74
|
+
@knife.instance_variable_set(:@name_args, ["name:my_custom_name"])
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should allow a custom query to be specified" do
|
78
|
+
expect(@query).to receive(:search).with(:node, "name:my_custom_name", opts)
|
79
|
+
@knife.run
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should filter healthy nodes" do
|
83
|
+
@knife.config[:hide_healthy] = true
|
84
|
+
expect(@query).to receive(:search).with(:node, "name:my_custom_name NOT ohai_time:[1428569820 TO 1428573420]", opts)
|
85
|
+
@knife.run
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should filter by environment" do
|
89
|
+
@knife.config[:environment] = "production"
|
90
|
+
expect(@query).to receive(:search).with(:node, "name:my_custom_name AND chef_environment:production", opts)
|
91
|
+
@knife.run
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should filter by environment and health" do
|
95
|
+
@knife.config[:environment] = "production"
|
96
|
+
@knife.config[:hide_healthy] = true
|
97
|
+
expect(@query).to receive(:search).with(:node, "name:my_custom_name AND chef_environment:production NOT ohai_time:[1428569820 TO 1428573420]", opts)
|
98
|
+
@knife.run
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
36
102
|
it "should not colorize output unless it's writing to a tty" do
|
37
103
|
@knife.run
|
38
104
|
expect(@stdout.string.match(/foobar/)).not_to be_nil
|
data/spec/unit/knife_spec.rb
CHANGED
@@ -271,6 +271,11 @@ describe Chef::Knife do
|
|
271
271
|
expect(knife_command.config[:opt_with_default]).to eq("from-cli")
|
272
272
|
end
|
273
273
|
|
274
|
+
it "merges `listen` config to Chef::Config" do
|
275
|
+
Chef::Knife.run(%w[test yourself --no-listen], Chef::Application::Knife.options)
|
276
|
+
expect(Chef::Config[:listen]).to be(false)
|
277
|
+
end
|
278
|
+
|
274
279
|
context "verbosity is greater than zero" do
|
275
280
|
let(:fake_config) { "/does/not/exist/knife.rb" }
|
276
281
|
|
@@ -547,6 +547,25 @@ describe Chef::Provider::Package::Rubygems do
|
|
547
547
|
expect(@new_resource).to be_updated_by_last_action
|
548
548
|
end
|
549
549
|
|
550
|
+
it "installs the gem with rubygems.org as an added source" do
|
551
|
+
@new_resource.gem_binary('/foo/bar')
|
552
|
+
@new_resource.source('http://mirror.ops.rhcloud.com/mirror/ruby')
|
553
|
+
expected ="/foo/bar install rspec-core -q --no-rdoc --no-ri -v \"#{@spec_version}\" --source=#{@new_resource.source} --source=https://rubygems.org"
|
554
|
+
expect(@provider).to receive(:shell_out!).with(expected, :env => nil)
|
555
|
+
@provider.run_action(:install)
|
556
|
+
expect(@new_resource).to be_updated_by_last_action
|
557
|
+
end
|
558
|
+
|
559
|
+
it "installs the gem with cleared sources and explict source when specified" do
|
560
|
+
@new_resource.gem_binary('/foo/bar')
|
561
|
+
@new_resource.source('http://mirror.ops.rhcloud.com/mirror/ruby')
|
562
|
+
@new_resource.clear_sources(true)
|
563
|
+
expected ="/foo/bar install rspec-core -q --no-rdoc --no-ri -v \"#{@spec_version}\" --clear-sources --source=#{@new_resource.source}"
|
564
|
+
expect(@provider).to receive(:shell_out!).with(expected, :env => nil)
|
565
|
+
@provider.run_action(:install)
|
566
|
+
expect(@new_resource).to be_updated_by_last_action
|
567
|
+
end
|
568
|
+
|
550
569
|
context "when no version is given" do
|
551
570
|
let(:target_version) { nil }
|
552
571
|
|
@@ -58,248 +58,275 @@ describe Chef::Provider::Service::Macosx do
|
|
58
58
|
</plist>
|
59
59
|
XML
|
60
60
|
|
61
|
-
["
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
allow(provider).to receive(:shell_out!).
|
73
|
-
with(/plutil -convert xml1 -o/).
|
74
|
-
and_return(double("Status", :stdout => plutil_stdout))
|
75
|
-
|
76
|
-
allow(File).to receive(:stat).and_return(double("stat", :gid => 1001, :uid => 101))
|
77
|
-
end
|
78
|
-
|
79
|
-
context "#{service_name}" do
|
80
|
-
let(:new_resource) { Chef::Resource::Service.new(service_name) }
|
81
|
-
let!(:current_resource) { Chef::Resource::Service.new(service_name) }
|
82
|
-
|
83
|
-
describe "#load_current_resource" do
|
84
|
-
|
85
|
-
# CHEF-5223 "you can't glob for a file that hasn't been converged
|
86
|
-
# onto the node yet."
|
87
|
-
context "when the plist doesn't exist" do
|
88
|
-
|
89
|
-
def run_resource_setup_for_action(action)
|
90
|
-
new_resource.action(action)
|
91
|
-
provider.action = action
|
92
|
-
provider.load_current_resource
|
93
|
-
provider.define_resource_requirements
|
94
|
-
provider.process_resource_requirements
|
95
|
-
end
|
96
|
-
|
97
|
-
before do
|
98
|
-
allow(Dir).to receive(:glob).and_return([])
|
99
|
-
allow(provider).to receive(:shell_out!).
|
100
|
-
with(/plutil -convert xml1 -o/).
|
101
|
-
and_raise(Mixlib::ShellOut::ShellCommandFailed)
|
102
|
-
end
|
103
|
-
|
104
|
-
it "works for action :nothing" do
|
105
|
-
expect { run_resource_setup_for_action(:nothing) }.not_to raise_error
|
106
|
-
end
|
107
|
-
|
108
|
-
it "works for action :start" do
|
109
|
-
expect { run_resource_setup_for_action(:start) }.not_to raise_error
|
110
|
-
end
|
111
|
-
|
112
|
-
it "errors if action is :enable" do
|
113
|
-
expect { run_resource_setup_for_action(:enable) }.to raise_error(Chef::Exceptions::Service)
|
114
|
-
end
|
115
|
-
|
116
|
-
it "errors if action is :disable" do
|
117
|
-
expect { run_resource_setup_for_action(:disable) }.to raise_error(Chef::Exceptions::Service)
|
61
|
+
["Daemon", "Agent"].each do |service_type|
|
62
|
+
["redis-server", "io.redis.redis-server"].each do |service_name|
|
63
|
+
["10.9", "10.10"].each do |platform_version|
|
64
|
+
let(:plist) {'/Library/LaunchDaemons/io.redis.redis-server.plist'}
|
65
|
+
let(:session) { StringIO.new }
|
66
|
+
if service_type == 'Agent'
|
67
|
+
let(:plist) {'/Library/LaunchAgents/io.redis.redis-server.plist'}
|
68
|
+
let(:session) {'-S Aqua '}
|
69
|
+
let(:su_cmd) {'su igor -c'}
|
70
|
+
if platform_version != "10.10"
|
71
|
+
let(:su_cmd) {'su -l igor -c'}
|
118
72
|
end
|
119
73
|
end
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
end
|
135
|
-
|
136
|
-
it "sets resouce enabled state to true" do
|
137
|
-
expect(provider.current_resource.enabled).to be_truthy
|
138
|
-
end
|
74
|
+
let(:service_label) {'io.redis.redis-server'}
|
75
|
+
before do
|
76
|
+
allow(Dir).to receive(:glob).and_return([plist], [])
|
77
|
+
allow(Etc).to receive(:getlogin).and_return('igor')
|
78
|
+
allow(node).to receive(:[]).with("platform_version").and_return(platform_version)
|
79
|
+
cmd = "launchctl list #{service_label}"
|
80
|
+
allow(provider).to receive(:shell_out_with_systems_locale).
|
81
|
+
with(/(#{su_cmd} '#{cmd}'|#{cmd})/).
|
82
|
+
and_return(double("Status",
|
83
|
+
:stdout => launchctl_stdout, :exitstatus => 0))
|
84
|
+
allow(File).to receive(:exists?).and_return([true], [])
|
85
|
+
allow(provider).to receive(:shell_out_with_systems_locale!).
|
86
|
+
with(/plutil -convert xml1 -o/).
|
87
|
+
and_return(double("Status", :stdout => plutil_stdout))
|
139
88
|
end
|
140
89
|
|
141
|
-
|
142
|
-
let(:
|
143
|
-
|
144
|
-
|
145
|
-
|
90
|
+
context "#{service_name} that is a #{service_type} running Osx #{platform_version}" do
|
91
|
+
let(:new_resource) { Chef::Resource::MacosxService.new(service_name) }
|
92
|
+
let!(:current_resource) { Chef::Resource::MacosxService.new(service_name) }
|
93
|
+
|
94
|
+
describe "#load_current_resource" do
|
95
|
+
|
96
|
+
# CHEF-5223 "you can't glob for a file that hasn't been converged
|
97
|
+
# onto the node yet."
|
98
|
+
context "when the plist doesn't exist" do
|
99
|
+
|
100
|
+
def run_resource_setup_for_action(action)
|
101
|
+
new_resource.action(action)
|
102
|
+
provider.action = action
|
103
|
+
provider.load_current_resource
|
104
|
+
provider.define_resource_requirements
|
105
|
+
provider.process_resource_requirements
|
106
|
+
end
|
107
|
+
|
108
|
+
before do
|
109
|
+
allow(Dir).to receive(:glob).and_return([])
|
110
|
+
allow(File).to receive(:exists?).and_return([true], [])
|
111
|
+
allow(provider).to receive(:shell_out!).
|
112
|
+
with(/plutil -convert xml1 -o/).
|
113
|
+
and_raise(Mixlib::ShellOut::ShellCommandFailed)
|
114
|
+
end
|
115
|
+
|
116
|
+
it "works for action :nothing" do
|
117
|
+
expect { run_resource_setup_for_action(:nothing) }.not_to raise_error
|
118
|
+
end
|
119
|
+
|
120
|
+
it "works for action :start" do
|
121
|
+
expect { run_resource_setup_for_action(:start) }.not_to raise_error
|
122
|
+
end
|
123
|
+
|
124
|
+
it "errors if action is :enable" do
|
125
|
+
expect { run_resource_setup_for_action(:enable) }.to raise_error(Chef::Exceptions::Service)
|
126
|
+
end
|
127
|
+
|
128
|
+
it "errors if action is :disable" do
|
129
|
+
expect { run_resource_setup_for_action(:disable) }.to raise_error(Chef::Exceptions::Service)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context "when launchctl returns pid in service list" do
|
134
|
+
let(:launchctl_stdout) { StringIO.new <<-SVC_LIST }
|
135
|
+
{
|
136
|
+
"LimitLoadToSessionType" = "System";
|
137
|
+
"Label" = "io.redis.redis-server";
|
138
|
+
"TimeOut" = 30;
|
139
|
+
"OnDemand" = false;
|
140
|
+
"LastExitStatus" = 0;
|
141
|
+
"PID" = 62803;
|
142
|
+
"Program" = "do_some.sh";
|
143
|
+
"ProgramArguments" = (
|
144
|
+
"path/to/do_something.sh";
|
145
|
+
"-f";
|
146
|
+
);
|
147
|
+
};
|
146
148
|
SVC_LIST
|
147
149
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
it "should throw an exception when reload action is attempted" do
|
152
|
-
expect {provider.run_action(:reload)}.to raise_error(Chef::Exceptions::UnsupportedAction)
|
153
|
-
end
|
154
|
-
end
|
155
|
-
context "when launchctl returns empty service pid" do
|
156
|
-
let(:launchctl_stdout) { StringIO.new <<-SVC_LIST }
|
157
|
-
12761 - 0x100114220.old.machinit.thing
|
158
|
-
- - io.redis.redis-server
|
159
|
-
- - com.lol.stopped-thing
|
160
|
-
SVC_LIST
|
161
|
-
|
162
|
-
before do
|
163
|
-
provider.load_current_resource
|
164
|
-
end
|
150
|
+
before do
|
151
|
+
provider.load_current_resource
|
152
|
+
end
|
165
153
|
|
166
|
-
|
167
|
-
|
168
|
-
|
154
|
+
it "sets resource running state to true" do
|
155
|
+
expect(provider.current_resource.running).to be_truthy
|
156
|
+
end
|
169
157
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
158
|
+
it "sets resouce enabled state to true" do
|
159
|
+
expect(provider.current_resource.enabled).to be_truthy
|
160
|
+
end
|
161
|
+
end
|
174
162
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
163
|
+
describe "running unsupported actions" do
|
164
|
+
before do
|
165
|
+
allow(Dir).to receive(:glob).and_return(["#{plist}"], [])
|
166
|
+
allow(File).to receive(:exists?).and_return([true], [])
|
167
|
+
end
|
168
|
+
it "should throw an exception when reload action is attempted" do
|
169
|
+
expect {provider.run_action(:reload)}.to raise_error(Chef::Exceptions::UnsupportedAction)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
context "when launchctl returns empty service pid" do
|
173
|
+
let(:launchctl_stdout) { StringIO.new <<-SVC_LIST }
|
174
|
+
{
|
175
|
+
"LimitLoadToSessionType" = "System";
|
176
|
+
"Label" = "io.redis.redis-server";
|
177
|
+
"TimeOut" = 30;
|
178
|
+
"OnDemand" = false;
|
179
|
+
"LastExitStatus" = 0;
|
180
|
+
"Program" = "do_some.sh";
|
181
|
+
"ProgramArguments" = (
|
182
|
+
"path/to/do_something.sh";
|
183
|
+
"-f";
|
184
|
+
);
|
185
|
+
};
|
186
|
+
SVC_LIST
|
180
187
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
end
|
188
|
+
before do
|
189
|
+
provider.load_current_resource
|
190
|
+
end
|
185
191
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
provider.load_current_resource
|
190
|
-
end
|
192
|
+
it "sets resource running state to false" do
|
193
|
+
expect(provider.current_resource.running).to be_falsey
|
194
|
+
end
|
191
195
|
|
192
|
-
|
193
|
-
|
196
|
+
it "sets resouce enabled state to true" do
|
197
|
+
expect(provider.current_resource.enabled).to be_truthy
|
198
|
+
end
|
194
199
|
end
|
195
|
-
end
|
196
200
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
end
|
201
|
+
context "when launchctl doesn't return service entry at all" do
|
202
|
+
let(:launchctl_stdout) { StringIO.new <<-SVC_LIST }
|
203
|
+
Could not find service "io.redis.redis-server" in domain for system
|
204
|
+
SVC_LIST
|
202
205
|
|
203
|
-
|
204
|
-
|
206
|
+
it "sets service running state to false" do
|
207
|
+
provider.load_current_resource
|
208
|
+
expect(provider.current_resource.running).to be_falsey
|
209
|
+
end
|
210
|
+
|
211
|
+
context "and plist for service is not available" do
|
212
|
+
before do
|
213
|
+
allow(Dir).to receive(:glob).and_return([])
|
214
|
+
provider.load_current_resource
|
215
|
+
end
|
216
|
+
|
217
|
+
it "sets resouce enabled state to false" do
|
218
|
+
expect(provider.current_resource.enabled).to be_falsey
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
context "and plist for service is available" do
|
223
|
+
before do
|
224
|
+
allow(Dir).to receive(:glob).and_return(["#{plist}"], [])
|
225
|
+
provider.load_current_resource
|
226
|
+
end
|
227
|
+
|
228
|
+
it "sets resouce enabled state to true" do
|
229
|
+
expect(provider.current_resource.enabled).to be_truthy
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
describe "and several plists match service name" do
|
234
|
+
it "throws exception" do
|
235
|
+
allow(Dir).to receive(:glob).and_return(["#{plist}",
|
236
|
+
"/Users/wtf/something.plist"])
|
237
|
+
provider.load_current_resource
|
238
|
+
provider.define_resource_requirements
|
239
|
+
expect { provider.process_resource_requirements }.to raise_error(Chef::Exceptions::Service)
|
240
|
+
end
|
241
|
+
end
|
205
242
|
end
|
206
243
|
end
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
allow(Dir).to receive(:glob).and_return(["/Users/igor/Library/LaunchAgents/io.redis.redis-server.plist",
|
211
|
-
"/Users/wtf/something.plist"])
|
244
|
+
describe "#start_service" do
|
245
|
+
before do
|
246
|
+
allow(Chef::Resource::MacosxService).to receive(:new).and_return(current_resource)
|
212
247
|
provider.load_current_resource
|
213
|
-
|
214
|
-
expect { provider.process_resource_requirements }.to raise_error(Chef::Exceptions::Service)
|
248
|
+
allow(current_resource).to receive(:running).and_return(false)
|
215
249
|
end
|
216
|
-
end
|
217
|
-
end
|
218
|
-
end
|
219
|
-
describe "#start_service" do
|
220
|
-
before do
|
221
|
-
allow(Chef::Resource::Service).to receive(:new).and_return(current_resource)
|
222
|
-
provider.load_current_resource
|
223
|
-
allow(current_resource).to receive(:running).and_return(false)
|
224
|
-
end
|
225
250
|
|
226
|
-
|
227
|
-
|
251
|
+
it "calls the start command if one is specified and service is not running" do
|
252
|
+
allow(new_resource).to receive(:start_command).and_return("cowsay dirty")
|
228
253
|
|
229
|
-
|
230
|
-
|
231
|
-
|
254
|
+
expect(provider).to receive(:shell_out_with_systems_locale!).with("cowsay dirty")
|
255
|
+
provider.start_service
|
256
|
+
end
|
232
257
|
|
233
|
-
|
234
|
-
|
235
|
-
|
258
|
+
it "shows warning message if service is already running" do
|
259
|
+
allow(current_resource).to receive(:running).and_return(true)
|
260
|
+
expect(Chef::Log).to receive(:debug).with("macosx_service[#{service_name}] already running, not starting")
|
236
261
|
|
237
|
-
|
238
|
-
|
262
|
+
provider.start_service
|
263
|
+
end
|
239
264
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
265
|
+
it "starts service via launchctl if service found" do
|
266
|
+
cmd = 'launchctl load -w ' + session + plist
|
267
|
+
expect(provider).to receive(:shell_out_with_systems_locale).
|
268
|
+
with(/(#{su_cmd} .#{cmd}.|#{cmd})/).
|
269
|
+
and_return(0)
|
245
270
|
|
246
|
-
|
247
|
-
|
248
|
-
|
271
|
+
provider.start_service
|
272
|
+
end
|
273
|
+
end
|
249
274
|
|
250
|
-
|
251
|
-
|
252
|
-
|
275
|
+
describe "#stop_service" do
|
276
|
+
before do
|
277
|
+
allow(Chef::Resource::MacosxService).to receive(:new).and_return(current_resource)
|
253
278
|
|
254
|
-
|
255
|
-
|
256
|
-
|
279
|
+
provider.load_current_resource
|
280
|
+
allow(current_resource).to receive(:running).and_return(true)
|
281
|
+
end
|
257
282
|
|
258
|
-
|
259
|
-
|
283
|
+
it "calls the stop command if one is specified and service is running" do
|
284
|
+
allow(new_resource).to receive(:stop_command).and_return("kill -9 123")
|
260
285
|
|
261
|
-
|
262
|
-
|
263
|
-
|
286
|
+
expect(provider).to receive(:shell_out_with_systems_locale!).with("kill -9 123")
|
287
|
+
provider.stop_service
|
288
|
+
end
|
264
289
|
|
265
|
-
|
266
|
-
|
267
|
-
|
290
|
+
it "shows warning message if service is not running" do
|
291
|
+
allow(current_resource).to receive(:running).and_return(false)
|
292
|
+
expect(Chef::Log).to receive(:debug).with("macosx_service[#{service_name}] not running, not stopping")
|
268
293
|
|
269
|
-
|
270
|
-
|
294
|
+
provider.stop_service
|
295
|
+
end
|
271
296
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
297
|
+
it "stops the service via launchctl if service found" do
|
298
|
+
cmd = 'launchctl unload -w '+ plist
|
299
|
+
expect(provider).to receive(:shell_out_with_systems_locale).
|
300
|
+
with(/(#{su_cmd} .#{cmd}.|#{cmd})/).
|
301
|
+
and_return(0)
|
277
302
|
|
278
|
-
|
279
|
-
|
280
|
-
|
303
|
+
provider.stop_service
|
304
|
+
end
|
305
|
+
end
|
281
306
|
|
282
|
-
|
283
|
-
|
284
|
-
|
307
|
+
describe "#restart_service" do
|
308
|
+
before do
|
309
|
+
allow(Chef::Resource::Service).to receive(:new).and_return(current_resource)
|
285
310
|
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
311
|
+
provider.load_current_resource
|
312
|
+
allow(current_resource).to receive(:running).and_return(true)
|
313
|
+
allow(provider).to receive(:sleep)
|
314
|
+
end
|
290
315
|
|
291
|
-
|
292
|
-
|
316
|
+
it "issues a command if given" do
|
317
|
+
allow(new_resource).to receive(:restart_command).and_return("reload that thing")
|
293
318
|
|
294
|
-
|
295
|
-
|
296
|
-
|
319
|
+
expect(provider).to receive(:shell_out_with_systems_locale!).with("reload that thing")
|
320
|
+
provider.restart_service
|
321
|
+
end
|
297
322
|
|
298
|
-
|
299
|
-
|
300
|
-
|
323
|
+
it "stops and then starts service" do
|
324
|
+
expect(provider).to receive(:unload_service)
|
325
|
+
expect(provider).to receive(:load_service);
|
301
326
|
|
302
|
-
|
327
|
+
provider.restart_service
|
328
|
+
end
|
329
|
+
end
|
303
330
|
end
|
304
331
|
end
|
305
332
|
end
|