Issue #5224 has been updated by Chris Price.

Notes on solution (pending github pull request and code review):

* we are now unsetting "HOME", "USER", and "LOGNAME" for the duration of any 
process that is launched by puppet.
* had some concerns about the best way to ensure that we still respected the 
custom "environment" property defined in an Exec resource;  we were formally 
handling the temporary environment var manipulation directly in the exec 
provider, but this would have made it tricky to know which user-related 
environment vars to unset further down in the code (in Util.execute_*).  
Instead, we now handle the temporary/custom environment variable manipulation 
(e.g., from Exec resource "environment" property) all the way down inside of 
the Util.execute_* methods.  This way there is no chance that Exec resource's 
"environment" vars are stomped on in between the provider code and the final 
execution code.
* This also allows the possibility for exec commands to be called with custom 
environment variable settings from other spots in our code, which seems 
generally useful.
* a different idea that was discussed was the possibility of simply unsetting 
HOME/USER/LOGNAME globally at puppet startup; I decided against this for a few 
different reasons.  First, globally modifying environment variables seems a bit 
frightening.  Second, concern about unintended side effects; we just dealt with 
a similar set of problems due to the fact that Facter was globally setting 
ENV['LANG'] to 'C' and causing unintended side effects.  Third, keeping the 
scope of these overrides as narrow as possible limits the possibility that 
other Ruby code (e.g., user's custom module code) does something unexpected to 
them in between puppet startup and the point in time when we launch processes.
----------------------------------------
Bug #5224: puppetd does not set environment correctly from Exec
https://projects.puppetlabs.com/issues/5224

Author: Simon Mudd
Status: Accepted
Priority: High
Assignee: Chris Price
Category: exec
Target version: 
Affected Puppet version: 0.25.5
Keywords: exec,crontab,service,environment,HOME
Branch: 


It's possible to run a script using Exec. This can sometimes cause confusion if 
the environment is not set correctly. It's not terribly clear to me exactly 
what environment the user should expect when running Exec. This should be 
better documented if nothing else.

In any case I see on a box we use to run puppet:

    # ps auwx | grep puppetd
    root     25736  0.1  0.1 173072 78728 ?        Ssl  04:02   0:52 
/usr/bin/ruby /usr/sbin/puppetd --logdest=/var/log/puppet/puppetd.log
    root     30268  0.0  0.0  61148   756 pts/0    S+   14:11   0:00 grep 
puppetd
    # strings /proc/25736/environ
    SHELL=/bin/bash
    MAILTO=root
    USER=root
    PATH=/sbin:/usr/sbin:/bin:/usr/bin
    PWD=/
    LANG=en_US.UTF-8
    HOME=/                              <======== started at boot and HOME here 
is _not_ root's HOME directory.
    SHLVL=6
    LOGNAME=root
    _=/usr/sbin/puppetd
    #
    
Now if I restart puppet using service(5) or directly with /etc/init.d/puppet 
restart I get different results:

    ### Using service(5)
    # service puppet restart
    Stopping puppet:                                           [  OK  ]
    Starting puppet:                                           [  OK  ]
    # ps auwx | grep puppetd
    root     13089  1.8  0.0 128100 35264 ?        Ssl  14:24   0:00 
/usr/bin/ruby /usr/sbin/puppetd --logdest=/var/log/puppet/puppetd.log
    root     13158  0.0  0.0  61148   756 pts/0    S+   14:25   0:00 grep 
puppetd
    [root@bc29bprdb-01 ~]# strings /proc/13089/environ
    TERM=xterm-color
    PATH=/sbin:/usr/sbin:/bin:/usr/bin
    PWD=/
    LANG=en_US.UTF-8
    SHLVL=2
    _=/usr/sbin/puppetd
    # cat /etc/redhat-release
    CentOS release 5.4 (Final)
    
    ### Using /etc/init.d/puppet
    # /etc/init.d/puppet restart
    Stopping puppet:                                           [  OK  ]
    Starting puppet:                                           [  OK  ]
    # ps auwx | grep puppetd
    root     14328  3.0  0.0 128108 35272 ?        Ssl  14:26   0:00 
/usr/bin/ruby /usr/sbin/puppetd --logdest=/var/log/puppet/puppetd.log
    root     14808  0.0  0.0  61148   752 pts/0    S+   14:26   0:00 grep 
puppetd
    [root@bc29bprdb-01 ~]# strings /proc/14328/environ
    HOSTNAME=xxxxxxxxx.xxxxxxx.com
    TERM=xterm-color
    SHELL=/bin/bash
    HISTSIZE=1000
    SSH_CLIENT=10.111.22.33 38508 22
    SSH_TTY=/dev/pts/0
    USER=root
    
LS_COLORS=no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=01;32:*.cmd=01;32:*.exe=01;32:*.com=01;32:*.btm=01;32:*.bat=01;32:*.sh=01;32:*.csh=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.bz=01;31:*.tz=01;31:*.rpm=01;31:*.cpio=01;31:*.jpg=01;35:*.gif=01;35:*.bmp=01;35:*.xbm=01;35:*.xpm=01;35:*.png=01;35:*.tif=01;35:
    SSH_AUTH_SOCK=/tmp/ssh-GrzGm30026/agent.30026
    MAIL=/var/spool/mail/root
    PATH=/sbin:/usr/sbin:/bin:/usr/bin
    INPUTRC=/etc/inputrc
    PWD=/root
    LANG=en_US.UTF-8
    SHLVL=3
    HOME=/root
    LOGNAME=root
    SSH_CONNECTION=....
    LESSOPEN=|/usr/bin/lesspipe.sh %s
    G_BROKEN_FILENAMES=1
    _=/usr/sbin/puppetd
    #
    
This box runs CentOS Linux and root's home directory is /root.
The end result is that the environment may vary quite considerably depending on 
the precise puppetd innovation.

Looking at the service man page in Linux (RH's is a bit vague) or better still 
FreeBSD's which does the same you see it says:

    ENVIRONMENT
    When used to run rc.d scripts the service command sets HOME to / and PATH
    to /sbin:/bin:/usr/sbin:/usr/bin which is how they are set in /etc/rc at
    boot time.
    
This makes sense as during startup the only filesystem and directory you can be 
sure to exist is /.

I'd suggest that the environment is set prior to using Exec as follows being 
compatible with crontab(5):

Several environment variables are set up automatically by the cron(8)
     daemon.  SHELL is set to /bin/sh, PATH is set to /usr/bin:/bin, and
     LOGNAME and HOME are set from the /etc/passwd line of the crontab's
     owner.  HOME, PATH and SHELL may be overridden by settings in the
     crontab; LOGNAME may not.

     (Another note: the LOGNAME variable is sometimes called USER on BSD sys-
     tems...  On these systems, USER will be set also).

This behaviour seems standard in Linux and the various BSD flavours. That is 
while you can't expect many environment variables to be set when running Exec 
you do expect $HOME to be set, $SHELL and that's about all. The fact that $HOME 
is not set correctly broke several scripts which assumed that as it was defined 
it was correct.  Specifically MySQL access it's default configuration file 
~/.my.cnf to determine how to access the server. With puppet started at bootup 
HOME was incorrect set and this is the value passed on to the root user.

Note: this issue has taken a while for me to figure out as restarting puppet on 
CentOS where I use it if done via /etc/init.d/puppet would make puppet pick up 
the new $HOME value of /root and then it would work properly and if using 
service(5) I would get different results. Again in both cases these results are 
also different from the behaviour if puppet starts on bootup.

References:
* 
http://www.freebsd.org/cgi/man.cgi?query=crontab&apropos=0&sektion=5&manpath=FreeBSD+8.1-RELEASE&format=html
* 
http://www.freebsd.org/cgi/man.cgi?query=service&apropos=0&sektion=0&manpath=FreeBSD+8.1-RELEASE&format=html

While it is possible to set the environment in Exec (I don't see examples of 
how to do this in http://docs.puppetlabs.com/references/stable/type.html#exec) 
it also seems sensible to document the behaviour and make it consistent 
irrespective of how puppetd is started. cron' default behaviour seems like a 
reasonable starting point.



-- 
You have received this notification because you have either subscribed to it, 
or are involved in it.
To change your notification preferences, please click here: 
http://projects.puppetlabs.com/my/account

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Bugs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-bugs?hl=en.

Reply via email to