Add RedHat support for packages resource

Fix dpkg trimming of first line
Signed-off-by: Alex Pop <apop@chef.io>
This commit is contained in:
Alex Pop 2017-02-13 13:13:22 +00:00
parent 29e0dbebd1
commit fae96f6249
4 changed files with 74 additions and 20 deletions

View file

@ -23,12 +23,17 @@ module Inspec::Resources
"
def initialize(pattern)
@command = packages_command
return skip_resource "The packages resource is not yet supported on OS #{inspec.os.name}" unless @command
os = inspec.os
if os.debian?
@pkgs = Debs.new(inspec)
elsif %w{redhat suse amazon fedora}.include?(os[:family])
@pkgs = Rpms.new(inspec)
else
return skip_resource "The packages resource is not yet supported on OS #{inspec.os.name}"
end
@pattern = pattern_regexp(pattern)
all_pkgs = build_package_list(@command)
all_pkgs = @pkgs.build_package_list
@list = all_pkgs.find_all do |hm|
hm[:name] =~ @pattern
end
@ -48,14 +53,6 @@ module Inspec::Resources
private
def packages_command
os = inspec.os
if os.debian?
command = "dpkg-query -W -f='${db:Status-Abbrev} ${Package} ${Version}\\n'"
end
command
end
def pattern_regexp(p)
if p.class == String
Regexp.new(Regexp.escape(p))
@ -67,21 +64,46 @@ module Inspec::Resources
end
def filtered_packages
warn "The packages resource is not yet supported on OS #{inspec.os.name}" unless @command
warn "The packages resource is not yet supported on OS #{inspec.os.name}" if resource_skipped
@list
end
end
Package = Struct.new(:status, :name, :version)
class PkgsManagement
PackageStruct = Struct.new(:status, :name, :version)
attr_reader :inspec
def initialize(inspec)
@inspec = inspec
end
end
def build_package_list(command)
# Debian / Ubuntu
class Debs < PkgsManagement
def build_package_list
command = "dpkg-query -W -f='${db:Status-Abbrev} ${Package} ${Version}\\n'"
cmd = inspec.command(command)
all = cmd.stdout.split("\n")[1..-1]
all = cmd.stdout.split("\n")
return [] if all.nil?
all.map do |m|
a = m.split
a[0] = 'installed' if a[0] =~ /^.i/
a[2] = a[2].split(':').last
Package.new(*a)
PackageStruct.new(*a)
end
end
end
# RedHat family
class Rpms < PkgsManagement
def build_package_list
command = "rpm -qa --queryformat '%{NAME} %{VERSION}-%{RELEASE}\\n'"
cmd = inspec.command(command)
all = cmd.stdout.split("\n")
return [] if all.nil?
all.map do |m|
a = m.split(' ')
a.unshift('installed')
PackageStruct.new(*a)
end
end
end

View file

@ -250,8 +250,10 @@ class MockLoader
'pkginfo -l SUNWzfsr' => cmd.call('pkginfo-l-SUNWzfsr'),
# solaris 11 package manager
'pkg info system/file-system/zfs' => cmd.call('pkg-info-system-file-system-zfs'),
# dpkg-query package list
# dpkg-query all packages
"dpkg-query -W -f='${db:Status-Abbrev} ${Package} ${Version}\\n'" => cmd.call('dpkg-query-W'),
# rpm query all packages
"rpm -qa --queryformat '%{NAME} %{VERSION}-%{RELEASE}\\n'" => cmd.call('rpm-qa-queryformat'),
# port netstat on solaris 10 & 11
'netstat -an -f inet -f inet6' => cmd.call('s11-netstat-an-finet-finet6'),
# xinetd configuration

View file

@ -0,0 +1,10 @@
attr 2.4.44-7.el6
perl-Pod-Escapes 1.04-141.el6_7.1
perl-version 0.77-141.el6_7.1
perl-Pod-Simple 3.13-141.el6_7.1
vim-filesystem 7.4.629-5.el6
gpm-libs 1.20.6-12.el6
mlocate 0.22.2-6.el6
ntpdate 4.2.6p5-10.el6.centos.1
chef-compliance 1.3.1-1.el6
nc 1.84-24.el6

View file

@ -42,10 +42,30 @@ describe 'Inspec::Resources::Packages' do
_(resource.entries.length).must_equal 3
end
it 'all packages on Ubuntu' do
resource = MockLoader.new(:ubuntu1604).load_resource('packages', /.+/)
_(resource.entries.length).must_equal 12
end
it 'all packages on CentOS' do
resource = MockLoader.new(:centos6).load_resource('packages', /.+/)
_(resource.entries.length).must_equal 10
end
it 'packages on CentOS' do
resource = MockLoader.new(:centos6).load_resource('packages', /^chef\-.+/)
_(resource.entries.length).must_equal 1
_(resource.where { status == 'installed' }.names).must_equal(['chef-compliance'])
_(resource.entries[0].to_h).must_equal({
status: "installed",
name: "chef-compliance",
version: "1.3.1-1.el6",
})
end
it 'skips on non debian platforms' do
resource = MockLoader.new(:centos6).load_resource('packages', [:a, :b])
_(resource.resource_skipped).must_equal 'The packages resource is not yet supported on OS centos'
resource = MockLoader.new(:hpux).load_resource('packages', 'bash')
_(resource.resource_skipped).must_equal 'The packages resource is not yet supported on OS hpux'
end
it 'fails if the packages name is not a string or regexp' do