3b2ef8e29e
Before converting to cfg, glance-control would use find_config_file() to locate the servers config file if the user did not explicitly specify it. With the change over to cfg, we screwed that code up. However, we should instead just allow the server to locate its own config file rather than trying to guess what it will use. Change-Id: I422839ae4c684ff2de3a0a96dd54c6b74ce6df97
238 lines
7.5 KiB
Python
Executable File
238 lines
7.5 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
|
|
# Copyright (c) 2011 OpenStack, LLC.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
# implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
"""
|
|
Helper script for starting/stopping/reloading Glance server programs.
|
|
Thanks for some of the code, Swifties ;)
|
|
"""
|
|
|
|
from __future__ import with_statement
|
|
|
|
import errno
|
|
import gettext
|
|
import os
|
|
import resource
|
|
import signal
|
|
import sys
|
|
import time
|
|
|
|
# If ../glance/__init__.py exists, add ../ to Python search path, so that
|
|
# it will override what happens to be installed in /usr/(local/)lib/python...
|
|
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
|
|
os.pardir,
|
|
os.pardir))
|
|
if os.path.exists(os.path.join(possible_topdir, 'glance', '__init__.py')):
|
|
sys.path.insert(0, possible_topdir)
|
|
|
|
gettext.install('glance', unicode=1)
|
|
|
|
from glance import version
|
|
from glance.common import cfg
|
|
from glance.common import config
|
|
|
|
ALL_COMMANDS = ['start', 'stop', 'shutdown', 'restart',
|
|
'reload', 'force-reload']
|
|
ALL_SERVERS = ['glance-api', 'glance-registry', 'glance-scrubber']
|
|
GRACEFUL_SHUTDOWN_SERVERS = ['glance-api', 'glance-registry',
|
|
'glance-scrubber']
|
|
MAX_DESCRIPTORS = 32768
|
|
MAX_MEMORY = (1024 * 1024 * 1024) * 2 # 2 GB
|
|
USAGE = """%prog [options] <SERVER> <COMMAND> [CONFPATH]
|
|
|
|
Where <SERVER> is one of:
|
|
|
|
all, api, registry, scrubber
|
|
|
|
And command is one of:
|
|
|
|
start, stop, shutdown, restart, reload, force-reload
|
|
|
|
And CONFPATH is the optional configuration file to use."""
|
|
|
|
|
|
def pid_files(server, conf):
|
|
pid_files = []
|
|
if conf.pid_file:
|
|
if os.path.exists(os.path.abspath(conf.pid_file)):
|
|
pid_files = [os.path.abspath(conf.pid_file)]
|
|
else:
|
|
if os.path.exists('/var/run/glance/%s.pid' % server):
|
|
pid_files = ['/var/run/glance/%s.pid' % server]
|
|
for pid_file in pid_files:
|
|
pid = int(open(pid_file).read().strip())
|
|
yield pid_file, pid
|
|
|
|
|
|
def do_start(server, conf, args):
|
|
server_type = '-'.join(server.split('-')[:-1])
|
|
|
|
for pid_file, pid in pid_files(server, conf):
|
|
if os.path.exists('/proc/%s' % pid):
|
|
print "%s appears to already be running: %s" % (server, pid_file)
|
|
return
|
|
else:
|
|
print "Removing stale pid file %s" % pid_file
|
|
os.unlink(pid_file)
|
|
|
|
try:
|
|
resource.setrlimit(resource.RLIMIT_NOFILE,
|
|
(MAX_DESCRIPTORS, MAX_DESCRIPTORS))
|
|
resource.setrlimit(resource.RLIMIT_DATA,
|
|
(MAX_MEMORY, MAX_MEMORY))
|
|
except ValueError:
|
|
print "Unable to increase file descriptor limit. Running as non-root?"
|
|
os.environ['PYTHON_EGG_CACHE'] = '/tmp'
|
|
|
|
def write_pid_file(pid_file, pid):
|
|
dir, file = os.path.split(pid_file)
|
|
if not os.path.exists(dir):
|
|
try:
|
|
os.makedirs(dir)
|
|
except OSError, err:
|
|
if err.errno == errno.EACCES:
|
|
sys.exit('Unable to create %s. Running as non-root?'
|
|
% dir)
|
|
fp = open(pid_file, 'w')
|
|
fp.write('%d\n' % pid)
|
|
fp.close()
|
|
|
|
def launch(pid_file, conf_file=None):
|
|
args = [server]
|
|
print 'Starting %s' % server,
|
|
if conf_file:
|
|
args += ['--config-file', conf_file]
|
|
print 'with %s' % conf_file,
|
|
print
|
|
|
|
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
|
|
try:
|
|
os.execlp('%s' % server, *args)
|
|
except OSError, e:
|
|
sys.exit('unable to launch %s. Got error: %s'
|
|
% (server, "%s" % e))
|
|
sys.exit(0)
|
|
else:
|
|
write_pid_file(pid_file, pid)
|
|
|
|
if not conf.pid_file:
|
|
pid_file = '/var/run/glance/%s.pid' % server
|
|
else:
|
|
pid_file = os.path.abspath(conf.pid_file)
|
|
|
|
conf_file = None
|
|
if args and os.path.exists(args[0]):
|
|
conf_file = os.path.abspath(os.path.expanduser(args[0]))
|
|
|
|
launch(pid_file, conf_file)
|
|
|
|
|
|
def do_stop(server, conf, args, graceful=False):
|
|
if graceful and server in GRACEFUL_SHUTDOWN_SERVERS:
|
|
sig = signal.SIGHUP
|
|
else:
|
|
sig = signal.SIGTERM
|
|
|
|
did_anything = False
|
|
pfiles = pid_files(server, conf)
|
|
for pid_file, pid in pfiles:
|
|
did_anything = True
|
|
try:
|
|
print 'Stopping %s pid: %s signal: %s' % (server, pid, sig)
|
|
os.kill(pid, sig)
|
|
except OSError:
|
|
print "Process %d not running" % pid
|
|
try:
|
|
os.unlink(pid_file)
|
|
except OSError:
|
|
pass
|
|
for pid_file, pid in pfiles:
|
|
for _junk in xrange(150): # 15 seconds
|
|
if not os.path.exists('/proc/%s' % pid):
|
|
break
|
|
time.sleep(0.1)
|
|
else:
|
|
print 'Waited 15 seconds for pid %s (%s) to die; giving up' % \
|
|
(pid, pid_file)
|
|
if not did_anything:
|
|
print 'No %s running' % server
|
|
|
|
|
|
if __name__ == '__main__':
|
|
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'))
|
|
args = conf()
|
|
|
|
if len(args) < 2:
|
|
conf.print_usage()
|
|
sys.exit(1)
|
|
|
|
server = args.pop(0).lower()
|
|
if server == 'all':
|
|
servers = ALL_SERVERS
|
|
else:
|
|
if not server.startswith('glance-'):
|
|
server = 'glance-%s' % server
|
|
if server not in ALL_SERVERS:
|
|
server_list = ", ".join([s.replace('glance-', '')
|
|
for s in ALL_SERVERS])
|
|
msg = ("Unknown server '%(server)s' specified. Please specify "
|
|
"all, or one of the servers: %(server_list)s" % locals())
|
|
sys.exit(msg)
|
|
servers = [server]
|
|
|
|
command = args.pop(0).lower()
|
|
if command not in ALL_COMMANDS:
|
|
command_list = ", ".join(ALL_COMMANDS)
|
|
msg = ("Unknown command %(command)s specified. Please specify a "
|
|
"command in this list: %(command_list)s" % locals())
|
|
sys.exit(msg)
|
|
|
|
if command == 'start':
|
|
for server in servers:
|
|
do_start(server, conf, args)
|
|
|
|
if command == 'stop':
|
|
for server in servers:
|
|
do_stop(server, conf, args)
|
|
|
|
if command == 'shutdown':
|
|
for server in servers:
|
|
do_stop(server, conf, args, graceful=True)
|
|
|
|
if command == 'restart':
|
|
for server in servers:
|
|
do_stop(server, conf, args)
|
|
for server in servers:
|
|
do_start(server, conf, args)
|
|
|
|
if command == 'reload' or command == 'force-reload':
|
|
for server in servers:
|
|
do_stop(server, conf, args, graceful=True)
|
|
do_start(server, conf, args)
|