How to remove Cron job through puppet - puppet

I was wondering if there is any way that i can remove my cron which got created through puppet. It works fine when i add "ensure => absent" to my manifest. But the challenge for me is, I have to wait an hour to run my puppet agent on my clients since agent is configured to run on every hour. Also i have to manually edit each job to add "ensure => absent".
Is there any other way that i can remove the cron than adding `"ensure => absent"` to each cron jobs
for example, how can we remove "job1" from all applied servers without adding "ensure => absent"
class cron::my_cron
(
)
{
cron::hourly { 'Job1':
minute => '0',
user => 'root',
command => 'cmd',
environment => [ 'MAILTO=root', 'PATH="/usr/bin:/bin"', ],
}
cron::hourly { 'job2':
minute => '0,5,10,15,20,25,30,35,40,45,50,55',
user => 'root',
command => 'cmd',
environment => [ 'MAILTO=root', 'PATH="/usr/bin:/bin"', ],
}
}

Here is the work around I found.
On my puppet class I have created an array with all my active crons. Then I will pass those list to my bash script. My bash script will install and execute once puppet agent run on my clients.
On my bash script i will grep for all my crons which installed via puppet then i loop through each cron job and compare with my active cron array, If it does not match with my active cron list, will execute the rm command to remove the cron entry.
class cron (
$active_cron=['cron1', 'cron2', 'cron3', 'cron4')
)
{
file {
'/usr/sbin/remove_cron.sh':
ensure => present,
mode => 755,
owner => 'root',
group => 'root',
content => template('cron/remove_cron.erb'),
notify => Exec['remove_cron'],
}
exec { 'remove_cron':
command => "/usr/sbin/remove_cron.sh >> /var/log/remove_cron.log",
path => '/usr/local/bin/:/bin/:/usr/bin/',
require => File['/usr/sbin/remove_cron.sh'],
refreshonly => true,
}
}
My Bash script template
#!/bin/bash
LIST='<%= #active %>'
grep -il puppet* /etc/cron.d/* | grep -il puppet* /etc/cron.d/* | awk -F"/" '{print $NF}' |while read CRON
do
FOUNDIT=$(echo $LIST |grep "\"$CRON\"" |wc -l)
if [ $FOUNDIT -eq 0 ]
then
echo "$(date) : Cron $CRON Removed"
rm -r /etc/cron.d/$CRON
fi
done

You don't have to wait for 30 minutes for the agents to run
Do "mco runall 5" on the puppetmaster to provoke a puppet agent run on all hosts
Then you can use "ensure => absent" and not have to bother with an exec hack

Related

conditions to chain bash scripts with puppet

I am new to puppet and I have two questions. I want to execute 2 successive custom bash scripts:
file{ 'deploy_0':
ensure => 'file',
path => '/home/user_name/scripts/deploy_0.sh',
...
notify => Exec['deploy_core']
}
file{ 'deploy_1':
ensure => 'file',
path => '/home/user_name/scripts/deploy_1.sh',
...
notify => Exec['deploy_core_api']
}
exec { 'deploy_core':
command => '/bin/bash -c "/home/user_name/scripts/deploy_0"',
}
exec { 'deploy_core_api':
command => '/bin/bash -c "/home/user_name/scripts/deploy_1.sh"',
onlyif => 'deploy_core'
}
But this does not work
I know I can put for the onlyif paramter a bash command such as /bin/bash -c "/home/user_name/scripts/deploy_0.sh, but I prefer to declare a file resource.
You used the notify metaparameters correctly and well to specify the scripts needed to be deployed before execution (file before corresponding exec) and should be executed again if the file content changes. You need similar metaparameters for application order on the exec resources if you want similar functionality there. Note that onlyif is an exec attribute that executes a local command on the client and causes the resource to be considered already in sync (not applied due to idempotence) during catalog application if it returns something falsey.
Since you do not need refreshing here from one exec to the other like you did with the file resource, we can use require or before instead.
# before
exec { 'deploy_core':
command => '/bin/bash -c "/home/user_name/scripts/deploy_0"',
before => File['deploy_core_api'],
}
exec { 'deploy_core_api':
command => '/bin/bash -c "/home/user_name/scripts/deploy_1.sh"',
}
# require
exec { 'deploy_core':
command => '/bin/bash -c "/home/user_name/scripts/deploy_0"',
}
exec { 'deploy_core_api':
command => '/bin/bash -c "/home/user_name/scripts/deploy_1.sh"',
require => File['deploy_core'],
}
This will give you the behavior you are looking for.

puppet not able to run shell script from master to client

I am new to puppet. I want to run a shell script call crfs.sh located under /myscripts on a RHEL linux puppet master server.
How do I execute this script on a client or target server?
What you want can be solved using the file and the exec modules of puppet.
class mymodule::myclass {
file { 'my_bash_script':
ensure => 'file',
source => 'puppet:///modules/mymodule/my_bash_script.sh',
path => '/usr/local/bin/my_bash_script.sh',
owner => 'root'
group => 'root'
mode => '0744', # Use 0700 if it is sensitive
notify => Exec['run_my_script'],
}
exec { 'run_my_script':
command => '/usr/local/bin/my_bash_script.sh',
refreshonly => true,
}
}

Puppet test and remove an array of files/folders

I'm looking to make the following code work somehow, it seems if i do not test the files/folders first I end up with the error:
Error: Failed to apply catalog: Parameter path failed on
File[/opt/dynatrace-6.2]: File paths must be fully qualified, not
'["/opt/dynatrace-6.2", "/opt/dynatrace-5.6.0",
"/opt/rh/httpd24/root/etc/httpd/conf.d/dtload.conf",
"/opt/rh/httpd24/root/etc/httpd/conf.d/01_dtagent.conf"]' at
newrelic.pp:35
The pertinent parts
$dtdeps = [
"/opt/dynatrace-6.2",
"/opt/dynatrace-5.6.0",
"${httpd_root}/conf.d/dtload.conf",
"${httpd_root}/conf.d/01_dtagent.conf",
]
exec { "check_presence":
require => File[$dtdeps],
command => '/bin/true',
onlyif => "/usr/bin/test -e $dtdeps",
}
file { $dtdeps:
require => Exec["check_presence"],
path => $dtdeps,
ensure => absent,
recurse => true,
purge => true,
force => true,
} ## this is line 35 btw
exec { "stop_dt_agent":
command => "PID=$(ps ax |grep dtwsagent |grep -v grep |awk '{print$1}') ; [ ! -z $PID ] && kill -9 $PID",
provider => shell,
}
service { "httpd_restart" :
ensure => running,
enable => true,
restart => "/usr/sbin/apachectl configtest && /etc/init.d/httpd reload",
subscribe => Package["httpd"],
}
Your code looks basically correct, but you went overboard with your file resources:
file { $dtdeps:
require => Exec["check_presence"],
path => $dtdeps,
...
This does create all the file resources from your array (since you use an array for the resource title) but each single one of them will then try to use the same array as the path value, which does not make sense.
TL;DR remove the path parameter and it should Just Work.
You can actually simplify this down a lot. Puppet only runs the file removal if the files don't exist, so the check_presence exec is not required.
You can't give a path an array, but you can pass the title as an array and then the paths get automatically made.
$dtdeps = [
"/opt/dynatrace-6.2",
"/opt/dynatrace-5.6.0",
"${httpd_root}/conf.d/dtload.conf",
"${httpd_root}/conf.d/01_dtagent.conf",
]
file { $dtdeps:
ensure => absent,
recurse => true,
purge => true,
force => true,
}
exec { "stop_dt_agent":
command => '[ ! -z $PID ] && kill -9 $PID',
environment => ["PID=\$(ps ax |grep dtwsagent |grep -v grep |awk '{print$1}'))"],
provider => shell,
}
However, running the stop_dt_agent exec is a bit fragile. You could probably refactor this into a service resource instead:
service { 'dynatrace':
ensure => stopped,
provider => 'base',
stop => 'kill -TERM $(ps ax | grep \"dtwsagent\"|grep -v grep|awk '{print \$1}')',
status => "ps ax | grep "dtwsagent"",
}

run Exec only if another Exec ran

how can I configure a Exec to run only if another Exec ran?
I have a manifest like this:
file { $target:
ensure => directory
}
exec { "unzip foobar.zip -C ${target}":
unless => "file ${target}/some-file-form-archive"
}
exec { "chown -R $user ${target}":
onlyif => ???
}
I would like the chown to run only if unzip foobar.zip ran. Of course I could start checking whether some-file-from-archive is already owned by $user, but somehow it does not seem right.
There's an answer here already: http://ask.puppetlabs.com/question/14726/run-exec-only-if-another-exec-ran/
Changing the manifest like this fixes my problem:
exec { 'unpack file':
command => "unzip foobar.zip -C ${target}",
path => '/usr/bin',
creates => "${target}/some-file-form-archive",
require => File[$target, '<archive>'],
notify => Exec[fix archive],
}
exec { 'fix archive':
command => "chown -R ${user} ${target}",
path => '/bin',
refreshonly => true,
}
UPDATE 28.11.2014
motivated by Felix Frank's comment i tried out something else. instead of notify/refreshonly you can ensure all resource in a file-tree are owned by a user like this:
exec { 'fix archive':
command => "chown -R ${user} ${target}",
path => '/bin',
unless => "test 0 -eq $(find ${target} \\! -user ${user} | wc -l)"
}
this way owner is ensured to be $user even if it was changed after unpack file ran.

puppet service wont start

I have the following code for a small class for Tomcat, The class runs fine but the service at the end of the script doesn't start. any guidance would be great. i dont know why the service wont start.
content of the Tomcat6 class
# Class: tomcat6
#
# This module manages tomcat6
#
# Parameters: none
#
# Actions:
#
# Requires: see Modulefile
#
# Sample Usage:
#
class tomcat6 ( $parentdir = '/usr/share',
$tomcat_version = '6.0.37',
$tomcat_major_version = '6',
$digest_string = '171d255cd60894b29a41684ce0ff93a8',
$tomcat_exe = 'tomcat6/tomcat.erb',
$java_home = '/usr/java/latest',
$jvm_route = 'jvm1',
$shutdown_password = 'SHUTDOWN',
$admin_port = 8005,
$http_port = 8080,
$tomcat_user = 'root',
$tomcat_group = 'root',
$admin_user = 'tomcat',
$admin_password = 'tomcat'
) {
$basedir = "${parentdir}/apache-tomcat-6.0.37"
file {'/installs':
ensure => 'directory',
source => 'puppet:///modules/tomcat6/',
recurse => 'remote',
owner => 'root',
group => 'root',
mode => '0755',
}
exec { 'tomcat_untar':
command => 'tar -zxvf /installs/apache-tomcat-6.0.37.tar.gz -C /usr/share/',
cwd => '/usr/share/',
creates => "/usr/share/apache-tomcat-6.0.37",
path => ["/bin"],
require => [File["/installs"]]
}
file { "/etc/init.d/tomcat":
ensure => present,
owner => root,
group => root,
mode => 0755,
content => template($tomcat_exe),
require => Exec["tomcat_untar"]
}
service { "tomcat":
ensure => "running",
enable => "true",
require => File["/etc/init.d/tomcat"]
}
}
contents of tomcat.erb
#!/bin/bash
# description: Tomcat Start Stop Restart
# processname: tomcat
# chkconfig: 234 20 80
JAVA_HOME=/usr/java/jdk1.6.0_26
export JAVA_HOME
PATH=$JAVA_HOME/bin:$PATH
export PATH
CATALINA_HOME=/usr/share/apache-tomcat-6.0.37
case $1 in
start)
sh $CATALINA_HOME/bin/startup.sh
;;
stop)
sh $CATALINA_HOME/bin/shutdown.sh
;;
restart)
sh $CATALINA_HOME/bin/shutdown.sh
sh $CATALINA_HOME/bin/startup.sh
;;
esac
exit 0
Puppet does an /etc/init.d/tomcat status to see if the service is running. If it gets no proper return status if the service is stopped, it will not try to start it.
http://docs.puppetlabs.com/references/latest/type.html#service
Check out hasstatus.
An alternative is to make Puppet grep through the process table with 'pattern' and 'hasstatus' set to false.

Resources