The Puppet Labs Issue Tracker has Moved: https://tickets.puppetlabs.com

This issue tracker is now in read-only archive mode and automatic ticket export has been disabled. Redmine users will need to create a new JIRA account to file tickets using https://tickets.puppetlabs.com. See the following page for information on filing tickets with JIRA:

Feature #1014

Services should support 'reload' in addition to 'restart'

Added by Adrian Bridgett over 8 years ago. Updated over 2 years ago.

Status:AcceptedStart date:
Priority:NormalDue date:
Assignee:-% Done:

0%

Category:service
Target version:3.x
Affected Puppet version:0.24.7 Branch:
Keywords:

We've Moved!

Ticket tracking is now hosted in JIRA: https://tickets.puppetlabs.com

This ticket is now tracked at: https://tickets.puppetlabs.com/browse/PUP-1054


Description

currently if a service needs kicking (e.g. a config file changed) you can notify the service, but this leads to a restart. It would be nice if a reload was done if the service was already running (although I suppose there are bound to be some services which require restarts for some files, reloads for others).

A reload would be far faster (shorter service interruption) and potentially more robust.

I’m looking at this since bind stop/start (I hadn’t set “hasrestart”) on Debian etch can fail – it looks like stop command doesn’t wait for bind to exit (I’ll raise a bug with Debian about that)


Related issues

Related to Puppet - Feature #7594: It should be possible to trigger specific actions with no... Accepted 05/19/2011
Related to Puppet - Feature #3323: Create hasreload similar to hasrestart Needs More Information 03/03/2010
Related to Puppet - Feature #3950: Service notifies should be able to specify a type of rest... Accepted 06/07/2010
Duplicated by Puppet - Bug #1353: Red Hat service provider should be enhanced to support bo... Duplicate 06/10/2008

History

#1 Updated by shamot - about 8 years ago

Hello

I am definitely up for this feature as Apache restart instead of reload (suppose the change where reload is sufficient was made) could be very dangerous in certain situations. If restart on production servers is done then in case of apache configuration typo Apache wont IMO start again. Concerning we are running more Apache servers and one config typo resulting to stop them all could be a serious problem.

as far as new configuration design is concerned what about something like:

notify => Service[[apache2""reload]]
notify => Service[[apache2""restart]]

It’s just a suggestion, which maybe isn’t even possible due to puppy configuration concept/design.

Thanks

Tomas

#2 Updated by Luke Kanies about 8 years ago

How would you want this to be configured? I’ve been thinking we need to redesign the service parameters anyway, so that we had a single ‘has’ parameter, that could then accept ‘restart’, ‘reload’, ‘status’, and more.

#3 Updated by Russ Allbery about 8 years ago

I certainly do agree that the feature is desireable, but as a matter of best practice you should also make the restart action in the Apache init script depend on the successful completion of apache2ctl/apachectl configtest. That will help prevent any restarts, whether from Puppet or by an administrator, from causing nasty surprises.

One way to do this is to modify the init script. Another way in Puppet would be:

    restart => "/usr/sbin/apache2ctl configtest && /etc/init.d/apache2 restart"

(using the Debian paths).

#4 Updated by Luke Kanies about 8 years ago

So some relationships would result in a restart, and some would result in a reload, in this Apache example?

How would you want to differentiate between those two in the language?

#5 Updated by Adrian Bridgett about 8 years ago

Thinking about it, I wonder if supporting generic actions would be possible. There is restart and reload, but there could be other actions too (e.g. test, stop, start). Asterisk for example has several kinds of reloads (sip reload, extension reload). These should be associated with the service I think. Oh for object orientated puppet ;–)

#6 Updated by Adrian Bridgett about 8 years ago

The most complex example I can think of is something like Apache. Normally you can just ask it to reload, however sometimes you need to request a restart instead (if you add/remove modules for example).

I presume “has” can be added to? We are shortly going to turn “hasrestart” on by default (due to that bind issue above, all the init scripts I’ve seen so far have supported restart). So we’d be setting hasrestart on a global level and then possibly overriding it for specific services (either unsetting it or adding “status” to the list of haves).

FWIW on Debian there is a “force-reload” which should be provided by most init.d scripts – this does reload (if the program supports it) or restart (if it doesn’t).

What we currently do is this which isn’t too bad, but hides the fact that we are reloading the apache2 service.

class apache2::apache2 {
        service { "apache2":
                enable => true,
                ensure => true,
                hasrestart => true,
       }
        exec { "reload":
                command => "/etc/init.d/apache2 reload",
                refreshonly => true,
                require => Service[[apache2]],
        }
        define site ( $ensure = 'present' ) {
                ...
                notify => Exec[[reload]],
        }
        define mod ( $ensure = 'present') {
               ...
                notify => Service[[apache2]],
        }
}

Many thanks

#7 Updated by Redmine Admin almost 8 years ago

  • Status changed from 1 to Needs Decision

#8 Updated by anarcat - about 7 years ago

  • Affected Puppet version set to 0.24.7

I agree with Luke that making “has” more generic would definitly help here. However, we have yet to resolve the reload vs restart paradigm: if you notify the service, is reload or restart fired?

I would think that reload should be fired if available and that’s it.

Note that this currently breaks Nagios under moderate load here: if Puppet adds a new configuration file to the nagios setup (using files, I haven’t tried the native resources yet) and then goes around restarting nagios, nagios will simly crash because ‘restart’ is unreliable (it properly restarts the server, which sometimes fails because of timeoouts) whereas reload is much more reliable (it just SIGHUP’s the server).

Maybe this should be a fix in the Debian provider to use reload when available…

#9 Updated by Eric Eisenhart about 7 years ago

It’s terrible, but the descriptions earlier in this ticket don’t properly capture the complexity of managing apache. With apache, there’s a third option, “graceful”.

On RHEL, I use:

      restart => "/sbin/service httpd graceful",

From the man page: “[graceful] differs from a normal restart in that currently open connections are not aborted.”. In other words, it takes longer, but it eliminates the possibility of user problems (closed connections halfway through downloading something, etc.) This is normally what I prefer for changing the configuration of apache, and is what I would recommend for most cases.

Apache aside, there’s also some init scripts on my RHEL systems that have other kinds of “restart”, such as “force-reload”, “forcerestart”. Yes, in some cases those are equivalent to something else (such as “force-reload” == “restart”), but for others it really does something different (with autofs it adds —force to command-lines which unmounts things). I haven’t had to use any of those, but surely somebody someday will need to…

#10 Updated by James Turnbull almost 7 years ago

  • Assignee deleted (Puppet Community)

#11 Updated by Nigel Kersten over 5 years ago

  • Assignee set to Nigel Kersten

#12 Updated by Jordan Sissel over 5 years ago

I think notify doing reload-or-restart oversimplifies things. There are other possibly-confusing issues like when you notify a custom define. If that defines a service and an exec, both will get notified. It’s possible the notify-custom-define issue is worth another ticket.

Some thoughts –

That said, if we want a reusable solution, I think it’s about ‘who’ and ‘how’ – who to notify, and how to notify them. The complexities in some applications (apache) mean a human needs to understand when a restart is required or when a reload is sufficient, which begs for some kind of syntax for describing this in puppet.

It gets more complex because you can notify multiple things from a single change. Notify is a special case in puppet in that it puts data on edges in the graph, right? A notify is just a ‘before’ relationship plus some data with that relationship (not sure how it’s implemented in the code, but that’s how I think of it). What if we expanded that a bit? Are there other things we want to store in the edges?

Alternately, notify can be thought of a as a way for one resource to message another when that first resource changes.

Maybe we can expand on 2.6’s –> and <– syntax? Something like

# Syntax idea 1
File["/etc/apache2/sites-enabled/mysite.conf"] -> Service["apache2"]("reload")
Package["apache2"] -> reload Service["apache2"]("restart")
# the () syntax is optional, having (...) would imply a notify

# Syntax idea 2
File["/etc/apache2/sites-enabled/mysite.conf"] -> reload Service["apache2"]
Package["apache2"] -> restart Service["apache2"]
# The first token after the -> would be the 'how' in our notify

# Defining the service:
service {
  "apache2":
    ensure => ...,.
    reload => "some command", # defaults to the provider's "reload"
    restart => "some command", # just like today
    hasrestart => ..., # just like today
    hasreload =>  ...,
}

Custom defines get a bit trickier and may require some new syntax. Maybe a new meta resource called ‘notification’ or ‘notify’ ? Classes could use this, too!

define foo() {
  notify {
    "restart": Exec["some command"];
    "something": [Service["apache2"], AnotherResource["..."]];
  }
}

class bar {
  notify {
    "config-updated": Service["apache2"];
  }
}

# Now we could do:
MyResource["..."] -> "config-updated" Class["bar"]
MyResource["..."] -> "something" Foo["..."]

Thoughts?

#13 Updated by Nigel Kersten over 5 years ago

  • Status changed from Needs Decision to Accepted
  • Assignee deleted (Nigel Kersten)

“if we want a reusable solution, I think it’s about ‘who’ and ‘how’ – who to notify, and how to notify them. ”

Absolutely. I don’t want to keep hacking special cases up when we could solve them all by solving the “how” problem.

#14 Updated by Nigel Kersten almost 5 years ago

  • Target version changed from 4 to 3.x

Just noting #7594 where we’re aiming at more useful notifications.

This ticket will remain targeted at adding “reload” to the Service type.

#15 Updated by James Turnbull over 4 years ago

I added some code that doesn’t make this simpler in #3323 but provides the capability to reload and graceful where the init script has those.

#16 Updated by Jonathan Boyett about 4 years ago

+1 to the code in #3323.

#17 Updated by Anonymous about 4 years ago

Jonathan Boyett wrote:

+1 to the code in #3323.

The same basic commentary applies to this as it does to the graceful equivalent: having more and more boolean values representing what is really a “pick one” option is terrible. This should unify the various “please restart like this” options in a sane way, and until then folks can work around it by explicitly setting the command by hand.

#18 Updated by Patrick Hemmer over 2 years ago

Redmine Issue #1014 has been migrated to JIRA:

https://tickets.puppetlabs.com/browse/PUP-1054

Also available in: Atom PDF