Puppet exec/wget - puppet

I am trying to download a file from remote location into a directory in puppet.
.pp file
class test::test {
exec { 'wget http://10.0.0.1/test/test.txt':
cwd => '/opt/check',
path => ['/usr/bin', '/usr/sbin',],
}
}
I also tried with wget module in puppet :
class test::test {
include ::wget
wget::fetch { 'http://10.0.0.1/test/test.txt':
destination => '/tmp/',
timeout => 0,
verbose => false,
}
}
I am not getting the file downloaded, is there something i am doing wrong or is there a better way?
Please let me know.

Run which wget on your node to ensure you are including the right path, on my centos machine it's /bin/wget.
I often (and it's probably a bad habit) include the full path in the comand so I'd put /bin/wget http://10.0.0.1/test/test.txt
Have you tried running that command on the machine manualy?
Check this link out https://puppet.com/docs/puppet/5.5/type.html#exec
exec { 'get-test.txt':
cwd => '/opt/check',
command => '/bin/wget http://10.0.0.1/test/test.txt',
path => ['/usr/bin', '/usr/sbin',],
creates => '/opt/check/test.txt',
}
The "creates" stops running the exec if the file exists, you want to do that or every time puppet runs (default every 30 minutes) it'll run that command again.
I just ran a test on my machine, I created a file test.pp and put this in it;
exec { 'get-google':
cwd => '/tmp',
command => '/bin/wget http://www.google.com',
path => ['/usr/bin', '/usr/sbin',],
creates => '/tmp/index.html',
}
Then ran puppet apply test.ppand it worked, if you want to test small blocks of code that's a handy way of doing it.
Also, does the /opt/check directory exist?

Related

How to provide a startup service file in Puppet

We have RedHat 7.2 Linux OS and use puppet to perform our tasks. I am using puppet to install some software, which has worked fine and now the final step is to create an OS level service. In earlier versions of RHEL, we used chkconfig but that has been replaced with systemctl. Of course, the recommended way of performing this task is using a service. Since this is a custom software, I have my own startup script that I usually copy over to /etc/init.d, run chkconfig and then startup the service. How do I perform these tasks via Puppet for RedHat 7.2 OS ? I only want to create the service (not start it up or anything). This way, when the server reboots, the service will startup the app.
EDIT :
#redstonemercury for RHEL 7 I would think the following would be required. But your suggestion definitely helps as I was thinking along the same lines.
https://serverfault.com/questions/814611/puppet-generated-systemd-unit-files
file { '/lib/systemd/system/myservice.service':
mode => '0644',
owner => 'root',
group => 'root',
content => template('modulename/myservice.systemd.erb'),
}~>
exec { 'myservice-systemd-reload':
command => 'systemctl daemon-reload',
path => [ '/usr/bin', '/bin', '/usr/sbin' ],
refreshonly => true,
}
In puppet, use a package resource to install the package (assuming it's in repos that you're declaring already), then use a file resource to declare the /etc/init.d file, and put require => Package[<package_resource_name>] as a parameter in the file declaration to ensure the custom file gets created after the package has installed (so doesn't potentially get overwritten by the package's /etc/init.d file). E.g.:
package { 'mypackage':
ensure => present,
}
file { '/etc/init.d/mypackage':
ensure => present,
content => template('mypackage/myinitd'),
require => Package['mypackage'],
}
This is if you want to use a template. For a file, instead of content use source: source => puppet://modules/mypackage/myinitd

Puppet exec a command before the package is installed

I am trying to run a power shell script just before the Pacakage starts installing an msi installer. The script cleans up certain un-managed resources that would block installer.
What I tried is,
file { 'c:\Test\cleanup.ps1.file' :
path => 'c:\Test\cleanup.ps1',
ensure => present,
source => 'puppet:///modules/test/cleanup.ps1',
source_permissions => ignore,
}
exec { 'c:\Test\cleanup.ps1.file':
refreshonly => true,
provider => powershell,
}
package { 'ServiceInstaller':
ensure => $version,
require => [Package['Service1Installer'],Exec['c:\Test\cleanup.ps1']],
}
But require attribute doesn't fire the command. Could someone please help me to achieve this behaviour.
There is this notify command, that would send a EXEC notification, but that happens after the installation. What I need is before the installation. Thanks in advance.
The trick to getting this working properly is that something has to write c:\Test\cleanup.ps1.file only when you need the script to be triggered to run, and the exec resource has to subscribe to it. Otherwise, if that file doesn't change, and the exec isn't subscribed, the exec resource does not think it needs to run so the puppet run completes but the script never fires.
Based on the code you pasted here, it looks like you're specifying $version in the class? And I'm guessing you're updating this either in the class or in hiera explicitly when you want to upgrade? If so, you could have the c:\Test\cleanup.ps1.file file write an inline template and just put the version number in that file. When you update the version in the class/hiera/wherever in puppet you're doing this, the file would update and the exec would kick off.
This would look something like:
file { 'c:\Test\cleanup.ps1.file' :
path => 'c:\Test\cleanup.ps1',
ensure => present,
content => inline_template("<%= #version %>"),
source_permissions => ignore,
}
exec { 'c:\Test\cleanup.ps1.file':
refreshonly => true,
provider => powershell,
subscribe => File['c:\Test\cleanup.ps1.file'],
}
package { 'ServiceInstaller':
ensure => $version,
require => [Package['Service1Installer'],Exec['c:\Test\cleanup.ps1']],
}
This is assuming you were just trying to use the cleanup.ps1.file as a trigger for the exec. If there is stuff in that file you need for other purposes, then leave that declaration as you had it, and make another file declaration as a trigger file with just the version in an inline template, and subscribe the exec to that one instead of the cleanup.ps1.file

Running a command using puppet only if it has not been executed earlier

Suppose I want to make sure that my VM has devstack on it.
exec{ "openstack":
command => "git clone https://git.openstack.org/openstack-dev/devstack",
}
This is the puppet code I write for it and it works fine for the first time. Now I want to put a check. I want to clone the repository only if it has not been done already. How to do that
You say
exec { 'openstack':
command => 'git clone https://git.openstack.org/openstack-dev/devstack',
creates => '/path/to/somewhere/devstack',
cwd => '/path/to/somewhere',
path => '/usr/bin',
}
Now if the directory /path/to/somewhere/devstack exists the clone command won't run.
exec { "openstack":
command => 'git clone https://git.openstack.org/openstack-dev/devstack /path/to/devstack",
unless => 'test -d /path/to/devstack'
}
its a really hacky way to handle this. you should look into the vcsrepo puppet module https://github.com/puppetlabs/puppetlabs-vcsrepo

Puppet not executing command. Getting stuck and giving timeout

exec { "stop old application instance":
cwd => "${install_dir}",
path => ['/usr/bin','/bin','/usr/sbin','/sbin', '/bin/unlink', '/usr/local', '/usr/local/bin/'],
onlyif => "test -e '${install_dir}/${app_package_dir}/processes.json'",
group => 0,
user => 'root',
command => "pm2 delete /var/lib/application_folder/processes.json"
}
Puppet is getting stuck here and not able to execute the command. Not understanding the reason. Error log is given bellow
Error: Command exceeded timeout
Wrapped exception:
execution expired
Error: /Stage[main]/application::Install/Exec[stop old application instance]/returns: change from notrun to 0 failed: Command exceeded timeout
Any help will be much appreciated.
https://ask.puppet.com/question/1308/command-exceeded-timeout/
Puppet by default expects your command to finish running in 300 seconds or less. Then it gives up waiting and assumes the command failed.
I know nothing about pm2 to help you figure out why your command is taking so long. But if that's normal, then the link above suggests you add
timeout => 1800,
to your puppet definition.
I would recommend to manually find where the pm2 command is coming from ( $ which pm2 ) and then using the entire path of the command instead of using the path property. Something like this:
exec { "stop old application instance":
cwd => "${install_dir}",
onlyif => "test -e '${install_dir}/${app_package_dir}/processes.json'",
user => 'root',
command => "/usr/bin/pm2 delete /var/lib/application_folder/processes.json",
logoutput => 'onfailure',
}
Notice the logoutput property to see the output of the command only in case something breaks. I don't think you need to specify the group
You can try to put below in your puppet global script file :
Exec {
timeout => 0,
}

Puppet refuses to unzip archive

I want to download several libraries (guzzle, pimple) and unzip them immediately after.
For guzzle it works without any problems, however it refuses to unzip pimple and returns following error:
Exec[unflate-pimple]/returns: change from notrun to 0 failed: tar
-zvxf pimple-v1.1.1-0.tar.gz returned 2 instead of one of [0]
My exec:
exec {
"unflate-$lib_name":
cwd => "/var/www/lib/$lib_name",
command => "tar -zvxf $lib_name-$lib_version_prefix$lib_version.tar.gz",
path => "/usr/bin:/usr/sbin:/bin",
require => Exec["download-$lib_name"]
}
Where
$lib_name = "pimple"
$lib_version_prefix = "v"
$lib_version = "1.1.1-0"
Unzipping it manually in the terminal when connecting through SSH works fine.
I already tried unzipping and zipping it again.
I feel completely lost, where is the problem?
To debug this kind of misbehavior, add the logoutput => true parameter to the exec resource.
exec {
"unflate-$lib_name":
cwd => "/var/www/lib/$lib_name",
command => "tar -zvxf $lib_name-$lib_version_prefix$lib_version.tar.gz",
path => "/usr/bin:/usr/sbin:/bin",
require => Exec["download-$lib_name"],
logoutput => true,
}
Newer versions of Puppet default to on_error, which would be fine for your case, too.
The agent will then add the output of tar to the log. I cannot debug this for you further without seeing that output, but I suspect you will be able to solve the issue on your own once you see it.

Resources