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:

Bug #12146

Unable to implement upstart when starting puppet agent in default daemon mode

Added by Glenn Aaldering over 4 years ago. Updated about 4 years ago.

Status:RejectedStart date:01/25/2012
Priority:NormalDue date:
Assignee:-% Done:

0%

Category:-
Target version:-
Affected Puppet version:2.7.9 Branch:
Keywords:upstart ubuntu sysv puppet agent daemon pid fork system programs

We've Moved!

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


Description

It is currently not possible to implement an upstart script when using the puppet agent in default daemon mode. The current workaround is to start the daemon with the —no-daemonize option in the upstart script. Another solution would be to create a flag in puppet like —upstart which will make use of the SIGSTOP function.

After looking at the strace it seems that when starting the puppet agent in daemon mode (this is the default starting behaviour of puppet agent) the daemon seems to ‘detach’ and then exec more then 20 system programs before it will spawn the final process. This is no problem with SysV since that supports pid files. Upstart though currently has no support for pid files and will try to find the pid by itself. The issue though is that upstart will only go to a maximum of 2 forks. More on this can be found here: http://upstart.ubuntu.com/cookbook/#expect

After discussing with masterzen on #puppet-dev he suggested me to file a bug for this since he thought this could be caused by redmine/facter. Before puppet is actually started in ‘daemon’ mode the puppet agent will load providers which will call system programs. Each of these calls spawns a new pid and when all these calls are done the final process is started. Since this is more then 2 forks, upstart cannot track this PID and therefore upstart is unaware of the ‘daemon’.

Some examples on the system program calls:

* arp
* which
* uname
* hostname
* ip
* ifconfig
* whoami
* lsb_release
* lsdev

small example of a working upstart script for puppet agent:

description "puppet agent"
start on runlevel [2345]
stop on runlevel [!2345]
exec /usr/bin/puppet agent --no-daemonize

small example of the failing upstart script for puppet agent:

description "puppet agent"
start on runlevel [2345]
stop on runlevel [!2345]
exec /usr/bin/puppet agent

This has been tested on both Ubuntu Lucid 10.04 64bits with puppet 2.7.1 and Ubuntu 12.04 64bits with puppet 2.7.9. Using upstart for puppetmaster was not tested.

History

#1 Updated by Anonymous over 4 years ago

  • Status changed from Unreviewed to Needs More Information

I thought the general strategy for upstart was that the daemon wouldn’t fork itself, no? In which case using the option to tell it not to seems like the most reasonable choice to me. Is there a reason you don’t want to go down that path, or am I misunderstanding something?

It would also help if you could point to official documentation about what upstart wants processes to do, so that if we add support we can do it properly.

#2 Updated by Glenn Aaldering over 4 years ago

Daniel Pittman wrote:

I thought the general strategy for upstart was that the daemon wouldn’t fork itself, no? In which case using the option to tell it not to seems like the most reasonable choice to me. Is there a reason you don’t want to go down that path, or am I misunderstanding something?

Not sure but seems that you are misunderstanding something. Did you check the link that is in the issue? That would explain a lot probably.

Also to clarify things ill give 2 examples:

—no-daemonize: when using the —no-daemonize flag of puppet agent (/usr/bin/puppet agent —no-daemonize) in the upstart script everything works as expected. Upstart will start puppet agent. Puppet agent keep its starting PID. Example: using “start puppet” will spawn pid 1000. Puppet agent runs with pid 1000.

—daemonize: when using the default deamonized function of puppet agent (/usr/bin/puppet agent) the upstart script will fail. Upstart will start puppet agent. Puppet agent will fork 20+ system programs and then actually start the daemon itself. Example: using “start puppet” will spawn pid 1000. That process forks about 20 system programs. After thats done puppet agent will run on pid 1021.

If the final pid would be 1002 or if puppet sends a sigstop i think we could use expect for the daemonized mode of puppet agent in upstart.

It would also help if you could point to official documentation about what upstart wants processes to do, so that if we add support we can do it properly.

http://upstart.ubuntu.com/cookbook/

#3 Updated by Anonymous over 4 years ago

Glenn Aaldering wrote:

Daniel Pittman wrote:

I thought the general strategy for upstart was that the daemon wouldn’t fork itself, no? In which case using the option to tell it not to seems like the most reasonable choice to me. Is there a reason you don’t want to go down that path, or am I misunderstanding something?

Not sure but seems that you are misunderstanding something. Did you check the link that is in the issue? That would explain a lot probably.

So it would. I totally didn’t see that when I read through, and it is the link to the documentation I wanted. :)

Also to clarify things ill give 2 examples:

—no-daemonize: when using the —no-daemonize flag of puppet agent (/usr/bin/puppet agent —no-daemonize) in the upstart script everything works as expected. Upstart will start puppet agent. Puppet agent keep its starting PID. Example: using “start puppet” will spawn pid 1000. Puppet agent runs with pid 1000.

—daemonize: when using the default deamonized function of puppet agent (/usr/bin/puppet agent) the upstart script will fail. Upstart will start puppet agent. Puppet agent will fork 20+ system programs and then actually start the daemon itself. Example: using “start puppet” will spawn pid 1000. That process forks about 20 system programs. After thats done puppet agent will run on pid 1021.

Yup. So, I understand that: if you daemonize, the Puppet agent doesn’t play nicely with Upstart. If you don’t daemonize, it all works fine.

So, why isn’t “just don’t daemonize” the right answer here?

#4 Updated by Glenn Aaldering about 4 years ago

So, why isn’t “just don’t daemonize” the right answer here?

In Unix and other multitasking computer operating systems, a daemon is a computer program that runs as a background process, rather than being under the direct control of an interactive user.

To me it does not make sense to manage/control the puppet ‘daemon’ with upstart when it is forced to run in the foreground (which is what happens with —no-daemonize). The ideal situation would be that the upstart init script starts the puppet daemon the same way as the sysv init script does.

#5 Updated by Anonymous about 4 years ago

  • Status changed from Needs More Information to Rejected

Glenn Aaldering wrote:

So, why isn’t “just don’t daemonize” the right answer here?

In Unix and other multitasking computer operating systems, a daemon is a computer program that runs as a background process, rather than being under the direct control of an interactive user.

…but that statement isn’t very connected to the “daemonizing” process, which is to fork and detach from the controlling terminal, start a new process group, etc, etc.

To me it does not make sense to manage/control the puppet ‘daemon’ with upstart when it is forced to run in the foreground (which is what happens with —no-daemonize). The ideal situation would be that the upstart init script starts the puppet daemon the same way as the sysv init script does.

I have no idea what you mean here. Upstart, like most other modern process supervision schemes, doesn’t want the daemon to fork away randomly. So, tell it not to. Passing --no-daemonize, or setting that in the configuration file, is absolutely the right thing to do here.

Adding more options, or trying to pacify the stupid heuristic in Upstart that guesses wrong, have no value. Implementing SIGSTOP to ourselves has no value to Puppet, or to anyone else. Just run Puppet without having it fork.

Unless you can come back with some problem that is caused by specifying that option when run under upstart, there is nothing to be done here.

Also available in: Atom PDF