diff --git a/nova/cmd/compute.py b/nova/cmd/compute.py index 169b753c76a..ad7bab4a295 100644 --- a/nova/cmd/compute.py +++ b/nova/cmd/compute.py @@ -34,9 +34,7 @@ from nova import utils CONF = cfg.CONF -CONF.import_opt('host', 'nova.netconf') CONF.import_opt('compute_topic', 'nova.compute.rpcapi') -CONF.import_opt('compute_processes', 'nova.compute.simulator') CONF.import_opt('use_local', 'nova.conductor.api', group='conductor') @@ -65,15 +63,8 @@ def main(): objects_base.NovaObject.indirection_api = \ conductor_rpcapi.ConductorAPI() - for i in xrange(CONF.compute_processes): - if i > 0: - host = '%s-%s' % (CONF.host, str(i)) - else: - host = CONF.host - - server = service.Service.create(binary='nova-compute', + server = service.Service.create(binary='nova-compute', topic=CONF.compute_topic, - host=host, db_allowed=False) - service.serve(server) + service.serve(server) service.wait() diff --git a/nova/cmd/simulator.py b/nova/cmd/simulator.py new file mode 100644 index 00000000000..a40c296b8e8 --- /dev/null +++ b/nova/cmd/simulator.py @@ -0,0 +1,69 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Rights Reserved. +# +# 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. + +"""Starter script for Simulator.""" +import sys +import traceback + +from oslo.config import cfg + +from nova.conductor import rpcapi as conductor_rpcapi +from nova import config +import nova.db.api +from nova import exception +from nova import objects +from nova.objects import base as objects_base +from nova.openstack.common import log as logging +from nova import service +from nova import utils + +CONF = cfg.CONF +CONF.import_opt('compute_topic', 'nova.compute.rpcapi') +CONF.import_opt('use_local', 'nova.conductor.api', group='conductor') + +def block_db_access(): + class NoDB(object): + def __getattr__(self, attr): + return self + + def __call__(self, *args, **kwargs): + stacktrace = "".join(traceback.format_stack()) + LOG = logging.getLogger('nova.compute') + LOG.error('No db access allowed in nova-compute: %s', stacktrace) + raise exception.DBNotAllowed('nova-compute') + + nova.db.api.IMPL = NoDB() + +def main(host): + objects.register_all() + config.parse_args(sys.argv) + logging.setup('nova') + utils.monkey_patch() + + if not CONF.conductor.use_local: + block_db_access() + objects_base.NovaObject.indirection_api = \ + conductor_rpcapi.ConductorAPI() + + server = service.Service.create(binary='nova-compute', + topic=CONF.compute_topic, + host=host, + db_allowed=False) + service.serve(server) + service.wait() + diff --git a/nova/service.py b/nova/service.py index ec2b1f3b184..60bd6403d6d 100644 --- a/nova/service.py +++ b/nova/service.py @@ -383,14 +383,16 @@ def process_launcher(): # NOTE(vish): the global launcher is to maintain the existing # functionality of calling service.serve + # service.wait -_launcher = [] +_launcher = None def serve(server, workers=None): global _launcher - _launcher.append(service.launch(server, workers=workers)) + if _launcher: + raise RuntimeError(_('serve() can only be called once')) + + _launcher = service.launch(server, workers=workers) def wait(): - for service in _launcher: - service.wait() + _launcher.wait() diff --git a/nova/simulator/config.py b/nova/simulator/config.py new file mode 100644 index 00000000000..ab1083274cc --- /dev/null +++ b/nova/simulator/config.py @@ -0,0 +1,30 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2012, Red Hat, Inc. +# +# 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. + +""" +Nova-compute simulator for stress testing. +""" + +from oslo.config import cfg + +simulator_opts = [ + cfg.IntOpt('compute_processes', + default=20, + help='the number of compute services to simulate'), +] + +CONF = cfg.CONF +CONF.register_opts(simulator_opts) diff --git a/nova/simulator/simulator b/nova/simulator/simulator new file mode 100644 index 00000000000..f96455e6b14 --- /dev/null +++ b/nova/simulator/simulator @@ -0,0 +1,24 @@ +#!/usr/bin/python + +import start +from oslo.config import cfg +from multiprocessing import Process + +CONF = cfg.CONF +CONF.import_opt('compute_processes', 'nova.compute.simulator') + +if __name__ == "__main__": + workers = [] + for i in xrange(CONF.compute_processes): + host = '%s-%s' % (CONF.host, str(i + 1)) + p = Process(target=start.start, args=(host, )) + p.start() + workers.append(p) + + try: + for worker in workers: + worker.join() + except KeyboardInterrupt: + for worker in workers: + worker.terminate() + worker.join() \ No newline at end of file diff --git a/nova/simulator/start.py b/nova/simulator/start.py new file mode 100644 index 00000000000..40b43142cca --- /dev/null +++ b/nova/simulator/start.py @@ -0,0 +1,11 @@ +#!/usr/bin/python + +import sys +from nova.cmd.simulator import main + +def start(host): + main(host) + sys.exit() + +if __name__ == "__main__": + start('i do nothing') \ No newline at end of file