Add --capture-output option to glance-control.

Fixes bug 923894

Previously all stdout/err from glance services was discarded
if launched via glance-control.

The --capture-output option allows such output to be instead
captured in the syslog.

Non-termination output should be flushed to ensure timely
arrival in /var/log/messages.

Change-Id: I5c11ad4b9f7f321a3d1cab71e34c2a6707ef1b5e
This commit is contained in:
Eoghan Glynn 2012-01-26 14:49:20 +00:00
parent 7c2e32511a
commit 132c54f173
3 changed files with 72 additions and 20 deletions

View File

@ -24,10 +24,12 @@ Thanks for some of the code, Swifties ;)
from __future__ import with_statement
import errno
import fcntl
import gettext
import os
import resource
import signal
import subprocess
import sys
import time
@ -123,6 +125,40 @@ def do_start(server, conf, args):
break
time.sleep(0.05)
def redirect_to_null(fds):
with open(os.devnull, 'r+b') as nullfile:
for desc in fds: # close fds
try:
os.dup2(nullfile.fileno(), desc)
except OSError:
pass
def redirect_to_syslog(fds, server):
log_cmd = '/usr/bin/logger -t "%s[%d]"' % (server, os.getpid())
process = subprocess.Popen(log_cmd,
shell=True,
stdin=subprocess.PIPE)
for desc in fds: # pipe to logger command
try:
os.dup2(process.stdin.fileno(), desc)
except OSError:
pass
def redirect_stdio(conf, server):
input = [sys.stdin.fileno()]
output = [sys.stdout.fileno(), sys.stderr.fileno()]
redirect_to_null(input)
if conf.capture_output:
redirect_to_syslog(output, server)
else:
redirect_to_null(output)
def close_stdio_on_exec():
fds = [sys.stdin.fileno(), sys.stdout.fileno(), sys.stderr.fileno()]
for desc in fds: # set close on exec flag
fcntl.fcntl(desc, fcntl.F_SETFD, fcntl.FD_CLOEXEC)
def launch(pid_file, conf_file=None):
args = [server]
print 'Starting %s' % server,
@ -131,15 +167,12 @@ def do_start(server, conf, args):
print 'with %s' % conf_file,
print
close_stdio_on_exec()
pid = os.fork()
if pid == 0:
os.setsid()
with open(os.devnull, 'r+b') as nullfile:
for desc in (0, 1, 2): # close stdio
try:
os.dup2(nullfile.fileno(), desc)
except OSError:
pass
redirect_stdio(conf, server)
try:
os.execlp('%s' % server, *args)
except OSError, e:
@ -197,16 +230,25 @@ if __name__ == '__main__':
exitcode = 0
conf = config.GlanceConfigOpts(usage=USAGE)
conf.register_cli_opt(cfg.StrOpt('pid-file',
metavar='PATH',
help='File to use as pid file. Default: '
'/var/run/glance/$server.pid'))
conf.register_cli_opt(cfg.IntOpt('await-child',
metavar='DELAY',
default=0,
help='Period to wait for service death '
'in order to report exit code '
'(default is to not wait at all)'))
opts = [
cfg.StrOpt('pid-file',
metavar='PATH',
help='File to use as pid file. Default: '
'/var/run/glance/$server.pid'),
cfg.IntOpt('await-child',
metavar='DELAY',
default=0,
help='Period to wait for service death '
'in order to report exit code '
'(default is to not wait at all)'),
cfg.BoolOpt('capture-output',
default=False,
help='Capture stdout/err in syslog '
'instead of discarding'),
]
conf.register_cli_opts(opts)
args = conf()
if len(args) < 2:

View File

@ -149,7 +149,7 @@ To start a Glance server with ``glance-control``, simply call
any command-line options you wish to provide. Start the server with ``glance-control``
in the following way::
$> sudo glance-control <SERVER> start [CONFPATH]
$> sudo glance-control [OPTIONS] <SERVER> start [CONFPATH]
.. note::
@ -172,9 +172,17 @@ with the ``glance-control`` wrapper script. ::
jsuh 20042 0.0 0.0 3368 744 pts/1 S+ 12:51 0:00 grep glance
The same ``paste.deploy`` configuration files are used by ``glance-control``
to start the Glance server programs, and you can specify (as the example above
shows) a configuration file when starting the server.
The same configuration files are used by ``glance-control`` to start the
Glance server programs, and you can specify (as the example above shows)
a configuration file when starting the server.
By default, output from glance services is discarded when launched with ``glance-control``.
In order to capture such output via syslog, use the following option:
$ sudo glance-control --capture-output ...
Stopping a server
-----------------

View File

@ -203,6 +203,7 @@ class ApiServer(Server):
self.image_cache_driver = 'sqlite'
self.policy_file = policy_file
self.policy_default_rule = 'default'
self.server_control_options = '--capture-output'
self.conf_base = """[DEFAULT]
verbose = %(verbose)s
debug = %(debug)s
@ -292,6 +293,7 @@ class RegistryServer(Server):
"registry.pid")
self.log_file = os.path.join(self.test_dir, "registry.log")
self.owner_is_tenant = True
self.server_control_options = '--capture-output'
self.conf_base = """[DEFAULT]
verbose = %(verbose)s
debug = %(debug)s