Puppet: System Administration Automated

Support

Ticket #1268 (new enhancement)

Opened 5 months ago

Last modified 5 months ago

Improve the documentation of how exec works

Reported by: sjmudd Assigned to: community
Priority: normal Milestone:
Component: documentation Version: 0.24.4
Severity: normal Keywords: exec and shell commands
Cc: Triage Stage: Needs more info
Attached Patches: None Complexity: Unknown

Description (Last modified by jamtur01)

The documentation regarding shell commands while reasonably complete doesn't say various things: 1. Exactly how "command" is executed. This seems to be through the shell (which one /bin/sh? /bin/bash?, can this be determined or influenced?) 2. How complex the command can be. Thus are all shell meta characters such as > >> && & etc. allowed 3. Variable interpolation, both by puppet and the shell. I assume puppet variables get evaluated first and this is what is passed to the shell to evaluate. If we want to use shell variables must the $VARIABLE be escaped as \$VARIABLE in order to reach the shell correctly as $VARIABLE? 4. Comments about which file descriptors command can assume are open (only stdout/stderr? is stdin redirected?) 5. Any limits (command size limit) that puppet imposes on "command" 6. A comment regarding the best practice of:

(a) making a large complex command, or (b) writing a separate script which is distributed by puppet from the master and executed from command on the client

I think that for certain more complex actions which might be done inside puppet this information would be invaluable.

Change History

05/28/08 11:32:18 changed by jamtur01

  • description changed.

05/28/08 15:55:20 changed by jamtur01

  • stage changed from Unreviewed to Needs more info.

A lot of this can be found out by examining the exec type - I recommend starting there.

05/28/08 18:28:37 changed by sjmudd

I've done that. http://reductivelabs.com/trac/puppet/wiki/TypeReference#exec

For command no mention of the shell is actually made. Yet implicitly if I can do something like "test du /var/log/messages | cut -f1 -gt 100000" this is actually executing (or appears to be) shell code.

- How this is being done is not documented.

I still don't think my points are answered in the URL I posted.

05/28/08 18:43:20 changed by jamtur01

I meant the code itself.

05/29/08 10:10:03 changed by sjmudd

Yes, but the code doesn't say what you can do or what you can't do. I notice for example that if I want to run shell code using strings with "" I must escape them. This is not explicitly mentioned but it would be useful to say something like:

Escaping: In order to include certain characters in a command such as ", the character may need to be escaped. For example if you want to execute the shell command /bin/echo "hello" then you need to do this in puppet as follows:

exec {

command => "/bin/echo \"hello\"", ...

}

Also note: While you can run multiple commands as follows using the unless construct

exec {

... unless => [ "/bin/echo hello", "/bin/echo me" ],

}

You can't use this construct for the command section. (That's actually a shame as it would be a very nice facility, and make code written this way much more readable.)

The shell used on my CentOS 5 box is /bin/bash. I don't have a freebsd box available but since the default shell is not bash I would imagine that it will be /bin/sh which is not identical to Bash. That's why I think it's worth mentioning that the commands are executed in a shell and how to determine which one it is. It might be nice to even be able to specify this with shell => "/bin/tsch"?

When executing commands from exec there is no explicit mention of what is in the environment and when running puppet I get the following environment: debug: /:main/Node[master.wl0.org]/Exec[some name]: Executing '/bin/env' debug: Executing '/bin/env' /usr/lib/site_ruby/1.8/puppet/util.rb:312: warning: fork terminates thread at /usr/lib/ruby/1.8/timeout.rb:41 notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: HOSTNAME=master.wl0.org notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: TERM=xterm notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: SHELL=/bin/bash notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: HISTSIZE=1000 notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: SSH_CLIENT=::ffff:192.168.0.2 42706 22 notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: SSH_TTY=/dev/pts/2 notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: USER=root notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: LS_COLORS=no=00:fi=00:di=00;34:ln=00;36:pi=40;33:so=00;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=00;32:*.cmd=00;32:*.exe=00;32:*.com=00;32:*.btm=00;32:*.bat=00;32:*.sh=00;32:*.csh=00;32:*.tar=00;31:*.tgz=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.zip=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.bz=00;31:*.tz=00;31:*.rpm=00;31:*.cpio=00;31:*.jpg=00;35:*.gif=00;35:*.bmp=00;35:*.xbm=00;35:*.xpm=00;35:*.png=00;35:*.tif=00;35: notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: SSH_AUTH_SOCK=/tmp/ssh-VVXAA22191/agent.22191 notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: MAIL=/var/spool/mail/root notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: INPUTRC=/etc/inputrc notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: PWD=/var/lib/puppet notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: LANG=C notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: SHLVL=1 notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: HOME=/root notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: LOGNAME=root notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: SSH_CONNECTION=::ffff:192.168.0.2 42706 ::ffff:192.168.0.200 22 notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: LESSOPEN=|/usr/bin/lesspipe.sh %s notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: G_BROKEN_FILENAMES=1 notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: _=/usr/sbin/puppetd notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: OLDPWD=/etc/puppet notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: LANGUAGE=C notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: LC_MESSAGES=C notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: LC_ALL=C notice: /:main/Node[master.wl0.org]/Exec[some name]/returns: executed successfully debug: Finishing transaction -604682804 with 1 changes

This shows that the exec environment is not cleaned prior to exec execution. The 'environment' => option to exec only allows you to add new values according to the documentation. This also means that behaviour may differ when running exec code testing by hand as I did using puppet --debug --test -o and when running it from init scripts and this may be hard to debug.

That's why I suggest that you add a comment about the environment in the exec section and perhaps consider cleaning the environment before running exec.

Sorry for the long post and thanks for considering adding some extra documentation to make some of these things clearer.