Puppet: Duplicate delcaration on same line when using `define` - node.js

Trying to get some NPM packages installed both locally and globally. I am doing it like this:
$npm_packages_loc = {
'mysql' => {
'version' => 'latest',
'ensure' => 'present',
},
'googleapis' => {
'version' => 'latest',
'ensure' => 'present',
}
}
This simply says that I want the 'mysql' and 'googleapi' packages installed, and I want them at the latest version.
## Install NPM local packages
# Obtains and multiplexes NPM packages defgined in '$npm_modules_loc'
define npm_packages($version, $ensure) {
npm_packages_loc_inst { $version:
package => $name,
ensure => $ensure,
}
}
# Installs the packages via nodejs::npm
define npm_packages_loc_inst($package, $ensure) {
$version = name
nodejs::npm { "/opt/app/:${package}":
ensure => $ensure,
version => $version,
}
}
create_resources ('npm_packages', $npm_packages_loc)
However, when doing a puppet run I get the following error:
Duplicate declaration: myapp::Npm_packages_loc_inst[latest] is already declared in file /etc/puppet/modules/test/myapp/manifests/init.pp:79; cannot redeclare at /etc/puppet/modules/test/myapp/manifests/init.pp:79
Not sure why it is behaving like this, but I am obviously doing something wrong. Any help is appreciated :)

I figured it out. It was because of this line:
npm_packages_loc_inst { $version:
As both 'versions' were set to 'latest', it thought there was a duplicate declaration (Npm_packages_loc_inst[latest]). Changing this to 'name' fixed the issue:
npm_packages_loc_inst { $name:
Now looks like:
Npm_packages_loc_inst[googleapis] \
Npm_packages_loc_inst[mysql]
Hence no duplicate declaration. Hope that helps other people out there.

Related

fail when a file exist in puppet

I am trying to write a puppet script which will install a module by un-tar. I want puppet to fail if it is already un tar. I tried to do below code but it always fails even if directory is absent.
I am checking if /opt/sk is present then fail otherwise proceed on installation.
define splunk::fail($target)
{
$no = 'true'
case $no {
default : { notice($no) }#fail('sk is already installed.')}
}
}
define splunk::forwarder( $filename , $target )
{
file{"$target/sk":
ensure => present
}
splunk::fail{"NO":
target => '/opt/',
require => File[$target],
}
file{"$target/A.tgz":
source => $filename ,
replace => false ,
}
exec{"NO1":
command => "tar xzvf A.tgz" ,
cwd => $target ,
require => File["$target/A.tgz"] ,
}
exec{"Clean":
command => "rm -rf A.tgz" ,
cwd => target ,
require => Exec["NO1"],
}
}
splunk::forwarder {"non":
filename => 'puppet:///modules/splunk/files/NO.tgz' ,
target => '/opt/',
}
Thanks
Define custom_fact and use it combined with fail resource.
In your ruby directory e.g /usr/lib/ruby/vendor_ruby/facter define file tmp_exist.rb with content:
# tmp_exist.rb
Facter.add('tmp_exist') do
setcode do
File.exist? '/root/tmp'
end
end
Next use it in puppet manifest. E.g I combined it with str2bool function from stdlib:
class test {
if !str2bool($::tmp_exist) {
fail('TMP NOT EXIST')
}
if !str2bool($::foo_exist) {
fail('FOO NOT EXIST')
}
}
include test
In /root create only tmp file.
In result you will have:
Error: FOO NOT EXIST at /etc/puppet/deploy/tests/test.pp:8 on node dbmaster
UPDATED: I updated my answer. Chris Pitman was right, my previous solution works only on puppet master or with puppet apply.
I have also found an article describing how to define custom function file_exists in puppet. That also might be helpful.
You should use "creates" attribute of exec, for example:
exec { 'install':
command => "tar zxf ${package}",
cwd => $some_location,
path => $path,
creates => "${some_location}/my_package",
}
Puppet will only execute 'install' if "${some_location}/my_package" doesn't exist.

How can i install a local rpm using puppet

I am trying to install a particular rpm using puppet, my init.pp is:
class nmap {
package {'nmap':
provider => 'rpm',
source => "<Local PATH to the RPM>",
}
}
and the rpm is in ...modules/nmap/files
If i move the rpm to manifests, and provide the rpm name in source => ''
class nmap {
package {'nmap':
provider => 'rpm',
source => "rpm-name.rpm",
}
}
it works, but how can i specify source path with ../files/ and do puppet apply successfully
When i use :
source => 'puppet:///files/nmap-6.45-1.x86_64.rpm',
i get an error:
Debug: Executing '/bin/rpm -i puppet:///files/nmap-6.45-1.x86_64.rpm'
Error: Execution of '/bin/rpm -i puppet:///files/nmap-6.45-1.x86_64.rpm' returned 1: error: open of puppet:///files/nmap-6.45-1.x86_64.rpm failed: No such file or directory
Error: /Stage[main]/Nmap/Package[nmap]/ensure: change from absent to present failed: Execution of '/bin/rpm -i puppet:///files/nmap-6.45-1.x86_64.rpm' returned 1: error: open of puppet:///files/nmap-6.45-1.x86_64.rpm failed: No such file or directory
`
when running the command:
sudo puppet apply --modulepath=/home/user1/qa/puppet_qa/modules/ -e "include nmap" --debug
Unlike the file resource type, the package type has no support for Puppet fileserver URLs. You will need to use a file resource to download the rpm prior to installing it. If this is a recurring problem for you, make a defined type that does those in one go (think macros), e.g.
define fileserver_package($source, $ensure='installed') {
file { "/my/tmp/dir/$name.rpm": source => $source }
package { $name:
ensure => $ensure,
provider => 'rpm',
source => "/my/tmp/dir/$name.rpm",
require => File["/my/tmp/dir/$name.rpm"],
}
}
Edit: it is generally advisable to use a local yum repo instead, see also the first comment by #rojs below.
The RPM package can be installed this way:
package { 'epel-release-6':
provider => 'rpm',
ensure => 'present',
source => '/usr/local/rpms/epel-release-latest-6.noarch.rpm',
}
It seems the module name you are using is nmap. You can use the same source parameter like this,
source => 'puppet:///modules/nmap/nmap-6.45-1.x86_64.rpm',
The syntax to access a file under a module goes like this,
puppet:///modules/<modulename>/<file you want to access>
See this link here, http://docs.puppetlabs.com/puppet/latest/reference/modules_fundamentals.html#files
Lets start from start :
on server:
$rpm -ivh https://yum.puppetlabs.com/puppetlabs-release-pc1-el-7.noarch.rpm
$yum -y install puppetserver
$vi /etc/sysconfig/puppetserver #change JAVA args
$systemctl start puppetserver
$systemctl enable puppetserver
$vi /etc/puppetlabs/puppet/puppet.conf #Add “dns_alt_names” in [master]
On Agent:
$rpm -ivh https://yum.puppetlabs.com/puppetlabs-release-pc1-el-7.noarch.rpm
$yum -y install puppet-agent
$systemctl start puppet
$systemctl enable puppet
$vi /etc/puppetlabs/puppet/puppet.conf # Add “server = pupmaster” in [main]
puppet cert list
puppet cert sign
/etc/puppetlabs/code/environments/production/manifests/site.pp:
node webserver {
class { 'apache': }
}
node dbserver {
class { ‘mysql’: }
}
mkdir –p /etc/puppetlabs/code/environments/production/modules/apache/{manifests, files}
apacheinstall.pp:
class apache::apacheinstall {
if $osfamily == 'redhat' {
package { 'httpd':
ensure => 'latest'
}
service {'httpd':
ensure => 'running',
require => Package["httpd"],
}
file { '/var/www/html/ndex.html':
mode => "0644",
owner => 'root',
group => 'root',
source => 'puppet:///modules/apache/index.html',
}
}
elsif $osfamily == 'debian' {
package { 'apache2':
ensure => 'latest'
}
service {'httpd':
ensure => 'running',
require => Package["httpd"],
}
}
}
INIT.pp
class apache {
notify { 'Installing and Configuring Webserver for $osfamily': }
include apache::mysqlinstall
}
Mysqlinstall.pp:
class apache::mysqlinstall {
exec { 'wget':
path => [ "/bin/", "/sbin/", "/usr/bin/", "/usr/sbin/" ],
command => "/usr/bin/wget https://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm && rpm -ivh /tmp/mysql57-community-release-el7-9.noarch.rpm",
cwd => '/tmp/',
creates => '/etc/firstruns/p1.done',
}
}

Puppet and composer project

A small puppet question
I am creating a composer project like so.
composer::project { 'project-test':
ensure => 'latest', #or installed?
target => '/home/test/www',
dev => false,
require => Package ['php', 'apache']
}
And then from an exec I want to require it as a resource. How can I?
Example of exec:
exec { 'generate-tests' :
command => 'php tests.php',
path => '/usr/bin/',
cwd => "/home/test/www/bin",
logoutput => 'true',
#require => composer::project['project-test']
}
Since what you're requiring is a resource, it should be capitalized as follows:
require => Composer::Project['project-test']

Puppet installing packages, but these do not seem to work

I have the following puppet file. It seems to have installed everything without errors, but commands such as yo or bower dont seem to work. Any idea why?
class yeoman {
Exec { path => [ "/bin/", "/sbin/" , "/usr/bin/", "/usr/sbin/" ] }
$yeomanPackages = ["git", "rubygems", "libjpeg-turbo-progs", "optipng", "phantomjs", "python-software-properties" ]
package { $yeomanPackages:
ensure => "installed",
require => Exec['apt-get update'],
}
exec { "apt-get update":
command => "/usr/bin/apt-get update"
}
package { 'compass':
ensure => latest,
provider => 'gem',
require => Package["rubygems"],
}
package { 'yo':
ensure => present,
provider => 'npm',
require => Class["nodejs"],
}
package { 'grunt-cli':
ensure => present,
provider => 'npm',
require => Class["nodejs"],
}
package { 'bower':
ensure => present,
provider => 'npm',
require => Class["nodejs"],
}
}
include nodejs
include yeoman
I have used the following nodejs module:
https://forge.puppetlabs.com/willdurand/nodejs
Running yo / bower prints out:
-bash: yo: command not found
Thanks!

Puppet - Install PHP with LibXML module, with the XSLT extension enabled (--with-xsl)

I need to ensure puppet installs Php with LibXML with the '--with-xsl' flag.
I have the following class for all things php:
class php {
package { "php5-cli": ensure => present }
package { "php5-dev": ensure => present }
package { "php5-mysql": ensure => present }
package { "php-pear": ensure => present }
package { "php5-common": ensure => present}
package { "php5-fpm": ensure => present}
package { "php5-cgi": ensure => present}
package { "php-apc": ensure => present}
exec { "pear upgrade":
command => "/usr/bin/pear upgrade",
require => Package["php-pear"],
}
}
Not sure how to use flags here.
Many thanks in advance.
You can try this if you want to install with --with-xsl flag for all of them :
all_php_packages = ["php5-cli","php5-dev","php5-mysql","php-pear",
"php5-common","php5-fpm","php5-cgi","php-apc"]
package{ $all_php_packages :
ensure => present,
install_options => ["--with-xsl","--some-other-option",],
}

Resources