mirror of
https://github.com/inspec/inspec
synced 2024-11-23 13:13:22 +00:00
service resource: attempt a SysV fallback if SystemD unit file is not found (#2473)
* service resource: Fix no `.service` + systemd bug This modifies the `enabled?` check to fallback to `sysv_service` in the event that a `.service` file cannot be found. For example: On Debian 8.7 the stock apache2 package does not deploy a `.service` file but deploys a SysV style service. This causes `systemctl is-enabled` to fail when the service is in fact enabled. * Remove `cmd_stderr` and clean up `cmd_exit_1` * Clean up `stderr` assignment using ternary
This commit is contained in:
parent
acf9ce379d
commit
98546984ae
7 changed files with 55 additions and 4 deletions
|
@ -250,7 +250,17 @@ module Inspec::Resources
|
|||
end
|
||||
|
||||
def is_enabled?(service_name)
|
||||
inspec.command("#{service_ctl} is-enabled #{service_name} --quiet").exit_status == 0
|
||||
result = inspec.command("#{service_ctl} is-enabled #{service_name} --quiet")
|
||||
return true if result.exit_status == 0
|
||||
|
||||
# Some systems may not have a `.service` file for a particular service
|
||||
# which causes the `systemctl is-enabled` check to fail despite the
|
||||
# service being enabled. In that event we fallback to `sysv_service`.
|
||||
if result.stderr =~ /Failed to get.*No such file or directory/
|
||||
return inspec.sysv_service(service_name).enabled?
|
||||
end
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
def is_active?(service_name)
|
||||
|
|
|
@ -201,7 +201,10 @@ class MockLoader
|
|||
mock.mock_command('', '', '', 0)
|
||||
}
|
||||
|
||||
cmd_exit_1 = mock.mock_command('', '', '', 1)
|
||||
cmd_exit_1 = lambda { |x = nil|
|
||||
stderr = x.nil? ? '' : File.read(File.join(scriptpath, 'unit/mock/cmd', x))
|
||||
mock.mock_command('', '', stderr, 1)
|
||||
}
|
||||
|
||||
mock.commands = {
|
||||
'' => empty.call,
|
||||
|
@ -234,7 +237,7 @@ class MockLoader
|
|||
'dpkg -s held-package' => cmd.call('dpkg-s-held-package'),
|
||||
'rpm -qia curl' => cmd.call('rpm-qia-curl'),
|
||||
'rpm -qia --dbpath /var/lib/fake_rpmdb curl' => cmd.call('rpm-qia-curl'),
|
||||
'rpm -qia --dbpath /var/lib/rpmdb_does_not_exist curl' => cmd_exit_1,
|
||||
'rpm -qia --dbpath /var/lib/rpmdb_does_not_exist curl' => cmd_exit_1.call,
|
||||
'pacman -Qi curl' => cmd.call('pacman-qi-curl'),
|
||||
'brew info --json=v1 curl' => cmd.call('brew-info--json-v1-curl'),
|
||||
'/usr/local/bin/brew info --json=v1 curl' => cmd.call('brew-info--json-v1-curl'),
|
||||
|
@ -248,7 +251,7 @@ class MockLoader
|
|||
"Rscript -e 'packageVersion(\"DBI\")'" => cmd.call('r-print-version'),
|
||||
"Rscript -e 'packageVersion(\"DoesNotExist\")'" => cmd.call('r-print-version-not-installed'),
|
||||
"perl -le 'eval \"require $ARGV[0]\" and print $ARGV[0]->VERSION or exit 1' DBD::Pg" => cmd.call('perl-print-version'),
|
||||
"perl -le 'eval \"require $ARGV[0]\" and print $ARGV[0]->VERSION or exit 1' DOES::Not::Exist" => cmd_exit_1,
|
||||
"perl -le 'eval \"require $ARGV[0]\" and print $ARGV[0]->VERSION or exit 1' DOES::Not::Exist" => cmd_exit_1.call,
|
||||
'pip show jinja2' => cmd.call('pip-show-jinja2'),
|
||||
'pip show django' => cmd.call('pip-show-django'),
|
||||
'/test/path/pip show django' => cmd.call('pip-show-non-standard-django'),
|
||||
|
@ -281,6 +284,7 @@ class MockLoader
|
|||
'initctl --version' => cmd.call('initctl--version'),
|
||||
# show ssh service Centos 7
|
||||
'systemctl show --all sshd' => cmd.call('systemctl-show-all-sshd'),
|
||||
'systemctl show --all apache2' => cmd.call('systemctl-show-all-apache2'),
|
||||
'/path/to/systemctl show --all sshd' => cmd.call('systemctl-show-all-sshd'),
|
||||
'systemctl show --all dbus' => cmd.call('systemctl-show-all-dbus'),
|
||||
'/path/to/systemctl show --all dbus' => cmd.call('systemctl-show-all-dbus'),
|
||||
|
@ -454,13 +458,16 @@ class MockLoader
|
|||
"bash -c 'type \"firewall-cmd\"'" => cmd.call('firewall-cmd'),
|
||||
'rpm -qia firewalld' => cmd.call('pkg-info-firewalld'),
|
||||
'systemctl is-active sshd --quiet' => empty.call,
|
||||
'systemctl is-active apache2 --quiet' => empty.call,
|
||||
'systemctl is-enabled sshd --quiet' => empty.call,
|
||||
'systemctl is-enabled apache2 --quiet' => cmd_exit_1.call('systemctl-is-enabled-apache2-stderr'),
|
||||
'systemctl is-active dbus --quiet' => empty.call,
|
||||
'systemctl is-enabled dbus --quiet' => empty.call,
|
||||
'/path/to/systemctl is-active sshd --quiet' => empty.call,
|
||||
'/path/to/systemctl is-enabled sshd --quiet' => empty.call,
|
||||
'/usr/sbin/service sshd status' => empty.call,
|
||||
'/sbin/service sshd status' => empty.call,
|
||||
'service apache2 status' => cmd_exit_1.call,
|
||||
'type "lsof"' => empty.call,
|
||||
|
||||
# http resource - remote worker'
|
||||
|
|
|
@ -10,3 +10,7 @@
|
|||
/etc/rc.d/rc4.d/S08ip6tables
|
||||
/etc/rc.d/rc4.d/S90crond
|
||||
/etc/rc.d/rc4.d/S55sshd
|
||||
/etc/rc2.d/S02apache2
|
||||
/etc/rc3.d/S02apache2
|
||||
/etc/rc4.d/S02apache2
|
||||
/etc/rc5.d/S02apache2
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
crond
|
||||
sshd
|
||||
apache2
|
||||
|
|
1
test/unit/mock/cmd/systemctl-is-enabled-apache2-stderr
Normal file
1
test/unit/mock/cmd/systemctl-is-enabled-apache2-stderr
Normal file
|
@ -0,0 +1 @@
|
|||
Failed to get unit file state for apache2.service: No such file or directory
|
7
test/unit/mock/cmd/systemctl-show-all-apache2
Normal file
7
test/unit/mock/cmd/systemctl-show-all-apache2
Normal file
|
@ -0,0 +1,7 @@
|
|||
Id=apache2.service
|
||||
Names=apache2.service
|
||||
Description=LSB: Apache2 web server
|
||||
LoadState=loaded
|
||||
UnitFileState=
|
||||
SubState=running
|
||||
ActiveState=active
|
|
@ -268,6 +268,27 @@ describe 'Inspec::Resources::Service' do
|
|||
_(resource.params).must_equal params
|
||||
end
|
||||
|
||||
# debian 8 with systemd but no service file
|
||||
it 'gets the correct service info when the `.service` file is missing' do
|
||||
resource = MockLoader.new(:debian8).load_resource('service', 'apache2')
|
||||
params = Hashie::Mash.new(
|
||||
'ActiveState' => 'active',
|
||||
'Description' => 'LSB: Apache2 web server',
|
||||
'Id' => 'apache2.service',
|
||||
'LoadState' => 'loaded',
|
||||
'Names' => 'apache2.service',
|
||||
'SubState' => 'running',
|
||||
'UnitFileState' => ''
|
||||
)
|
||||
_(resource.type).must_equal 'systemd'
|
||||
_(resource.name).must_equal 'apache2.service'
|
||||
_(resource.description).must_equal 'LSB: Apache2 web server'
|
||||
_(resource.installed?).must_equal true
|
||||
_(resource.enabled?).must_equal true
|
||||
_(resource.running?).must_equal true
|
||||
_(resource.params).must_equal params
|
||||
end
|
||||
|
||||
# macos test
|
||||
it 'verify mac osx service parsing' do
|
||||
resource = MockLoader.new(:osx104).load_resource('service', 'ssh')
|
||||
|
|
Loading…
Reference in a new issue