Skip to content

Commit 29ffbfc

Browse files
authored
Merge pull request #9257 from cthorn42/maint/main/systemd_resource_not_found_error
Add options for failing resource check on command line
2 parents 57a00cc + 248dbe5 commit 29ffbfc

File tree

8 files changed

+80
-12
lines changed

8 files changed

+80
-12
lines changed

lib/puppet/application/resource.rb

+9-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def preinit
1515
option("--verbose", "-v")
1616
option("--edit", "-e")
1717
option("--to_yaml", "-y")
18+
option('--fail', '-f')
1819

1920
option("--types", "-t") do |_arg|
2021
env = Puppet.lookup(:environments).get(Puppet[:environment]) || create_default_environment
@@ -109,6 +110,9 @@ def help
109110
Output found resources in yaml format, suitable to use with Hiera and
110111
create_resources.
111112
113+
* --fail:
114+
Fails and returns an exit code of 1 if the resource is not found.
115+
112116
EXAMPLE
113117
-------
114118
This example uses `puppet resource` to return a Puppet configuration for
@@ -236,8 +240,11 @@ def find_or_save_resources(type, name, params)
236240
resource = Puppet::Resource.new(type, name, :parameters => params)
237241

238242
# save returns [resource that was saved, transaction log from applying the resource]
239-
save_result = Puppet::Resource.indirection.save(resource, key)
240-
[save_result.first]
243+
save_result, report = Puppet::Resource.indirection.save(resource, key)
244+
status = report.resource_statuses[resource.ref]
245+
raise "Failed to manage resource #{resource.ref}" if status&.failed? && !options[:fail].nil? && options[:fail]
246+
247+
[save_result]
241248
end
242249
else
243250
if type == "file"

lib/puppet/provider/service/systemd.rb

+14
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,20 @@ def daemon_reload?
165165
end
166166
end
167167

168+
# override base#status
169+
def status
170+
if exist?
171+
status = service_command(:status, false)
172+
if status.exitstatus == 0
173+
return :running
174+
else
175+
return :stopped
176+
end
177+
else
178+
return :absent
179+
end
180+
end
181+
168182
def enable
169183
self.unmask
170184
systemctl_change_enable(:enable)

lib/puppet/provider/service/windows.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def stop
9090
end
9191

9292
def status
93-
return :stopped unless Puppet::Util::Windows::Service.exists?(@resource[:name])
93+
return :absent unless Puppet::Util::Windows::Service.exists?(@resource[:name])
9494

9595
current_state = Puppet::Util::Windows::Service.service_state(@resource[:name])
9696
state = case current_state

lib/puppet/type/service.rb

+6
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,12 @@ def insync?(current)
110110
provider.start
111111
end
112112

113+
newvalue(:absent)
114+
115+
validate do |val|
116+
fail "Managing absent on a service is not supported" if val.to_s == 'absent'
117+
end
118+
113119
aliasvalue(:false, :stopped)
114120
aliasvalue(:true, :running)
115121

spec/unit/application/resource_spec.rb

+10-1
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,19 @@
118118
@resource_app.main
119119
end
120120

121+
before :each do
122+
allow(@res).to receive(:ref).and_return("type/name")
123+
end
124+
121125
it "should add given parameters to the object" do
122126
allow(@resource_app.command_line).to receive(:args).and_return(['type','name','param=temp'])
123127

124128
expect(Puppet::Resource.indirection).to receive(:save).with(@res, 'type/name').and_return([@res, @report])
125129
expect(Puppet::Resource).to receive(:new).with('type', 'name', {:parameters => {'param' => 'temp'}}).and_return(@res)
126130

131+
resource_status = instance_double('Puppet::Resource::Status')
132+
allow(@report).to receive(:resource_statuses).and_return({'type/name' => resource_status})
133+
allow(resource_status).to receive(:failed?).and_return(false)
127134
@resource_app.main
128135
end
129136
end
@@ -140,11 +147,13 @@ def exists?
140147
true
141148
end
142149

150+
def string=(value)
151+
end
152+
143153
def string
144154
Puppet::Util::Execution::ProcessOutput.new('test', 0)
145155
end
146156
end
147-
148157
it "should not emit puppet class tags when printing yaml when strict mode is off" do
149158
Puppet[:strict] = :warning
150159

spec/unit/provider/service/systemd_spec.rb

+32-6
Original file line numberDiff line numberDiff line change
@@ -389,26 +389,52 @@
389389
# Note: systemd provider does not care about hasstatus or a custom status
390390
# command. I just assume that it does not make sense for systemd.
391391
describe "#status" do
392-
it "should return running if the command returns 0" do
393-
provider = provider_class.new(Puppet::Type.type(:service).new(:name => 'sshd.service'))
394-
expect(provider).to receive(:execute)
395-
.with(['/bin/systemctl','is-active', '--', 'sshd.service'], {:failonfail => false, :override_locale => false, :squelch => false, :combine => true})
396-
.and_return(Puppet::Util::Execution::ProcessOutput.new("active\n", 0))
392+
it 'when called on a service that does not exist returns absent' do
393+
provider = provider_class.new(Puppet::Type.type(:service).new(:name => 'doesnotexist.service'))
394+
expect(provider).to receive(:exist?).and_return(false)
395+
expect(provider.status).to eq(:absent)
396+
end
397+
398+
it 'when called on a service that does exist and is running returns running' do
399+
provider = provider_class.new(Puppet::Type.type(:service).new(:name => 'doesexist.service'))
400+
expect(provider).to receive(:execute).
401+
with(['/bin/systemctl','cat', '--', 'doesexist.service'], {:failonfail=>false}).
402+
and_return(Puppet::Util::Execution::ProcessOutput.new("# /lib/systemd/system/doesexist.service\n...", 0)).once
403+
expect(provider).to receive(:execute).
404+
with(['/bin/systemctl','is-active', '--', 'doesexist.service'], {:combine=>true, :failonfail=>false, :override_locale=>false, :squelch=>false}).
405+
and_return(Puppet::Util::Execution::ProcessOutput.new("# /lib/systemd/system/doesexist.service\n...", 0)).once
397406
expect(provider.status).to eq(:running)
398407
end
399408

409+
it 'when called on a service that does exist and is not running returns stopped' do
410+
provider = provider_class.new(Puppet::Type.type(:service).new(:name => 'doesexist.service'))
411+
expect(provider).to receive(:execute).
412+
with(['/bin/systemctl','cat', '--', 'doesexist.service'], {:failonfail=>false}).
413+
and_return(Puppet::Util::Execution::ProcessOutput.new("# /lib/systemd/system/doesexist.service\n...", 0)).once
414+
expect(provider).to receive(:execute).
415+
with(['/bin/systemctl','is-active', '--', 'doesexist.service'], {:combine=>true, :failonfail=>false, :override_locale=>false, :squelch=>false}).
416+
and_return(Puppet::Util::Execution::ProcessOutput.new("inactive\n", 3)).once
417+
expect(provider.status).to eq(:stopped)
418+
end
419+
400420
[-10,-1,3,10].each { |ec|
401421
it "should return stopped if the command returns something non-0" do
402422
provider = provider_class.new(Puppet::Type.type(:service).new(:name => 'sshd.service'))
423+
expect(provider).to receive(:execute).
424+
with(['/bin/systemctl','cat', '--', 'sshd.service'], {:failonfail=>false}).
425+
and_return(Puppet::Util::Execution::ProcessOutput.new("# /lib/systemd/system/sshd.service\n...", 0)).once
403426
expect(provider).to receive(:execute)
404-
.with(['/bin/systemctl','is-active', '--', 'sshd.service'], {:failonfail => false, :override_locale => false, :squelch => false, :combine => true})
427+
.with(['/bin/systemctl','is-active', '--', 'sshd.service'], {:failonfail => false, :override_locale => false, :squelch => false, :combine => true})
405428
.and_return(Puppet::Util::Execution::ProcessOutput.new("inactive\n", ec))
406429
expect(provider.status).to eq(:stopped)
407430
end
408431
}
409432

410433
it "should use the supplied status command if specified" do
411434
provider = provider_class.new(Puppet::Type.type(:service).new(:name => 'sshd.service', :status => '/bin/foo'))
435+
expect(provider).to receive(:execute).
436+
with(['/bin/systemctl','cat', '--', 'sshd.service'], {:failonfail=>false}).
437+
and_return(Puppet::Util::Execution::ProcessOutput.new("# /lib/systemd/system/sshd.service\n...", 0)).once
412438
expect(provider).to receive(:execute)
413439
.with(['/bin/foo'], {:failonfail => false, :override_locale => false, :squelch => false, :combine => true})
414440
.and_return(process_output)

spec/unit/provider/service/windows_spec.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,10 @@
8181
end
8282

8383
describe "#status" do
84-
it "should report a nonexistent service as stopped" do
84+
it "should report a nonexistent service as absent" do
8585
allow(service_util).to receive(:exists?).with(resource[:name]).and_return(false)
8686

87-
expect(provider.status).to eql(:stopped)
87+
expect(provider.status).to eql(:absent)
8888
end
8989

9090
it "should report service as stopped when status cannot be retrieved" do

spec/unit/type/service_spec.rb

+6
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ def safely_load_service_type
6767
expect(svc.should(:ensure)).to eq(:stopped)
6868
end
6969

70+
describe 'the absent property' do
71+
it 'should fail validate if it is a service' do
72+
expect { Puppet::Type.type(:service).new(:name => "service_name", :ensure => :absent) }.to raise_error(Puppet::Error, /Managing absent on a service is not supported/)
73+
end
74+
end
75+
7076
describe "the enable property" do
7177
before :each do
7278
allow(@provider.class).to receive(:supports_parameter?).and_return(true)

0 commit comments

Comments
 (0)