diff --git a/README b/README index 560e4054ce..e70b1f4d98 100644 --- a/README +++ b/README @@ -20,6 +20,16 @@ implementation and enables them to switch out a plug-in by simple editing a config file - plugins.ini +# -- Layout + + The Quantum project includes 3 core packages: + + quantum-common (General utils for Quantum and its plugins) + quantum-server (The actual Quantum service itself) + quantum-client (The Quantum CLI and API Python library) + + As well as some plugins. + # -- Dependencies The following python packages are required to run quantum. These can be @@ -44,6 +54,24 @@ this) 3) Install packages with pip: $ pip install +# -- Running from the source code + + bin/quantum-server #Server + bin/quantum #CLI + sh run_tests.sh #Tests + +# -- Installing from the source code + + You have 3 options: + a) sudo python setup.py install + # Installs to /usr/lib, /usr/bin, /etc, etc + + b) python setup.py install --user + # Install into $HOME/.local/... + + c) python setup.py install --venv + # Creates and installs into a virtual-env at ~/.quantum-venv + # -- Configuring Quantum plug-in 1) Identify your desired plug-in. Choose a plugin from one of he options in @@ -60,29 +88,30 @@ this) # -- Launching the Quantum Service -1) Start quantum using the following command [on the quantum service host]: -~/src/quantum$ PYTHONPATH=.:$PYTHONPATH python bin/quantum etc/quantum.conf + # If you're running from the source + bin/quantum-server + + # If you installed Quantum + quantum-server # -- Making requests against the Quantum Service -Please refer to sample Web Service client code in: + Quantum comes with a programmatic CLI that is driven by the Quantum Web + Service. You can use the CLI by issuing the following command: -../quantum/test_scripts/miniclient.py + # If you're running from the source + bin/quantum -# -- CLI tools to program the Quantum-managed Cloud networking fabric + # If you installed Quantum + quantum -Quantum comes with a programmatic CLI that is driven by the Quantum Web -Service. You can use the CLI by issuing the following command: + This will show help all of the available commands. -~/src/quantum$ PYTHONPATH=.:$PYTHONPATH python quantum/cli.py + An example session looks like this: -This will show help all of the available commands. - -An example session looks like this: - -$ export TENANT=t1 -$ PYTHONPATH=. python quantum/cli.py -v create_net $TENANT network1 -Created a new Virtual Network with ID:e754e7c0-a8eb-40e5-861a-b182d30c3441 + $ export TENANT=t1 + $ quantum -v create_net $TENANT network1 + Created a new Virtual Network with ID:e754e7c0-a8eb-40e5-861a-b182d30c3441 # -- Authentication and Authorization @@ -102,12 +131,12 @@ pipeline = authN authZ extensions quantumapiapp The final step concerns configuring access to Keystone. The following attributes must be specified in the [filter:authN] section of quantum.conf: -auth_host IP address or host name of the server where Keystone is running -auth_port Port where the Keystone Admin API is listening -auth_protocol Protocol used for communicating with Keystone (http/https) -auth_version Keystone API version (default: 2.0) -auth_admin_token Keystone token for administrative access -auth_admin_user Keystone user with administrative rights +auth_host IP address or host name of the server where Keystone is running +auth_port Port where the Keystone Admin API is listening +auth_protocol Protocol used for communicating with Keystone (http/https) +auth_version Keystone API version (default: 2.0) +auth_admin_token Keystone token for administrative access +auth_admin_user Keystone user with administrative rights auth_admin_password Password for the user specified with auth_admin_user NOTE: aut_admin_token and auth_admin_user/password are exclusive. @@ -200,3 +229,11 @@ There are a few requirements to writing your own plugin: The QuantumEchoPlugin lists foxinsox in its supported_extension_aliases and implements the method from FoxInSocksPluginInterface. + +# -- Building packages + + rpms: + python setup.py build rpm + + debs: + python setup.py build deb diff --git a/quantum/common/__init__.py b/bin/__init__.py similarity index 81% rename from quantum/common/__init__.py rename to bin/__init__.py index 7e695ff08d..8e233bcf42 100644 --- a/quantum/common/__init__.py +++ b/bin/__init__.py @@ -1,5 +1,6 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright 2011 Nicira Networks, Inc. + +# Copyright 2011 Cisco Systems # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -13,4 +14,8 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -# @author: Somik Behera, Nicira Networks, Inc. +# @author: Tyler Smith, Cisco Systems +import os +import sys + +sys.path.append(os.path.join(os.getcwd(), 'tools')) diff --git a/bin/quantum b/bin/quantum index 48abd18ae9..649047493c 100755 --- a/bin/quantum +++ b/bin/quantum @@ -19,43 +19,8 @@ # If ../quantum/__init__.py exists, add ../ to Python search path, so that # it will override what happens to be installed in /usr/(local/)lib/python... -import gettext -import optparse -import os -import sys +import __init__ +import source_environment +from quantum.cli import main as cli - -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, 'quantum', '__init__.py')): - sys.path.insert(0, possible_topdir) - -gettext.install('quantum', unicode=1) - -from quantum import service -from quantum.common import config - - -def create_options(parser): - """ - Sets up the CLI and config-file options that may be - parsed and program commands. - :param parser: The option parser - """ - config.add_common_options(parser) - config.add_log_options(parser) - - -if __name__ == '__main__': - oparser = optparse.OptionParser(version='%%prog VERSION') - create_options(oparser) - (options, args) = config.parse_options(oparser) - - try: - service = service.serve_wsgi(service.QuantumApiService, - options=options, - args=args) - service.wait() - except RuntimeError, e: - sys.exit("ERROR: %s" % e) +cli() diff --git a/bin/quantum-server b/bin/quantum-server new file mode 100755 index 0000000000..d6b9fbe2a2 --- /dev/null +++ b/bin/quantum-server @@ -0,0 +1,26 @@ +#!/usr/bin/env python +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 Nicira Neworks, Inc. +# 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. + +# If ../quantum/__init__.py exists, add ../ to Python search path, so that +# it will override what happens to be installed in /usr/(local/)lib/python... + +import __init__ +import source_environment +from quantum.server import main as server + +server() diff --git a/quantum/plugins/cisco/nova/__init__.py b/client/lib/__init__.py similarity index 100% rename from quantum/plugins/cisco/nova/__init__.py rename to client/lib/__init__.py diff --git a/client/lib/quantum/__init__.py b/client/lib/quantum/__init__.py new file mode 100644 index 0000000000..d407605e19 --- /dev/null +++ b/client/lib/quantum/__init__.py @@ -0,0 +1,5 @@ +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) diff --git a/bin/cli b/client/lib/quantum/cli.py similarity index 99% rename from bin/cli rename to client/lib/quantum/cli.py index 2bc1cb3d6d..138d75d5e6 100755 --- a/bin/cli +++ b/client/lib/quantum/cli.py @@ -112,7 +112,7 @@ def build_args(cmd, cmdargs, arglist): return args -if __name__ == "__main__": +def main(): usagestr = "Usage: %prog [OPTIONS] [args]" parser = OptionParser(usage=usagestr) parser.add_option("-H", "--host", dest="host", diff --git a/quantum/cli_lib.py b/client/lib/quantum/cli_lib.py similarity index 100% rename from quantum/cli_lib.py rename to client/lib/quantum/cli_lib.py diff --git a/quantum/client.py b/client/lib/quantum/client.py similarity index 99% rename from quantum/client.py rename to client/lib/quantum/client.py index cf72f8a7ec..afba7efb94 100644 --- a/quantum/client.py +++ b/client/lib/quantum/client.py @@ -22,7 +22,7 @@ import socket import urllib from quantum.common import exceptions -from quantum.common.wsgi import Serializer +from quantum.common.serializer import Serializer LOG = logging.getLogger('quantum.client') EXCEPTIONS = { diff --git a/tests/__init__.py b/client/lib/quantum/tests/__init__.py similarity index 100% rename from tests/__init__.py rename to client/lib/quantum/tests/__init__.py diff --git a/quantum/plugins/cisco/tests/unit/__init__.py b/client/lib/quantum/tests/unit/__init__.py similarity index 85% rename from quantum/plugins/cisco/tests/unit/__init__.py rename to client/lib/quantum/tests/unit/__init__.py index 5910e35494..726786924d 100644 --- a/quantum/plugins/cisco/tests/unit/__init__.py +++ b/client/lib/quantum/tests/unit/__init__.py @@ -17,6 +17,12 @@ # See http://code.google.com/p/python-nose/issues/detail?id=373 # The code below enables nosetests to work with i18n _() blocks +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) + import __builtin__ import unittest setattr(__builtin__, '_', lambda x: x) diff --git a/tests/unit/test_clientlib.py b/client/lib/quantum/tests/unit/test_clientlib.py similarity index 99% rename from tests/unit/test_clientlib.py rename to client/lib/quantum/tests/unit/test_clientlib.py index ce3e7186b0..4e2c920c76 100644 --- a/tests/unit/test_clientlib.py +++ b/client/lib/quantum/tests/unit/test_clientlib.py @@ -20,7 +20,7 @@ import logging import unittest import re -from quantum.common.wsgi import Serializer +from quantum.common.serializer import Serializer from quantum.client import Client LOG = logging.getLogger('quantum.tests.test_api') diff --git a/client/setup.py b/client/setup.py new file mode 100644 index 0000000000..b0d4a30388 --- /dev/null +++ b/client/setup.py @@ -0,0 +1,57 @@ +try: + from setuptools import setup, find_packages +except ImportError: + from ez_setup import use_setuptools + use_setuptools() + from setuptools import setup, find_packages + +Name = 'quantum-client' +Url = "https://launchpad.net/quantum" +Version = '2012.1-dev' +License = 'Apache License 2.0' +# Change as required +Author = 'Netstack' +AuthorEmail = 'netstack@lists.launchpad.net' +Maintainer = '' +Summary = 'Client functionalities for Quantum' +ShortDescription = Summary +Description = Summary + +requires = [ + 'quantum-common' +] + +EagerResources = [ + 'quantum', +] + +ProjectScripts = [ +] + +PackageData = { +} + + +setup( + name=Name, + version=Version, + url=Url, + author=Author, + author_email=AuthorEmail, + description=ShortDescription, + long_description=Description, + license=License, + scripts=ProjectScripts, + install_requires=requires, + include_package_data=True, + packages=find_packages('lib'), + package_data=PackageData, + package_dir={'': 'lib'}, + eager_resources=EagerResources, + namespace_packages=['quantum'], + entry_points={ + 'console_scripts': [ + 'quantum = quantum.cli:main' + ] + }, +) diff --git a/common/README b/common/README new file mode 100644 index 0000000000..51b0f1efbd --- /dev/null +++ b/common/README @@ -0,0 +1,239 @@ +# -- Welcome! + + You have come across a cloud computing network fabric controller. It has + identified itself as "Quantum." It aims to tame your (cloud) networking! + +# -- Basics: + +1) Quantum REST API: Quantum supports a REST-ful programmatic interface to + manage your cloud networking fabric. + +2) Quantum Plugins: Quantum sports a plug-able architecture that allows + Quantum's REST API to be backed by various entities that can create a + cloud-class virtual networking fabric. The advantages of this plug-able + architecture is two-folds: + + a) Allows for ANY open-source project or commercial vendor to write a + Quantum plug-in. + + b) Allows Quantum users to not be tied down to a single Quantum + implementation and enables them to switch out a plug-in by simple editing a + config file - plugins.ini + +# -- Layout + + The Quantum project includes 3 core packages: + + quantum-common (General utils for Quantum and its plugins) + quantum-server (The actual Quantum service itself) + quantum-client (The Quantum CLI and API Python library) + + As well as some plugins. + +# -- Dependencies + + The following python packages are required to run quantum. These can be + installed using pip: + + eventlet>=0.9.12 + nose + Paste + PasteDeploy + pep8==0.5.0 + python-gflags + routes + simplejson + webob + webtest + +1) Install easy_install (there is probably a distribution specific package for +this) + +2) Install pip: + $ easy_install pip==dev +3) Install packages with pip: + $ pip install + +# -- Running from the source code + + bin/quantum-server #Server + bin/quantum #CLI + python run_tests.py #Tests + +# -- Installing from the source code + + You have 3 options: + a) sudo python setup.py install + # Installs to /usr/lib, /usr/bin, /etc, etc + + b) python setup.py install --user + # Install into $HOME/.local/... + + c) python setup.py install --venv + # Creates and installs into a virtual-env at ~/.quantum-venv + +# -- Configuring Quantum plug-in + +1) Identify your desired plug-in. Choose a plugin from one of he options in + the quantum/plugins directory. + +2) Update plug-in configuration by editing the quantum/plugins.ini file and + modify "provider" property to point to the location of the Quantum plug-in. + It should specify the class path to the plugin and the class name (i.e. for + a plugin class MyPlugin in quantum/plugins/myplugin/myplugin.py the + provider would be: quantum.plugins.myplugin.myplugin.MyPlugin) + +3) Read the plugin specific README, this is usually found in the same + directory as your Quantum plug-in, and follow configuration instructions. + +# -- Launching the Quantum Service + + # If you're running from the source + bin/quantum-server + + # If you installed Quantum + quantum-server + +# -- Making requests against the Quantum Service + + Quantum comes with a programmatic CLI that is driven by the Quantum Web + Service. You can use the CLI by issuing the following command: + + # If you're running from the source + bin/quantum + + # If you installed Quantum + quantum + + This will show help all of the available commands. + + An example session looks like this: + + $ export TENANT=t1 + $ quantum -v create_net $TENANT network1 + Created a new Virtual Network with ID:e754e7c0-a8eb-40e5-861a-b182d30c3441 + +# -- Authentication and Authorization + +Requests to Quantum API are authenticated with the Keystone identity service +using a token-based authentication protocol. + +1) Enabling Authentication and Authorization +The Keystone identity service is a requirement. It must be installed, although +not necessarily on the same machine where Quantum is running; both Keystone's +admin API and service API should be running + +Authentication and Authorization middleware should be enabled in the Quantum +pipeline. To this aim, uncomment the following line in /etc/quantum.conf: + +pipeline = authN authZ extensions quantumapiapp + +The final step concerns configuring access to Keystone. The following attributes +must be specified in the [filter:authN] section of quantum.conf: + +auth_host IP address or host name of the server where Keystone is running +auth_port Port where the Keystone Admin API is listening +auth_protocol Protocol used for communicating with Keystone (http/https) +auth_version Keystone API version (default: 2.0) +auth_admin_token Keystone token for administrative access +auth_admin_user Keystone user with administrative rights +auth_admin_password Password for the user specified with auth_admin_user + +NOTE: aut_admin_token and auth_admin_user/password are exclusive. +If both are specified, auth_admin_token has priority. + +2) Authenticating and Authorizing request for Quantum API + +A user should first authenticate with Keystone, supplying user credentials; +the Keystone service will return an authentication token, together with +informations concerning token expirations and endpoint where that token can +be used. + +The authentication token must be included in every request for the Quantum +API, in the 'X_AUTH_TOKEN' header. Quantum will look for the authentication +token in this header, and validate it with the Keystone service. + +In order to validate authentication tokens, Quantum uses Keystone's +administrative API. It therefore requires credentials for an administrative +user, which can be specified in Quantum's configuration file +(etc/quantum.conf) +Either username and password, or an authentication token for an administrative +user can be specified in the configuration file: + +- Credentials: + +auth_admin_user = admin +auth_admin_password = secrete + +- Admin token: + +auth_admin_token = 9a82c95a-99e9-4c3a-b5ee-199f6ba7ff04 + +As of the current release, any user for a tenant is allowed to perform +every operation on the networks owned by the tenant itself, except for +plugging interfaces. In order to perform such operation, the user must have +the Quantum:NetworkAdmin roles. Roles can be configured in Keystone using +the administrative API. + + +# -- Writing your own Quantum plug-in + +If you wish the write your own Quantum plugin, please refer to some concrete as +well as sample plugins available in: + +../quantum/quantum/plugins/.. directory. + +There are a few requirements to writing your own plugin: + +1) Your plugin should implement all methods defined in the + quantum/quantum_plugin_base.QuantumPluginBase class + +2) Copy your Quantum plug-in over to the quantum/quantum/plugins/.. directory + +3) The next step is to edit the plugins.ini file in the same directory + as QuantumPluginBase class and specify the location of your custom plugin + as the "provider" + +4) Launch the Quantum Service, and your plug-in is configured and ready to + manage a Cloud Networking Fabric. + +# -- Extensions + +1) Creating Extensions: + a) Extension files should be placed under ./extensions folder. + b) The extension file should have a class with the same name as the filename. + This class should implement the contract required by the extension framework. + See ExtensionDescriptor class in ./quantum/common/extensions.py for details + c) To stop a file in ./extensions folder from being loaded as an extension, + the filename should start with an "_" + For an example of an extension file look at Foxinsocks class in + ./tests/unit/extensions/foxinsocks.py + The unit tests in ./tests/unit/test_extensions.py document all the ways in + which you can use extensions + +2) Associating plugins with extensions: + a) A Plugin can advertize all the extensions it supports through the + 'supported_extension_aliases' attribute. Eg: + + class SomePlugin: + ... + supported_extension_aliases = ['extension1_alias', + 'extension2_alias', + 'extension3_alias'] + Any extension not in this list will not be loaded for the plugin + + b) Extension Interfaces for plugins (optional) + The extension can mandate an interface that plugins have to support with the + 'get_plugin_interface' method in the extension. + For an example see the FoxInSocksPluginInterface in foxinsocks.py. + + The QuantumEchoPlugin lists foxinsox in its supported_extension_aliases + and implements the method from FoxInSocksPluginInterface. + +# -- Building packages + + rpms: + python setup.py build rpm + + debs: + python setup.py build deb diff --git a/quantum/plugins/openvswitch/__init__.py b/common/lib/__init__.py similarity index 100% rename from quantum/plugins/openvswitch/__init__.py rename to common/lib/__init__.py diff --git a/common/lib/quantum/__init__.py b/common/lib/quantum/__init__.py new file mode 100644 index 0000000000..d407605e19 --- /dev/null +++ b/common/lib/quantum/__init__.py @@ -0,0 +1,5 @@ +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) diff --git a/quantum/__init__.py b/common/lib/quantum/common/__init__.py similarity index 100% rename from quantum/__init__.py rename to common/lib/quantum/common/__init__.py diff --git a/quantum/common/bufferedhttp.py b/common/lib/quantum/common/bufferedhttp.py similarity index 100% rename from quantum/common/bufferedhttp.py rename to common/lib/quantum/common/bufferedhttp.py diff --git a/quantum/common/config.py b/common/lib/quantum/common/config.py similarity index 90% rename from quantum/common/config.py rename to common/lib/quantum/common/config.py index 320c3b2cf0..6cf47779d4 100644 --- a/quantum/common/config.py +++ b/common/lib/quantum/common/config.py @@ -38,7 +38,7 @@ DEFAULT_LOG_FORMAT = "%(asctime)s %(levelname)8s [%(name)s] %(message)s" DEFAULT_LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S" FLAGS = flags.FLAGS -LOG = logging.getLogger('quantum.common.wsgi') +LOG = logging.getLogger('quantum.wsgi') def parse_options(parser, cli_args=None): @@ -179,14 +179,14 @@ def setup_logging(options, conf): root_logger.addHandler(handler) -def find_config_file(options, args): +def find_config_file(options, args, config_file='quantum.conf'): """ Return the first config file found. We search for the paste config file in the following order: * If --config-file option is used, use that * If args[0] is a file, use that - * Search for quantum.conf in standard directories: + * Search for the configuration file in standard directories: * . * ~.quantum/ * ~ @@ -204,16 +204,31 @@ def find_config_file(options, args): if os.path.exists(args[0]): return fix_path(args[0]) - # Handle standard directory search for quantum.conf - config_file_dirs = [fix_path(os.getcwd()), - fix_path(os.path.join('~', '.quantum')), + dir_to_common = os.path.dirname(os.path.abspath(__file__)) + root = os.path.join(dir_to_common, '..', '..', '..', '..') + # Handle standard directory search for the config file + config_file_dirs = [fix_path(os.path.join(os.getcwd(), 'server', 'etc')), + fix_path(os.path.join('~', '.quantum-venv', 'etc', + 'quantum')), fix_path('~'), os.path.join(FLAGS.state_path, 'etc'), os.path.join(FLAGS.state_path, 'etc', 'quantum'), + os.path.join(root, 'server', 'etc'), + fix_path(os.path.join('~', '.local', + 'etc', 'quantum')), + '/usr/etc/quantum', + '/usr/local/etc/quantum', '/etc/quantum/', '/etc'] + + if os.path.exists(os.path.join(root, 'plugins')): + plugins = [fix_path(os.path.join(root, 'plugins', p, 'etc')) + for p in os.listdir(os.path.join(root, 'plugins'))] + plugins = [p for p in plugins if os.path.isdir(p)] + config_file_dirs.extend(plugins) + for cfg_dir in config_file_dirs: - cfg_file = os.path.join(cfg_dir, 'quantum.conf') + cfg_file = os.path.join(cfg_dir, config_file) if os.path.exists(cfg_file): return cfg_file diff --git a/quantum/common/exceptions.py b/common/lib/quantum/common/exceptions.py similarity index 100% rename from quantum/common/exceptions.py rename to common/lib/quantum/common/exceptions.py diff --git a/quantum/common/extensions.py b/common/lib/quantum/common/extensions.py similarity index 99% rename from quantum/common/extensions.py rename to common/lib/quantum/common/extensions.py index 380572c0c2..b77ce75b95 100644 --- a/quantum/common/extensions.py +++ b/common/lib/quantum/common/extensions.py @@ -27,7 +27,7 @@ from gettext import gettext as _ from abc import ABCMeta from quantum.common import exceptions from quantum.manager import QuantumManager -from quantum.common import wsgi +from quantum import wsgi LOG = logging.getLogger('quantum.common.extensions') diff --git a/quantum/common/flags.py b/common/lib/quantum/common/flags.py similarity index 100% rename from quantum/common/flags.py rename to common/lib/quantum/common/flags.py diff --git a/common/lib/quantum/common/serializer.py b/common/lib/quantum/common/serializer.py new file mode 100644 index 0000000000..b596cf89e7 --- /dev/null +++ b/common/lib/quantum/common/serializer.py @@ -0,0 +1,153 @@ +from xml.dom import minidom +import webob.exc + +from quantum.common import utils + + +class Serializer(object): + """Serializes and deserializes dictionaries to certain MIME types.""" + + def __init__(self, metadata=None, default_xmlns=None): + """Create a serializer based on the given WSGI environment. + + 'metadata' is an optional dict mapping MIME types to information + needed to serialize a dictionary to that type. + + """ + self.metadata = metadata or {} + self.default_xmlns = default_xmlns + + def _get_serialize_handler(self, content_type): + handlers = { + 'application/json': self._to_json, + 'application/xml': self._to_xml, + } + + try: + return handlers[content_type] + except Exception: + raise exception.InvalidContentType(content_type=content_type) + + def serialize(self, data, content_type): + """Serialize a dictionary into the specified content type.""" + return self._get_serialize_handler(content_type)(data) + + def deserialize(self, datastring, content_type): + """Deserialize a string to a dictionary. + + The string must be in the format of a supported MIME type. + + """ + try: + return self.get_deserialize_handler(content_type)(datastring) + except Exception: + raise webob.exc.HTTPBadRequest("Could not deserialize data") + + def get_deserialize_handler(self, content_type): + handlers = { + 'application/json': self._from_json, + 'application/xml': self._from_xml, + } + + try: + return handlers[content_type] + except Exception: + raise exception.InvalidContentType(content_type=content_type) + + def _from_json(self, datastring): + return utils.loads(datastring) + + def _from_xml(self, datastring): + xmldata = self.metadata.get('application/xml', {}) + plurals = set(xmldata.get('plurals', {})) + node = minidom.parseString(datastring).childNodes[0] + return {node.nodeName: self._from_xml_node(node, plurals)} + + def _from_xml_node(self, node, listnames): + """Convert a minidom node to a simple Python type. + + listnames is a collection of names of XML nodes whose subnodes should + be considered list items. + + """ + if len(node.childNodes) == 1 and node.childNodes[0].nodeType == 3: + return node.childNodes[0].nodeValue + elif node.nodeName in listnames: + return [self._from_xml_node(n, listnames) + for n in node.childNodes if n.nodeType != node.TEXT_NODE] + else: + result = dict() + for attr in node.attributes.keys(): + result[attr] = node.attributes[attr].nodeValue + for child in node.childNodes: + if child.nodeType != node.TEXT_NODE: + result[child.nodeName] = self._from_xml_node(child, + listnames) + return result + + def _to_json(self, data): + return utils.dumps(data) + + def _to_xml(self, data): + metadata = self.metadata.get('application/xml', {}) + # We expect data to contain a single key which is the XML root. + root_key = data.keys()[0] + doc = minidom.Document() + node = self._to_xml_node(doc, metadata, root_key, data[root_key]) + + xmlns = node.getAttribute('xmlns') + if not xmlns and self.default_xmlns: + node.setAttribute('xmlns', self.default_xmlns) + + return node.toprettyxml(indent='', newl='') + + def _to_xml_node(self, doc, metadata, nodename, data): + """Recursive method to convert data members to XML nodes.""" + result = doc.createElement(nodename) + + # Set the xml namespace if one is specified + # TODO(justinsb): We could also use prefixes on the keys + xmlns = metadata.get('xmlns', None) + if xmlns: + result.setAttribute('xmlns', xmlns) + if type(data) is list: + collections = metadata.get('list_collections', {}) + if nodename in collections: + metadata = collections[nodename] + for item in data: + node = doc.createElement(metadata['item_name']) + node.setAttribute(metadata['item_key'], str(item)) + result.appendChild(node) + return result + singular = metadata.get('plurals', {}).get(nodename, None) + if singular is None: + if nodename.endswith('s'): + singular = nodename[:-1] + else: + singular = 'item' + for item in data: + node = self._to_xml_node(doc, metadata, singular, item) + result.appendChild(node) + elif type(data) is dict: + collections = metadata.get('dict_collections', {}) + if nodename in collections: + metadata = collections[nodename] + for k, v in data.items(): + node = doc.createElement(metadata['item_name']) + node.setAttribute(metadata['item_key'], str(k)) + text = doc.createTextNode(str(v)) + node.appendChild(text) + result.appendChild(node) + return result + attrs = metadata.get('attributes', {}).get(nodename, {}) + for k, v in data.items(): + if k in attrs: + result.setAttribute(k, str(v)) + else: + node = self._to_xml_node(doc, metadata, k, v) + result.appendChild(node) + else: + # Type is atom. + node = doc.createTextNode(str(data)) + result.appendChild(node) + return result diff --git a/quantum/common/test_lib.py b/common/lib/quantum/common/test_lib.py similarity index 100% rename from quantum/common/test_lib.py rename to common/lib/quantum/common/test_lib.py diff --git a/quantum/common/utils.py b/common/lib/quantum/common/utils.py similarity index 76% rename from quantum/common/utils.py rename to common/lib/quantum/common/utils.py index 5662e7465a..849337a3b7 100644 --- a/quantum/common/utils.py +++ b/common/lib/quantum/common/utils.py @@ -1,7 +1,6 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright 2011 Nicira Networks, Inc -# All Rights Reserved. +# Copyright 2011, Nicira Networks, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain @@ -14,14 +13,16 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. +# +# Borrowed from nova code base, more utilities will be added/borrowed as and +# when needed. +# @author: Somik Behera, Nicira Networks, Inc. + +"""Utilities and helper functions.""" -""" -System-level utilities and helper functions. -""" import ConfigParser import datetime import exceptions as exception -import flags import inspect import logging import os @@ -29,11 +30,73 @@ import random import subprocess import socket import sys +import base64 +import functools +import json +import re +import string +import struct +import time +import types + +from quantum.common import flags +from quantum.common import exceptions as exception +from quantum.common.exceptions import ProcessExecutionError -from exceptions import ProcessExecutionError +def import_class(import_str): + """Returns a class from a string including module and class.""" + mod_str, _sep, class_str = import_str.rpartition('.') + try: + __import__(mod_str) + return getattr(sys.modules[mod_str], class_str) + except (ImportError, ValueError, AttributeError), exc: + print(('Inner Exception: %s'), exc) + raise exception.ClassNotFound(class_name=class_str) +def import_object(import_str): + """Returns an object including a module or module and class.""" + try: + __import__(import_str) + return sys.modules[import_str] + except ImportError: + cls = import_class(import_str) + return cls() + + +def to_primitive(value): + if type(value) is type([]) or type(value) is type((None,)): + o = [] + for v in value: + o.append(to_primitive(v)) + return o + elif type(value) is type({}): + o = {} + for k, v in value.iteritems(): + o[k] = to_primitive(v) + return o + elif isinstance(value, datetime.datetime): + return str(value) + elif hasattr(value, 'iteritems'): + return to_primitive(dict(value.iteritems())) + elif hasattr(value, '__iter__'): + return to_primitive(list(value)) + else: + return value + + +def dumps(value): + try: + return json.dumps(value) + except TypeError: + pass + return json.dumps(to_primitive(value)) + + +def loads(s): + return json.loads(s) + TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ" FLAGS = flags.FLAGS @@ -78,7 +141,7 @@ def import_class(import_str): return getattr(sys.modules[mod_str], class_str) except (ImportError, ValueError, AttributeError) as e: print e - raise exception.NotFound('Class %s cannot be found' % class_str) + raise exception.ClassNotFound(class_name=class_str) def import_object(import_str): diff --git a/common/lib/quantum/run_tests.py b/common/lib/quantum/run_tests.py new file mode 100644 index 0000000000..7043196035 --- /dev/null +++ b/common/lib/quantum/run_tests.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 OpenStack, LLC +# 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. + + +"""Unittest runner for quantum + +To run all test:: + python run_tests.py + +To run all unit tests:: + python run_tests.py unit + +To run all functional tests:: + python run_tests.py functional + +To run a single unit test:: + python run_tests.py unit.test_stores:TestSwiftBackend.test_get + +To run a single functional test:: + python run_tests.py functional.test_service:TestController.test_create + +To run a single unit test module:: + python run_tests.py unit.test_stores + +To run a single functional test module:: + python run_tests.py functional.test_stores +""" + +import gettext +import os +import unittest +import sys + +from quantum.common.test_lib import run_tests +from nose import config +from nose import core + +import quantum.tests.unit + + +def main(): + c = config.Config(stream=sys.stdout, + env=os.environ, + verbosity=3, + includeExe=True, + traverseNamespace=True, + plugins=core.DefaultPluginManager()) + c.configureWhere(quantum.tests.unit.__path__) + sys.exit(run_tests(c)) + +if __name__ == "__main__": + main() diff --git a/common/setup.py b/common/setup.py new file mode 100644 index 0000000000..f5ffb683b8 --- /dev/null +++ b/common/setup.py @@ -0,0 +1,67 @@ +try: + from setuptools import setup, find_packages +except ImportError: + from ez_setup import use_setuptools + use_setuptools() + from setuptools import setup, find_packages + +Name = 'quantum-common' +Url = "https://launchpad.net/quantum" +Version = '2012.1-dev' +License = 'Apache License 2.0' +# Change as required +Author = 'Netstack' +AuthorEmail = 'netstack@lists.launchpad.net' +Maintainer = '' +Summary = 'Common functionalities for Quantum' +ShortDescription = Summary +Description = Summary + +requires = [ + 'eventlet>=0.9.12', + 'Routes>=1.12.3', + 'nose', + 'Paste', + 'PasteDeploy', + 'pep8>=0.6.1', + 'python-gflags', + 'simplejson', + 'sqlalchemy', + 'webob', + 'webtest' +] + +EagerResources = [ + 'quantum', +] + +ProjectScripts = [ +] + +PackageData = { +} + + +setup( + name=Name, + version=Version, + url=Url, + author=Author, + author_email=AuthorEmail, + description=ShortDescription, + long_description=Description, + license=License, + scripts=ProjectScripts, + install_requires=requires, + include_package_data=True, + packages=find_packages('lib'), + package_data=PackageData, + package_dir={'': 'lib'}, + eager_resources=EagerResources, + namespace_packages=['quantum'], + entry_points={ + 'console_scripts': [ + 'quantum-tests = quantum.run_tests:main' + ] + }, +) diff --git a/plugins/cisco-plugin/MANIFEST.in b/plugins/cisco-plugin/MANIFEST.in new file mode 100644 index 0000000000..8f082901d0 --- /dev/null +++ b/plugins/cisco-plugin/MANIFEST.in @@ -0,0 +1 @@ +include etc/* diff --git a/quantum/plugins/cisco/README b/plugins/cisco-plugin/README similarity index 100% rename from quantum/plugins/cisco/README rename to plugins/cisco-plugin/README diff --git a/quantum/plugins/cisco/conf/plugins.ini b/plugins/cisco-plugin/etc/cisco_plugins.ini similarity index 100% rename from quantum/plugins/cisco/conf/plugins.ini rename to plugins/cisco-plugin/etc/cisco_plugins.ini diff --git a/quantum/plugins/cisco/conf/credentials.ini b/plugins/cisco-plugin/etc/credentials.ini similarity index 100% rename from quantum/plugins/cisco/conf/credentials.ini rename to plugins/cisco-plugin/etc/credentials.ini diff --git a/quantum/plugins/cisco/conf/db_conn.ini b/plugins/cisco-plugin/etc/db_conn.ini similarity index 100% rename from quantum/plugins/cisco/conf/db_conn.ini rename to plugins/cisco-plugin/etc/db_conn.ini diff --git a/quantum/plugins/cisco/conf/l2network_plugin.ini b/plugins/cisco-plugin/etc/l2network_plugin.ini similarity index 100% rename from quantum/plugins/cisco/conf/l2network_plugin.ini rename to plugins/cisco-plugin/etc/l2network_plugin.ini diff --git a/quantum/plugins/cisco/conf/nexus.ini b/plugins/cisco-plugin/etc/nexus.ini similarity index 100% rename from quantum/plugins/cisco/conf/nexus.ini rename to plugins/cisco-plugin/etc/nexus.ini diff --git a/quantum/plugins/cisco/conf/quantum.conf.ciscoext b/plugins/cisco-plugin/etc/quantum.conf.ciscoext similarity index 100% rename from quantum/plugins/cisco/conf/quantum.conf.ciscoext rename to plugins/cisco-plugin/etc/quantum.conf.ciscoext diff --git a/quantum/plugins/cisco/conf/ucs.ini b/plugins/cisco-plugin/etc/ucs.ini similarity index 100% rename from quantum/plugins/cisco/conf/ucs.ini rename to plugins/cisco-plugin/etc/ucs.ini diff --git a/quantum/plugins/cisco/conf/ucs_inventory.ini b/plugins/cisco-plugin/etc/ucs_inventory.ini similarity index 100% rename from quantum/plugins/cisco/conf/ucs_inventory.ini rename to plugins/cisco-plugin/etc/ucs_inventory.ini diff --git a/quantum/plugins/openvswitch/tests/__init__.py b/plugins/cisco-plugin/lib/__init__.py similarity index 100% rename from quantum/plugins/openvswitch/tests/__init__.py rename to plugins/cisco-plugin/lib/__init__.py diff --git a/plugins/cisco-plugin/lib/quantum/__init__.py b/plugins/cisco-plugin/lib/quantum/__init__.py new file mode 100644 index 0000000000..d407605e19 --- /dev/null +++ b/plugins/cisco-plugin/lib/quantum/__init__.py @@ -0,0 +1,5 @@ +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) diff --git a/plugins/cisco-plugin/lib/quantum/plugins/__init__.py b/plugins/cisco-plugin/lib/quantum/plugins/__init__.py new file mode 100644 index 0000000000..d407605e19 --- /dev/null +++ b/plugins/cisco-plugin/lib/quantum/plugins/__init__.py @@ -0,0 +1,5 @@ +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) diff --git a/quantum/plugins/cisco/__init__.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/__init__.py similarity index 100% rename from quantum/plugins/cisco/__init__.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/__init__.py diff --git a/quantum/plugins/cisco/client/cli.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/client/cli.py similarity index 100% rename from quantum/plugins/cisco/client/cli.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/client/cli.py diff --git a/quantum/plugins/cisco/common/__init__.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/common/__init__.py similarity index 100% rename from quantum/plugins/cisco/common/__init__.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/common/__init__.py diff --git a/quantum/plugins/cisco/common/cisco_configparser.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/common/cisco_configparser.py similarity index 100% rename from quantum/plugins/cisco/common/cisco_configparser.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/common/cisco_configparser.py diff --git a/quantum/plugins/cisco/common/cisco_constants.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/common/cisco_constants.py similarity index 100% rename from quantum/plugins/cisco/common/cisco_constants.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/common/cisco_constants.py diff --git a/quantum/plugins/cisco/common/cisco_credentials.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/common/cisco_credentials.py similarity index 91% rename from quantum/plugins/cisco/common/cisco_credentials.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/common/cisco_credentials.py index e3f395f988..1a1bae9235 100644 --- a/quantum/plugins/cisco/common/cisco_credentials.py +++ b/plugins/cisco-plugin/lib/quantum/plugins/cisco/common/cisco_credentials.py @@ -20,18 +20,21 @@ """ import os +import logging as LOG +from quantum.common.config import find_config_file from quantum.plugins.cisco.common import cisco_configparser as confp from quantum.plugins.cisco.common import cisco_constants as const from quantum.plugins.cisco.common import cisco_exceptions as cexc from quantum.plugins.cisco.db import l2network_db as cdb +LOG.basicConfig(level=LOG.WARN) +LOG.getLogger(const.LOGGER_COMPONENT_NAME) + +CREDENTIALS_FILE = find_config_file({}, None, "credentials.ini") TENANT = const.NETWORK_ADMIN -CREDENTIALS_FILE = "../conf/credentials.ini" - -cp = confp.CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) \ - + "/" + CREDENTIALS_FILE) +cp = confp.CiscoConfigParser(CREDENTIALS_FILE) _creds_dictionary = cp.walk(cp.dummy) diff --git a/quantum/plugins/cisco/common/cisco_exceptions.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/common/cisco_exceptions.py similarity index 100% rename from quantum/plugins/cisco/common/cisco_exceptions.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/common/cisco_exceptions.py diff --git a/quantum/plugins/cisco/common/cisco_faults.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/common/cisco_faults.py similarity index 100% rename from quantum/plugins/cisco/common/cisco_faults.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/common/cisco_faults.py diff --git a/quantum/plugins/cisco/common/cisco_utils.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/common/cisco_utils.py similarity index 100% rename from quantum/plugins/cisco/common/cisco_utils.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/common/cisco_utils.py diff --git a/quantum/plugins/cisco/db/__init__.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/db/__init__.py similarity index 100% rename from quantum/plugins/cisco/db/__init__.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/db/__init__.py diff --git a/quantum/plugins/cisco/db/api.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/db/api.py similarity index 100% rename from quantum/plugins/cisco/db/api.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/db/api.py diff --git a/quantum/plugins/cisco/db/l2network_db.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/db/l2network_db.py similarity index 100% rename from quantum/plugins/cisco/db/l2network_db.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/db/l2network_db.py diff --git a/quantum/plugins/cisco/db/l2network_models.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/db/l2network_models.py similarity index 100% rename from quantum/plugins/cisco/db/l2network_models.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/db/l2network_models.py diff --git a/quantum/plugins/cisco/db/models.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/db/models.py similarity index 100% rename from quantum/plugins/cisco/db/models.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/db/models.py diff --git a/quantum/plugins/cisco/db/nexus_db.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/db/nexus_db.py similarity index 100% rename from quantum/plugins/cisco/db/nexus_db.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/db/nexus_db.py diff --git a/quantum/plugins/cisco/db/nexus_models.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/db/nexus_models.py similarity index 100% rename from quantum/plugins/cisco/db/nexus_models.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/db/nexus_models.py diff --git a/quantum/plugins/cisco/db/ucs_db.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/db/ucs_db.py similarity index 100% rename from quantum/plugins/cisco/db/ucs_db.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/db/ucs_db.py diff --git a/quantum/plugins/cisco/db/ucs_models.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/db/ucs_models.py similarity index 100% rename from quantum/plugins/cisco/db/ucs_models.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/db/ucs_models.py diff --git a/quantum/plugins/cisco/l2device_inventory_base.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/l2device_inventory_base.py similarity index 100% rename from quantum/plugins/cisco/l2device_inventory_base.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/l2device_inventory_base.py diff --git a/quantum/plugins/cisco/l2device_plugin_base.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/l2device_plugin_base.py similarity index 100% rename from quantum/plugins/cisco/l2device_plugin_base.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/l2device_plugin_base.py diff --git a/quantum/plugins/cisco/l2network_model_base.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/l2network_model_base.py similarity index 100% rename from quantum/plugins/cisco/l2network_model_base.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/l2network_model_base.py diff --git a/quantum/plugins/cisco/l2network_plugin.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/l2network_plugin.py similarity index 100% rename from quantum/plugins/cisco/l2network_plugin.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/l2network_plugin.py diff --git a/quantum/plugins/cisco/l2network_plugin_configuration.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/l2network_plugin_configuration.py similarity index 81% rename from quantum/plugins/cisco/l2network_plugin_configuration.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/l2network_plugin_configuration.py index ec20fcceb0..b4abf32da3 100644 --- a/quantum/plugins/cisco/l2network_plugin_configuration.py +++ b/plugins/cisco-plugin/lib/quantum/plugins/cisco/l2network_plugin_configuration.py @@ -20,14 +20,11 @@ """ import os - +from quantum.common.config import find_config_file from quantum.plugins.cisco.common import cisco_configparser as confp -CONF_FILE = "conf/l2network_plugin.ini" - -CONF_PARSER_OBJ = confp.\ -CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) + \ -"/" + CONF_FILE) +CONF_FILE = find_config_file({}, None, "l2network_plugin.ini") +CONF_PARSER_OBJ = confp.CiscoConfigParser(CONF_FILE) """ Reading the conf for the l2network_plugin @@ -49,25 +46,22 @@ MAX_NETWORKS = SECTION_CONF['max_networks'] SECTION_CONF = CONF_PARSER_OBJ['MODEL'] MODEL_CLASS = SECTION_CONF['model_class'] +CONF_FILE = find_config_file({}, None, "cisco_plugins.ini") + SECTION_CONF = CONF_PARSER_OBJ['SEGMENTATION'] MANAGER_CLASS = SECTION_CONF['manager_class'] -CONF_FILE = "conf/plugins.ini" -CONF_PARSER_OBJ = confp.\ -CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) + \ -"/" + CONF_FILE) +CONF_PARSER_OBJ = confp.CiscoConfigParser(CONF_FILE) """ Reading the config for the device plugins """ PLUGINS = CONF_PARSER_OBJ.walk(CONF_PARSER_OBJ.dummy) -CONF_FILE = "conf/db_conn.ini" +CONF_FILE = find_config_file({}, None, "db_conn.ini") -CONF_PARSER_OBJ = confp.\ -CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) + \ -"/" + CONF_FILE) +CONF_PARSER_OBJ = confp.CiscoConfigParser(CONF_FILE) """ Reading DB config for the Quantum DB diff --git a/quantum/plugins/cisco/l2network_segmentation_base.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/l2network_segmentation_base.py similarity index 100% rename from quantum/plugins/cisco/l2network_segmentation_base.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/l2network_segmentation_base.py diff --git a/quantum/plugins/cisco/models/__init__.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/models/__init__.py similarity index 100% rename from quantum/plugins/cisco/models/__init__.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/models/__init__.py diff --git a/quantum/plugins/cisco/models/l2network_multi_blade.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/models/l2network_multi_blade.py similarity index 100% rename from quantum/plugins/cisco/models/l2network_multi_blade.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/models/l2network_multi_blade.py diff --git a/quantum/plugins/cisco/models/l2network_single_blade.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/models/l2network_single_blade.py similarity index 100% rename from quantum/plugins/cisco/models/l2network_single_blade.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/models/l2network_single_blade.py diff --git a/quantum/plugins/cisco/nexus/__init__.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/nexus/__init__.py similarity index 100% rename from quantum/plugins/cisco/nexus/__init__.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/nexus/__init__.py diff --git a/quantum/plugins/cisco/nexus/cisco_nexus_configuration.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/nexus/cisco_nexus_configuration.py similarity index 100% rename from quantum/plugins/cisco/nexus/cisco_nexus_configuration.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/nexus/cisco_nexus_configuration.py diff --git a/quantum/plugins/cisco/nexus/cisco_nexus_network_driver.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/nexus/cisco_nexus_network_driver.py similarity index 100% rename from quantum/plugins/cisco/nexus/cisco_nexus_network_driver.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/nexus/cisco_nexus_network_driver.py diff --git a/quantum/plugins/cisco/nexus/cisco_nexus_plugin.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/nexus/cisco_nexus_plugin.py similarity index 100% rename from quantum/plugins/cisco/nexus/cisco_nexus_plugin.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/nexus/cisco_nexus_plugin.py diff --git a/quantum/plugins/cisco/nexus/cisco_nexus_snippets.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/nexus/cisco_nexus_snippets.py similarity index 100% rename from quantum/plugins/cisco/nexus/cisco_nexus_snippets.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/nexus/cisco_nexus_snippets.py diff --git a/plugins/cisco-plugin/lib/quantum/plugins/cisco/nova/__init__.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/nova/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/quantum/plugins/cisco/nova/quantum_port_aware_scheduler.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/nova/quantum_port_aware_scheduler.py similarity index 100% rename from quantum/plugins/cisco/nova/quantum_port_aware_scheduler.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/nova/quantum_port_aware_scheduler.py diff --git a/quantum/plugins/cisco/nova/vifdirect.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/nova/vifdirect.py similarity index 100% rename from quantum/plugins/cisco/nova/vifdirect.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/nova/vifdirect.py diff --git a/quantum/plugins/cisco/segmentation/__init__.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/segmentation/__init__.py similarity index 100% rename from quantum/plugins/cisco/segmentation/__init__.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/segmentation/__init__.py diff --git a/quantum/plugins/cisco/segmentation/l2network_vlan_mgr.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/segmentation/l2network_vlan_mgr.py similarity index 100% rename from quantum/plugins/cisco/segmentation/l2network_vlan_mgr.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/segmentation/l2network_vlan_mgr.py diff --git a/quantum/plugins/cisco/ucs/__init__.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/ucs/__init__.py similarity index 100% rename from quantum/plugins/cisco/ucs/__init__.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/ucs/__init__.py diff --git a/quantum/plugins/cisco/ucs/cisco_getvif.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/ucs/cisco_getvif.py similarity index 100% rename from quantum/plugins/cisco/ucs/cisco_getvif.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/ucs/cisco_getvif.py diff --git a/quantum/plugins/cisco/ucs/cisco_ucs_configuration.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/ucs/cisco_ucs_configuration.py similarity index 78% rename from quantum/plugins/cisco/ucs/cisco_ucs_configuration.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/ucs/cisco_ucs_configuration.py index a4fbec42b1..55921bf23c 100644 --- a/quantum/plugins/cisco/ucs/cisco_ucs_configuration.py +++ b/plugins/cisco-plugin/lib/quantum/plugins/cisco/ucs/cisco_ucs_configuration.py @@ -20,13 +20,10 @@ """ import os - +from quantum.common.config import find_config_file from quantum.plugins.cisco.common import cisco_configparser as confp -CONF_FILE = "../conf/ucs.ini" - -CP = confp.CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) \ - + "/" + CONF_FILE) +CP = confp.CiscoConfigParser(find_config_file({}, [], 'ucs.ini')) SECTION = CP['UCSM'] UCSM_IP_ADDRESS = SECTION['ip_address'] @@ -38,9 +35,7 @@ PROFILE_NAME_PREFIX = SECTION['profile_name_prefix'] SECTION = CP['DRIVER'] UCSM_DRIVER = SECTION['name'] -CONF_FILE = "../conf/ucs_inventory.ini" - -CP = confp.CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) \ - + "/" + CONF_FILE) +CP = confp.CiscoConfigParser(find_config_file({}, [], + 'ucs_inventory.ini')) INVENTORY = CP.walk(CP.dummy) diff --git a/quantum/plugins/cisco/ucs/cisco_ucs_inventory.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/ucs/cisco_ucs_inventory.py similarity index 100% rename from quantum/plugins/cisco/ucs/cisco_ucs_inventory.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/ucs/cisco_ucs_inventory.py diff --git a/quantum/plugins/cisco/ucs/cisco_ucs_inventory_configuration.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/ucs/cisco_ucs_inventory_configuration.py similarity index 83% rename from quantum/plugins/cisco/ucs/cisco_ucs_inventory_configuration.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/ucs/cisco_ucs_inventory_configuration.py index 3183658c36..721ee11f5c 100644 --- a/quantum/plugins/cisco/ucs/cisco_ucs_inventory_configuration.py +++ b/plugins/cisco-plugin/lib/quantum/plugins/cisco/ucs/cisco_ucs_inventory_configuration.py @@ -20,12 +20,10 @@ """ import os - +from quantum.common.config import find_config_file from quantum.plugins.cisco.common import cisco_configparser as confp -CONF_FILE = "../conf/ucs_inventory.ini" - -CP = confp.CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) \ - + "/" + CONF_FILE) +CP = confp.CiscoConfigParser(find_config_file({}, [], + 'plugins/cisco/ucs_inventory.ini')) INVENTORY = CP.walk(CP.dummy) diff --git a/quantum/plugins/cisco/ucs/cisco_ucs_network_driver.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/ucs/cisco_ucs_network_driver.py similarity index 100% rename from quantum/plugins/cisco/ucs/cisco_ucs_network_driver.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/ucs/cisco_ucs_network_driver.py diff --git a/quantum/plugins/cisco/ucs/cisco_ucs_plugin.py b/plugins/cisco-plugin/lib/quantum/plugins/cisco/ucs/cisco_ucs_plugin.py similarity index 100% rename from quantum/plugins/cisco/ucs/cisco_ucs_plugin.py rename to plugins/cisco-plugin/lib/quantum/plugins/cisco/ucs/cisco_ucs_plugin.py diff --git a/quantum/plugins/cisco/tests/__init__.py b/plugins/cisco-plugin/lib/quantum/tests/__init__.py similarity index 81% rename from quantum/plugins/cisco/tests/__init__.py rename to plugins/cisco-plugin/lib/quantum/tests/__init__.py index db695fb0af..383dfaa982 100644 --- a/quantum/plugins/cisco/tests/__init__.py +++ b/plugins/cisco-plugin/lib/quantum/tests/__init__.py @@ -16,3 +16,8 @@ # # @author: Sumit Naiksatam, Cisco Systems, Inc. # +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) diff --git a/tests/unit/__init__.py b/plugins/cisco-plugin/lib/quantum/tests/unit/__init__.py similarity index 85% rename from tests/unit/__init__.py rename to plugins/cisco-plugin/lib/quantum/tests/unit/__init__.py index 5910e35494..726786924d 100644 --- a/tests/unit/__init__.py +++ b/plugins/cisco-plugin/lib/quantum/tests/unit/__init__.py @@ -17,6 +17,12 @@ # See http://code.google.com/p/python-nose/issues/detail?id=373 # The code below enables nosetests to work with i18n _() blocks +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) + import __builtin__ import unittest setattr(__builtin__, '_', lambda x: x) diff --git a/quantum/plugins/cisco/tests/unit/test_cisco_extension.py b/plugins/cisco-plugin/lib/quantum/tests/unit/test_cisco_extension.py similarity index 100% rename from quantum/plugins/cisco/tests/unit/test_cisco_extension.py rename to plugins/cisco-plugin/lib/quantum/tests/unit/test_cisco_extension.py diff --git a/quantum/plugins/cisco/tests/unit/test_database.py b/plugins/cisco-plugin/lib/quantum/tests/unit/test_database.py similarity index 100% rename from quantum/plugins/cisco/tests/unit/test_database.py rename to plugins/cisco-plugin/lib/quantum/tests/unit/test_database.py diff --git a/quantum/plugins/cisco/tests/unit/test_l2networkApi.py b/plugins/cisco-plugin/lib/quantum/tests/unit/test_l2networkApi.py similarity index 100% rename from quantum/plugins/cisco/tests/unit/test_l2networkApi.py rename to plugins/cisco-plugin/lib/quantum/tests/unit/test_l2networkApi.py diff --git a/quantum/plugins/cisco/tests/unit/test_l2network_multi_blade.py b/plugins/cisco-plugin/lib/quantum/tests/unit/test_l2network_multi_blade.py similarity index 100% rename from quantum/plugins/cisco/tests/unit/test_l2network_multi_blade.py rename to plugins/cisco-plugin/lib/quantum/tests/unit/test_l2network_multi_blade.py diff --git a/quantum/plugins/cisco/tests/unit/test_nexus_plugin.py b/plugins/cisco-plugin/lib/quantum/tests/unit/test_nexus_plugin.py similarity index 100% rename from quantum/plugins/cisco/tests/unit/test_nexus_plugin.py rename to plugins/cisco-plugin/lib/quantum/tests/unit/test_nexus_plugin.py diff --git a/quantum/plugins/cisco/tests/unit/test_ucs_driver.py b/plugins/cisco-plugin/lib/quantum/tests/unit/test_ucs_driver.py similarity index 100% rename from quantum/plugins/cisco/tests/unit/test_ucs_driver.py rename to plugins/cisco-plugin/lib/quantum/tests/unit/test_ucs_driver.py diff --git a/quantum/plugins/cisco/tests/unit/test_ucs_inventory.py b/plugins/cisco-plugin/lib/quantum/tests/unit/test_ucs_inventory.py similarity index 100% rename from quantum/plugins/cisco/tests/unit/test_ucs_inventory.py rename to plugins/cisco-plugin/lib/quantum/tests/unit/test_ucs_inventory.py diff --git a/quantum/plugins/cisco/tests/unit/test_ucs_plugin.py b/plugins/cisco-plugin/lib/quantum/tests/unit/test_ucs_plugin.py similarity index 100% rename from quantum/plugins/cisco/tests/unit/test_ucs_plugin.py rename to plugins/cisco-plugin/lib/quantum/tests/unit/test_ucs_plugin.py diff --git a/quantum/plugins/cisco/tests/unit/test_vlan_mgr.py b/plugins/cisco-plugin/lib/quantum/tests/unit/test_vlan_mgr.py similarity index 100% rename from quantum/plugins/cisco/tests/unit/test_vlan_mgr.py rename to plugins/cisco-plugin/lib/quantum/tests/unit/test_vlan_mgr.py diff --git a/plugins/cisco-plugin/setup.py b/plugins/cisco-plugin/setup.py new file mode 100644 index 0000000000..8b47f6378e --- /dev/null +++ b/plugins/cisco-plugin/setup.py @@ -0,0 +1,72 @@ +try: + from setuptools import setup, find_packages +except ImportError: + from ez_setup import use_setuptools + use_setuptools() + from setuptools import setup, find_packages + +import sys + +Name = 'quantum-cisco-plugin' +ProjecUrl = "" +Version = '0.1' +License = 'Apache License 2.0' +# Change as required +Author = 'Cisco Systems' +AuthorEmail = '' +Maintainer = '' +Summary = 'Cisco plugin for Quantum' +ShortDescription = Summary +Description = Summary + +requires = [ + 'quantum-common', + 'quantum-server', +] + +EagerResources = [ + 'quantum', +] + +ProjectScripts = [ +] + +PackageData = { +} + +# If we're installing server-wide, use an aboslute path for config +# if not, use a relative path +config_path = '/etc/quantum/plugins/cisco' +relative_locations = ['--user', '--virtualenv', '--venv'] +if [x for x in relative_locations if x in sys.argv]: + config_path = 'etc/quantum/plugins/cisco' + +DataFiles = [ + (config_path, + ['etc/credentials.ini', 'etc/l2network_plugin.ini', 'etc/nexus.ini', + 'etc/ucs.ini', 'etc/cisco_plugins.ini', 'etc/db_conn.ini']) +] + +setup( + name=Name, + version=Version, + author=Author, + author_email=AuthorEmail, + description=ShortDescription, + long_description=Description, + license=License, + scripts=ProjectScripts, + install_requires=requires, + include_package_data=True, + packages=find_packages('lib'), + package_data=PackageData, + data_files=DataFiles, + package_dir={'': 'lib'}, + eager_resources=EagerResources, + namespace_packages=['quantum'], + entry_points={ + 'console_scripts': [ + 'quantum-cisco-tests = quantum.plugins.cisco.run_tests:main' + ] + }, +) diff --git a/plugins/openvswitch-plugin/MANIFEST.in b/plugins/openvswitch-plugin/MANIFEST.in new file mode 100644 index 0000000000..8f082901d0 --- /dev/null +++ b/plugins/openvswitch-plugin/MANIFEST.in @@ -0,0 +1 @@ +include etc/* diff --git a/quantum/plugins/openvswitch/README b/plugins/openvswitch-plugin/README similarity index 100% rename from quantum/plugins/openvswitch/README rename to plugins/openvswitch-plugin/README diff --git a/quantum/plugins/openvswitch/ovs_quantum_plugin.ini b/plugins/openvswitch-plugin/etc/ovs_quantum_plugin.ini similarity index 100% rename from quantum/plugins/openvswitch/ovs_quantum_plugin.ini rename to plugins/openvswitch-plugin/etc/ovs_quantum_plugin.ini diff --git a/plugins/openvswitch-plugin/lib/__init__.py b/plugins/openvswitch-plugin/lib/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/plugins/openvswitch-plugin/lib/quantum/__init__.py b/plugins/openvswitch-plugin/lib/quantum/__init__.py new file mode 100644 index 0000000000..d407605e19 --- /dev/null +++ b/plugins/openvswitch-plugin/lib/quantum/__init__.py @@ -0,0 +1,5 @@ +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) diff --git a/plugins/openvswitch-plugin/lib/quantum/plugins/__init__.py b/plugins/openvswitch-plugin/lib/quantum/plugins/__init__.py new file mode 100644 index 0000000000..d407605e19 --- /dev/null +++ b/plugins/openvswitch-plugin/lib/quantum/plugins/__init__.py @@ -0,0 +1,5 @@ +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) diff --git a/quantum/plugins/openvswitch/Makefile b/plugins/openvswitch-plugin/lib/quantum/plugins/openvswitch/Makefile similarity index 100% rename from quantum/plugins/openvswitch/Makefile rename to plugins/openvswitch-plugin/lib/quantum/plugins/openvswitch/Makefile diff --git a/plugins/openvswitch-plugin/lib/quantum/plugins/openvswitch/__init__.py b/plugins/openvswitch-plugin/lib/quantum/plugins/openvswitch/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/quantum/plugins/openvswitch/agent/ovs_quantum_agent.py b/plugins/openvswitch-plugin/lib/quantum/plugins/openvswitch/agent/ovs_quantum_agent.py similarity index 100% rename from quantum/plugins/openvswitch/agent/ovs_quantum_agent.py rename to plugins/openvswitch-plugin/lib/quantum/plugins/openvswitch/agent/ovs_quantum_agent.py diff --git a/quantum/plugins/openvswitch/agent/xenserver_install.sh b/plugins/openvswitch-plugin/lib/quantum/plugins/openvswitch/agent/xenserver_install.sh similarity index 100% rename from quantum/plugins/openvswitch/agent/xenserver_install.sh rename to plugins/openvswitch-plugin/lib/quantum/plugins/openvswitch/agent/xenserver_install.sh diff --git a/quantum/plugins/openvswitch/ovs_db.py b/plugins/openvswitch-plugin/lib/quantum/plugins/openvswitch/ovs_db.py similarity index 100% rename from quantum/plugins/openvswitch/ovs_db.py rename to plugins/openvswitch-plugin/lib/quantum/plugins/openvswitch/ovs_db.py diff --git a/quantum/plugins/openvswitch/ovs_models.py b/plugins/openvswitch-plugin/lib/quantum/plugins/openvswitch/ovs_models.py similarity index 100% rename from quantum/plugins/openvswitch/ovs_models.py rename to plugins/openvswitch-plugin/lib/quantum/plugins/openvswitch/ovs_models.py diff --git a/quantum/plugins/openvswitch/ovs_quantum_plugin.py b/plugins/openvswitch-plugin/lib/quantum/plugins/openvswitch/ovs_quantum_plugin.py similarity index 97% rename from quantum/plugins/openvswitch/ovs_quantum_plugin.py rename to plugins/openvswitch-plugin/lib/quantum/plugins/openvswitch/ovs_quantum_plugin.py index f25893e7f0..70e895f8a1 100644 --- a/quantum/plugins/openvswitch/ovs_quantum_plugin.py +++ b/plugins/openvswitch-plugin/lib/quantum/plugins/openvswitch/ovs_quantum_plugin.py @@ -24,24 +24,18 @@ import os import sys from quantum.common import exceptions as q_exc +from quantum.common.config import find_config_file from quantum.quantum_plugin_base import QuantumPluginBase import quantum.db.api as db import ovs_db -CONF_FILE = "ovs_quantum_plugin.ini" +CONF_FILE = find_config_file({}, None, "ovs_quantum_plugin.ini") LOG.basicConfig(level=LOG.WARN) LOG.getLogger("ovs_quantum_plugin") -def find_config(basepath): - for root, dirs, files in os.walk(basepath): - if CONF_FILE in files: - return os.path.join(root, CONF_FILE) - return None - - class VlanMap(object): vlans = {} diff --git a/quantum/plugins/openvswitch/run_tests.py b/plugins/openvswitch-plugin/lib/quantum/plugins/openvswitch/run_tests.py similarity index 100% rename from quantum/plugins/openvswitch/run_tests.py rename to plugins/openvswitch-plugin/lib/quantum/plugins/openvswitch/run_tests.py diff --git a/plugins/openvswitch-plugin/lib/quantum/tests/__init__.py b/plugins/openvswitch-plugin/lib/quantum/tests/__init__.py new file mode 100644 index 0000000000..d407605e19 --- /dev/null +++ b/plugins/openvswitch-plugin/lib/quantum/tests/__init__.py @@ -0,0 +1,5 @@ +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) diff --git a/plugins/openvswitch-plugin/lib/quantum/tests/unit/__init__.py b/plugins/openvswitch-plugin/lib/quantum/tests/unit/__init__.py new file mode 100644 index 0000000000..d407605e19 --- /dev/null +++ b/plugins/openvswitch-plugin/lib/quantum/tests/unit/__init__.py @@ -0,0 +1,5 @@ +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) diff --git a/quantum/plugins/openvswitch/tests/test_vlan_map.py b/plugins/openvswitch-plugin/lib/quantum/tests/unit/test_vlan_map.py similarity index 100% rename from quantum/plugins/openvswitch/tests/test_vlan_map.py rename to plugins/openvswitch-plugin/lib/quantum/tests/unit/test_vlan_map.py diff --git a/plugins/openvswitch-plugin/setup.py b/plugins/openvswitch-plugin/setup.py new file mode 100644 index 0000000000..b52b3f4860 --- /dev/null +++ b/plugins/openvswitch-plugin/setup.py @@ -0,0 +1,66 @@ +try: + from setuptools import setup, find_packages +except ImportError: + from ez_setup import use_setuptools + use_setuptools() + from setuptools import setup, find_packages + +import sys + +Name = 'quantum-openvswitch-plugin' +ProjecUrl = "" +Version = '0.1' +License = 'Apache License 2.0' +# Change as required +Author = 'Open vSwitch Team' +AuthorEmail = 'discuss@openvswitch.org' +Maintainer = '' +Summary = 'OpenVSwitch plugin for Quantum' +ShortDescription = Summary +Description = Summary + +requires = [ + 'quantum-common', + 'quantum-server', +] + +EagerResources = [ + 'quantum', +] + +ProjectScripts = [ +] + +PackageData = { +} + +# If we're installing server-wide, use an aboslute path for config +# if not, use a relative path +config_path = '/etc/quantum/plugins/openvswitch' +relative_locations = ['--user', '--virtualenv', '--venv'] +if [x for x in relative_locations if x in sys.argv]: + config_path = 'etc/quantum/plugins/openvswitch' + +DataFiles = [ + (config_path, + ['etc/ovs_quantum_plugin.ini']) +] + +setup( + name=Name, + version=Version, + author=Author, + author_email=AuthorEmail, + description=ShortDescription, + long_description=Description, + license=License, + scripts=ProjectScripts, + install_requires=requires, + include_package_data=True, + packages=find_packages('lib'), + package_data=PackageData, + data_files=DataFiles, + package_dir={'': 'lib'}, + eager_resources=EagerResources, + namespace_packages=['quantum'], +) diff --git a/plugins/sample-plugin/lib/__init__.py b/plugins/sample-plugin/lib/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/plugins/sample-plugin/lib/quantum/__init__.py b/plugins/sample-plugin/lib/quantum/__init__.py new file mode 100644 index 0000000000..d407605e19 --- /dev/null +++ b/plugins/sample-plugin/lib/quantum/__init__.py @@ -0,0 +1,5 @@ +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) diff --git a/quantum/plugins/SamplePlugin.py b/plugins/sample-plugin/lib/quantum/plugins/SamplePlugin.py similarity index 100% rename from quantum/plugins/SamplePlugin.py rename to plugins/sample-plugin/lib/quantum/plugins/SamplePlugin.py diff --git a/plugins/sample-plugin/lib/quantum/plugins/__init__.py b/plugins/sample-plugin/lib/quantum/plugins/__init__.py new file mode 100644 index 0000000000..d407605e19 --- /dev/null +++ b/plugins/sample-plugin/lib/quantum/plugins/__init__.py @@ -0,0 +1,5 @@ +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) diff --git a/plugins/sample-plugin/setup.py b/plugins/sample-plugin/setup.py new file mode 100644 index 0000000000..6a8097a129 --- /dev/null +++ b/plugins/sample-plugin/setup.py @@ -0,0 +1,55 @@ +try: + from setuptools import setup, find_packages +except ImportError: + from ez_setup import use_setuptools + use_setuptools() + from setuptools import setup, find_packages + +Name = 'quantum-sample-plugin' +ProjecUrl = "https://launchpad.net/quantum" +Version = '2012.1-dev' +License = 'Apache License 2.0' +# Change as required +Author = 'Netstack' +AuthorEmail = 'netstack@lists.launchpad.net' +Maintainer = '' +Summary = 'Sample functionalities for Quantum' +ShortDescription = Summary +Description = Summary + +requires = [ + 'quantum-common', + 'quantum-server', +] + +EagerResources = [ + 'quantum', +] + +ProjectScripts = [ +] + +PackageData = { +} + +DataFiles = [ +] + +setup( + name=Name, + version=Version, + author=Author, + author_email=AuthorEmail, + description=ShortDescription, + long_description=Description, + license=License, + scripts=ProjectScripts, + install_requires=requires, + include_package_data=True, + packages=find_packages('lib'), + package_data=PackageData, + data_files=DataFiles, + package_dir={'': 'lib'}, + eager_resources=EagerResources, + namespace_packages=['quantum'], +) diff --git a/quantum/plugins/cisco/run_tests.py b/quantum/plugins/cisco/run_tests.py deleted file mode 100644 index 690e61ba80..0000000000 --- a/quantum/plugins/cisco/run_tests.py +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env python -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 OpenStack, LLC -# 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. - - -"""Unittest runner for quantum Cisco plugin - -This file should be run from the top dir in the quantum directory - -To run all test:: - python quantum/plugins/cisco/run_tests.py - -To run all unit tests:: - python quantum/plugins/cisco/run_tests.py quantum.plugins.cisco.tests.unit - -To run all functional tests:: - python quantum/plugins/cisco/run_tests.py functional - -To run a single unit test:: - python quantum/plugins/cisco/run_tests.py \ - quantum.plugins.cisco.tests.unit.test_stores:TestSwiftBackend.test_get - -To run a single functional test:: - python quantum/plugins/cisco/run_tests.py \ - quantum.plugins.cisco.tests.functional.test_service \ - :TestController.test_create - -To run a single unit test module:: - python quantum/plugins/cisco/run_tests.py unit.test_stores - -To run a single functional test module:: - python quantum/plugins/cisco/run_tests.py functional.test_stores -""" - -import gettext -import logging -import os -import unittest -import sys - -from nose import config - -sys.path.append(os.getcwd()) - -from quantum.common.test_lib import run_tests, test_config - -if __name__ == '__main__': - exit_status = False - - # if a single test case was specified, - # we should only invoked the tests once - invoke_once = len(sys.argv) > 1 - - cwd = os.getcwd() - - working_dir = os.path.abspath("tests") - c = config.Config(stream=sys.stdout, - env=os.environ, - verbosity=3, - workingDir=working_dir) - exit_status = run_tests(c) - - if invoke_once: - sys.exit(0) - - os.chdir(cwd) - - working_dir = os.path.abspath("quantum/plugins/cisco/tests") - c = config.Config(stream=sys.stdout, - env=os.environ, - verbosity=3, - workingDir=working_dir) - exit_status = exit_status or run_tests(c) - - sys.exit(exit_status) diff --git a/quantum/setup.py b/quantum/setup.py new file mode 100644 index 0000000000..3693883cb9 --- /dev/null +++ b/quantum/setup.py @@ -0,0 +1,49 @@ +try: + from setuptools import setup, find_packages +except ImportError: + from ez_setup import use_setuptools + use_setuptools() + from setuptools import setup, find_packages + +Name = 'quantum' +Url = "https://launchpad.net/quantum" +Version = '2012.1-dev' +License = 'Apache License 2.0' +Author = 'Netstack' +AuthorEmail = 'netstack@lists.launchpad.net' +Maintainer = '' +Summary = 'Layer 2 network as a service for Openstack' +ShortDescription = Summary +Description = Summary + +requires = [ + 'quantum-common', + 'quantum-client', + 'quantum-server' +] + +EagerResources = [ + 'quantum', +] + +ProjectScripts = [ +] + +PackageData = { +} + + +setup( + name=Name, + version=Version, + url=Url, + author=Author, + author_email=AuthorEmail, + description=ShortDescription, + long_description=Description, + license=License, + scripts=ProjectScripts, + install_requires=requires, + include_package_data=True, + package_data=PackageData, +) diff --git a/quantum/utils.py b/quantum/utils.py deleted file mode 100644 index 508debb35b..0000000000 --- a/quantum/utils.py +++ /dev/null @@ -1,92 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2011, Nicira Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# -# Borrowed from nova code base, more utilities will be added/borrowed as and -# when needed. -# @author: Somik Behera, Nicira Networks, Inc. - -"""Utilities and helper functions.""" - -import base64 -import datetime -import functools -import inspect -import json -import os -import random -import re -import socket -import string -import struct -import sys -import time -import types - -from common import exceptions as exception - - -def import_class(import_str): - """Returns a class from a string including module and class.""" - mod_str, _sep, class_str = import_str.rpartition('.') - try: - __import__(mod_str) - return getattr(sys.modules[mod_str], class_str) - except (ImportError, ValueError, AttributeError), exc: - print(('Inner Exception: %s'), exc) - raise exception.ClassNotFound(class_name=class_str) - - -def import_object(import_str): - """Returns an object including a module or module and class.""" - try: - __import__(import_str) - return sys.modules[import_str] - except ImportError: - cls = import_class(import_str) - return cls() - - -def to_primitive(value): - if type(value) is type([]) or type(value) is type((None,)): - o = [] - for v in value: - o.append(to_primitive(v)) - return o - elif type(value) is type({}): - o = {} - for k, v in value.iteritems(): - o[k] = to_primitive(v) - return o - elif isinstance(value, datetime.datetime): - return str(value) - elif hasattr(value, 'iteritems'): - return to_primitive(dict(value.iteritems())) - elif hasattr(value, '__iter__'): - return to_primitive(list(value)) - else: - return value - - -def dumps(value): - try: - return json.dumps(value) - except TypeError: - pass - return json.dumps(to_primitive(value)) - - -def loads(s): - return json.loads(s) diff --git a/run_tests.py b/run_tests.py old mode 100644 new mode 100755 index 34d56c5029..847b686228 --- a/run_tests.py +++ b/run_tests.py @@ -1,61 +1,5 @@ #!/usr/bin/env python -# vim: tabstop=4 shiftwidth=4 softtabstop=4 +import tools.source_nonplugin_environment +from quantum.run_tests import main as tests -# Copyright 2010 OpenStack, LLC -# 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. - - -"""Unittest runner for quantum - -To run all test:: - python run_tests.py - -To run all unit tests:: - python run_tests.py unit - -To run all functional tests:: - python run_tests.py functional - -To run a single unit test:: - python run_tests.py unit.test_stores:TestSwiftBackend.test_get - -To run a single functional test:: - python run_tests.py functional.test_service:TestController.test_create - -To run a single unit test module:: - python run_tests.py unit.test_stores - -To run a single functional test module:: - python run_tests.py functional.test_stores -""" - -import gettext -import os -import unittest -import sys - -from quantum.common.test_lib import run_tests -from nose import config -from nose import core - - -if __name__ == '__main__': - working_dir = os.path.abspath("tests") - c = config.Config(stream=sys.stdout, - env=os.environ, - verbosity=3, - workingDir=working_dir, - plugins=core.DefaultPluginManager()) - sys.exit(run_tests(c)) +tests() diff --git a/run_tests.sh b/run_tests.sh index aee422a623..9b0a92c344 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -102,7 +102,7 @@ fi # PEP8_EXCLUDE=vcsversion.py PEP8_OPTIONS="--exclude=$PEP8_EXCLUDE --repeat --show-source" -PEP8_INCLUDE="bin/* quantum tests tools run_tests.py" +PEP8_INCLUDE="bin/* quantum server client common plugins tools run_tests.py setup.py" RV=0 run_tests && pep8 $PEP8_OPTIONS $PEP8_INCLUDE || RV=1 diff --git a/server/MANIFEST.in b/server/MANIFEST.in new file mode 100644 index 0000000000..a42c1a7258 --- /dev/null +++ b/server/MANIFEST.in @@ -0,0 +1,2 @@ +include etc/* +include etc/init.d/* diff --git a/server/etc/init.d/quantum-server b/server/etc/init.d/quantum-server new file mode 100755 index 0000000000..f526868384 --- /dev/null +++ b/server/etc/init.d/quantum-server @@ -0,0 +1,68 @@ +#! /bin/sh +### BEGIN INIT INFO +# Provides: quantum-server +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: quantum-server +# Description: Provides the Quantum networking service +### END INIT INFO + +set -e + +PIDFILE=/var/run/quantum/quantum-server.pid +LOGFILE=/var/log/quantum/quantum-server.log + +DAEMON=/usr/bin/quantum-server +DAEMON_ARGS="--log-file=$LOGFILE" +DAEMON_DIR=/var/run + +ENABLED=true + +if test -f /etc/default/quantum-server; then + . /etc/default/quantum-server +fi + +mkdir -p /var/run/quantum +mkdir -p /var/log/quantum + +. /lib/lsb/init-functions + +export PATH="${PATH:+$PATH:}/usr/sbin:/sbin" +export TMPDIR=/var/lib/quantum/tmp + +if [ ! -x ${DAEMON} ] ; then + exit 0 +fi + +case "$1" in + start) + test "$ENABLED" = "true" || exit 0 + log_daemon_msg "Starting quantum server" "quantum-server" + start-stop-daemon -Sbmv --pidfile $PIDFILE --chdir $DAEMON_DIR --exec $DAEMON -- $DAEMON_ARGS + log_end_msg $? + ;; + stop) + test "$ENABLED" = "true" || exit 0 + log_daemon_msg "Stopping quantum server" "quantum-server" + start-stop-daemon --stop --oknodo --pidfile ${PIDFILE} + log_end_msg $? + ;; + restart|force-reload) + test "$ENABLED" = "true" || exit 1 + $0 stop + sleep 1 + $0 start + ;; + status) + test "$ENABLED" = "true" || exit 0 + status_of_proc -p $PIDFILE $DAEMON quantum-server && exit 0 || exit $? + ;; + *) + log_action_msg "Usage: /etc/init.d/quantum-server {start|stop|restart|force-reload|status}" + exit 1 + ;; +esac + +exit 0 diff --git a/quantum/plugins.ini b/server/etc/plugins.ini similarity index 100% rename from quantum/plugins.ini rename to server/etc/plugins.ini diff --git a/etc/quantum.conf b/server/etc/quantum.conf similarity index 100% rename from etc/quantum.conf rename to server/etc/quantum.conf diff --git a/etc/quantum.conf.sample b/server/etc/quantum.conf.sample similarity index 100% rename from etc/quantum.conf.sample rename to server/etc/quantum.conf.sample diff --git a/etc/quantum.conf.test b/server/etc/quantum.conf.test similarity index 89% rename from etc/quantum.conf.test rename to server/etc/quantum.conf.test index a7134d2848..6157d5b028 100644 --- a/etc/quantum.conf.test +++ b/server/etc/quantum.conf.test @@ -21,4 +21,4 @@ pipeline = extensions extensions_test_app paste.filter_factory = quantum.common.extensions:plugin_aware_extension_middleware_factory [app:extensions_test_app] -paste.app_factory = tests.unit.test_extensions:app_factory +paste.app_factory = quantum.tests.unit.test_extensions:app_factory diff --git a/server/lib/__init__.py b/server/lib/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/server/lib/quantum/__init__.py b/server/lib/quantum/__init__.py new file mode 100644 index 0000000000..5846cd9f52 --- /dev/null +++ b/server/lib/quantum/__init__.py @@ -0,0 +1,21 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# Copyright 2011 Nicira Networks, Inc. +# 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. +# @author: Somik Behera, Nicira Networks, Inc. +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) diff --git a/quantum/api/__init__.py b/server/lib/quantum/api/__init__.py similarity index 99% rename from quantum/api/__init__.py rename to server/lib/quantum/api/__init__.py index ea02d26779..4de6bce8d6 100644 --- a/quantum/api/__init__.py +++ b/server/lib/quantum/api/__init__.py @@ -30,7 +30,7 @@ from quantum.api import attachments from quantum.api import networks from quantum.api import ports from quantum.common import flags -from quantum.common import wsgi +from quantum import wsgi LOG = logging.getLogger('quantum.api') diff --git a/quantum/api/api_common.py b/server/lib/quantum/api/api_common.py similarity index 99% rename from quantum/api/api_common.py rename to server/lib/quantum/api/api_common.py index 8201f38b31..11d56fd079 100644 --- a/quantum/api/api_common.py +++ b/server/lib/quantum/api/api_common.py @@ -20,7 +20,7 @@ import webob from webob import exc -from quantum.common import wsgi +from quantum import wsgi XML_NS_V01 = 'http://netstack.org/quantum/api/v0.1' XML_NS_V10 = 'http://netstack.org/quantum/api/v1.0' diff --git a/quantum/api/attachments.py b/server/lib/quantum/api/attachments.py similarity index 100% rename from quantum/api/attachments.py rename to server/lib/quantum/api/attachments.py diff --git a/quantum/api/faults.py b/server/lib/quantum/api/faults.py similarity index 99% rename from quantum/api/faults.py rename to server/lib/quantum/api/faults.py index ef4d50bc6b..51cc9974c0 100644 --- a/quantum/api/faults.py +++ b/server/lib/quantum/api/faults.py @@ -20,7 +20,7 @@ import webob.dec import webob.exc from quantum.api import api_common as common -from quantum.common import wsgi +from quantum import wsgi class Fault(webob.exc.HTTPException): diff --git a/quantum/api/networks.py b/server/lib/quantum/api/networks.py similarity index 100% rename from quantum/api/networks.py rename to server/lib/quantum/api/networks.py diff --git a/quantum/api/ports.py b/server/lib/quantum/api/ports.py similarity index 100% rename from quantum/api/ports.py rename to server/lib/quantum/api/ports.py diff --git a/quantum/api/versions.py b/server/lib/quantum/api/versions.py similarity index 98% rename from quantum/api/versions.py rename to server/lib/quantum/api/versions.py index 2fd6812e29..6e730b5e38 100644 --- a/quantum/api/versions.py +++ b/server/lib/quantum/api/versions.py @@ -18,7 +18,7 @@ import logging import webob.dec -from quantum.common import wsgi +from quantum import wsgi from quantum.api.views import versions as versions_view LOG = logging.getLogger('quantum.api.versions') diff --git a/quantum/api/views/__init__.py b/server/lib/quantum/api/views/__init__.py similarity index 100% rename from quantum/api/views/__init__.py rename to server/lib/quantum/api/views/__init__.py diff --git a/quantum/api/views/attachments.py b/server/lib/quantum/api/views/attachments.py similarity index 100% rename from quantum/api/views/attachments.py rename to server/lib/quantum/api/views/attachments.py diff --git a/quantum/api/views/networks.py b/server/lib/quantum/api/views/networks.py similarity index 100% rename from quantum/api/views/networks.py rename to server/lib/quantum/api/views/networks.py diff --git a/quantum/api/views/ports.py b/server/lib/quantum/api/views/ports.py similarity index 100% rename from quantum/api/views/ports.py rename to server/lib/quantum/api/views/ports.py diff --git a/quantum/api/views/versions.py b/server/lib/quantum/api/views/versions.py similarity index 100% rename from quantum/api/views/versions.py rename to server/lib/quantum/api/views/versions.py diff --git a/quantum/db/__init__.py b/server/lib/quantum/db/__init__.py similarity index 100% rename from quantum/db/__init__.py rename to server/lib/quantum/db/__init__.py diff --git a/quantum/db/api.py b/server/lib/quantum/db/api.py similarity index 100% rename from quantum/db/api.py rename to server/lib/quantum/db/api.py diff --git a/quantum/db/models.py b/server/lib/quantum/db/models.py similarity index 100% rename from quantum/db/models.py rename to server/lib/quantum/db/models.py diff --git a/extensions/__init__.py b/server/lib/quantum/extensions/__init__.py similarity index 100% rename from extensions/__init__.py rename to server/lib/quantum/extensions/__init__.py diff --git a/extensions/_credential_view.py b/server/lib/quantum/extensions/_credential_view.py similarity index 100% rename from extensions/_credential_view.py rename to server/lib/quantum/extensions/_credential_view.py diff --git a/extensions/_novatenant_view.py b/server/lib/quantum/extensions/_novatenant_view.py similarity index 100% rename from extensions/_novatenant_view.py rename to server/lib/quantum/extensions/_novatenant_view.py diff --git a/extensions/_pprofiles.py b/server/lib/quantum/extensions/_pprofiles.py similarity index 100% rename from extensions/_pprofiles.py rename to server/lib/quantum/extensions/_pprofiles.py diff --git a/extensions/_qos_view.py b/server/lib/quantum/extensions/_qos_view.py similarity index 100% rename from extensions/_qos_view.py rename to server/lib/quantum/extensions/_qos_view.py diff --git a/extensions/credential.py b/server/lib/quantum/extensions/credential.py similarity index 100% rename from extensions/credential.py rename to server/lib/quantum/extensions/credential.py diff --git a/extensions/multiport.py b/server/lib/quantum/extensions/multiport.py similarity index 100% rename from extensions/multiport.py rename to server/lib/quantum/extensions/multiport.py diff --git a/extensions/novatenant.py b/server/lib/quantum/extensions/novatenant.py similarity index 100% rename from extensions/novatenant.py rename to server/lib/quantum/extensions/novatenant.py diff --git a/extensions/portprofile.py b/server/lib/quantum/extensions/portprofile.py similarity index 100% rename from extensions/portprofile.py rename to server/lib/quantum/extensions/portprofile.py diff --git a/extensions/qos.py b/server/lib/quantum/extensions/qos.py similarity index 100% rename from extensions/qos.py rename to server/lib/quantum/extensions/qos.py diff --git a/quantum/manager.py b/server/lib/quantum/manager.py similarity index 76% rename from quantum/manager.py rename to server/lib/quantum/manager.py index 782b71cee7..eb3ffba84d 100644 --- a/quantum/manager.py +++ b/server/lib/quantum/manager.py @@ -29,7 +29,9 @@ import os gettext.install('quantum', unicode=1) -from common import utils +from quantum.common import utils +from quantum.common.config import find_config_file +from quantum.common.exceptions import ClassNotFound from quantum_plugin_base import QuantumPluginBase LOG = logging.getLogger('quantum.manager') @@ -49,19 +51,28 @@ class QuantumManager(object): _instance = None def __init__(self, options=None, config_file=None): - if config_file == None: - self.configuration_file = find_config( - os.path.abspath(os.path.dirname(__file__))) - else: - self.configuration_file = config_file # If no options have been provided, create an empty dict if not options: options = {} + + if config_file: + config_file = [config_file] + + self.configuration_file = find_config_file(options, config_file, + CONFIG_FILE) if not 'plugin_provider' in options: options['plugin_provider'] = \ utils.get_plugin_from_config(self.configuration_file) LOG.debug("Plugin location:%s", options['plugin_provider']) - plugin_klass = utils.import_class(options['plugin_provider']) + + # If the plugin can't be found let them know gracefully + try: + plugin_klass = utils.import_class(options['plugin_provider']) + except ClassNotFound: + raise Exception("Plugin not found. You can install a " \ + "plugin with: pip install \n" \ + "Example: pip install quantum-sample-plugin") + if not issubclass(plugin_klass, QuantumPluginBase): raise Exception("Configured Quantum plug-in " \ "didn't pass compatibility test") diff --git a/quantum/quantum_plugin_base.py b/server/lib/quantum/quantum_plugin_base.py similarity index 100% rename from quantum/quantum_plugin_base.py rename to server/lib/quantum/quantum_plugin_base.py diff --git a/server/lib/quantum/server.py b/server/lib/quantum/server.py new file mode 100755 index 0000000000..709eeda15b --- /dev/null +++ b/server/lib/quantum/server.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 Nicira Neworks, Inc. +# 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. + +# If ../quantum/__init__.py exists, add ../ to Python search path, so that +# it will override what happens to be installed in /usr/(local/)lib/python... + +import gettext +import optparse +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, 'quantum', '__init__.py')): + sys.path.insert(0, possible_topdir) + +gettext.install('quantum', unicode=1) + +from quantum import service +from quantum.common import config + + +def create_options(parser): + """ + Sets up the CLI and config-file options that may be + parsed and program commands. + :param parser: The option parser + """ + config.add_common_options(parser) + config.add_log_options(parser) + + +def main(): + oparser = optparse.OptionParser(version='%%prog VERSION') + create_options(oparser) + (options, args) = config.parse_options(oparser) + + try: + quantum_service = service.serve_wsgi(service.QuantumApiService, + options=options, + args=args) + quantum_service.wait() + except RuntimeError, e: + sys.exit("ERROR: %s" % e) + +if __name__ == "__main__": + main() diff --git a/quantum/service.py b/server/lib/quantum/service.py similarity index 99% rename from quantum/service.py rename to server/lib/quantum/service.py index 0c27bcc5b7..307c9900dd 100644 --- a/quantum/service.py +++ b/server/lib/quantum/service.py @@ -17,7 +17,7 @@ import logging from quantum.common import config -from quantum.common import wsgi +from quantum import wsgi from quantum.common import exceptions as exception diff --git a/quantum/plugins/__init__.py b/server/lib/quantum/tests/__init__.py similarity index 88% rename from quantum/plugins/__init__.py rename to server/lib/quantum/tests/__init__.py index 7e695ff08d..9578283b2d 100644 --- a/quantum/plugins/__init__.py +++ b/server/lib/quantum/tests/__init__.py @@ -1,5 +1,6 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright 2011 Nicira Networks, Inc. + +# Copyright 2011 OpenStack LLC. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -13,4 +14,6 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -# @author: Somik Behera, Nicira Networks, Inc. + +import logging +logging.basicConfig() diff --git a/server/lib/quantum/tests/unit/__init__.py b/server/lib/quantum/tests/unit/__init__.py new file mode 100644 index 0000000000..726786924d --- /dev/null +++ b/server/lib/quantum/tests/unit/__init__.py @@ -0,0 +1,38 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# 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. + +# See http://code.google.com/p/python-nose/issues/detail?id=373 +# The code below enables nosetests to work with i18n _() blocks +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) + +import __builtin__ +import unittest +setattr(__builtin__, '_', lambda x: x) + + +class BaseTest(unittest.TestCase): + + def setUp(self): + pass + + +def setUp(): + pass diff --git a/tests/unit/client_tools/__init__.py b/server/lib/quantum/tests/unit/client_tools/__init__.py similarity index 100% rename from tests/unit/client_tools/__init__.py rename to server/lib/quantum/tests/unit/client_tools/__init__.py diff --git a/tests/unit/client_tools/stubs.py b/server/lib/quantum/tests/unit/client_tools/stubs.py similarity index 97% rename from tests/unit/client_tools/stubs.py rename to server/lib/quantum/tests/unit/client_tools/stubs.py index 7b66cac592..99f1410d69 100644 --- a/tests/unit/client_tools/stubs.py +++ b/server/lib/quantum/tests/unit/client_tools/stubs.py @@ -17,7 +17,7 @@ from quantum import api as server -from tests.unit import testlib_api +from quantum.tests.unit import testlib_api class FakeStdout: diff --git a/tests/unit/database_stubs.py b/server/lib/quantum/tests/unit/database_stubs.py similarity index 100% rename from tests/unit/database_stubs.py rename to server/lib/quantum/tests/unit/database_stubs.py diff --git a/tests/unit/extension_stubs.py b/server/lib/quantum/tests/unit/extension_stubs.py similarity index 98% rename from tests/unit/extension_stubs.py rename to server/lib/quantum/tests/unit/extension_stubs.py index c8a7385f60..09af1da60d 100644 --- a/tests/unit/extension_stubs.py +++ b/server/lib/quantum/tests/unit/extension_stubs.py @@ -16,7 +16,7 @@ from abc import abstractmethod from quantum.common import extensions -from quantum.common import wsgi +from quantum import wsgi class StubExtension(object): diff --git a/tests/unit/extensions/__init__.py b/server/lib/quantum/tests/unit/extensions/__init__.py similarity index 100% rename from tests/unit/extensions/__init__.py rename to server/lib/quantum/tests/unit/extensions/__init__.py diff --git a/tests/unit/extensions/foxinsocks.py b/server/lib/quantum/tests/unit/extensions/foxinsocks.py similarity index 99% rename from tests/unit/extensions/foxinsocks.py rename to server/lib/quantum/tests/unit/extensions/foxinsocks.py index 4a1aa2377f..581aeefbd7 100644 --- a/tests/unit/extensions/foxinsocks.py +++ b/server/lib/quantum/tests/unit/extensions/foxinsocks.py @@ -17,7 +17,7 @@ import json -from quantum.common import wsgi +from quantum import wsgi from quantum.common import extensions from abc import abstractmethod diff --git a/tests/unit/test_api.py b/server/lib/quantum/tests/unit/test_api.py similarity index 99% rename from tests/unit/test_api.py rename to server/lib/quantum/tests/unit/test_api.py index ed5bdcbd37..0f5e4967e4 100644 --- a/tests/unit/test_api.py +++ b/server/lib/quantum/tests/unit/test_api.py @@ -20,12 +20,13 @@ import logging import unittest -import tests.unit.testlib_api as testlib + +import quantum.tests.unit.testlib_api as testlib from quantum import api as server -from quantum.db import api as db +from quantum.common.serializer import Serializer from quantum.common.test_lib import test_config -from quantum.common.wsgi import Serializer +from quantum.db import api as db LOG = logging.getLogger('quantum.tests.test_api') diff --git a/tests/unit/test_cli.py b/server/lib/quantum/tests/unit/test_cli.py similarity index 99% rename from tests/unit/test_cli.py rename to server/lib/quantum/tests/unit/test_cli.py index 4e98391cae..001db66790 100644 --- a/tests/unit/test_cli.py +++ b/server/lib/quantum/tests/unit/test_cli.py @@ -30,7 +30,7 @@ from quantum import api as server from quantum import cli_lib as cli from quantum.client import Client from quantum.db import api as db -from tests.unit.client_tools import stubs as client_stubs +from quantum.tests.unit.client_tools import stubs as client_stubs LOG = logging.getLogger('quantum.tests.test_cli') FORMAT = 'json' diff --git a/tests/unit/test_database.py b/server/lib/quantum/tests/unit/test_database.py similarity index 98% rename from tests/unit/test_database.py rename to server/lib/quantum/tests/unit/test_database.py index 3e56b652e8..dae4f24664 100644 --- a/tests/unit/test_database.py +++ b/server/lib/quantum/tests/unit/test_database.py @@ -24,7 +24,7 @@ import unittest from quantum.db import api as db -from tests.unit import database_stubs as db_stubs +from quantum.tests.unit import database_stubs as db_stubs LOG = logging.getLogger('quantum.tests.test_database') diff --git a/tests/unit/test_extensions.py b/server/lib/quantum/tests/unit/test_extensions.py similarity index 98% rename from tests/unit/test_extensions.py rename to server/lib/quantum/tests/unit/test_extensions.py index a33897e47e..5309c28ddb 100644 --- a/tests/unit/test_extensions.py +++ b/server/lib/quantum/tests/unit/test_extensions.py @@ -14,18 +14,19 @@ # License for the specific language governing permissions and limitations # under the License. import json -import os.path +import logging +import os import routes import unittest -from tests.unit import BaseTest +from quantum.tests.unit import BaseTest from webtest import TestApp -from quantum.common import wsgi +from quantum import wsgi from quantum.common import config from quantum.common import extensions from quantum.plugins.SamplePlugin import QuantumEchoPlugin -from tests.unit.extension_stubs import (StubExtension, StubPlugin, +from quantum.tests.unit.extension_stubs import (StubExtension, StubPlugin, StubPluginInterface, StubBaseAppController, ExtensionExpectingPluginInterface) @@ -33,9 +34,9 @@ from quantum.common.extensions import (ExtensionManager, PluginAwareExtensionManager, ExtensionMiddleware) +LOG = logging.getLogger('test_extensions') -test_conf_file = os.path.join(os.path.dirname(__file__), os.pardir, - os.pardir, 'etc', 'quantum.conf.test') +test_conf_file = config.find_config_file({}, None, "quantum.conf.test") extensions_path = os.path.join(os.path.dirname(__file__), "extensions") diff --git a/tests/unit/testlib_api.py b/server/lib/quantum/tests/unit/testlib_api.py similarity index 99% rename from tests/unit/testlib_api.py rename to server/lib/quantum/tests/unit/testlib_api.py index cd3cce0063..1b7214531a 100644 --- a/tests/unit/testlib_api.py +++ b/server/lib/quantum/tests/unit/testlib_api.py @@ -1,6 +1,6 @@ import webob -from quantum.common.wsgi import Serializer +from quantum.common.serializer import Serializer def create_request(path, body, content_type, method='GET'): diff --git a/quantum/common/wsgi.py b/server/lib/quantum/wsgi.py similarity index 99% rename from quantum/common/wsgi.py rename to server/lib/quantum/wsgi.py index 11fdd68c1e..2bee9705d1 100644 --- a/quantum/common/wsgi.py +++ b/server/lib/quantum/wsgi.py @@ -31,7 +31,7 @@ from xml.dom import minidom from quantum.common import exceptions as exception -from quantum import utils +from quantum.common import utils LOG = logging.getLogger('quantum.common.wsgi') diff --git a/server/setup.py b/server/setup.py new file mode 100644 index 0000000000..618a5d15bc --- /dev/null +++ b/server/setup.py @@ -0,0 +1,76 @@ +try: + from setuptools import setup, find_packages +except ImportError: + from ez_setup import use_setuptools + use_setuptools() + from setuptools import setup, find_packages + +import os +import sys + +Name = 'quantum-server' +Url = "https://launchpad.net/quantum" +Version = '2012.1-dev' +License = 'Apache License 2.0' +Author = 'Netstatck' +AuthorEmail = 'netstack@lists.launchpad.net' +Maintainer = '' +Summary = 'Server functionalities for Quantum' +ShortDescription = Summary +Description = Summary + +requires = [ + 'quantum-common' +] + +EagerResources = [ + 'quantum', +] + +ProjectScripts = [ +] + +PackageData = { +} + +# If we're installing server-wide, use an aboslute path for config +# if not, use a relative path +config_path = '/etc/quantum/' +init_path = '/etc/init.d' + +relative_locations = ['--user', '--virtualenv', '--venv'] +if [x for x in relative_locations if x in sys.argv]: + config_path = 'etc/quantum/' + init_path = 'etc/init.d' + +DataFiles = [ + (config_path, + ['etc/quantum.conf', 'etc/quantum.conf.sample', + 'etc/quantum.conf.test', 'etc/plugins.ini']), + (init_path, ['etc/init.d/quantum-server']) +] + +setup( + name=Name, + version=Version, + url=Url, + author=Author, + author_email=AuthorEmail, + description=ShortDescription, + long_description=Description, + license=License, + scripts=ProjectScripts, + install_requires=requires, + include_package_data=True, + packages=find_packages('lib'), + package_data=PackageData, + data_files=DataFiles, + package_dir={'': 'lib'}, + eager_resources=EagerResources, + namespace_packages=['quantum'], + entry_points={ + 'console_scripts': [ + 'quantum-server = quantum.server:main' + ] + }, +) diff --git a/setup.py b/setup.py index 8ddc6fccf2..cdb14e4abc 100644 --- a/setup.py +++ b/setup.py @@ -1,35 +1,153 @@ -import os +from copy import deepcopy +from optparse import OptionParser +from os import path +import re import sys -from setuptools import setup, find_packages + +from tools import install_venv + +ROOT = path.abspath(path.dirname(__file__)) +CONFIG_PATH = path.abspath('/etc/quantum') +BASE_PACKAGES = ['common', 'server', 'client'] +PLUGINS = ['plugins/sample-plugin', 'plugins/cisco-plugin', + 'plugins/openvswitch-plugin'] + +RELATIVE = False -def read(fname): - return open(os.path.join(os.path.dirname(__file__), fname)).read() +def clean_path(dirty): + """Makes sure path delimiters are OS compliant""" + return path.join(*dirty.split('/')) -requirements = ['httplib2', 'eventlet', 'routes', 'webob'] -setup( - name='Quantum', - version='0.1', - description='Layer 2 network as a service for Openstack', - long_description=read('README'), - url='http://launchpad.net/quantum', - license='Apache', - author='Netstack', - author_email='netstack@launchpad.net', - packages=find_packages(exclude=['tests']), - classifiers=[ - 'Development Status :: 4 - Beta', - 'Environment :: Console', - 'Intended Audience :: Developers', - 'Intended Audience :: Information Technology', - 'License :: OSI Approved :: BSD License', - 'Operating System :: OS Independent', - 'Programming Language :: Python', - ], - namespace_packages=["quantum"], - install_requires=requirements, +def script_dir(): + script_dir = '/usr/sbin/' + if RELATIVE: + script_dir = 'usr/sbin/' + return script_dir - tests_require=["nose"], - test_suite="nose.collector", -) + +def create_parser(): + """Setup the option parser""" + usagestr = "Usage: %prog [OPTIONS] [args]" + parser = OptionParser(usage=usagestr) + parser.add_option("-V", "--virtualenv", "--venv", dest="venv", + action="store_true", default=False, help="Install to a virtual-env") + parser.add_option("-U", "--user", dest="user", action="store_true", + default=False, help="Install to users's home") + options, args = parser.parse_args() + + if args.__len__() is 0: + print usagestr + print "Commands:\ninstall\nuninstall\nbuild\nclean" + exit(0) + + cmd = args[0] + args = args[1:] + return (options, cmd, args) + + +def install_packages(options, args=None): + """Builds and installs packages""" + # Start building a command list + cmd = ['pip', 'install'] + + # If no options, just a regular install. If venv, create, prepare and + # install in venv. If --user install in user's local dir. Usually + # ~/.local/ + if options.venv: + if install_venv.VENV_EXISTS: + print "Virtual-env exists" + else: + install_venv.create_virtualenv(install_pip=False) + install_venv.install_dependencies() + cmd.extend(['-E', install_venv.VENV]) + elif options.user: + cmd.append('--user') + + # Install packages + # TODO(Tyler) allow users to pass in packages in cli + for package in BASE_PACKAGES + PLUGINS: + print "Installing %s" % package + # Each package needs its own command list, and it needs the path + # in the correct place (after "pip install") + pcmd = deepcopy(cmd) + pcmd.insert(2, path.join(ROOT, clean_path(package))) + + if package is 'server': + pcmd.append("--install-option=--install-scripts=%s" %\ + script_dir()) + print pcmd + install_venv.run_command(pcmd) + print "done." + + +def uninstall_packages(options, args=None): + """Removes packages""" + cmd = ['pip', 'uninstall', '-y'] + + for package in ['quantum-' + x.split('/')[-1] \ + for x in BASE_PACKAGES + PLUGINS]: + print "Uninstalling %s" % package + # Each package needs its own command list, and it needs the path + # in the correct place (after "pip uninstall" + pcmd = deepcopy(cmd) + pcmd.insert(2, package) + print pcmd + install_venv.run_command(pcmd) + print "done." + + +def build_packages(options, args=None): + """Build RPM and/or deb packages""" + if not args: + print "To build packages you must specifiy either 'rpm', " \ + "'deb', or 'all'" + exit(0) + if args[0] not in ['rpm', 'deb', 'all']: + raise Exception("Packge type must be rpm, deb, or all") + + if 'rpm' in args or 'all' in args: + # Since we need to cd to build rpms, we call this sh script + cmd = ['tools/build_rpms.sh'] + for package in BASE_PACKAGES + PLUGINS: + print "Building %s rpm" % package + pcmd = deepcopy(cmd) + pcmd.append(package) + install_venv.run_command(pcmd) + print "done." + + if 'deb' in args or 'all' in args: + cmd = ['tools/build_debs.sh'] + for p in BASE_PACKAGES + PLUGINS: + print "Building %s deb" % p + pcmd = deepcopy(cmd) + pcmd.append(p) + install_venv.run_command(pcmd) + print "done." + + +def clean_packages(options, args): + """Cleans build packages""" + cmd = ["tools/clean.sh"] + install_venv.run_command(cmd) + + +def main(): + """Main Build script for Quantum""" + options, cmd, args = create_parser() + + if options.user: + RELATIVE = True + + print "Checking for virtual-env and easy_install" + install_venv.check_dependencies() + + # Execute command + try: + globals()["%s_packages" % cmd](options, args) + except KeyError as exc: + print "Command %s' not found" % exc.__str__().split('_')[0] + +if __name__ == "__main__": + main() diff --git a/tools/__init__.py b/tools/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/build_debs.sh b/tools/build_debs.sh new file mode 100755 index 0000000000..557876349a --- /dev/null +++ b/tools/build_debs.sh @@ -0,0 +1,27 @@ +#!/bin/bash +ALIEN=`which alien` +if [ $? -ne 0 ]; then + echo "You must have alien installed to build debian packages" + exit 1 +fi +FAKEROOT="" +if [ `id -u` != 0 ]; then + FAKEROOT=`which fakeroot` + if [ $? -ne 0 ]; then + echo "You must be root or have fakeroot installed to build debian packages" + exit 1 + fi +fi + +ls $@/dist/*.rpm >/dev/null 2>&1 +if [ $? -ne 0 ]; then + echo "You must build rpms before building debian packages" + exit 1 +fi + +cd $@ +if [ $? -ne 0 ]; then + echo "Directory $@ doesn't exist -- what do you want me to build?" + exit 1 +fi +$FAKEROOT $ALIEN -c -v -d dist/*.noarch.rpm diff --git a/tools/build_rpms.sh b/tools/build_rpms.sh new file mode 100755 index 0000000000..7ae6ef7a2e --- /dev/null +++ b/tools/build_rpms.sh @@ -0,0 +1,2 @@ +#!/bin/bash +cd $@ && python setup.py bdist_rpm diff --git a/tools/clean.sh b/tools/clean.sh new file mode 100755 index 0000000000..c1deb844c6 --- /dev/null +++ b/tools/clean.sh @@ -0,0 +1,5 @@ +#!/bin/bash +rm -rf ./*.deb ./*.tar.gz ./*.dsc ./*.changes +rm -rf */*.deb +rm -rf ./plugins/**/build/ ./plugins/**/dist +rm -rf ./plugins/**/lib/quantum_*_plugin.egg-info ./plugins/quantum-* diff --git a/tools/install_venv.py b/tools/install_venv.py index 5c3ef374b6..f6fb708f06 100644 --- a/tools/install_venv.py +++ b/tools/install_venv.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python # vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2010 United States Government as represented by the @@ -28,7 +29,8 @@ import sys ROOT = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) -VENV = os.path.join(ROOT, '.quantum-venv') +VENV = os.path.expanduser('~/.quantum-venv') +VENV_EXISTS = bool(os.path.exists(VENV)) PIP_REQUIRES = os.path.join(ROOT, 'tools', 'pip-requires') @@ -46,11 +48,10 @@ def run_command(cmd, redirect_output=True, check_exit_code=True): stdout = subprocess.PIPE else: stdout = None - proc = subprocess.Popen(cmd, cwd=ROOT, stdout=stdout) output = proc.communicate()[0] if check_exit_code and proc.returncode != 0: - die('Command "%s" failed.\n%s', ' '.join(cmd), output) + raise Exception('Command "%s" failed.\n%s' % (' '.join(cmd), output)) return output @@ -64,27 +65,24 @@ def check_dependencies(): """Make sure virtualenv is in the path.""" if not HAS_VIRTUALENV: - print 'not found.' - # Try installing it via easy_install... - if HAS_EASY_INSTALL: - print 'Installing virtualenv via easy_install...', - if not run_command(['which', 'easy_install']): - die('ERROR: virtualenv not found.\n\n' - 'Quantum requires virtualenv, please install' - ' it using your favorite package management tool') - print 'done.' + raise Exception('Virtualenv not found. ' + \ + 'Try installing python-virtualenv') print 'done.' -def create_virtualenv(venv=VENV): +def create_virtualenv(venv=VENV, install_pip=False): """Creates the virtual environment and installs PIP only into the virtual environment """ print 'Creating venv...', - run_command(['virtualenv', '-q', '--no-site-packages', VENV]) + + install = ['virtualenv', '-q', venv] + run_command(install) + print 'done.' print 'Installing pip in virtualenv...', - if not run_command(['tools/with_venv.sh', 'easy_install', 'pip']).strip(): + if install_pip and \ + not run_command(['tools/with_venv.sh', 'easy_install', 'pip']): die("Failed to install pip.") print 'done.' @@ -94,9 +92,8 @@ def install_dependencies(venv=VENV): # Install greenlet by hand - just listing it in the requires file does not # get it in stalled in the right order - venv_tool = 'tools/with_venv.sh' - run_command([venv_tool, 'pip', 'install', '-E', venv, '-r', PIP_REQUIRES], - redirect_output=False) + run_command(['tools/with_venv.sh', 'pip', 'install', '-E', venv, + '-r', PIP_REQUIRES], redirect_output=False) # Tell the virtual env how to "import quantum" pthfile = os.path.join(venv, "lib", "python2.6", "site-packages", diff --git a/tools/source_environment.py b/tools/source_environment.py new file mode 100644 index 0000000000..960225cb8b --- /dev/null +++ b/tools/source_environment.py @@ -0,0 +1,28 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 Cisco Systems +# 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. +# @author: Tyler Smith, Cisco Systems +import os +import sys + +# To run from the source code, we need to add the various packages +# to our path so we can find all of the modules correctly +packages = ['common', 'server', 'client'] +plugins = ["plugins/%s" % p for p in + os.listdir(os.path.join(os.getcwd(), 'plugins'))] + +for project in packages + plugins: + sys.path.insert(0, os.path.join(os.getcwd(), project, 'lib')) diff --git a/tools/source_nonplugin_environment.py b/tools/source_nonplugin_environment.py new file mode 100644 index 0000000000..0891c2f709 --- /dev/null +++ b/tools/source_nonplugin_environment.py @@ -0,0 +1,26 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 Cisco Systems +# 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. +# @author: Tyler Smith, Cisco Systems +import os +import sys + +# To run from the source code, we need to add the various packages +# to our path so we can find all of the modules correctly +packages = ['common', 'server', 'client'] + +for project in packages + ["plugins/sample-plugin"]: + sys.path.insert(0, os.path.join(os.getcwd(), project, 'lib')) diff --git a/tools/with_venv.sh b/tools/with_venv.sh index 83149462c1..88444a2403 100755 --- a/tools/with_venv.sh +++ b/tools/with_venv.sh @@ -17,5 +17,5 @@ # under the License. TOOLS=`dirname $0` -VENV=$TOOLS/../.quantum-venv +VENV=~/.quantum-venv source $VENV/bin/activate && $@