Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(PUP-10102) fix service crash #7794

Merged
merged 2 commits into from
Nov 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions lib/puppet/provider/service/daemontools.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,8 @@ class << self

# Determine the daemon path.
def defpath
unless @defpath
["/var/lib/service", "/etc"].each do |path|
if Puppet::FileSystem.exist?(path)
@defpath = path
break
end
end
raise "Could not find the daemon directory (tested [/var/lib/service,/etc])" unless @defpath
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally we could confine the provider based on the existence on one of the daemon directories, so that the framework never calls the unsuitable provider. Something like:

confine :exists => defpath

And then change defpath to:

def self.defpath
  ["/var/lib/service", "/etc"].find do |path|
    Puppet::FileSystem.exist?(path) && FileTest.directory?(path)
  end
end

If we can't confine based on those directories (see the init provider's comment), then I think we should check for defpath returning nil, otherwise we'll call FileTest.directory?(nil) which happens to be nil-safe. Suggest checking for nil explicitly:

def self.instances
  path = self.defpath
  unless path
    Puppet.info("daemontools is unsuitable because service directory is nil")
  end
  ...
end

Copy link
Contributor Author

@gimmyxd gimmyxd Oct 30, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are no other confines on defpath so i opt on using the second options as i do not have enough context on why the confine on defpath is problematic. Having the attr_writer :defpath means that @defpath can be set from different places.

https://github.com/puppetlabs/puppet/blob/5.5.x/lib/puppet/provider/service/daemontools.rb#L45

@defpath ||= ["/var/lib/service", "/etc"].find do |path|
Puppet::FileSystem.exist?(path) && FileTest.directory?(path)
end
@defpath
end
Expand All @@ -65,6 +59,10 @@ def defpath
# ie enabled or not
def self.instances
path = self.defpath
unless path
Puppet.info("#{self.name} is unsuitable because service directory is nil")
return
end
unless FileTest.directory?(path)
Puppet.notice "Service path #{path} does not exist"
return
Expand Down Expand Up @@ -109,7 +107,9 @@ def service
# note that this path can be overridden in the resource
# definition
def daemon
File.join(resource[:path], resource[:name])
path = resource[:path]
raise Puppet::Error.new("#{self.class.name} must specify a path for daemon directory") unless path
File.join(path, resource[:name])
end

def status
Expand Down
10 changes: 2 additions & 8 deletions lib/puppet/provider/service/runit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,8 @@ class << self
# this is necessary to autodetect a valid resource
# default path, since there is no standard for such directory.
def defpath
unless @defpath
["/etc/sv", "/var/lib/service"].each do |path|
if Puppet::FileSystem.exist?(path)
@defpath = path
break
end
end
raise "Could not find the daemon directory (tested [/etc/sv,/var/lib/service])" unless @defpath
@defpath ||= ["/var/lib/service", "/etc/sv"].find do |path|
Puppet::FileSystem.exist?(path) && FileTest.directory?(path)
end
@defpath
end
Expand Down
24 changes: 24 additions & 0 deletions spec/unit/provider/service/daemontools_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,28 @@
expect(@provider.status).to eq(:stopped)
end
end

context '.instances' do
before do
allow(described_class).to receive(:defpath).and_return(path)
end

context 'when defpath is nil' do
let(:path) { nil }

it 'returns info message' do
expect(Puppet).to receive(:info).with(/daemontools is unsuitable because service directory is nil/)
described_class.instances
end
end

context 'when defpath does not exist' do
let(:path) { '/inexistent_path' }

it 'returns notice about missing path' do
expect(Puppet).to receive(:notice).with(/Service path #{path} does not exist/)
described_class.instances
end
end
end
end
24 changes: 24 additions & 0 deletions spec/unit/provider/service/runit_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,28 @@
expect(@provider.status).to eq(:stopped)
end
end

context '.instances' do
before do
allow(described_class).to receive(:defpath).and_return(path)
end

context 'when defpath is nil' do
let(:path) { nil }

it 'returns info message' do
expect(Puppet).to receive(:info).with(/runit is unsuitable because service directory is nil/)
described_class.instances
end
end

context 'when defpath does not exist' do
let(:path) { '/inexistent_path' }

it 'returns notice about missing path' do
expect(Puppet).to receive(:notice).with(/Service path #{path} does not exist/)
described_class.instances
end
end
end
end