How to run shell command on puppet agent

1,099 views
Skip to first unread message

Sans

unread,
Jan 29, 2016, 1:16:45 PM1/29/16
to Puppet Users

Hi all,

Just trying to solve a little thing: I understand that inline_template() gets complied on the PM and return the result that is not native to puppet agent . i.e.

$ls_users = inline_template("<%= `cat /etc/passwd|awk -F: '{print $1}'` %>")
notify
{ "THE SITE NAME: ${ls_users}": }

will print all the users that exist on the PuppetMaster. What's the equivalent thing to do to get the result from the Puppet Agent? I know exec{} can be used but I need to put that value in a variable. Any help?

-S

Steve Traylen

unread,
Jan 29, 2016, 1:19:41 PM1/29/16
to Puppet Users


Hi Santanu,
Hope your well.
This kind of thing is exactly what custom facts are for. Write a custom fact to report the users.
Steve.

---
Steve Traylen
--
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...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/a47c2632-5c8d-4e94-bf25-2563fc071e8f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Sans

unread,
Jan 29, 2016, 1:43:17 PM1/29/16
to Puppet Users

Steve, how you doing?? It's been very long time.......

The list-of-users was just an example.  The command that I actually wanna run is:

$site_id = inline_template("<%= `/usr/bin/mysql -h0 -u${db_user} -p${db_password} -s -r -N -e 'SELECT id FROM ${db_name}.${wp_table_prefix}domain_mapping;'` %>")


on a multi-tenant server where domain_mapping is not  present for all the ${db_name}. I thought about the custom fact and I think I can work around it that way but having something equivalent to inline_template()that I can run on the fly is useful and simpler in this case.

-S

jcbollinger

unread,
Feb 1, 2016, 9:31:08 AM2/1/16
to Puppet Users


On Friday, January 29, 2016 at 12:43:17 PM UTC-6, Sans wrote:

Steve, how you doing?? It's been very long time.......

The list-of-users was just an example.  The command that I actually wanna run is [...]


It makes no difference.  Steve's answer was spot on: facts are the mechanism for conveying information about current node state to the master.  There are multiple mechanisms by which you can implement custom facts, some of them accommodating shell scripting quite directly.

 
I thought about the custom fact and I think I can work around it that way but having something equivalent to inline_template()that I can run on the fly is useful and simpler in this case.


You can use ERB on the client side to evaluate your custom fact if you really want to do, but I don't see what the gains you even in your revised example.  There, ERB is just a wrapper around a shell-out; it would be simpler to just implement that particular fact via a shell script, cutting Ruby and ERB out of the picture entirely.  Even if you used a traditional Ruby custom fact implementation, the ERB in that particular example would be needless, as you could instead just use the Ruby embedded inside, directly.

More generally, ERB is most useful for formatting.  If you find yourself wanting to do much formatting in your custom fact implementations then you're doing something wrong.  Neither of your examples so far actually exhibits that problem, however; instead, the ERB in them is altogether extraneous.


John

Sans

unread,
Feb 1, 2016, 4:16:16 PM2/1/16
to Puppet Users
I agree with Steve comment but the point you guys are missing here it's a multi-tenant system and I'm getting hard time to visualize how a custom fact will handle the situation as the the same command will return different result for different databases, based on the client.

It does make difference in the sense as /etc/passwd is unique for given puppet agent but it's not when you running, e.g. ls ~/Documents|wc -l for different users on the same puppet agent. How you will do the with a custom fact? I'm glad to be educated.

-S

jcbollinger

unread,
Feb 2, 2016, 9:31:03 AM2/2/16
to Puppet Users


On Monday, February 1, 2016 at 3:16:16 PM UTC-6, Sans wrote:
I agree with Steve comment but the point you guys are missing here it's a multi-tenant system and I'm getting hard time to visualize how a custom fact will handle the situation as the the same command will return different result for different databases, based on the client.



Well yes, it's easy to miss something that you never mention.

Multi-tenancy is not an issue of any particular significance here, but if in the same run you want to evaluate that template multiple times with different values of the interpolated variables (i.e. in each of several instances of some defined type), or more generally, if it would be hard for the agent to know for itself which values to use, then that does bring in some additional considerations.  You might still be able to implement it as a custom fact, maybe using a structured fact value such as a hash keyed on DB name, but that's probably a long shot.

The other way to run your own shell (or any other) code on the target node during a catalog run is via the provider for a resource that is being applied.  You might think first of the Exec type, which is built around executing commands on the target node, but that type doesn't allow you to capture the command output for any purpose other than logging.  To capture the output and do anything with it, you must either encapsulate the whole process in a script or other program and Exec that, or you must write a custom type and provider that implement your objective.  In no event do approaches such as these, that work during catalog application, provide any data back to the master beyond what goes into the agent's report.

 
It does make difference in the sense as /etc/passwd is unique for given puppet agent but it's not when you running, e.g. ls ~/Documents|wc -l for different users on the same puppet agent. How you will do the with a custom fact? I'm glad to be educated.


If each of several distinct users is running the agent under his own identity, then the agent will report a possibly-different set of facts for each user.  This is why multi-tenancy is not, in itself, a significant issue.  Indeed, it would be best if each user were identified to the master via a distinct cert with, therefore, a distinct name.  In that case, the master doesn't see it any differently than multiple separate machines.  If instead the different tenants share a cert then they can relatively easily steal configuration data from each other, which might include sensitive and/or confidential information.

It is no special problem if the agent provides different fact values on different runs, even in the case that the tenants share a cert.  The fact-based approach presents a problem only if the agent does not know all the details of the command to run.


John

Reply all
Reply to author
Forward
0 new messages