I am trying to use Hammer in Foreman 1.20.1 on Centos 7.6 to refresh proxy features (or just about any other command other than --version) in a Puppet exec. The command I am using works fine at the shell. It fails in Puppet exec with:
Error: undefined local variable or method `dotfile' for
Notice: /Stage[main]/Profiles::Test/Exec[test]/returns: Did you mean?
##dotfile Notice: /Stage[main]/Profiles::Test/Exec[test]/returns:
Error: No such sub-command 'proxy'.
The code I am using is:
class profiles::test{
exec {'test':
command => '/usr/bin/hammer proxy refresh-features --name $(hostname)',
}
}
include profiles::test
I'm not concerned about idempotency as it will have a refreshonly, I just want to get the command to work.
I have tried adding other options such as path, user, environment etc to no avail. Any help appreciated.
from clues I found at https://github.com/awesome-print/awesome_print/issues/316 and https://grokbase.com/t/gg/puppet-users/141mrjg2bw/problems-with-onlyif-in-exec, it turns out that the HOME environment has to be set. So the working code is:
exec {'test':
command => '/usr/bin/hammer proxy refresh-features --name $(hostname)',
environment => ["HOME=/root"],
refreshonly => true,
}
f'ing ruby!
Related
I've created a puppet script to install Azure client and in the last step before using yum install, I want to make sure that the package haven't installed before for prevent from duplicate install.
My concept is
Execute the script if the output from az --help give nothing (which mean there's no Azure install)
or if you guys have any better choices please guide me, thanks!
And my code is
#install azure client
exec { 'install-azure':
command => '/bin/yum install azure-cli -y',
path => '/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:',
unless => 'az --help',
#require => Exec['yumrepolist']
}
It seems like there're something wrong with the code, I've checked a particular agent by using
puppet agent -t
Notice:
/Stage[main]/Os_preparation::Azure_install/Exec[yumrepolist]/returns:
executed successfully Error:
/Stage[main]/Os_preparation::Azure_install/Exec[install-azure]: Could
not evaluate: Could not find command 'az'
Any ideas? Thanks
You should install azure-cli using a package resource. Also, you should add its Yum repository as a yumrepo resource.
Try something like the following, which replicates the instructions on https://learn.microsoft.com/en-us/cli/azure/install-azure-cli-yum?view=azure-cli-latest.
yumrepo { 'azure-cli':
descr => 'Azure CLI',
baseurl => 'https://packages.microsoft.com/yumrepos/azure-cli',
enabled => 1,
gpgcheck => 1,
gpgkey => 'https://packages.microsoft.com/keys/microsoft.asc',
}
package { 'azure-cli':
ensure => installed,
require => Yumrepo['azure-cli'],
}
I'll need to add a apt repository key to a bunch of ubuntu hosts using puppet.
Would a statement like this work for that?
exec {"add apt key for elastic":
command => "/usr/bin/curl https://packages.elasticsearch.org/GPG-KEY-elasticsearch | /usr/bin/apt-key add -",
}
thanks
Yes, this should work but this will also apply the same configuration whenever you rerun Puppet.
From exec docs:
Any command in an exec resource must be able to run multiple times without causing harm — that is, it must be idempotent. There are three main ways for an exec to be idempotent:
The command itself is already idempotent. (For example, apt-get update.)
The exec has an onlyif, unless, or creates attribute, which prevents Puppet from running the command unless some condition is met.
The exec has refreshonly => true, which only allows Puppet to run the command when some other resource is changed. (See the notes on refreshing below.)
I try and only use execs if I really have to. One of the reasons being that you have to code the exec so that it only runs when you want to. Instead, you can use the apt module. This will only place the key on the host if it does not already exist. The resource is under puppet control so will not be added on subsequent runs:
include apt
apt::key { 'elasticsearch':
id => '46095ACC8548582C1A2699A9D27D666CD88E42B4',
options => 'https://packages.elasticsearch.org/GPG-KEY-elasticsearch',
}
I'm trying to install Groovy via Puppet on SUSE SLES 11 SP2. I have the Groovy files installed, but now I need to set the environment variables. I'm using a shell script to set the values and when I echo the values, they are correct.
echo $JAVA_HOME
/myapplication/mypath/jdk1.6.0_30
When I run the command "groovy -version" I get this error: /bin/javaAVA_HOME is not defined correctly, can not execute: /myapplication/mypath/jdk1.6.0_30.
That's not a typo, that's actually the output I get! :)
This is the correct path to my java installation. Why is "/bin/java" replacing the "J" in "JAVA_HOME"? I searched /bin and /usr/bin and neither directory has a java directory.
If I set the values from the command line on the server, everything works fine.
Here is my shell script:
# groovy.sh
export JAVA_HOME=/myapplication/mypath/jdk1.6.0_30
export GROOVY_HOME=/myapplication/mypath/groovy-2.0.7
export PATH=$PATH:/myapplication/mypath/groovy-2.0.7/bin
Here is the snippet from my puppet module:
$groovy_sh = "/etc/profile.d/groovy.sh"
file { $groovy_sh:
ensure => present,
source => "puppet:///modules/groovy/groovy.sh",
owner => "myuser",
group => "mygroup",
mode => 777,
}
I am trying to develop a CakePHP application, and I am using Vagrant to run a testing environment. However, I was getting this error in the browser
Warning (2):
session_start() [http://php.net/function.session-start]:
open(/var/lib/php/session/sess_speva7ghaftl8n98r9id5a7434, O_RDWR) failed:
Permission denied (13) [CORE/Cake/Model/Datasource/CakeSession.php, line 614]
I can get rid of the error by SSHing to the vm and doing
[vagrant#myserver ~]$ sudo su -
[root#myserver ~]# chown -R vagrant. /var/lib/php/session/
I don't want to have to do this every time I restart the vm, so I tried adding this to myserver.pp
exec { 'chown':
command => 'chown -R vagrant. /var/lib/php/session/',
path => '/bin',
user => 'root'
}
but it gets an error while starting up the vm...
err:
/Stage[main]/Myserver/Exec[chown]/returns: change from notrun to 0 failed:
chown -R vagrant. /var/lib/php/session/
returned 1 instead of one of [0] at /tmp/vagrant-puppet/manifests/myserver.pp:35
I was unable to find any useful examples of how to use exec on the internet, and I have never used Vagrant or Puppet before, so the above code is just the best guess I could come up with, and I apologize if it is a simple fix to get this working.
I have verified using which chown within the vm that the path is /bin, and the command is exactly the same as when I run it in the vm myself. I'm thinking it is the user that is causing problem. Do I have that line right? Is it even possible to exec commands as root from a .pp file?
When using exec, you normally have to enter the full path to the command you execute. So if you change your command into
exec { 'chown':
command => '/bin/chown -R vagrant:vagrant /var/lib/php/session/',
path => '/bin',
user => 'root'
}
it should work imo.
However, it depends a lot how you install your application. If the setup/start of the application is also managed with Puppet, you can also manage the directory you're interested in with Puppet, like this
file { "/var/lib/php/session" :
ensure => directory,
group => "vagrant",
owner => "vagrant",
recurse => true,
}
before you start your app. This would be much more the Puppet way, as you manage a reource then instead of executing commands. However, normally /var/lib/... should not be owned by someone other than root.
So you should maybe look into how your app is started and make it start with another user or as root. If it is started with an exec, you can add an additional property
user => root
to it and that should also do the trick.
I want to print out messages and variables when Puppet runs.
I saw there are two functions that might help but couldn't really use them.
My site.pp file:
info "running site.pp info"
debug "running site.pp debug"
When I run on the client:
puppet -t
I don't get those prints.
Here is the puppet script with all the available puppet log functions.
log_levels.pp
node default {
notice("try to run this script with -v and -d to see difference between log levels")
notice("function documentation is available here: http://docs.puppetlabs.com/references/latest/function.html")
notice("--------------------------------------------------------------------------")
debug("this is debug. visible only with -d or --debug")
info("this is info. visible only with -v or --verbose or -d or --debug")
alert("this is alert. always visible")
crit("this is crit. always visible")
emerg("this is emerg. always visible")
err("this is err. always visible")
warning("and this is warning. always visible")
notice("this is notice. always visible")
#fail will break execution
fail("this is fail. always visible. fail will break execution process")
}
Script output (on puppet 2.7):
NB: puppet 3.x colours may alter (all the errors will be printed in red)!
from the Puppet function documentation
info: Log a message on the server at level info.
debug: Log a message on the server at level debug.
You have to look a your puppetmaster logfile to find your info/debug messages.
You may use
notify{"The value is: ${yourvar}": }
to produce some output to your puppet client
If you want to notify user with different type of messages like information, debug, error, warning, alerts, critical and emergency messages then use ‘loglevel’ metaparameter in puppet resources.
With the use of loglevel you can use the same resources for different type of error messages.
e.g for producing debug messages you can use it as,
notify {"debug message":
loglevel => debug,
}
Just as alternative you may consider using execs... (I wouldn't recommend it though)
exec { 'this will output stuff':
path => '/bin',
command => 'echo Hello World!',
logoutput => true,
}
So when you run puppet you should find some output like so:
notice: /Stage[main]//Exec[this will output stuff]/returns: Hello World!
notice: /Stage[main]//Exec[this will output stuff]/returns: executed successfully
notice: Finished catalog run in 0.08 seconds
The first line being logged output.
You can run the client like this ...
puppet agent --test --debug --noop
with that command you get all the output you can get.
excerpt puppet agent help
* --test:
Enable the most common options used for testing. These are 'onetime',
'verbose', 'ignorecache', 'no-daemonize', 'no-usecacheonfailure',
'detailed-exitcodes', 'no-splay', and 'show_diff'.
NOTE: No need to include --verbose when you use the --test|-t switch, it implies the --verbose as well.
That does the task for me. I use that to check vars and display notifications..
notify {"hello world $var1":}
Here's the documentation on Puppet website as well: http://docs.puppetlabs.com/learning/ordering.html#notify-and-subscribe
Easier way, use notice.
e.g
notice("foo.pp works")
or
notice($foo)
If, like me, you don't have access to the puppet master and need to print debug logs to inspect variables on your puppet client machine, you can try writing to a file from your puppet code itself:
file { '/tmp/puppet_debug.log':
content => inline_template('<%= #variable_x.to_s %>'),
}
Have you tried what is on the sample. I am new to this but here is the command: puppet --test --trace --debug. I hope this helps.
You could go a step further and break into the puppet code using a breakpoint.
http://logicminds.github.io/blog/2017/04/25/break-into-your-puppet-code/
This would only work with puppet apply or using a rspec test. Or you can manually type your code into the debugger console. Note: puppet still needs to know where your module code is at if you haven't set already.
gem install puppet puppet-debugger
puppet module install nwops/debug
cat > test.pp <<'EOF'
$var1 = 'test'
debug::break()
EOF
Should show something like.
puppet apply test.pp
From file: test.pp
1: $var1 = 'test'
2: # add 'debug::break()' where you want to stop in your code
=> 3: debug::break()
1:>> $var1
=> "test"
2:>>
https://www.puppet-debugger.com