On Monday, December 7, 2015 at 4:51:10 PM UTC-6, Sean wrote:
>
> John,
>
> Thanks for the reply.  To answer your first question, no I'm not 
> completely sure.  What I can say is that I can run the commands in a shell 
> by hand and the result is what I hope for.  When I run puppet, with this 
> particular class included, puppet hangs for a while with no screen output. 
>  This leads me to believe that the "unless" fails and the "command" 
> executes.
>


I suggest that instead of guessing, you run the agent with --debug output 
enabled, which indeed you have done.  That should give you a pretty good 
idea of which commands run and which do not, and at least a somewhat more 
certain understanding of why.

 

>  I can verify that by running (in another shell):
>
> [root@desktop ~]# ps -ef|grep aide
> root     28085     1  0 14:42 ?        00:00:00 sh -c /usr/sbin/aide --init 
> >/dev/null 2>&1 && cp -p ${DBDIR}/${DBNEW} ${DBDIR}/${DBFILE}
> root     28088 28085 20 14:42 ?        00:01:24 /usr/sbin/aide --init
>
>
> I can say when I run the various piece by hand inside an interactive shell 
> everything comes out as expected:
>
> [root@desktop ~]# DBDIR=$(egrep '^@@define DBDIR ' /etc/aide.conf |awk 
> '{print $NF}')
> [root@desktop ~]# echo $DBDIR
> /var/lib/aide
> [root@desktop ~]# DBFILE=$(egrep '^database=file' /etc/aide.conf |awk -F/ 
> '{print $NF}')
> [root@desktop ~]# echo $DBFILE
> aide.db.gz
> [root@desktop ~]# DBNEW=$(egrep '^database_out=file' /etc/aide.conf |awk 
> -F/ '{print $NF}')
> [root@desktop ~]# echo $DBNEW
> aide.db.new.gz
> [root@desktop ~]# test -f ${DBDIR}/${DBNEW} && test -f ${DBDIR}/${DBFILE}
> [root@desktop ~]# echo $?
> 0
> [root@desktop ~]# /usr/sbin/aide --init >/dev/null 2>&1 && cp -p 
> ${DBDIR}/${DBNEW} ${DBDIR}/${DBFILE}
> cp: overwrite ‘/var/lib/aide/aide.db.gz’? y
>
>

The most important point that I was trying to convey to you in my previous 
message was that Puppet does not use a mechanism anything like that to set 
up the environment for the Exec's commands.  It takes the environment 
strings you provide, as interpreted by Puppet at catalog-building time, and 
inserts them *directly* into the environment.  There will therefore be no 
command substitution performed, and any variable interpolation will be of 
Puppet variables, in catalog-building context, not of environment variables 
in the command's runtime context.

As I said, if you need to determine the values of your environment 
variables in the manner you present, then you absolutely do need to script 
that, and have Puppet execute the resulting script.  I also suggested that 
you might write Ruby code that computes the same values, and build a custom 
type and provider around that, with which to replace your Exec.  Although 
cleaner, that would probably require a lot more effort than it's worth.

 

> The cp overwrite prompt above comes from the alias cp='cp -i ' in my 
> shell.  I'm not sure if that would be there inside puppet, but if so I'll 
> modify to negate that option.
>
> For testing, I created a separate class for just this one exec.  I 
> modified the unless and command statements as follows:
>
>     command     => 'echo "/usr/sbin/aide --init >/dev/null 2>&1 && cp -p 
> ${DBDIR}/${DBNEW} ${DBDIR}/${DBFILE}"',
>     unless      => 'echo "test -f ${DBDIR}/${DBNEW} && test -f 
> ${DBDIR}/${DBFILE}" && test -f ${DBDIR}/${DBNEW} && test -f 
> ${DBDIR}/${DBFILE}',
>
> So basically the "unless" echo's what it's doing, then tries to do it. 
>  The "command" just echoes what it would do.  Here's the puppet agent 
> --test --debug output for the class:
>
> Debug: Exec[init-aide-database](provider=posix): Executing check 'echo 
> "test -f ${DBDIR}/${DBNEW} && test -f ${DBDIR}/${DBFILE}" && test -f 
> ${DBDIR}/${DBNEW} && test -f ${DBDIR}/${DBFILE}'
> Debug: Executing 'echo "test -f ${DBDIR}/${DBNEW} && test -f 
> ${DBDIR}/${DBFILE}" && test -f ${DBDIR}/${DBNEW} && test -f 
> ${DBDIR}/${DBFILE}'
> Debug: /Stage[main]/Testenv/Exec[init-aide-database]/unless: test -f $(egrep 
> '^@@define DBDIR ' /etc/aide.conf|awk '{print $NF}')/$(egrep 
> '^database_out=file' /etc/aide.conf|awk -F/ '{print $NF}') && test -f $(egrep 
> '^@@define DBDIR ' /etc/aide.conf|awk '{print $NF}')/$(egrep 
> '^database=file' /etc/aide.conf|awk -F/ '{print $NF}')
>


That last is the 'unless' command and its standard output.  Look carefully 
at what that's telling you: you set up the output to echo the command, and 
the result will reflect all shell expansions applicable to the command.  I 
say again: no further substitutions or expansions will be performed on the 
command or its arguments.  That's the literal command that Puppet is trying 
to execute for you.  I'm sure that if you analyze it carefully enough 
you'll be able to determine why the result is

 

> Debug: /Stage[main]/Testenv/Exec[init-aide-database]/unless: sh: line 0: 
> test: too many arguments
>


This is a failure result, albeit not one of the ones you intended, so 
Puppet proceeds to execute the main command:

 

> Debug: Exec[init-aide-database](provider=posix): Executing 'echo 
> "/usr/sbin/aide --init >/dev/null 2>&1 && cp -p ${DBDIR}/${DBNEW} 
> ${DBDIR}/${DBFILE}"'
>


At this point you should also take note of the "provider=posix".  This 
reflects the default Exec provider for your platform, which the agent seems 
to have determined is Unix-y.  It is extremely important to understand that 
the 'posix' provider executes your command directly, not via a shell.  
Thus, redirections, variable expansions, and other shell constructs in the 
command are not recognized as anything special.  Since this seems not to be 
what you want, you can instruct Puppet to execute the command via a shell 
by adding the parameter provider => 'shell' to your Exec declaration.

 

> Debug: Executing 'echo "/usr/sbin/aide --init >/dev/null 2>&1 && cp -p 
> ${DBDIR}/${DBNEW} ${DBDIR}/${DBFILE}"'
> Notice: /Stage[main]/Testenv/Exec[init-aide-database]/returns: /usr/sbin/aide 
> --init >/dev/null 2>&1 && cp -p $(egrep '^@@define DBDIR ' /etc/aide.conf|awk 
> '{print $NF}')/$(egrep '^database_out=file' /etc/aide.conf|awk -F/ '{print 
> $NF}') $(egrep '^@@define DBDIR ' /etc/aide.conf|awk '{print $NF}')/$(egrep 
> '^database=file' /etc/aide.conf|awk -F/ '{print $NF}')
> Notice: /Stage[main]/Testenv/Exec[init-aide-database]/returns: executed 
> successfully
>


And this shows the result: your Exec was executed successfully, producing 
the given output.  Since it was just an 'echo' command, it is unsurprising 
that this did not have the desired effect on your system's state.

 

> Debug: /Stage[main]/Testenv/Exec[init-aide-database]: The container Class[
> Testenv] will propagate my refresh event
> Debug: Class[Testenv]: The container Stage[main] will propagate my 
> refresh event
>
> So it looks like the strings inside the environment variables aren't 
> interpreted by the shell, they're just passed as literal strings.
>


Well yes, that's exactly what I said before.

 

>  But notably, the the unless test fails with an error from /usr/bin/test 
> that doesn't surface when running interactively.
>


For exactly the reason you just gave.

 

>  I will attempt to run in the shell provider instead of posix,
>


As I said, your approach to setting up the environment will not work as you 
want.  Using the 'shell' provider likely will solve some of your problems, 
but not that one.

 

> but if that fails, I just re-code everything into shell scripts and have 
> puppet push and execute them.  If we need to make this a bug,
>


I don't see any buggy behavior.  Puppet seems to be behaving exactly as I 
would expect, with the only potentially surprising thing being that even 
the 'posix' provider runs the 'unless' and 'onlyif' commands via the 
shell.  I do not account that a bug, however, as (1) it's probably more 
useful behavior, and (2) it's consistent with the example in the docs.


John

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to puppet-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/puppet-users/c06b7ff7-8836-47c2-accf-dc9f1a4218e5%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to