Skip to content

Commit

Permalink
Fix ensure with nonstandard versions
Browse files Browse the repository at this point in the history
This increases support for DragonFly BSD as well as FreeBSD, making
them first class citizens for this module. Additionally, it creates a
new structured fact called perl, which contains the various version
numbers that can be referenced for what version of Perl is the system
default. It was mainly added to properly support the config paths for
the default @inc on DragonFly and FreeBSD. The cpan provider was
updated to fix a few bugs around how it handled version strings, and
using rubocop, some additional cleanup was done while there.
  • Loading branch information
strangelittlemonkey committed Nov 17, 2017
1 parent 554d408 commit e5b665a
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 98 deletions.
13 changes: 13 additions & 0 deletions lib/facter/perl_version.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Facter.add(:perl) do
setcode do
perl = {}
current_info = Facter::Util::Resolution.exec('perl -v')
version = current_info.match(/v((\d+)\.(\d+)\.(\d*))/)
Facter.debug "Matching perl version as #{version}"
perl['version'] = version[1]
perl['majversion'] = version[2]
perl['minversion'] = version[3]
perl['subversion'] = version[4]
perl
end
end
73 changes: 29 additions & 44 deletions lib/puppet/provider/cpan/default.rb
Original file line number Diff line number Diff line change
@@ -1,38 +1,31 @@
Puppet::Type.type(:cpan).provide( :default ) do
@doc = "Manages cpan modules"
Puppet::Type.type(:cpan).provide(:default) do
@doc = 'Manages cpan modules'

commands :cpan => 'cpan'
commands :perl => 'perl'
confine :osfamily => [:Debian, :RedHat, :Windows]
commands cpan: 'cpan'
commands perl: 'perl'
confine osfamily: %i[Debian DragonFly FreeBSD RedHat Windows]
ENV['PERL_MM_USE_DEFAULT'] = '1'

def install
end
def install; end

def force
end
def force; end

def latest?
if resource[:local_lib]
ll = "-Mlocal::lib=#{resource[:local_lib]}"
ll = "-Mlocal::lib=#{resource[:local_lib]}" if resource[:local_lib]
current = `perl #{ll} -M#{resource[:name]} -e 'print $#{resource[:name]}::VERSION' 2>/dev/null;`
return false if current == ''
cpan_str = `perl #{ll} -e 'use CPAN; my $mod=CPAN::Shell->expand("Module","#{resource[:name]}"); printf("%s", $mod->cpan_version eq "undef" || !defined($mod->cpan_version) ? "-" : $mod->cpan_version);'`
latest = cpan_str.match(/^[a-zA-Z]?([0-9]+.?[0-9]*\.?[0-9]*)$/)[1]
if Puppet::Util::Package.versioncmp(latest.chomp, current.chomp) > 0
return true
end
current_version=`perl #{ll} -M#{resource[:name]} -e 'print $#{resource[:name]}::VERSION'`
cpan_str=`perl #{ll} -e 'use CPAN; my $mod=CPAN::Shell->expand("Module","#{resource[:name]}"); printf("%s", $mod->cpan_version eq "undef" || !defined($mod->cpan_version) ? "-" : $mod->cpan_version);'`
latest_version=cpan_str.match(/^[0-9]+.?[0-9]*$/)[0]
current_version.chomp
latest_version.chomp
if current_version < latest_version
return false else return true end
false
end

def create
Puppet.info("Installing cpan module #{resource[:name]}")
if resource[:local_lib]
ll = "-Mlocal::lib=#{resource[:local_lib]}"
end

ll = "-Mlocal::lib=#{resource[:local_lib]}" if resource[:local_lib]
umask = "umask #{resource[:umask]};" if resource[:umask]

Puppet.debug("cpan #{resource[:name]}")
if resource.force?
Puppet.info("Forcing install for #{resource[:name]}")
Expand All @@ -41,24 +34,20 @@ def create
system("#{umask} yes | perl #{ll} -MCPAN -e 'CPAN::install #{resource[:name]}'")
end

#cpan doesn't always provide the right exit code, so we double check
# cpan doesn't always provide the right exit code, so we double check
system("perl #{ll} -M#{resource[:name]} -e1 > /dev/null 2>&1")
estatus = $?.exitstatus
estatus = $CHILD_STATUS.exitstatus

if estatus != 0
raise Puppet::Error, "cpan #{resource[:name]} failed with error code #{estatus}"
end
raise Puppet::Error, "cpan #{resource[:name]} failed with error code #{estatus}" if estatus != 0
end

def destroy
end

def destroy; end

def update
Puppet.info("Upgrading cpan module #{resource[:name]}")
Puppet.debug("cpan #{resource[:name]}")
if resource[:local_lib]
ll = "-Mlocal::lib=#{resource[:local_lib]}"
end

ll = "-Mlocal::lib=#{resource[:local_lib]}" if resource[:local_lib]
umask = "umask #{resource[:umask]};" if resource[:umask]

if resource.force?
Expand All @@ -67,20 +56,17 @@ def update
else
system("#{umask} yes | perl #{ll} -MCPAN -e 'CPAN::install #{resource[:name]}'")
end
estatus = $?.exitstatus

if estatus != 0
raise Puppet::Error, "CPAN::install #{resource[:name]} failed with error code #{estatus}"
end
estatus = $CHILD_STATUS.exitstatus

raise Puppet::Error, "CPAN::install #{resource[:name]} failed with error code #{estatus}" if estatus != 0
end

def exists?
if resource[:local_lib]
ll = "-Mlocal::lib=#{resource[:local_lib]}"
end
ll = "-Mlocal::lib=#{resource[:local_lib]}" if resource[:local_lib]

Puppet.debug("perl #{ll} -M#{resource[:name]} -e1 > /dev/null 2>&1")
output = `perl #{ll} -M#{resource[:name]} -e1 > /dev/null 2>&1`
estatus = $?.exitstatus
estatus = $CHILD_STATUS.exitstatus

case estatus
when 0
Expand All @@ -92,5 +78,4 @@ def exists?
raise Puppet::Error, "perl #{ll} -M#{resource[:name]} -e1 failed with error code #{estatus}: #{output}"
end
end

end
45 changes: 17 additions & 28 deletions manifests/config.pp
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,27 @@
owner => root,
group => root,
mode => '0755',
}
file { '/etc/perl/CPAN/Config.pm':
ensure => present,
owner => root,
group => root,
mode => '0644',
content => template($::cpan::config_template),
require => File['/etc/perl/CPAN'],
before => File[$perl_config],
}
}
'RedHat': {
if versioncmp($::operatingsystemmajrelease, '6') >= 0 and $::operatingsystem != 'Fedora' {
file { '/usr/share/perl5/CPAN/Config.pm':
ensure => present,
owner => 'root',
group => 'root',
mode => '0644',
content => template($::cpan::config_template),
}
} else {
file { '/usr/lib/perl5/5.8.8/CPAN/Config.pm':
ensure => present,
owner => 'root',
group => 'root',
mode => '0644',
content => template($::cpan::config_template),
}
'DragonFly', 'FreeBSD': {
file { [ '/usr/local/perl5', "/usr/local/perl5/5.${::perl['minversion']}", "/usr/local/perl5/5.${::perl['minversion']}/CPAN" ]:
ensure => directory,
owner => 0,
group => 0,
mode => '0755',
before => File[$perl_config],
}
}
default: {
fail("Module ${module_name} is not supported on ${::osfamily} os.")
}
default: { }
}

file { $::cpan::perl_config:
ensure => present,
owner => $root_user,
group => $root_group,
mode => '0644',
content => template($::cpan::config_template),
}
}
}
11 changes: 7 additions & 4 deletions manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@
$local_lib = $cpan::params::local_lib,
$config_template = $cpan::params::config_template,
$config_hash = $cpan::params::config_hash,
$root_user = $cpan::params::root_user,
$root_group = $cpan::params::root_group,
$package_ensure = $cpan::params::package_ensure,
$perl_config = $cpan::params::perl_config,
$ftp_proxy = $cpan::params::ftp_proxy,
$http_proxy = $cpan::params::http_proxy,
$urllist = $cpan::params::urllist,
Expand All @@ -62,9 +65,9 @@
}
validate_array($urllist)

anchor { 'cpan::begin': } ->
class { '::cpan::install': } ->
class { '::cpan::config': } ->
anchor { 'cpan::end': }
anchor { 'cpan::begin': }
-> class { '::cpan::install': }
-> class { '::cpan::config': }
-> anchor { 'cpan::end': }

}
53 changes: 32 additions & 21 deletions manifests/params.pp
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
#
class cpan::params {

$manage_config = true
$installdirs = 'site'
$local_lib = false
$config_template = 'cpan/cpan.conf.erb'
$config_hash = { 'build_requires_install_policy' => 'no' }
$package_ensure = 'present'
$common_package = ['gcc','make']
$ftp_proxy = undef
$http_proxy = undef
$urllist = []
$manage_config = true
$installdirs = 'site'
$local_lib = false
$config_template = 'cpan/cpan.conf.erb'
$config_hash = { 'build_requires_install_policy' => 'no' }
$package_ensure = 'present'
$common_package = ['gcc','make']
$ftp_proxy = undef
$http_proxy = undef
$urllist = []

unless $installdirs =~ /^(perl|site|vendor)$/ {
fail('installdirs must be one of {perl,site,vendor}')
Expand All @@ -27,28 +27,39 @@
case $::osfamily {
'Debian': {
$common_os_package = ['perl-modules']
$perl_config = '/etc/perl/CPAN/Config.pm'
$root_user = 'root'
$root_group = 'root'
if $local_lib {
$local_lib_package = ['liblocal-lib-perl']
$local_lib_package = ['liblocal-lib-perl']
} else {
$local_lib_package = []
$local_lib_package = []
}
}
'RedHat': {
$common_os_package = ['perl-CPAN']

if $local_lib {
if ($::operatingsystem == 'RedHat' and versioncmp($::operatingsystemmajrelease, '6') >= 0) {
$local_lib_package = ['perl-local-lib']
} elsif ($::operatingsystem == 'Fedora' and versioncmp($::operatingsystemmajrelease, '16') >=0) {
$local_lib_package = ['perl-local-lib']
case $::operatingsystemmajrelease {
5, 6: {
$local_lib_package = ['perl-local-lib']
$perl_config = '/usr/share/perl5/CPAN/Config.pm'
$root_user = 'root'
$root_group = 'root'
}
} else {
$local_lib_package = []
7: {
$root_user = 'root'
$root_group = 'wheel'
}
default: { }
}
}
'DragonFly', 'FreeBSD': {
$perl_config = "/usr/local/perl5/5.${::perl['minversion']}/CPAN/Config.pm"
$root_user = 'root'
$root_group = 'wheel'
}
default: {
fail("Module ${module_name} is not supported on ${::osfamily}")
}
}
$package_name = concat($common_package,$common_os_package,$local_lib_package )
$package_name = concat($common_package,$common_os_package,$local_lib_package )
}
2 changes: 1 addition & 1 deletion spec/classes/cpan_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
describe 'cpan::config on RedHat and operatingsystemrelease 7' do
let(:facts) { super().merge(:osfamily => 'RedHat', :operatingsystemmajrelease => '7') }
it { should contain_file('/usr/share/perl5/CPAN/Config.pm').with_owner('root') }
it { should contain_file('/usr/share/perl5/CPAN/Config.pm').with_group('root') }
it { should contain_file('/usr/share/perl5/CPAN/Config.pm').with_group('wheel') }
it { should contain_file('/usr/share/perl5/CPAN/Config.pm').with_mode('0644') }
end

Expand Down

0 comments on commit e5b665a

Please sign in to comment.