diff --git a/bin/nova-all b/bin/nova-all index af947d36dfb9..f419b28255f3 100755 --- a/bin/nova-all +++ b/bin/nova-all @@ -1,102 +1,22 @@ #!/usr/bin/env python # vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright 2011 OpenStack Foundation -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # -# 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 +# 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 +# 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. +# 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 all nova services. +# Temporary shim to do a devstack transition +from nova.cmd import all -This script attempts to start all the nova services in one process. Each -service is started in its own greenthread. Please note that exceptions and -sys.exit() on the starting of a service are logged and the script will -continue attempting to launch the rest of the services. - -""" - -import eventlet -eventlet.monkey_patch(os=False) - -import gettext -import os -import sys - -from oslo.config import cfg - -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, "nova", "__init__.py")): - sys.path.insert(0, possible_topdir) - -gettext.install('nova', unicode=1) - -from nova import config -from nova.objectstore import s3server -from nova.openstack.common import log as logging -from nova import service -from nova import utils -from nova.vnc import xvp_proxy - - -CONF = cfg.CONF -CONF.import_opt('manager', 'nova.conductor.api', group='conductor') -CONF.import_opt('topic', 'nova.conductor.api', group='conductor') -CONF.import_opt('enabled_apis', 'nova.service') -LOG = logging.getLogger('nova.all') - -if __name__ == '__main__': - config.parse_args(sys.argv) - logging.setup("nova") - utils.monkey_patch() - launcher = service.ProcessLauncher() - - # nova-api - for api in CONF.enabled_apis: - try: - server = service.WSGIService(api) - launcher.launch_server(server, workers=server.workers or 1) - except (Exception, SystemExit): - LOG.exception(_('Failed to load %s') % '%s-api' % api) - - for mod in [s3server, xvp_proxy]: - try: - launcher.launch_server(mod.get_wsgi_server()) - except (Exception, SystemExit): - LOG.exception(_('Failed to load %s') % mod.__name__) - - for binary in ['nova-compute', 'nova-network', 'nova-scheduler', - 'nova-cert', 'nova-conductor']: - - # FIXME(sirp): Most service configs are defined in nova/service.py, but - # conductor has set a new precedent of storing these configs - # nova//api.py. - # - # We should update the existing services to use this new approach so we - # don't have to treat conductor differently here. - if binary == 'nova-conductor': - topic = CONF.conductor.topic - manager = CONF.conductor.manager - else: - topic = None - manager = None - - try: - launcher.launch_server(service.Service.create(binary=binary, - topic=topic, - manager=manager)) - except (Exception, SystemExit): - LOG.exception(_('Failed to load %s'), binary) - launcher.wait() +all.main() diff --git a/bin/nova-api b/bin/nova-api index 171a23ea039b..4620dfc21786 100755 --- a/bin/nova-api +++ b/bin/nova-api @@ -1,65 +1,22 @@ #!/usr/bin/env python # 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. +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # -# 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 +# 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 +# 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. +# 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 Nova API. +# Temporary shim to do a devstack transition +from nova.cmd import api -Starts both the EC2 and OpenStack APIs in separate greenthreads. - -""" - -import eventlet -eventlet.monkey_patch(os=False) - -import gettext -import os -import sys - -from oslo.config import cfg - -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, "nova", "__init__.py")): - sys.path.insert(0, possible_topdir) - -gettext.install('nova', unicode=1) - -from nova import config -from nova.openstack.common import log as logging -from nova import service -from nova import utils - -CONF = cfg.CONF -CONF.import_opt('enabled_apis', 'nova.service') -CONF.import_opt('enabled_ssl_apis', 'nova.service') - -if __name__ == '__main__': - config.parse_args(sys.argv) - logging.setup("nova") - utils.monkey_patch() - - launcher = service.ProcessLauncher() - for api in CONF.enabled_apis: - should_use_ssl = api in CONF.enabled_ssl_apis - if api == 'ec2': - server = service.WSGIService(api, use_ssl=should_use_ssl, - max_url_len=16384) - else: - server = service.WSGIService(api, use_ssl=should_use_ssl) - launcher.launch_server(server, workers=server.workers or 1) - launcher.wait() +api.main() diff --git a/bin/nova-api-ec2 b/bin/nova-api-ec2 index a3e1be0185ea..9b14cf658a9c 100755 --- a/bin/nova-api-ec2 +++ b/bin/nova-api-ec2 @@ -1,48 +1,22 @@ #!/usr/bin/env python # 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. +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # -# 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 +# 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 +# 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. +# 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 Nova EC2 API.""" +# Temporary shim to do a devstack transition +from nova.cmd import api_ec2 -import eventlet -eventlet.monkey_patch(os=False) - -import gettext -import os -import sys - - -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, "nova", "__init__.py")): - sys.path.insert(0, possible_topdir) - -gettext.install('nova', unicode=1) - -from nova import config -from nova.openstack.common import log as logging -from nova import service -from nova import utils - -if __name__ == '__main__': - config.parse_args(sys.argv) - logging.setup("nova") - utils.monkey_patch() - server = service.WSGIService('ec2', max_url_len=16384) - service.serve(server, workers=server.workers) - service.wait() +api_ec2.main() diff --git a/bin/nova-api-metadata b/bin/nova-api-metadata index 2005d6714f1c..5ea1ce4f4e99 100755 --- a/bin/nova-api-metadata +++ b/bin/nova-api-metadata @@ -1,48 +1,22 @@ #!/usr/bin/env python # 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. +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # -# 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 +# 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 +# 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. +# 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 Nova Metadata API.""" +# Temporary shim to do a devstack transition +from nova.cmd import api_metadata -import eventlet -eventlet.monkey_patch(os=False) - -import gettext -import os -import sys - - -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, "nova", "__init__.py")): - sys.path.insert(0, possible_topdir) - -gettext.install('nova', unicode=1) - -from nova import config -from nova.openstack.common import log as logging -from nova import service -from nova import utils - -if __name__ == '__main__': - config.parse_args(sys.argv) - logging.setup("nova") - utils.monkey_patch() - server = service.WSGIService('metadata') - service.serve(server, workers=server.workers) - service.wait() +api_metadata.main() diff --git a/bin/nova-api-os-compute b/bin/nova-api-os-compute index c2aa9e57cfb2..8ce4900136c7 100755 --- a/bin/nova-api-os-compute +++ b/bin/nova-api-os-compute @@ -1,48 +1,22 @@ #!/usr/bin/env python # 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. +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # -# 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 +# 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 +# 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. +# 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 Nova OS API.""" +# Temporary shim to do a devstack transition +from nova.cmd import api_os_compute -import eventlet -eventlet.monkey_patch(os=False) - -import gettext -import os -import sys - - -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, "nova", "__init__.py")): - sys.path.insert(0, possible_topdir) - -gettext.install('nova', unicode=1) - -from nova import config -from nova.openstack.common import log as logging -from nova import service -from nova import utils - -if __name__ == '__main__': - config.parse_args(sys.argv) - logging.setup("nova") - utils.monkey_patch() - server = service.WSGIService('osapi_compute') - service.serve(server, workers=server.workers) - service.wait() +api_os_compute.main() diff --git a/bin/nova-baremetal-deploy-helper b/bin/nova-baremetal-deploy-helper index 7336162e3d9a..09cf72b326ef 100755 --- a/bin/nova-baremetal-deploy-helper +++ b/bin/nova-baremetal-deploy-helper @@ -1,336 +1,23 @@ #!/usr/bin/env python +# vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright (c) 2012 NTT DOCOMO, INC. -# All Rights Reserved. +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # -# 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 +# 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 +# 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. +# 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 Bare-Metal Deployment Service.""" - -import eventlet - -# Do not monkey_patch in unittest -if __name__ == '__main__': - eventlet.monkey_patch() - -import gettext -import os -import sys -import threading -import time - -# If ../nova/__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, 'nova', '__init__.py')): - sys.path.insert(0, possible_topdir) - -gettext.install('nova', unicode=1) - -import cgi -import Queue -import re -import socket -import stat -from wsgiref import simple_server - -from nova import config -from nova import context as nova_context -from nova import exception -from nova.openstack.common import log as logging -from nova import utils -from nova.virt.baremetal import baremetal_states -from nova.virt.baremetal import db +# Temporary shim to do a devstack transition +from nova.cmd import baremetal_deploy_helper -LOG = logging.getLogger('nova.virt.baremetal.deploy_helper') - -QUEUE = Queue.Queue() - - -# All functions are called from deploy() directly or indirectly. -# They are split for stub-out. - -def discovery(portal_address, portal_port): - """Do iSCSI discovery on portal.""" - utils.execute('iscsiadm', - '-m', 'discovery', - '-t', 'st', - '-p', '%s:%s' % (portal_address, portal_port), - run_as_root=True, - check_exit_code=[0]) - - -def login_iscsi(portal_address, portal_port, target_iqn): - """Login to an iSCSI target.""" - utils.execute('iscsiadm', - '-m', 'node', - '-p', '%s:%s' % (portal_address, portal_port), - '-T', target_iqn, - '--login', - run_as_root=True, - check_exit_code=[0]) - # Ensure the login complete - time.sleep(3) - - -def logout_iscsi(portal_address, portal_port, target_iqn): - """Logout from an iSCSI target.""" - utils.execute('iscsiadm', - '-m', 'node', - '-p', '%s:%s' % (portal_address, portal_port), - '-T', target_iqn, - '--logout', - run_as_root=True, - check_exit_code=[0]) - - -def make_partitions(dev, root_mb, swap_mb): - """Create partitions for root and swap on a disk device.""" - # Lead in with 1MB to allow room for the partition table itself, otherwise - # the way sfdisk adjusts doesn't shift the partition up to compensate, and - # we lose the space. - # http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/raring/util-linux/ - # raring/view/head:/fdisk/sfdisk.c#L1940 - stdin_command = ('1 %d 83;\n- %d 82;\n0 0;\n0 0;\n' % (root_mb, swap_mb)) - utils.execute('sfdisk', '-uM', dev, process_input=stdin_command, - run_as_root=True, - check_exit_code=[0]) - # avoid "device is busy" - time.sleep(3) - - -def is_block_device(dev): - """Check whether a device is block or not.""" - s = os.stat(dev) - return stat.S_ISBLK(s.st_mode) - - -def dd(src, dst): - """Execute dd from src to dst.""" - utils.execute('dd', - 'if=%s' % src, - 'of=%s' % dst, - 'bs=1M', - 'oflag=direct', - run_as_root=True, - check_exit_code=[0]) - - -def mkswap(dev, label='swap1'): - """Execute mkswap on a device.""" - utils.execute('mkswap', - '-L', label, - dev, - run_as_root=True, - check_exit_code=[0]) - - -def block_uuid(dev): - """Get UUID of a block device.""" - out, _ = utils.execute('blkid', '-s', 'UUID', '-o', 'value', dev, - run_as_root=True, - check_exit_code=[0]) - return out.strip() - - -def switch_pxe_config(path, root_uuid): - """Switch a pxe config from deployment mode to service mode.""" - with open(path) as f: - lines = f.readlines() - root = 'UUID=%s' % root_uuid - rre = re.compile(r'\$\{ROOT\}') - dre = re.compile('^default .*$') - with open(path, 'w') as f: - for line in lines: - line = rre.sub(root, line) - line = dre.sub('default boot', line) - f.write(line) - - -def notify(address, port): - """Notify a node that it becomes ready to reboot.""" - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - try: - s.connect((address, port)) - s.send('done') - finally: - s.close() - - -def get_dev(address, port, iqn, lun): - """Returns a device path for given parameters.""" - dev = "/dev/disk/by-path/ip-%s:%s-iscsi-%s-lun-%s" \ - % (address, port, iqn, lun) - return dev - - -def get_image_mb(image_path): - """Get size of an image in Megabyte.""" - mb = 1024 * 1024 - image_byte = os.path.getsize(image_path) - # round up size to MB - image_mb = int((image_byte + mb - 1) / mb) - return image_mb - - -def work_on_disk(dev, root_mb, swap_mb, image_path): - """Creates partitions and write an image to the root partition.""" - root_part = "%s-part1" % dev - swap_part = "%s-part2" % dev - - if not is_block_device(dev): - LOG.warn("parent device '%s' not found", dev) - return - make_partitions(dev, root_mb, swap_mb) - if not is_block_device(root_part): - LOG.warn("root device '%s' not found", root_part) - return - if not is_block_device(swap_part): - LOG.warn("swap device '%s' not found", swap_part) - return - dd(image_path, root_part) - mkswap(swap_part) - root_uuid = block_uuid(root_part) - return root_uuid - - -def deploy(address, port, iqn, lun, image_path, pxe_config_path, - root_mb, swap_mb): - """All-in-one function to deploy a node.""" - dev = get_dev(address, port, iqn, lun) - image_mb = get_image_mb(image_path) - if image_mb > root_mb: - root_mb = image_mb - discovery(address, port) - login_iscsi(address, port, iqn) - try: - root_uuid = work_on_disk(dev, root_mb, swap_mb, image_path) - except exception.ProcessExecutionError, err: - # Log output if there was a error - LOG.error("Cmd : %s" % err.cmd) - LOG.error("StdOut : %s" % err.stdout) - LOG.error("StdErr : %s" % err.stderr) - finally: - logout_iscsi(address, port, iqn) - switch_pxe_config(pxe_config_path, root_uuid) - # Ensure the node started netcat on the port after POST the request. - time.sleep(3) - notify(address, 10000) - - -class Worker(threading.Thread): - """Thread that handles requests in queue.""" - - def __init__(self): - super(Worker, self).__init__() - self.setDaemon(True) - self.stop = False - self.queue_timeout = 1 - - def run(self): - while not self.stop: - try: - # Set timeout to check self.stop periodically - (node_id, params) = QUEUE.get(block=True, - timeout=self.queue_timeout) - except Queue.Empty: - pass - else: - # Requests comes here from BareMetalDeploy.post() - LOG.info(_('start deployment for node %(node_id)s, ' - 'params %(params)s') % locals()) - context = nova_context.get_admin_context() - try: - db.bm_node_update(context, node_id, - {'task_state': baremetal_states.DEPLOYING}) - deploy(**params) - except Exception: - LOG.error(_('deployment to node %s failed') % node_id) - db.bm_node_update(context, node_id, - {'task_state': baremetal_states.DEPLOYFAIL}) - else: - LOG.info(_('deployment to node %s done') % node_id) - db.bm_node_update(context, node_id, - {'task_state': baremetal_states.DEPLOYDONE}) - - -class BareMetalDeploy(object): - """WSGI server for bare-metal deployment.""" - - def __init__(self): - self.worker = Worker() - self.worker.start() - - def __call__(self, environ, start_response): - method = environ['REQUEST_METHOD'] - if method == 'POST': - return self.post(environ, start_response) - else: - start_response('501 Not Implemented', - [('Content-type', 'text/plain')]) - return 'Not Implemented' - - def post(self, environ, start_response): - LOG.info("post: environ=%s", environ) - inpt = environ['wsgi.input'] - length = int(environ.get('CONTENT_LENGTH', 0)) - - x = inpt.read(length) - q = dict(cgi.parse_qsl(x)) - try: - node_id = q['i'] - deploy_key = q['k'] - address = q['a'] - port = q.get('p', '3260') - iqn = q['n'] - lun = q.get('l', '1') - except KeyError as e: - start_response('400 Bad Request', [('Content-type', 'text/plain')]) - return "parameter '%s' is not defined" % e - - context = nova_context.get_admin_context() - d = db.bm_node_get(context, node_id) - - if d['deploy_key'] != deploy_key: - start_response('400 Bad Request', [('Content-type', 'text/plain')]) - return 'key is not match' - - params = {'address': address, - 'port': port, - 'iqn': iqn, - 'lun': lun, - 'image_path': d['image_path'], - 'pxe_config_path': d['pxe_config_path'], - 'root_mb': int(d['root_mb']), - 'swap_mb': int(d['swap_mb']), - } - # Restart worker, if needed - if not self.worker.isAlive(): - self.worker = Worker() - self.worker.start() - LOG.info("request is queued: node %s, params %s", node_id, params) - QUEUE.put((node_id, params)) - # Requests go to Worker.run() - start_response('200 OK', [('Content-type', 'text/plain')]) - return '' - - -if __name__ == '__main__': - config.parse_args(sys.argv) - logging.setup("nova") - app = BareMetalDeploy() - srv = simple_server.make_server('', 10000, app) - srv.serve_forever() +baremetal_deploy_helper.main() diff --git a/bin/nova-baremetal-manage b/bin/nova-baremetal-manage index 42200e5e173f..f84459c44fd0 100755 --- a/bin/nova-baremetal-manage +++ b/bin/nova-baremetal-manage @@ -1,221 +1,22 @@ #!/usr/bin/env python # vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright (c) 2011 X.commerce, a business unit of eBay Inc. -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # -# 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 +# 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 +# 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. +# 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. -# Interactive shell based on Django: -# -# Copyright (c) 2005, the Lawrence Journal-World -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# 3. Neither the name of Django nor the names of its contributors may be -# used to endorse or promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# Temporary shim to do a devstack transition +from nova.cmd import baremetal_manage - -""" - CLI interface for nova bare-metal management. -""" - -import gettext -import os -import sys - -from oslo.config import cfg - -# If ../nova/__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, 'nova', '__init__.py')): - sys.path.insert(0, POSSIBLE_TOPDIR) - -gettext.install('nova', unicode=1) - -from nova import config -from nova.openstack.common import cliutils -from nova.openstack.common import log as logging -from nova import version -from nova.virt.baremetal import db as bmdb -from nova.virt.baremetal.db import migration as bmdb_migration - -CONF = cfg.CONF - - -# Decorators for actions -def args(*args, **kwargs): - def _decorator(func): - func.__dict__.setdefault('args', []).insert(0, (args, kwargs)) - return func - return _decorator - - -class BareMetalDbCommands(object): - """Class for managing the bare-metal database.""" - - def __init__(self): - pass - - @args('--version', dest='version', metavar='', - help='Bare-metal Database version') - def sync(self, version=None): - """Sync the database up to the most recent version.""" - bmdb_migration.db_sync(version) - - def version(self): - """Print the current database version.""" - v = bmdb_migration.db_version() - print(v) - # return for unittest - return v - - -CATEGORIES = { - 'db': BareMetalDbCommands, -} - - -def methods_of(obj): - """Get all callable methods of an object that don't start with underscore - returns a list of tuples of the form (method_name, method)""" - result = [] - for i in dir(obj): - if callable(getattr(obj, i)) and not i.startswith('_'): - result.append((i, getattr(obj, i))) - return result - - -def add_command_parsers(subparsers): - parser = subparsers.add_parser('bash-completion') - parser.add_argument('query_category', nargs='?') - - for category in CATEGORIES: - command_object = CATEGORIES[category]() - - parser = subparsers.add_parser(category) - parser.set_defaults(command_object=command_object) - - category_subparsers = parser.add_subparsers(dest='action') - - for (action, action_fn) in methods_of(command_object): - parser = category_subparsers.add_parser(action) - - action_kwargs = [] - for args, kwargs in getattr(action_fn, 'args', []): - action_kwargs.append(kwargs['dest']) - kwargs['dest'] = 'action_kwarg_' + kwargs['dest'] - parser.add_argument(*args, **kwargs) - - parser.set_defaults(action_fn=action_fn) - parser.set_defaults(action_kwargs=action_kwargs) - - parser.add_argument('action_args', nargs='*') - - -category_opt = cfg.SubCommandOpt('category', - title='Command categories', - help='Available categories', - handler=add_command_parsers) - - -def main(): - """Parse options and call the appropriate class/method.""" - CONF.register_cli_opt(category_opt) - try: - config.parse_args(sys.argv) - logging.setup("nova") - except cfg.ConfigFilesNotFoundError: - cfgfile = CONF.config_file[-1] if CONF.config_file else None - if cfgfile and not os.access(cfgfile, os.R_OK): - st = os.stat(cfgfile) - print(_("Could not read %s. Re-running with sudo") % cfgfile) - try: - os.execvp('sudo', ['sudo', '-u', '#%s' % st.st_uid] + sys.argv) - except Exception: - print(_('sudo failed, continuing as if nothing happened')) - - print(_('Please re-run nova-manage as root.')) - sys.exit(2) - - if CONF.category.name == "version": - print(version.version_string_with_package()) - sys.exit(0) - - if CONF.category.name == "bash-completion": - if not CONF.category.query_category: - print(" ".join(CATEGORIES.keys())) - elif CONF.category.query_category in CATEGORIES: - fn = CATEGORIES[CONF.category.query_category] - command_object = fn() - actions = methods_of(command_object) - print(" ".join([k for (k, v) in actions])) - sys.exit(0) - - fn = CONF.category.action_fn - fn_args = [arg.decode('utf-8') for arg in CONF.category.action_args] - fn_kwargs = {} - for k in CONF.category.action_kwargs: - v = getattr(CONF.category, 'action_kwarg_' + k) - if v is None: - continue - if isinstance(v, basestring): - v = v.decode('utf-8') - fn_kwargs[k] = v - - # call the action with the remaining arguments - # check arguments - try: - cliutils.validate_args(fn, *fn_args, **fn_kwargs) - except cliutils.MissingArgs as e: - print(fn.__doc__) - parser.print_help() - print(e) - sys.exit(1) - try: - fn(*fn_args, **fn_kwargs) - sys.exit(0) - except Exception: - print(_("Command failed, please check log for more info")) - raise - - -if __name__ == '__main__': - main() +baremetal_manage.main() diff --git a/bin/nova-cells b/bin/nova-cells index 380e712668b7..763560b0203e 100755 --- a/bin/nova-cells +++ b/bin/nova-cells @@ -1,57 +1,22 @@ #!/usr/bin/env python # vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # -# Copyright (c) 2012 Rackspace Hosting -# 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 # -# 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 # -# 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. +# 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 Nova Cells Service.""" +# Temporary shim to do a devstack transition +from nova.cmd import cells -import eventlet -eventlet.monkey_patch() - -import gettext -import os -import sys - -from oslo.config import cfg - -# If ../nova/__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, 'nova', '__init__.py')): - sys.path.insert(0, possible_topdir) - -gettext.install('nova', unicode=1) - -from nova import config -from nova.openstack.common import log as logging -from nova import service -from nova import utils - -CONF = cfg.CONF -CONF.import_opt('topic', 'nova.cells.opts', group='cells') -CONF.import_opt('manager', 'nova.cells.opts', group='cells') - -if __name__ == '__main__': - config.parse_args(sys.argv) - logging.setup('nova') - utils.monkey_patch() - server = service.Service.create(binary='nova-cells', - topic=CONF.cells.topic, - manager=CONF.cells.manager) - service.serve(server) - service.wait() +cells.main() diff --git a/bin/nova-cert b/bin/nova-cert index 861f3ba8fad7..0cf04e0eaa59 100755 --- a/bin/nova-cert +++ b/bin/nova-cert @@ -1,53 +1,22 @@ #!/usr/bin/env python # vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright 2012 OpenStack Foundation +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # -# 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 +# 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 +# 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. +# 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 Nova Cert.""" +# Temporary shim to do a devstack transition +from nova.cmd import cert -import eventlet -eventlet.monkey_patch() - -import gettext -import os -import sys - -from oslo.config import cfg - -# If ../nova/__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, 'nova', '__init__.py')): - sys.path.insert(0, POSSIBLE_TOPDIR) - -gettext.install('nova', unicode=1) - -from nova import config -from nova.openstack.common import log as logging -from nova import service -from nova import utils - -CONF = cfg.CONF -CONF.import_opt('cert_topic', 'nova.cert.rpcapi') - -if __name__ == '__main__': - config.parse_args(sys.argv) - logging.setup("nova") - utils.monkey_patch() - server = service.Service.create(binary='nova-cert', topic=CONF.cert_topic) - service.serve(server) - service.wait() +cert.main() diff --git a/bin/nova-clear-rabbit-queues b/bin/nova-clear-rabbit-queues index 32a7fe5d1e0f..8de7c6d9e174 100755 --- a/bin/nova-clear-rabbit-queues +++ b/bin/nova-clear-rabbit-queues @@ -1,79 +1,22 @@ #!/usr/bin/env python # vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright (c) 2011 OpenStack Foundation -# All Rights Reserved. +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # -# 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 +# 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 +# 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. +# 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. -"""Admin/debug script to wipe rabbitMQ (AMQP) queues nova uses. - This can be used if you need to change durable options on queues, - or to wipe all messages in the queue system if things are in a - serious bad way. +# Temporary shim to do a devstack transition +from nova.cmd import clear_rabbit_queues -""" - -import gettext -import os -import sys - -from oslo.config import cfg - -# If ../nova/__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, 'nova', '__init__.py')): - sys.path.insert(0, POSSIBLE_TOPDIR) - -gettext.install('nova', unicode=1) - - -from nova import config -from nova.openstack.common import log as logging -from nova.openstack.common import rpc - - -opts = [ - cfg.MultiStrOpt('queues', - default=[], - positional=True, - help='Queues to delete'), - cfg.BoolOpt('delete_exchange', - default=False, - help='delete nova exchange too.'), -] - -CONF = cfg.CONF -CONF.register_cli_opts(opts) - - -def delete_exchange(exch): - conn = rpc.create_connection() - x = conn.get_channel() - x.exchange_delete(exch) - - -def delete_queues(queues): - conn = rpc.create_connection() - x = conn.get_channel() - for q in queues: - x.queue_delete(q) - -if __name__ == '__main__': - config.parse_args(sys.argv) - logging.setup("nova") - delete_queues(CONF.queues) - if CONF.delete_exchange: - delete_exchange(CONF.control_exchange) +clear_rabbit_queues.main() diff --git a/bin/nova-compute b/bin/nova-compute index a7ca4de5bd95..a2ab0d18be98 100755 --- a/bin/nova-compute +++ b/bin/nova-compute @@ -1,87 +1,22 @@ #!/usr/bin/env python # 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. +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # -# 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 +# 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 +# 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. +# 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 Nova Compute.""" +# Temporary shim to do a devstack transition +from nova.cmd import compute -import eventlet -import os - -if os.name == 'nt': - # eventlet monkey patching causes subprocess.Popen to fail on Windows - # when using pipes due to missing non blocking I/O support - eventlet.monkey_patch(os=False) -else: - eventlet.monkey_patch() - -import gettext -import os -import sys -import traceback - -from oslo.config import cfg - -# If ../nova/__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, 'nova', '__init__.py')): - sys.path.insert(0, POSSIBLE_TOPDIR) - -gettext.install('nova', unicode=1) - -from nova import config -import nova.db.api -from nova import exception -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') -LOG = logging.getLogger('nova.compute') - - -def block_db_access(): - class NoDB(object): - def __getattr__(self, attr): - return self - - def __call__(self, *args, **kwargs): - stacktrace = "".join(traceback.format_stack()) - LOG.error('No db access allowed in nova-compute: %s' % stacktrace) - raise exception.DBNotAllowed('nova-compute') - - nova.db.api.IMPL = NoDB() - - -if __name__ == '__main__': - config.parse_args(sys.argv) - logging.setup('nova') - utils.monkey_patch() - - if not CONF.conductor.use_local: - block_db_access() - - server = service.Service.create(binary='nova-compute', - topic=CONF.compute_topic, - db_allowed=False) - service.serve(server) - service.wait() +compute.main() diff --git a/bin/nova-conductor b/bin/nova-conductor index 72e89804f268..d88fe264da67 100755 --- a/bin/nova-conductor +++ b/bin/nova-conductor @@ -1,55 +1,22 @@ #!/usr/bin/env python # vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright 2012 IBM Corp. +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # -# 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 +# 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 +# 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. +# 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 Nova Conductor.""" +# Temporary shim to do a devstack transition +from nova.cmd import conductor -import eventlet -eventlet.monkey_patch() - -import gettext -import os -import sys - -from oslo.config import cfg - -# If ../nova/__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, 'nova', '__init__.py')): - sys.path.insert(0, possible_topdir) - -gettext.install('nova', unicode=1) - -from nova import config -from nova.openstack.common import log as logging -from nova import service -from nova import utils - -CONF = cfg.CONF -CONF.import_opt('topic', 'nova.conductor.api', group='conductor') - -if __name__ == '__main__': - config.parse_args(sys.argv) - logging.setup("nova") - utils.monkey_patch() - server = service.Service.create(binary='nova-conductor', - topic=CONF.conductor.topic, - manager=CONF.conductor.manager) - service.serve(server) - service.wait() +conductor.main() diff --git a/bin/nova-console b/bin/nova-console index af037bb3c4e0..bf6f0539d3de 100755 --- a/bin/nova-console +++ b/bin/nova-console @@ -1,53 +1,22 @@ #!/usr/bin/env python # vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright (c) 2010 OpenStack Foundation -# All Rights Reserved. +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # -# 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 +# 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 +# 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. +# 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 Nova Console Proxy.""" +# Temporary shim to do a devstack transition +from nova.cmd import console -import eventlet -eventlet.monkey_patch() - -import gettext -import os -import sys - -from oslo.config import cfg - -# If ../nova/__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, 'nova', '__init__.py')): - sys.path.insert(0, possible_topdir) - -gettext.install('nova', unicode=1) - -from nova import config -from nova.openstack.common import log as logging -from nova import service - -CONF = cfg.CONF -CONF.import_opt('console_topic', 'nova.console.rpcapi') - -if __name__ == '__main__': - config.parse_args(sys.argv) - logging.setup("nova") - server = service.Service.create(binary='nova-console', - topic=CONF.console_topic) - service.serve(server) - service.wait() +console.main() diff --git a/bin/nova-consoleauth b/bin/nova-consoleauth index f867c8c7b990..3de6bc2d3027 100755 --- a/bin/nova-consoleauth +++ b/bin/nova-consoleauth @@ -1,51 +1,22 @@ #!/usr/bin/env python # vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright (c) 2012 OpenStack Foundation -# All Rights Reserved. +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # -# 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 +# 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 +# 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. +# 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. -"""VNC Console Proxy Server.""" +# Temporary shim to do a devstack transition +from nova.cmd import consoleauth -import eventlet -eventlet.monkey_patch() - -import gettext -import os -import sys - -from oslo.config import cfg - -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, 'nova', '__init__.py')): - sys.path.insert(0, possible_topdir) - -gettext.install('nova', unicode=1) - -from nova import config -from nova.consoleauth import manager -from nova.openstack.common import log as logging -from nova import service - -CONF = cfg.CONF - -if __name__ == "__main__": - config.parse_args(sys.argv) - logging.setup("nova") - server = service.Service.create(binary='nova-consoleauth', - topic=CONF.consoleauth_topic) - service.serve(server) - service.wait() +consoleauth.main() diff --git a/bin/nova-dhcpbridge b/bin/nova-dhcpbridge index 1acaf4cd1704..de65f999d51f 100755 --- a/bin/nova-dhcpbridge +++ b/bin/nova-dhcpbridge @@ -1,153 +1,22 @@ #!/usr/bin/env python # 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. +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # -# 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 +# 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 +# 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. +# 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. -""" -Handle lease database updates from DHCP servers. -""" +# Temporary shim to do a devstack transition +from nova.cmd import dhcpbridge -import gettext -import os -import sys - -from oslo.config import cfg - -# If ../nova/__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, 'nova', '__init__.py')): - sys.path.insert(0, possible_topdir) - -gettext.install('nova', unicode=1) - -from nova import config -from nova import context -from nova import db -from nova.network import rpcapi as network_rpcapi -from nova.openstack.common import importutils -from nova.openstack.common import jsonutils -from nova.openstack.common import log as logging -from nova.openstack.common import rpc - -CONF = cfg.CONF -CONF.import_opt('host', 'nova.netconf') -CONF.import_opt('network_manager', 'nova.service') -LOG = logging.getLogger('nova.dhcpbridge') - - -def add_lease(mac, ip_address): - """Set the IP that was assigned by the DHCP server.""" - if CONF.fake_rabbit: - LOG.debug(_("leasing ip")) - network_manager = importutils.import_object(CONF.network_manager) - network_manager.lease_fixed_ip(context.get_admin_context(), - ip_address) - else: - api = network_rpcapi.NetworkAPI() - api.lease_fixed_ip(context.get_admin_context(), ip_address, CONF.host) - - -def old_lease(mac, ip_address): - """Called when an old lease is recognized.""" - # NOTE(vish): We assume we heard about this lease the first time. - # If not, we will get it the next time the lease is - # renewed. - pass - - -def del_lease(mac, ip_address): - """Called when a lease expires.""" - if CONF.fake_rabbit: - LOG.debug(_("releasing ip")) - network_manager = importutils.import_object(CONF.network_manager) - network_manager.release_fixed_ip(context.get_admin_context(), - ip_address) - else: - api = network_rpcapi.NetworkAPI() - api.release_fixed_ip(context.get_admin_context(), ip_address, - CONF.host) - - -def init_leases(network_id): - """Get the list of hosts for a network.""" - ctxt = context.get_admin_context() - network_ref = db.network_get(ctxt, network_id) - network_manager = importutils.import_object(CONF.network_manager) - return network_manager.get_dhcp_leases(ctxt, network_ref) - - -def add_action_parsers(subparsers): - parser = subparsers.add_parser('init') - - # NOTE(cfb): dnsmasq always passes mac, and ip. hostname - # is passed if known. We don't care about - # hostname, but argparse will complain if we - # do not accept it. - for action in ['add', 'del', 'old']: - parser = subparsers.add_parser(action) - parser.add_argument('mac') - parser.add_argument('ip') - parser.add_argument('hostname', nargs='?', default='') - parser.set_defaults(func=globals()[action + '_lease']) - - -CONF.register_cli_opt( - cfg.SubCommandOpt('action', - title='Action options', - help='Available dhcpbridge options', - handler=add_action_parsers)) - - -def main(): - """Parse environment and arguments and call the appropriate action.""" - try: - config_file = os.environ['CONFIG_FILE'] - except KeyError: - config_file = os.environ['FLAGFILE'] - - config.parse_args(sys.argv, - default_config_files=jsonutils.loads(config_file)) - - logging.setup("nova") - - if int(os.environ.get('TESTING', '0')): - from nova.tests import conf_fixture - - if CONF.action.name in ['add', 'del', 'old']: - msg = (_("Called '%(action)s' for mac '%(mac)s' with ip '%(ip)s'") % - {"action": CONF.action.name, - "mac": CONF.action.mac, - "ip": CONF.action.ip}) - LOG.debug(msg) - CONF.action.func(CONF.action.mac, CONF.action.ip) - else: - try: - network_id = int(os.environ.get('NETWORK_ID')) - except TypeError: - LOG.error(_("Environment variable 'NETWORK_ID' must be set.")) - sys.exit(1) - - print init_leases(network_id) - - rpc.cleanup() - - -if __name__ == "__main__": - main() +dhcpbridge.main() diff --git a/bin/nova-manage b/bin/nova-manage index 50a1923611c8..10169e0197e1 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -1,1256 +1,23 @@ #!/usr/bin/env python # vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright (c) 2011 X.commerce, a business unit of eBay Inc. -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. +# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # -# 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 +# 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 +# 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. +# 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. -# Interactive shell based on Django: -# -# Copyright (c) 2005, the Lawrence Journal-World -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# 3. Neither the name of Django nor the names of its contributors may be -# used to endorse or promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# Temporary shim to do a devstack transition +from nova.cmd import manage -""" - CLI interface for nova management. -""" - -import gettext -import netaddr -import os -import sys - -from oslo.config import cfg - -# If ../nova/__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, 'nova', '__init__.py')): - sys.path.insert(0, POSSIBLE_TOPDIR) - -gettext.install('nova', unicode=1) - -from nova.api.ec2 import ec2utils -from nova import availability_zones -from nova.compute import instance_types -from nova import config -from nova import context -from nova import db -from nova.db import migration -from nova import exception -from nova.openstack.common import cliutils -from nova.openstack.common.db import exception as db_exc -from nova.openstack.common import importutils -from nova.openstack.common import log as logging -from nova.openstack.common import rpc -from nova.openstack.common import timeutils -from nova import quota -from nova.scheduler import rpcapi as scheduler_rpcapi -from nova import servicegroup -from nova import version - -CONF = cfg.CONF -CONF.import_opt('network_manager', 'nova.service') -CONF.import_opt('service_down_time', 'nova.service') -CONF.import_opt('flat_network_bridge', 'nova.network.manager') -CONF.import_opt('num_networks', 'nova.network.manager') -CONF.import_opt('multi_host', 'nova.network.manager') -CONF.import_opt('network_size', 'nova.network.manager') -CONF.import_opt('vlan_start', 'nova.network.manager') -CONF.import_opt('vpn_start', 'nova.network.manager') -CONF.import_opt('default_floating_pool', 'nova.network.floating_ips') -CONF.import_opt('public_interface', 'nova.network.linux_net') - -QUOTAS = quota.QUOTAS - - -# Decorators for actions -def args(*args, **kwargs): - def _decorator(func): - func.__dict__.setdefault('args', []).insert(0, (args, kwargs)) - return func - return _decorator - - -def param2id(object_id): - """Helper function to convert various volume id types to internal id. - args: [object_id], e.g. 'vol-0000000a' or 'volume-0000000a' or '10' - """ - if '-' in object_id: - return ec2utils.ec2_vol_id_to_uuid(object_id) - else: - return object_id - - -class VpnCommands(object): - """Class for managing VPNs.""" - - @args('--project', dest='project_id', metavar='', - help='Project name') - @args('--ip', metavar='', help='IP Address') - @args('--port', metavar='', help='Port') - def change(self, project_id, ip, port): - """Change the ip and port for a vpn. - - this will update all networks associated with a project - not sure if that's the desired behavior or not, patches accepted - - """ - # TODO(tr3buchet): perhaps this shouldn't update all networks - # associated with a project in the future - admin_context = context.get_admin_context() - networks = db.project_get_networks(admin_context, project_id) - for network in networks: - db.network_update(admin_context, - network['id'], - {'vpn_public_address': ip, - 'vpn_public_port': int(port)}) - - -class ShellCommands(object): - def bpython(self): - """Runs a bpython shell. - - Falls back to Ipython/python shell if unavailable""" - self.run('bpython') - - def ipython(self): - """Runs an Ipython shell. - - Falls back to Python shell if unavailable""" - self.run('ipython') - - def python(self): - """Runs a python shell. - - Falls back to Python shell if unavailable""" - self.run('python') - - @args('--shell', metavar='', - help='Python shell') - def run(self, shell=None): - """Runs a Python interactive interpreter.""" - if not shell: - shell = 'bpython' - - if shell == 'bpython': - try: - import bpython - bpython.embed() - except ImportError: - shell = 'ipython' - if shell == 'ipython': - try: - import IPython - # Explicitly pass an empty list as arguments, because - # otherwise IPython would use sys.argv from this script. - shell = IPython.Shell.IPShell(argv=[]) - shell.mainloop() - except ImportError: - shell = 'python' - - if shell == 'python': - import code - try: - # Try activating rlcompleter, because it's handy. - import readline - except ImportError: - pass - else: - # We don't have to wrap the following import in a 'try', - # because we already know 'readline' was imported successfully. - import rlcompleter - readline.parse_and_bind("tab:complete") - code.interact() - - @args('--path', metavar='', help='Script path') - def script(self, path): - """Runs the script from the specified path with flags set properly. - arguments: path""" - exec(compile(open(path).read(), path, 'exec'), locals(), globals()) - - -def _db_error(caught_exception): - print caught_exception - print _("The above error may show that the database has not " - "been created.\nPlease create a database using " - "'nova-manage db sync' before running this command.") - exit(1) - - -class ProjectCommands(object): - """Class for managing projects.""" - - @args('--project', dest='project_id', metavar='', - help='Project name') - @args('--key', metavar='', help='Key') - @args('--value', metavar='', help='Value') - def quota(self, project_id, key=None, value=None): - """ - Create, update or display quotas for project - - If no quota key is provided, the quota will be displayed. - If a valid quota key is provided and it does not exist, - it will be created. Otherwise, it will be updated. - """ - - ctxt = context.get_admin_context() - project_quota = QUOTAS.get_project_quotas(ctxt, project_id) - # if key is None, that means we need to show the quotas instead - # of updating them - if key: - if key in project_quota: - if value.lower() == 'unlimited': - value = -1 - try: - db.quota_update(ctxt, project_id, key, value) - except exception.ProjectQuotaNotFound: - db.quota_create(ctxt, project_id, key, value) - else: - print _('%(key)s is not a valid quota key. Valid options are: ' - '%(options)s.') % {'key': key, - 'options': ', '.join(project_quota)} - sys.exit(2) - print_format = "%-36s %-10s %-10s %-10s" - print print_format % ( - _('Quota'), - _('Limit'), - _('In Use'), - _('Reserved')) - # Retrieve the quota after update - project_quota = QUOTAS.get_project_quotas(ctxt, project_id) - for key, value in project_quota.iteritems(): - if value['limit'] < 0 or value['limit'] is None: - value['limit'] = 'unlimited' - print print_format % (key, value['limit'], value['in_use'], - value['reserved']) - - @args('--project', dest='project_id', metavar='', - help='Project name') - def scrub(self, project_id): - """Deletes data associated with project.""" - admin_context = context.get_admin_context() - networks = db.project_get_networks(admin_context, project_id) - for network in networks: - db.network_disassociate(admin_context, network['id']) - groups = db.security_group_get_by_project(admin_context, project_id) - for group in groups: - db.security_group_destroy(admin_context, group['id']) - - -AccountCommands = ProjectCommands - - -class FixedIpCommands(object): - """Class for managing fixed ip.""" - - @args('--host', metavar='', help='Host') - def list(self, host=None): - """Lists all fixed ips (optionally by host).""" - ctxt = context.get_admin_context() - - try: - if host is None: - fixed_ips = db.fixed_ip_get_all(ctxt) - else: - fixed_ips = db.fixed_ip_get_all_by_instance_host(ctxt, host) - except exception.NotFound as ex: - print _("error: %s") % ex - sys.exit(2) - - instances = db.instance_get_all(context.get_admin_context()) - instances_by_uuid = {} - for instance in instances: - instances_by_uuid[instance['uuid']] = instance - - print "%-18s\t%-15s\t%-15s\t%s" % (_('network'), - _('IP address'), - _('hostname'), - _('host')) - - all_networks = {} - try: - # use network_get_all to retrieve all existing networks - # this is to ensure that IPs associated with deleted networks - # will not throw exceptions. - for network in db.network_get_all(context.get_admin_context()): - all_networks[network.id] = network - except exception.NoNetworksFound: - # do not have any networks, so even if there are IPs, these - # IPs should have been deleted ones, so return. - print _('No fixed IP found.') - return - - has_ip = False - for fixed_ip in fixed_ips: - hostname = None - host = None - network = all_networks.get(fixed_ip['network_id']) - if network: - has_ip = True - if fixed_ip.get('instance_uuid'): - instance = instances_by_uuid.get(fixed_ip['instance_uuid']) - if instance: - hostname = instance['hostname'] - host = instance['host'] - else: - print _('WARNING: fixed ip %s allocated to missing' - ' instance') % str(fixed_ip['address']) - print "%-18s\t%-15s\t%-15s\t%s" % ( - network['cidr'], - fixed_ip['address'], - hostname, host) - - if not has_ip: - print _('No fixed IP found.') - - @args('--address', metavar='', help='IP address') - def reserve(self, address): - """Mark fixed ip as reserved - arguments: address""" - self._set_reserved(address, True) - - @args('--address', metavar='', help='IP address') - def unreserve(self, address): - """Mark fixed ip as free to use - arguments: address""" - self._set_reserved(address, False) - - def _set_reserved(self, address, reserved): - ctxt = context.get_admin_context() - - try: - fixed_ip = db.fixed_ip_get_by_address(ctxt, address) - if fixed_ip is None: - raise exception.NotFound('Could not find address') - db.fixed_ip_update(ctxt, fixed_ip['address'], - {'reserved': reserved}) - except exception.NotFound as ex: - print _("error: %s") % ex - sys.exit(2) - - -class FloatingIpCommands(object): - """Class for managing floating ip.""" - - @staticmethod - def address_to_hosts(addresses): - """ - Iterate over hosts within an address range. - - If an explicit range specifier is missing, the parameter is - interpreted as a specific individual address. - """ - try: - return [netaddr.IPAddress(addresses)] - except ValueError: - net = netaddr.IPNetwork(addresses) - if net.size < 4: - reason = _("/%s should be specified as single address(es) " - "not in cidr format") % net.prefixlen - raise exception.InvalidInput(reason=reason) - elif net.size >= 1000000: - # NOTE(dripton): If we generate a million IPs and put them in - # the database, the system will slow to a crawl and/or run - # out of memory and crash. This is clearly a misconfiguration. - reason = _("Too many IP addresses will be generated. Please " - "increase /%s to reduce the number generated." - ) % net.prefixlen - raise exception.InvalidInput(reason=reason) - else: - return net.iter_hosts() - - @args('--ip_range', metavar='', help='IP range') - @args('--pool', metavar='', help='Optional pool') - @args('--interface', metavar='', help='Optional interface') - def create(self, ip_range, pool=None, interface=None): - """Creates floating ips for zone by range.""" - admin_context = context.get_admin_context() - if not pool: - pool = CONF.default_floating_pool - if not interface: - interface = CONF.public_interface - - ips = ({'address': str(address), 'pool': pool, 'interface': interface} - for address in self.address_to_hosts(ip_range)) - try: - db.floating_ip_bulk_create(admin_context, ips) - except exception.FloatingIpExists as exc: - # NOTE(simplylizz): Maybe logging would be better here - # instead of printing, but logging isn't used here and I - # don't know why. - print('error: %s' % exc) - sys.exit(1) - - @args('--ip_range', metavar='', help='IP range') - def delete(self, ip_range): - """Deletes floating ips by range.""" - admin_context = context.get_admin_context() - - ips = ({'address': str(address)} - for address in self.address_to_hosts(ip_range)) - db.floating_ip_bulk_destroy(admin_context, ips) - - @args('--host', metavar='', help='Host') - def list(self, host=None): - """Lists all floating ips (optionally by host) - Note: if host is given, only active floating IPs are returned""" - ctxt = context.get_admin_context() - try: - if host is None: - floating_ips = db.floating_ip_get_all(ctxt) - else: - floating_ips = db.floating_ip_get_all_by_host(ctxt, host) - except exception.NoFloatingIpsDefined: - print _("No floating IP addresses have been defined.") - return - for floating_ip in floating_ips: - instance_uuid = None - if floating_ip['fixed_ip_id']: - fixed_ip = db.fixed_ip_get(ctxt, floating_ip['fixed_ip_id']) - instance_uuid = fixed_ip['instance_uuid'] - - print "%s\t%s\t%s\t%s\t%s" % (floating_ip['project_id'], - floating_ip['address'], - instance_uuid, - floating_ip['pool'], - floating_ip['interface']) - - -class NetworkCommands(object): - """Class for managing networks.""" - - @args('--label', metavar='