Puppet execute command only if file does not exist - puppet

I am trying to use the following code which should perform some action only if a certain file does not exist. If the file exists, it should skip that task. I cannot get it to work.
exec {"is_file_there":
command => "true",
path => ["/usr/bin","/usr/sbin","/bin"],
unless => "test -e /tmp/some_file",
}
somecommand {
..
..
require => Exec['is_file_there'],
}
As an example, I tried using file but even that did not work. This is just an example for purpose of demonstrating the issue.
exec {"is_file_there":
command => "true",
path => ["/usr/bin","/usr/sbin","/bin"],
unless => "test -e /tmp/some_file",
}
file {'/tmp/success'
ensure => present,
require => Exec['is_file_there'],
}
EDIT : I am trying to create a dependency between another resource and exec. The other resource does not allow onlyif. The example about file is just that an example

According to https://puppet.com/docs/puppet/7/types/exec.html#exec-attribute-creates the "creates" option in "exec" will only run "command" if the file doesn't exist:
exec {"is_file_there":
command => "some_action_command",
path => ["/usr/bin","/usr/sbin","/bin"],
creates => "/tmp/some_file",
}

You could try something like this:
exec {"Some title":
command => "Your command",
path => ["/usr/bin","/usr/sbin","/bin"],
unless => "test -e /tmp/some_file",
}
So, your command is going to execute unless the result of test -e /tmp/some_file is success (exit code 0), that is, the file exists.

Related

Notify from an Exec only if the exec was succesfull

I am currently learning puppet, and I am attempting to have an exec that will notify another exec but only if the first exec is succsfull. However currently I am struggling to figure out how to do this. Right now I have:
exec { 'first command':
command => "some command"
path => '/usr/bin',
notify => Exec["second command"],
}
exec { 'second command':
command => "run another command if first command was succesfull",
path => '/usr/bin',
refreshonly => true,
}
How can this be modified so that the second command is only run if the first command is successful as currently it is run no matter what after the first command?

Puppet: how many times an exec block with creates run?

I have the below two exec resources and would like the exec resource run the script to run whenever the file /var/lib/my-file is not present. I'm wondering what would happen if the file never gets created. Would the exec resource check if file exists run forever in a loop until it gets created?
exec { 'run the script':
command => "python my-script.py",
path => '/bin:/usr/bin:/usr/local/bin',
timeout => 900,
subscribe => File["my-settings.yaml"],
refreshonly => true,
}
exec { 'check if file exists':
command => 'true',
path => '/bin:/usr/bin:/usr/local/bin',
creates => '/var/lib/my-file',
notify => Exec['run the script']
}
A resource is only applied once per catalog application, which occurs once per catalog compilation per node. You can verify this for yourself by trying it out.
If the Python script fails to create the file, the resource would simply be applied again during the next catalog application. Otherwise, idempotence prevails and the resource is not applied because the file already exists.
Additionally, you should simplify your resources into:
exec { 'run the script':
command => 'python my-script.py',
path => '/bin:/usr/bin:/usr/local/bin',
timeout => 900,
creates => '/var/lib/my-file',
subscribe => File["my-settings.yaml"],
refreshonly => true,
}
This is functionally the same as what you have in your question and is more efficient and easier to read.

How to install and run a script in Puppet

I am new to Puppet..I am trying to install a shell script and exceute it using Puppet. The shell script after running creates another conf file and places in a specific location /usr/local/conf/app.conf. How can I write a puppet code to execute this script and then take the output file and scp it to another server (in my case its the webserver). Can someone please help.
Let's assume you have developed a module named webconfig and your puppet config dir is /etc/puppet.
You would need to store your shell script as /etc/puppet/modules/webconfig/files/script.sh
Your puppet code would partially look like this:
file { '/path/to/script.sh':
ensure => present,
source => 'puppet:///modules/webconfig/script.sh',
mode => '0644',
owner => 'root',
group => 'root',
}
->
exec { 'Generate the config':
command => '/path/to/script.sh',
cwd => '/path/to',
user => 'root',
}
->
exec { 'SCP the config':
command => 'scp /usr/local/conf/app.conf user#remote-server:',
cwd => '/path/to',
user => 'root',
}

How to use ExtUtils::MakeMaker to install data in a custom directory

I need to install my main script (as executable) in /usr/bin (depends on the INSTALL_BASE). That part is done.
The next one is to install into the directory /usr/share/project_name/data options.txt, this one is hard for me, see my codes:
Manifest file:
data/options.txt
script/joel-perl
Makefile.PL
Makefile.PL
use ExtUtils::MakeMaker;
WriteMakefile (
NAME => 'joelperl',
VERSION_FROM => 'script/joel-perl',
PREREQ_PM => {
'Switch' => 0
},
EXE_FILES => ['script/joel-perl'],
PM => {
'data/options.txt' => '$(INSTALL_BASE)/share/project_name/data'
}
);
When running:
perl Makefile.PL INSTALL_BASE="/usr"
make
I get "ERROR: Can't create '/usr/share/project_name'", so my question is:
How to add/copy files to an especific place, like in my case?
See File::ShareDir::Install module:
use ExtUtils::MakeMaker;
use File::ShareDir::Install;
install_share 'data';
WriteMakefile(...);
package MY;
use File::ShareDir::Install qw(postamble);

Run custom services on startup with puppet

I'm migrating our old process of doing our linux configurations to be managed by puppet but I'm having issues trying to figure out how to do this. We add some custom scripts to the init.d folder on our systems to manage some processes, and then these need this command executed on them to launch on startup:
update-rc.d $file defaults
So what I'm doing with puppet is that I have all these scripts residing a directory, and I copy them over to init.d. I then want to call 'exec' on each of these files with the former command and use the file name as an argument. This is what I have so far:
#copy init files
file { '/etc/init.d/':
ensure => 'directory',
recurse => 'remote',
source => ["puppet:///files/init_files/"],
mode => 755,
notify => Exec[echo],
}
exec { "echo":
command => "update-rc.d $file defaults",
cwd => "/tmp", #directory to execute from
path => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:",
refreshonly => true
}
This will copy all the files and it calls exec when something is added/updated, but what I can't figure out is how to pass the name of the file as an argument into the exec command. It seems I'm really close but I just can't find anything to help with what I need to do. Is this the right way to try and achieve this?
Thanks.
Your probably not going to accomplish that if your using ensure => 'directory'. You will want to declare the file resource for each individual init script. And the exec isn't the way to go to enable a service. Use the service resource.
file { '/etc/init.d':
ensure => 'directory',
mode => '0755'
}
file { '/etc/init.d/init_script_1':
ensure => 'present',
owner => 'root',
group => 'root',
mode => '0755',
notify => Service['init_script_1']
}
file { '/etc/init.d/init_script_2':
ensure => 'present',
owner => 'root',
group => 'root',
mode => '0755',
notify => Service['init_script_2']
}
service { 'init_script_1':
ensure => running,
enable => true
}
service { 'init_script_2':
ensure => running,
enable => true
}
Hope this helps.

Resources