summaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
Diffstat (limited to 'bin')
-rwxr-xr-xbin/nova-api65
-rwxr-xr-xbin/nova-api-new34
-rwxr-xr-xbin/nova-compute15
-rwxr-xr-xbin/nova-dhcpbridge66
-rwxr-xr-xbin/nova-import-canonical-imagestore12
-rwxr-xr-xbin/nova-instancemonitor15
-rwxr-xr-xbin/nova-manage251
-rwxr-xr-xbin/nova-network19
-rwxr-xr-xbin/nova-objectstore13
-rwxr-xr-xbin/nova-scheduler43
-rwxr-xr-xbin/nova-volume15
11 files changed, 409 insertions, 139 deletions
diff --git a/bin/nova-api b/bin/nova-api
index 13baf22a7..a5027700b 100755
--- a/bin/nova-api
+++ b/bin/nova-api
@@ -1,61 +1,48 @@
#!/usr/bin/env python
+# pylint: disable-msg=C0103
# 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
+# 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.
-
+# 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.
"""
-Tornado daemon for the main API endpoint.
+Nova API daemon.
"""
-import logging
-from tornado import httpserver
-from tornado import ioloop
+import os
+import sys
+
+# 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)
from nova import flags
-from nova import rpc
-from nova import server
from nova import utils
-from nova.endpoint import admin
-from nova.endpoint import api
-from nova.endpoint import cloud
+from nova import server
FLAGS = flags.FLAGS
+flags.DEFINE_integer('api_port', 8773, 'API port')
-
-def main(_argv):
- """Load the controllers and start the tornado I/O loop."""
- controllers = {
- 'Cloud': cloud.CloudController(),
- 'Admin': admin.AdminController()}
- _app = api.APIServerApplication(controllers)
-
- conn = rpc.Connection.instance()
- consumer = rpc.AdapterConsumer(connection=conn,
- topic=FLAGS.cloud_topic,
- proxy=controllers['Cloud'])
-
- io_inst = ioloop.IOLoop.instance()
- _injected = consumer.attach_to_tornado(io_inst)
-
- http_server = httpserver.HTTPServer(_app)
- http_server.listen(FLAGS.cc_port)
- logging.debug('Started HTTP server on %s', FLAGS.cc_port)
- io_inst.start()
-
+def main(_args):
+ from nova import api
+ from nova import wsgi
+ wsgi.run_server(api.API(), FLAGS.api_port)
if __name__ == '__main__':
utils.default_flagfile()
diff --git a/bin/nova-api-new b/bin/nova-api-new
deleted file mode 100755
index fda42339c..000000000
--- a/bin/nova-api-new
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env python
-# pylint: disable-msg=C0103
-# 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.
-"""
-Nova API daemon.
-"""
-
-from nova import api
-from nova import flags
-from nova import utils
-from nova import wsgi
-
-FLAGS = flags.FLAGS
-flags.DEFINE_integer('api_port', 8773, 'API port')
-
-if __name__ == '__main__':
- utils.default_flagfile()
- wsgi.run_server(api.API(), FLAGS.api_port)
diff --git a/bin/nova-compute b/bin/nova-compute
index e0c12354f..1724e9659 100755
--- a/bin/nova-compute
+++ b/bin/nova-compute
@@ -21,12 +21,23 @@
Twistd daemon for the nova compute nodes.
"""
+import os
+import sys
+
+# 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)
+
+from nova import service
from nova import twistd
-from nova.compute import service
if __name__ == '__main__':
twistd.serve(__file__)
if __name__ == '__builtin__':
- application = service.ComputeService.create()
+ application = service.Service.create() # pylint: disable=C0103
diff --git a/bin/nova-dhcpbridge b/bin/nova-dhcpbridge
index f70a4482c..a127ed03c 100755
--- a/bin/nova-dhcpbridge
+++ b/bin/nova-dhcpbridge
@@ -25,53 +25,65 @@ import logging
import os
import sys
-#TODO(joshua): there is concern that the user dnsmasq runs under will not
-# have nova in the path. This should be verified and if it is
-# not true the ugly line below can be removed
-sys.path.append(os.path.abspath(os.path.join(__file__, "../../")))
-
+# 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)
+
+from nova import db
from nova import flags
from nova import rpc
from nova import utils
from nova.network import linux_net
-from nova.network import model
-from nova.network import service
FLAGS = flags.FLAGS
+flags.DECLARE('auth_driver', 'nova.auth.manager')
+flags.DECLARE('redis_db', 'nova.datastore')
+flags.DECLARE('network_size', 'nova.network.manager')
+flags.DECLARE('num_networks', 'nova.network.manager')
+flags.DECLARE('update_dhcp_on_disassociate', 'nova.network.manager')
-def add_lease(_mac, ip, _hostname, _interface):
+def add_lease(mac, ip_address, _hostname, _interface):
"""Set the IP that was assigned by the DHCP server."""
if FLAGS.fake_rabbit:
- service.VlanNetworkService().lease_ip(ip)
+ logging.debug("leasing ip")
+ network_manager = utils.import_object(FLAGS.network_manager)
+ network_manager.lease_fixed_ip(None, mac, ip_address)
else:
- rpc.cast("%s.%s" % (FLAGS.network_topic, FLAGS.node_name),
- {"method": "lease_ip",
- "args": {"fixed_ip": ip}})
+ rpc.cast("%s.%s" % (FLAGS.network_topic, FLAGS.host),
+ {"method": "lease_fixed_ip",
+ "args": {"context": None,
+ "mac": mac,
+ "address": ip_address}})
-def old_lease(_mac, _ip, _hostname, _interface):
+def old_lease(_mac, _ip_address, _hostname, _interface):
"""Do nothing, just an old lease update."""
logging.debug("Adopted old lease or got a change of mac/hostname")
-def del_lease(_mac, ip, _hostname, _interface):
+def del_lease(mac, ip_address, _hostname, _interface):
"""Called when a lease expires."""
if FLAGS.fake_rabbit:
- service.VlanNetworkService().release_ip(ip)
+ logging.debug("releasing ip")
+ network_manager = utils.import_object(FLAGS.network_manager)
+ network_manager.release_fixed_ip(None, mac, ip_address)
else:
- rpc.cast("%s.%s" % (FLAGS.network_topic, FLAGS.node_name),
- {"method": "release_ip",
- "args": {"fixed_ip": ip}})
+ rpc.cast("%s.%s" % (FLAGS.network_topic, FLAGS.host),
+ {"method": "release_fixed_ip",
+ "args": {"context": None,
+ "mac": mac,
+ "address": ip_address}})
def init_leases(interface):
"""Get the list of hosts for an interface."""
- net = model.get_network_by_interface(interface)
- res = ""
- for address in net.assigned_objs:
- res += "%s\n" % linux_net.host_dhcp(address)
- return res
+ network_ref = db.network_get_by_bridge(None, interface)
+ return linux_net.get_dhcp_hosts(None, network_ref['id'])
def main():
@@ -83,10 +95,16 @@ def main():
if int(os.environ.get('TESTING', '0')):
FLAGS.fake_rabbit = True
FLAGS.redis_db = 8
- FLAGS.network_size = 32
+ FLAGS.network_size = 16
FLAGS.connection_type = 'fake'
FLAGS.fake_network = True
FLAGS.auth_driver = 'nova.auth.ldapdriver.FakeLdapDriver'
+ FLAGS.num_networks = 5
+ path = os.path.abspath(os.path.join(os.path.dirname(__file__),
+ '..',
+ '_trial_temp',
+ 'nova.sqlite'))
+ FLAGS.sql_connection = 'sqlite:///%s' % path
action = argv[1]
if action in ['add', 'del', 'old']:
mac = argv[2]
diff --git a/bin/nova-import-canonical-imagestore b/bin/nova-import-canonical-imagestore
index 44e65191d..4ed9e8365 100755
--- a/bin/nova-import-canonical-imagestore
+++ b/bin/nova-import-canonical-imagestore
@@ -29,18 +29,26 @@ import subprocess
import sys
import urllib2
+# 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)
+
from nova import flags
from nova import utils
from nova.objectstore import image
FLAGS = flags.FLAGS
-api_url = 'https://imagestore.canonical.com/api/dashboard'
+API_URL = 'https://imagestore.canonical.com/api/dashboard'
def get_images():
"""Get a list of the images from the imagestore URL."""
- images = json.load(urllib2.urlopen(api_url))['images']
+ images = json.load(urllib2.urlopen(API_URL))['images']
images = [img for img in images if img['title'].find('amd64') > -1]
return images
diff --git a/bin/nova-instancemonitor b/bin/nova-instancemonitor
index 911fb6f42..094da4033 100755
--- a/bin/nova-instancemonitor
+++ b/bin/nova-instancemonitor
@@ -21,9 +21,19 @@
Daemon for Nova RRD based instance resource monitoring.
"""
+import os
import logging
+import sys
from twisted.application import service
+# 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)
+
from nova import twistd
from nova.compute import monitor
@@ -35,9 +45,10 @@ if __name__ == '__main__':
if __name__ == '__builtin__':
logging.warn('Starting instance monitor')
- m = monitor.InstanceMonitor()
+ # pylint: disable-msg=C0103
+ monitor = monitor.InstanceMonitor()
# This is the parent service that twistd will be looking for when it
# parses this file, return it so that we can get it into globals below
application = service.Application('nova-instancemonitor')
- m.setServiceParent(application)
+ monitor.setServiceParent(application)
diff --git a/bin/nova-manage b/bin/nova-manage
index 2b1651c00..d36b0f53a 100755
--- a/bin/nova-manage
+++ b/bin/nova-manage
@@ -17,20 +17,64 @@
# 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.
+
+
"""
CLI interface for nova management.
- Connects to the running ADMIN api in the api daemon.
"""
+import logging
+import os
import sys
import time
+import IPy
+
+# 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)
+
+from nova import db
+from nova import exception
from nova import flags
+from nova import quota
from nova import utils
from nova.auth import manager
-from nova.compute import model
+from nova.network import manager as network_manager
from nova.cloudpipe import pipelib
-from nova.endpoint import cloud
FLAGS = flags.FLAGS
@@ -41,23 +85,27 @@ class VpnCommands(object):
def __init__(self):
self.manager = manager.AuthManager()
- self.instdir = model.InstanceDirectory()
- self.pipe = pipelib.CloudPipe(cloud.CloudController())
+ self.pipe = pipelib.CloudPipe()
def list(self):
"""Print a listing of the VPNs for all projects."""
print "%-12s\t" % 'project',
- print "%-12s\t" % 'ip:port',
+ print "%-20s\t" % 'ip:port',
print "%s" % 'state'
for project in self.manager.get_projects():
print "%-12s\t" % project.name,
- print "%s:%s\t" % (project.vpn_ip, project.vpn_port),
+
+ try:
+ s = "%s:%s" % (project.vpn_ip, project.vpn_port)
+ except exception.NotFound:
+ s = "None"
+ print "%-20s\t" % s,
vpn = self._vpn_for(project.id)
if vpn:
command = "ping -c1 -w1 %s > /dev/null; echo $?"
- out, _err = utils.execute( command % vpn['private_dns_name'],
- check_exit_code=False)
+ out, _err = utils.execute(command % vpn['private_dns_name'],
+ check_exit_code=False)
if out.strip() == '0':
net = 'up'
else:
@@ -73,9 +121,8 @@ class VpnCommands(object):
def _vpn_for(self, project_id):
"""Get the VPN instance for a project ID."""
- for instance in self.instdir.all:
- if ('image_id' in instance.state
- and instance['image_id'] == FLAGS.vpn_image_id
+ for instance in db.instance_get_all(None):
+ if (instance['image_id'] == FLAGS.vpn_image_id
and not instance['state_description'] in
['shutting_down', 'shutdown']
and instance['project_id'] == project_id):
@@ -94,6 +141,67 @@ class VpnCommands(object):
self.pipe.launch_vpn_instance(project_id)
+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')
+
+ def run(self, shell=None):
+ """Runs a Python interactive interpreter.
+
+ args: [shell=bpython]"""
+ 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()
+
+ def script(self, path):
+ """Runs the script from the specifed path with flags set properly.
+ arguments: path"""
+ exec(compile(open(path).read(), path, 'exec'), locals(), globals())
+
+
class RoleCommands(object):
"""Class for managing roles."""
@@ -123,6 +231,13 @@ class RoleCommands(object):
class UserCommands(object):
"""Class for managing users."""
+ @staticmethod
+ def _print_export(user):
+ """Print export variables to use with API."""
+ print 'export EC2_ACCESS_KEY=%s' % user.access
+ print 'export EC2_SECRET_KEY=%s' % user.secret
+
+
def __init__(self):
self.manager = manager.AuthManager()
@@ -130,13 +245,13 @@ class UserCommands(object):
"""creates a new admin and prints exports
arguments: name [access] [secret]"""
user = self.manager.create_user(name, access, secret, True)
- print_export(user)
+ self._print_export(user)
def create(self, name, access=None, secret=None):
"""creates a new user and prints exports
arguments: name [access] [secret]"""
user = self.manager.create_user(name, access, secret, False)
- print_export(user)
+ self._print_export(user)
def delete(self, name):
"""deletes an existing user
@@ -148,7 +263,7 @@ class UserCommands(object):
arguments: name"""
user = self.manager.get_user(name)
if user:
- print_export(user)
+ self._print_export(user)
else:
print "User %s doesn't exist" % name
@@ -158,12 +273,18 @@ class UserCommands(object):
for user in self.manager.get_users():
print user.name
-
-def print_export(user):
- """Print export variables to use with API."""
- print 'export EC2_ACCESS_KEY=%s' % user.access
- print 'export EC2_SECRET_KEY=%s' % user.secret
-
+ def modify(self, name, access_key, secret_key, is_admin):
+ """update a users keys & admin flag
+ arguments: accesskey secretkey admin
+ leave any field blank to ignore it, admin should be 'T', 'F', or blank
+ """
+ if not is_admin:
+ is_admin = None
+ elif is_admin.upper()[0] == 'T':
+ is_admin = True
+ else:
+ is_admin = False
+ self.manager.modify_user(name, access_key, secret_key, is_admin)
class ProjectCommands(object):
"""Class for managing projects."""
@@ -189,7 +310,7 @@ class ProjectCommands(object):
def environment(self, project_id, user_id, filename='novarc'):
"""Exports environment variables to an sourcable file
arguments: project_id user_id [filename='novarc]"""
- rc = self.manager.get_environment_rc(project_id, user_id)
+ rc = self.manager.get_environment_rc(user_id, project_id)
with open(filename, 'w') as f:
f.write(rc)
@@ -199,6 +320,19 @@ class ProjectCommands(object):
for project in self.manager.get_projects():
print project.name
+ def quota(self, project_id, key=None, value=None):
+ """Set or display quotas for project
+ arguments: project_id [key] [value]"""
+ if key:
+ quo = {'project_id': project_id, key: value}
+ try:
+ db.quota_update(None, project_id, quo)
+ except exception.NotFound:
+ db.quota_create(None, quo)
+ project_quota = quota.get_quota(None, project_id)
+ for key, value in project_quota.iteritems():
+ print '%s: %s' % (key, value)
+
def remove(self, project, user):
"""Removes user from project
arguments: project user"""
@@ -212,11 +346,70 @@ class ProjectCommands(object):
f.write(zip_file)
-categories = [
+class FloatingIpCommands(object):
+ """Class for managing floating ip."""
+
+ def create(self, host, range):
+ """Creates floating ips for host by range
+ arguments: host ip_range"""
+ for address in IPy.IP(range):
+ db.floating_ip_create(None, {'address': str(address),
+ 'host': host})
+
+ def delete(self, ip_range):
+ """Deletes floating ips by range
+ arguments: range"""
+ for address in IPy.IP(ip_range):
+ db.floating_ip_destroy(None, str(address))
+
+
+ def list(self, host=None):
+ """Lists all floating ips (optionally by host)
+ arguments: [host]"""
+ if host == None:
+ floating_ips = db.floating_ip_get_all(None)
+ else:
+ floating_ips = db.floating_ip_get_all_by_host(None, host)
+ for floating_ip in floating_ips:
+ instance = None
+ if floating_ip['fixed_ip']:
+ instance = floating_ip['fixed_ip']['instance']['ec2_id']
+ print "%s\t%s\t%s" % (floating_ip['host'],
+ floating_ip['address'],
+ instance)
+
+class NetworkCommands(object):
+ """Class for managing networks."""
+
+ def create(self, fixed_range=None, num_networks=None,
+ network_size=None, vlan_start=None, vpn_start=None):
+ """Creates fixed ips for host by range
+ arguments: [fixed_range=FLAG], [num_networks=FLAG],
+ [network_size=FLAG], [vlan_start=FLAG],
+ [vpn_start=FLAG]"""
+ if not fixed_range:
+ fixed_range = FLAGS.fixed_range
+ if not num_networks:
+ num_networks = FLAGS.num_networks
+ if not network_size:
+ network_size = FLAGS.network_size
+ if not vlan_start:
+ vlan_start = FLAGS.vlan_start
+ if not vpn_start:
+ vpn_start = FLAGS.vpn_start
+ net_manager = utils.import_object(FLAGS.network_manager)
+ net_manager.create_networks(None, fixed_range, int(num_networks),
+ int(network_size), int(vlan_start),
+ int(vpn_start))
+
+CATEGORIES = [
('user', UserCommands),
('project', ProjectCommands),
('role', RoleCommands),
+ ('shell', ShellCommands),
('vpn', VpnCommands),
+ ('floating', FloatingIpCommands),
+ ('network', NetworkCommands)
]
@@ -255,15 +448,19 @@ def main():
"""Parse options and call the appropriate class/method."""
utils.default_flagfile('/etc/nova/nova-manage.conf')
argv = FLAGS(sys.argv)
+
+ if FLAGS.verbose:
+ logging.getLogger().setLevel(logging.DEBUG)
+
script_name = argv.pop(0)
if len(argv) < 1:
print script_name + " category action [<args>]"
print "Available categories:"
- for k, _ in categories:
+ for k, _ in CATEGORIES:
print "\t%s" % k
sys.exit(2)
category = argv.pop(0)
- matches = lazy_match(category, categories)
+ matches = lazy_match(category, CATEGORIES)
# instantiate the command group object
category, fn = matches[0]
command_object = fn()
@@ -282,9 +479,9 @@ def main():
fn(*argv)
sys.exit(0)
except TypeError:
- print "Wrong number of arguments supplied"
+ print "Possible wrong number of arguments supplied"
print "%s %s: %s" % (category, action, fn.__doc__)
- sys.exit(2)
+ raise
if __name__ == '__main__':
main()
diff --git a/bin/nova-network b/bin/nova-network
index ba9063f56..fa88aeb47 100755
--- a/bin/nova-network
+++ b/bin/nova-network
@@ -21,16 +21,23 @@
Twistd daemon for the nova network nodes.
"""
-from nova import flags
+import os
+import sys
+
+# 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)
+
+from nova import service
from nova import twistd
-from nova.network import service
-
-FLAGS = flags.FLAGS
-
if __name__ == '__main__':
twistd.serve(__file__)
if __name__ == '__builtin__':
- application = service.type_to_class(FLAGS.network_type).create()
+ application = service.Service.create() # pylint: disable-msg=C0103
diff --git a/bin/nova-objectstore b/bin/nova-objectstore
index 02f2bcb48..728f2ee5b 100755
--- a/bin/nova-objectstore
+++ b/bin/nova-objectstore
@@ -21,6 +21,17 @@
Twisted daemon for nova objectstore. Supports S3 API.
"""
+import os
+import sys
+
+# 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)
+
from nova import flags
from nova import utils
from nova import twistd
@@ -35,4 +46,4 @@ if __name__ == '__main__':
if __name__ == '__builtin__':
utils.default_flagfile()
- application = handler.get_application()
+ application = handler.get_application() # pylint: disable-msg=C0103
diff --git a/bin/nova-scheduler b/bin/nova-scheduler
new file mode 100755
index 000000000..38a8f213f
--- /dev/null
+++ b/bin/nova-scheduler
@@ -0,0 +1,43 @@
+#!/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.
+#
+# 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.
+
+"""
+ Twistd daemon for the nova scheduler nodes.
+"""
+
+import os
+import sys
+
+# 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)
+
+from nova import service
+from nova import twistd
+
+
+if __name__ == '__main__':
+ twistd.serve(__file__)
+
+if __name__ == '__builtin__':
+ application = service.Service.create()
diff --git a/bin/nova-volume b/bin/nova-volume
index f7a8fad37..b9e235717 100755
--- a/bin/nova-volume
+++ b/bin/nova-volume
@@ -21,12 +21,23 @@
Twistd daemon for the nova volume nodes.
"""
+import os
+import sys
+
+# 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)
+
+from nova import service
from nova import twistd
-from nova.volume import service
if __name__ == '__main__':
twistd.serve(__file__)
if __name__ == '__builtin__':
- application = service.VolumeService.create()
+ application = service.Service.create() # pylint: disable-msg=C0103