Resource ordering of Execs not working as expected

58 views
Skip to first unread message

Jake Lundberg

unread,
Sep 19, 2014, 1:59:34 PM9/19/14
to puppet...@googlegroups.com
Puppet 3.6.2

First, I understand that Execs try not to run multiple times if called many times by many resources and typically wait until they've all been "collected" from all resources, but I have a specific case where I need different Execs to run in a particular order based on a set of resources that change.   

The basic pattern is:
1.  Install/update Configuration file (configuration gets updated on all version changes)
2.  Stop Exec script subscribes to Configuration file
3.  Package Install/update notifies Start Exec script
4.  Package requires Configuration file

The basic resource ordering in the manifest looks like:

  require foo::config  # This contains the File['Config'] resource

  #This might be redundant, but trying to force this relationship
  File['Config'] -> Package["foo"]

  package { ["foo"]:
    ensure  => "${version}-${release}",
    notify  => Exec['start']
  }

  # Start, stop, restart functions for ads server
  file {"/usr/local/sbin/control.sh":
    source => "puppet:///modules/foo/control.sh",
    ensure => present,
    owner  => root,
    group  => root,
    mode   => 0744,
  }

  exec { "stop":
    path        => "/usr/local/sbin/:/usr/local/jdk/bin:/bin:/sbin:/usr/sbin:/usr/bin",
    command     => '/usr/local/sbin/control.sh stop',
    refreshonly => true,
    logoutput   => true,
    subscribe   => File['Config'],
    require     => File['/usr/local/sbin/control.sh']
  }

  exec { "start":
    path        => "/usr/local/sbin/:/usr/local/jdk/bin:/bin:/sbin:/usr/sbin:/usr/bin",
    command     => '/usr/local/sbin/control.sh start',
    refreshonly => true,
    logoutput   => true,
    require     => File['/usr/local/sbin/control.sh']
  }


However, when puppet apply runs this is what happens:

1.  Configuration file is installed/updated, schedules a refresh of Stop Exec
2.  Package is installed, schedules refresh of Start Exec
3.  Start Exec runs
4.  Stop Exec runs

There's probably a better way of doing this (possibly with run stages), I'm just curious why this plan does not work.   I'm very open to improvements.

Cristian Falcas

unread,
Sep 19, 2014, 2:13:11 PM9/19/14
to puppet...@googlegroups.com
The order of resources in the manifest doesn't matter. Puppet will build a graph from all resources and dependencies and executes resources from the same level randomly.

You need something like this:


exec { "start":
    path        => "/usr/local/sbin/:/usr/local/jdk/bin:/bin:/sbin:/usr/sbin:/usr/bin",
    command     => '/usr/local/sbin/control.sh start',
    refreshonly => true,
    logoutput   => true,
    require     => [File['/usr/local/sbin/control.sh'], Exec['stop'],
  }




--
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/b892a4d6-4356-40ab-95a2-ab8ca218e2d1%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jake Lundberg

unread,
Sep 19, 2014, 3:00:28 PM9/19/14
to puppet...@googlegroups.com
Yes Cristian, I understand that, but the issue is less the order of the Execs in relation to each other, but when the Execs run in relation to the config file resource and the package resource.   I need for the stop Exec to run before the package is installed, and then the start Exec to run.   This may be an issue with using Execs in the first place due to the way the get collected and their execution strategy to reduce duplicate runs.    

I'm hoping execution order is: File['Config'] -> Exec['stop'] -> Package['foo'] -> Exec['start'] 
(In fact I used that exact ordering syntax at one point).   

BTW, using:
Exec['stop'] -> Exec['start'] did cause stop to run before start, just AFTER Package['foo'] is installed, so thank you for that.   This doesn't solve my issue however as I really need the stop to run before package installation/upgrade.     

Jake

Cristian Falcas

unread,
Sep 19, 2014, 6:10:25 PM9/19/14
to puppet...@googlegroups.com
Your File['Config'] -> Exec['stop'] -> Package['foo'] -> Exec['start']  should do what you want.

Can you also try to require Exec['stop'] in your package foo?

Also, the refreshonly => true on you stop exec I don't think it matters. You will need a notify Exec[stop] in your config for that.



jcbollinger

unread,
Sep 22, 2014, 10:44:34 AM9/22/14
to puppet...@googlegroups.com


On Friday, September 19, 2014 12:59:34 PM UTC-5, Jake Lundberg wrote:
Puppet 3.6.2

First, I understand that Execs try not to run multiple times if called many times by many resources and typically wait until they've all been "collected" from all resources


Not exactly.  Execs run at most twice per Puppet run.  They run at most once if they are refreshonly or if they do not receive any events from other resources.  (If they are refreshonly then they run only if they receive an event from another resource.)  When they run relative to when other resources are applied (and whether resources send them events) is shaped by resource relationships, just as with all other resource types.

ObYoda: "Do... or do not.  There is no 'try'."

 
, but I have a specific case where I need different Execs to run in a particular order based on a set of resources that change.   



That's what resource relationships are for.  Cristian has showed you how.  If that doesn't seem to be working for you then it would help us help you if you present a complete -- but simple -- example that demonstrates your problem.


John

Jake Lundberg

unread,
Sep 22, 2014, 1:26:54 PM9/22/14
to puppet...@googlegroups.com
Hrm, well, with your help, I got this to work in the order I was expecting.   I think I had a few problems here.

1.  My original ordering was:
 File['Config'] -> Exec['stop'] -> Package['foo'] -> Exec['start'] 

I changed this to:
 File['Config'] ~> Exec['stop'] -> Package['foo'] ~> Exec['start'] 

It helps when I RTFM on using ~> for notifications instead of -> for pure ordering.

2.  When I wasn't using that ordering syntax, I had:

  exec { "stop":
    path        => "/usr/local/sbin/:/usr/local/jdk/bin:/bin:/sbin:/usr/sbin:/usr/bin",
    command     => '/usr/local/sbin/control.sh stop',
    refreshonly => true,
    logoutput   => true,
    subscribe   => File['Config'],
    require     => File['/usr/local/sbin/control.sh'"]
  }

This is because there are cases when the foo::config is created, but foo is not (meaning the control files are not created).   I figured this would create the proper order, but it doesn't seem to have.   

3.  Using different types of configuration patterns.  I kept flipping between using subscribe/notify and ->/~> ordering syntax and most likely screwed something up in the interim.   I eventually made a mistake and got some dependency cycle issues which actually helped quite a bit in figuring out my error in logic.

BTW, "refreshonly => true" is still set on both execs and is working properly.   

Thank you for the help!!!
Jake
Reply all
Reply to author
Forward
0 new messages