Defining and calling function in puppet 2.6 and 2.7 - puppet

I have a module core and a class core::logrotate defined in core/manifests/logrotate.pp.
class core::logrotate {
#...some stuff here
#
define confd ($ensure = "present" , $log_name = "dummy" ) {
if ( $ensure == present )
{
file {
"/etc/logrotate.d/$log_name":
ensure => present,
source => filelookup("core/${log_name}.logrotate"),
}
} else {
file {
"/etc/logrotate.d/$log_name":
ensure => absent,
}
}
}
}
calling this function inside of templates.pp as
core::logrotate::confd { "mkill": log_name => mkill }
This fails with the error
Error 400 on SERVER: Puppet::Parser::AST::Resource failed with error ArgumentError: Invalid resource type core::logrotate::confd
If the puppet master version is 2.6.x then this fails, to make it work there used to be a import "*" in the init.pp of the module. Now removed this as moving to puppet 2.7.20.
The code pasted here works in 2.7 but fails in 2.6. Any idea why? how can I make it work for both 2.6 and 2.7?

You should take the define outside of the class, see the style guide: http://docs.puppetlabs.com/guides/style_guide.html#classes
Also, I think that you might be using modules wrong, it would be much more logical to have a 'logrotate' module on its own.
So; in modulepath/logrotate/manifests/confd.pp you'd put this:
define logrotate::confd ($ensure = "present" , $log_name = "dummy" ) {
if ( $ensure == present )
{
file {
"/etc/logrotate.d/$log_name":
ensure => present,
source => filelookup("core/${log_name}.logrotate"),
}
} else {
file {
"/etc/logrotate.d/$log_name":
ensure => absent,
}
}
}
That should make it work properly.
Greetings,
Ger

Related

Operator '[]' is not applicable to an Undef Value

[tom#pe-server] cat site.pp
node 'mynode.com' {
include base::common::setup
$svn_url_disable_uac = {
svn_co_dir => 'automation/scripts/base/common',
svn_url => 'abc/trunk/automation/chv/modules/base/files/common/disable_uac.ps1',
}
}
[tom#pe-server] cat disable_uac.pp
class base::common::disable_uac inherits base::common::param {
base::common::svn::repo_checkout { 'Copy disable_uac PS script':
svn_url_params => $svn_url_disable_uac,
}
util::executeps { 'Disable UAC':
pspath => $disable_uac,
argument => '',
subscribe => Base::Common::Svn::Repo_checkout['Copy disable_uac PS script'],
}
}
[tom#pe-server] cat setup.pp
class base::common::setup inherits base::common::param {
include base::common::disable_uac
}
[tom#pe-server] cat param.pp
class base::common::param (
$repo_checkout_ps = 'C:/puppet/automation/scripts/infra/repo_checkout.ps1',
$disable_uac = 'C:/puppet/automation/scripts/base/common/disable_uac.ps1',
) {}
When i run the above code, i get the following error:
Error:
Evaluation Error: Error while evaluating a Resource Statement, Evaluation Error: Operator '[]' is not applicable to an Undef Value.
at /etc/puppetlabs/code/environments/client/modules/base/manifests/common/svn/repo_checkout.pp:7:19
at /etc/puppetlabs/code/environments/client/modules/base/manifests/common/disable_uac.pp:2 on node mynode.com
One thing to note is that if i move the following code from base::common::disable_uac to site.pp, then everything works fine:
base::common::svn::repo_checkout { 'Copy disable_uac PS script':
svn_url_params => $svn_url_disable_uac,
}
UPDATE:
Sorry, i missed putting that part in the post. Here it is:
[tom#pe-server] cat repo_checkout.pp
define base::common::svn::repo_checkout (
$svn_url_params,
) {
include base::common::param
$repo_checkout_ps = $base::common::param::repo_checkout_ps
$svn_co_dir = $svn_url_params[svn_co_dir] # Line 7
$svn_url = $svn_url_params[svn_url]
util::executeps { "Checking out build packet for URL \"$svn_url\"":
pspath => $repo_checkout_ps,
argument => "\"$svn_co_dir\" \"$svn_url\"",
}
}
I've spent few hours looking into it but unable to figure out the issue.

conditional within define in puppet

Running Puppet 3.8
I have two defines:
define desktop::vinstall () {
package { $title:
ensure => installed,
allow_virtual => true,
configfiles => keep,
}
}
and
define desktop::vinstallwseeds () {
package { $title:
ensure => installed,
allow_virtual => true,
configfiles => keep,
require => File["/var/cache/debconf/pkg-${title}.seeds"],
responsefile => "/var/cache/debconf/pkg-${title}.seeds",
}
file { "/var/cache/debconf/pkg-${title}.seeds":
source => "puppet:///modules/desktop/pkg-${title}.seeds",
ensure => present,
}
}
Would like to turn these into one define statement with an optional boolean argument, something like:
define desktop::vinstallopt ( $queryresponse = 'false', ) {
package { $title:
ensure => installed,
allow_virtual => true,
configfiles => keep,
if $queryresponse == 'true' {
require => File["/var/cache/debconf/pkg-${title}.seeds"],
responsefile => "/var/cache/debconf/pkg-${title}.seeds",
}
}
file { "/var/cache/debconf/pkg-${title}.seeds":
source => "puppet:///modules/desktop/pkg-${title}.seeds",
ensure => present,
}
}
and then instantiate it with statements like this one in init.pp:
#desktop::vinstallopt { 'gdebi': queryresponse => 'false', }
But doing so gives an error:
Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Puppet::Parser::AST::Resource failed with argument error ArgumentError: Invalid resource type desktop::vinstallopt at /etc/puppet/modules/desktop/manifests/init.pp:40 on node machine.prvt.net
where line 40 has the syntax above. I'm a newbie with puppet, so my apologies if this turns out the be a simple syntax question. I've tried to find a way to make this work from the PuppetLabs documentation and from other puppet users, so far without luck.
You are trying to embed an if block inside a resource declaration. Alas, this is not possible. The block must be global or in a regular block (e.g., class body, define body, lambda body).
In this case, you want to "amend" the package resource, so to speak. I like to use the following construct for this purpose:
package { $title:
ensure => installed,
allow_virtual => true,
configfiles => keep,
}
if $queryresponse {
Package[$title] {
require => File["/var/cache/debconf/pkg-${title}.seeds"],
responsefile => "/var/cache/debconf/pkg-${title}.seeds",
}
}
Please note that this override syntax is only allowed in this scope because the require and responsefile attributes don't have any value assigned originally.

puppet defined types and variables

I am new to puppet and I am trying to write a module to manage .bashrc file of 10 users. The following code is ok to manage the file of 1 user. However, I am unable to change the code to manage files for 10 users. I tried using defined types and variable with no luck. Can sombody please suggest me the right way to do this.
init.pp:
class profile (
$bashrc = $profile::params::bashrc,
$bashrc_host = $profile::params::bashrc_host,
) inherits profile::params {
anchor { 'profile::begin': } ->
class { '::profile::config': } ->
anchor { 'profile::end': }
}
config.pp:
class profile::config inherits profile {
file { $bashrc:
ensure => file,
source => "puppet:///$bashrc_host",
}
params.pp:
class profile::params {
$bashrc_host = "modules/profile/$fqdn_user1_bashrc"
}
case $::osfamily {
'RedHat': {
$bashrc = '/home/user1/.bashrc'
}
}
This is not at all a job for a class. As you noted yourself in your most recent comment, this calls for a define actually.
Please don't use verbs in the names of your defines. Instead of defineuser, just do
define profile::user($host_name) {
}
Off the top of my hat, I'm not aware of a good pattern to use module parameters in your defines. You can however use the following pattern:
class profile(
$default_shell = $profile::params::default_shell,
$default_prompt = $profile::params::default_prompt,
$users = {}
) inherits profile::params {
$defaults = { shell => $default_shell, prompt => $default_prompt }
create_resources('profile::user', $users, $defaults)
}
What happens is
values are taken from params, or hiera, or the invoking manifest
these values are gathered in the $defaults array
for any resource in the $users hash that has no shell or prompt, this default is used
If your aim of this module is to learn puppet then:
Add a param user to your class profile::params
class profile::params {
$bashrc_host = "modules/profile/$fqdn_user1_bashrc"
$user = 'user1',
}
case $::osfamily {
'RedHat': {
$bashrc = "/home/$user/.bashrc"
}
}
After this, you can use a combination of array or hiera and ensure_resource This still is not the most elegant solution, but baby steps.
If your intend is to actually manage the bashrc for various users, I would recommend using a pre existing module such as account

Function contain() vs. Anchor Pattern in Puppet

This post refers to Puppet "require" not working as expected.
Is it possible to replace the Anchor Pattern with the function contain maintaining execution order and hinder declared classes of floating out. The two manifests look as follows:
class profile::maven inherits profile::base {
# Hiera
$version = hiera('profile::maven::version', '3.2.1')
$settings = hiera_hash('profile::maven::settings', undef)
$environments = hiera_hash('profile::maven::environments', undef)
include 'profile::java'
anchor { 'profile::maven::begin': }
class { '::maven::maven': version => $version, }
anchor { 'profile::maven::end': }
if ($settings) {
create_resources('::maven::settings', $settings)
}
if ($environments) {
create_resources('::maven::environment', $environments)
}
Anchor['profile::maven::begin'] -> Class['profile::java'] -> Class['::maven::maven'] -> Anchor['profile::maven::end']
}
and
class profile::java inherits profile::base {
# Hiera
$distribution = hiera('profile::java::distribution', 'jdk')
$version = hiera('profile::java::version', 'present')
anchor { 'profile::java::begin': }
class { '::java':
distribution => $distribution,
version => $version,
}
anchor { 'profile::java::end': }
# Parameters
$java_home = $::java::java_home
file { 'profile-script:java.sh':
ensure => present,
path => '/etc/profile.d/java.sh',
content => template('profile/java.sh.erb'),
}
Anchor['profile::java::begin'] -> Class['::java'] -> File['profile-script:java.sh'] -> Anchor['profile::java::end']
}
Because of the current issue PUP-1597 in Puppet 3.6.x, the profile classes have to be renamed, otherwise we get Error: undefined method 'ref' for nil:NilClass. Applying the changes result in:
class profile::mavenp inherits profile::base {
# Hiera
$version = hiera('profile::maven::version', '3.2.1')
$settings = hiera_hash('profile::maven::settings', undef)
$environments = hiera_hash('profile::maven::environments', undef)
include 'profile::javap'
class { '::maven::maven': version => $version, }
contain 'maven::maven'
if ($settings) {
create_resources('::maven::settings', $settings)
}
if ($environments) {
create_resources('::maven::environment', $environments)
}
Class['profile::javap'] -> Class['::maven::maven']
}
and
class profile::javap inherits profile::base {
# Hiera
$distribution = hiera('profile::java::distribution', 'jdk')
$version = hiera('profile::java::version', 'present')
class { '::java':
distribution => $distribution,
version => $version,
}
contain 'java'
# Parameters
$java_home = $::java::java_home
file { 'profile-script:java.sh':
ensure => present,
path => '/etc/profile.d/java.sh',
content => template('profile/java.sh.erb'),
}
}
Are these changes equivalent?
If someone has a better idea of how to the deal with technologcial dependencies in Puppet using the profile/role approach, do not hesitate to share your thoughts.
The latter pair of classes are not completely equivalent equivalent to the former. The biggest issue is in profile::javap. Note that its analog profile::java has this as part of its dependency chain:
Class['::java'] -> File['profile-script:java.sh']
Class profile::javap has no analog of that.
I'm not 100% certain whether class profile::mavenp is equivalent to class profile::maven, though I think it is. Your intent would be clearer and my uncertainty would be resolved if the former included
contain 'profile::javap'
instead of (or in addition to)
include 'profile::javap'

Puppet - Variable for package name fails

I'm new to puppet, and I am stumped.
I am installing gcc, gcc-c++, openssl and openssl-devel.
In the code shown, $openssl_devel works but $c_plus is undefined.
Why is puppet setting $c_plus to 'undef' ?
Cent OS 6
class torque::prerequisites {
case $operatingsystem {
centos,redhat: {$openssl_devel = 'openssl-devel'}
centos,redhat: {$c_plus = 'gcc-c++'}
debian,ubuntu: {$openssl_devel = 'libssl-dev'}
debian,ubuntu: {$c_plus = 'build-essential'}
default:{fail("Unable identify opperating system. $operatingsytem not recognized") }
}
package {'openssl':
ensure => latest,
}
package {$openssl_devel:
ensure => latest,
require => Package['openssl'],
}
package {'gcc':
ensure => installed,
}
package {$c_plus:
ensure => installed,
require => Package['gcc'],
}
}
class {'torque::prerequisites':}
puppet apply torque_prerequisites
err: /Stage[main]/Torque::Prerequisites/Package[undef]/ensure: change from absent to present failed: Could not find package undef
I still don't know why the original syntax didn't work, but this syntax does works:
class torque::prerequisites {
case $::osfamily {
Redhat: {
$openssl_devel = 'openssl-devel'
$c_plus_compiler = 'gcc-c++'
}
Debian: {
$openssl_devel = 'libssl-dev'
$c_plus_compiler = 'build-essential'
}
default:{fail("Unable identify opperating system. $operatingsytem not recognized") }
}
package {'openssl':
ensure => latest,
}
package {$openssl_devel:
ensure => latest,
require => Package['openssl'],
}
package {'gcc':
ensure => installed,
}
package {$c_plus_compiler:
ensure => installed,
require => Package['gcc'],
}
}
class {'torque::prerequisites':}

Resources