15 changed files with 921 additions and 0 deletions
@ -0,0 +1,30 @@
|
||||
# Compiled files |
||||
*.py[co] |
||||
*.a |
||||
*.o |
||||
*.so |
||||
|
||||
# Sphinx |
||||
_build |
||||
|
||||
# Packages/installer info |
||||
*.egg |
||||
*.egg-info |
||||
dist |
||||
build |
||||
eggs |
||||
parts |
||||
bin |
||||
var |
||||
sdist |
||||
develop-eggs |
||||
.installed.cfg |
||||
|
||||
# Other |
||||
.testrepository |
||||
.tox |
||||
.*.swp |
||||
.coverage |
||||
cover |
||||
AUTHORS |
||||
ChangeLog |
@ -0,0 +1,4 @@
|
||||
[gerrit] |
||||
host=review.openstack.org |
||||
port=29418 |
||||
project=openstack/ironic.git |
@ -0,0 +1,17 @@
|
||||
If you would like to contribute to the development of OpenStack, |
||||
you must follow the steps in the "If you're a developer, start here" |
||||
section of this page: |
||||
|
||||
http://wiki.openstack.org/HowToContribute |
||||
|
||||
Once those steps have been completed, changes to OpenStack |
||||
should be submitted for review via the Gerrit tool, following |
||||
the workflow documented at: |
||||
|
||||
http://wiki.openstack.org/GerritWorkflow |
||||
|
||||
Pull requests submitted through GitHub will be ignored. |
||||
|
||||
Bugs should be filed on Launchpad, not GitHub: |
||||
|
||||
https://bugs.launchpad.net/ironic |
@ -0,0 +1,176 @@
|
||||
|
||||
Apache License |
||||
Version 2.0, January 2004 |
||||
http://www.apache.org/licenses/ |
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
||||
|
||||
1. Definitions. |
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, |
||||
and distribution as defined by Sections 1 through 9 of this document. |
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by |
||||
the copyright owner that is granting the License. |
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all |
||||
other entities that control, are controlled by, or are under common |
||||
control with that entity. For the purposes of this definition, |
||||
"control" means (i) the power, direct or indirect, to cause the |
||||
direction or management of such entity, whether by contract or |
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the |
||||
outstanding shares, or (iii) beneficial ownership of such entity. |
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity |
||||
exercising permissions granted by this License. |
||||
|
||||
"Source" form shall mean the preferred form for making modifications, |
||||
including but not limited to software source code, documentation |
||||
source, and configuration files. |
||||
|
||||
"Object" form shall mean any form resulting from mechanical |
||||
transformation or translation of a Source form, including but |
||||
not limited to compiled object code, generated documentation, |
||||
and conversions to other media types. |
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or |
||||
Object form, made available under the License, as indicated by a |
||||
copyright notice that is included in or attached to the work |
||||
(an example is provided in the Appendix below). |
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object |
||||
form, that is based on (or derived from) the Work and for which the |
||||
editorial revisions, annotations, elaborations, or other modifications |
||||
represent, as a whole, an original work of authorship. For the purposes |
||||
of this License, Derivative Works shall not include works that remain |
||||
separable from, or merely link (or bind by name) to the interfaces of, |
||||
the Work and Derivative Works thereof. |
||||
|
||||
"Contribution" shall mean any work of authorship, including |
||||
the original version of the Work and any modifications or additions |
||||
to that Work or Derivative Works thereof, that is intentionally |
||||
submitted to Licensor for inclusion in the Work by the copyright owner |
||||
or by an individual or Legal Entity authorized to submit on behalf of |
||||
the copyright owner. For the purposes of this definition, "submitted" |
||||
means any form of electronic, verbal, or written communication sent |
||||
to the Licensor or its representatives, including but not limited to |
||||
communication on electronic mailing lists, source code control systems, |
||||
and issue tracking systems that are managed by, or on behalf of, the |
||||
Licensor for the purpose of discussing and improving the Work, but |
||||
excluding communication that is conspicuously marked or otherwise |
||||
designated in writing by the copyright owner as "Not a Contribution." |
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity |
||||
on behalf of whom a Contribution has been received by Licensor and |
||||
subsequently incorporated within the Work. |
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of |
||||
this License, each Contributor hereby grants to You a perpetual, |
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||
copyright license to reproduce, prepare Derivative Works of, |
||||
publicly display, publicly perform, sublicense, and distribute the |
||||
Work and such Derivative Works in Source or Object form. |
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of |
||||
this License, each Contributor hereby grants to You a perpetual, |
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||
(except as stated in this section) patent license to make, have made, |
||||
use, offer to sell, sell, import, and otherwise transfer the Work, |
||||
where such license applies only to those patent claims licensable |
||||
by such Contributor that are necessarily infringed by their |
||||
Contribution(s) alone or by combination of their Contribution(s) |
||||
with the Work to which such Contribution(s) was submitted. If You |
||||
institute patent litigation against any entity (including a |
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work |
||||
or a Contribution incorporated within the Work constitutes direct |
||||
or contributory patent infringement, then any patent licenses |
||||
granted to You under this License for that Work shall terminate |
||||
as of the date such litigation is filed. |
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the |
||||
Work or Derivative Works thereof in any medium, with or without |
||||
modifications, and in Source or Object form, provided that You |
||||
meet the following conditions: |
||||
|
||||
(a) You must give any other recipients of the Work or |
||||
Derivative Works a copy of this License; and |
||||
|
||||
(b) You must cause any modified files to carry prominent notices |
||||
stating that You changed the files; and |
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works |
||||
that You distribute, all copyright, patent, trademark, and |
||||
attribution notices from the Source form of the Work, |
||||
excluding those notices that do not pertain to any part of |
||||
the Derivative Works; and |
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its |
||||
distribution, then any Derivative Works that You distribute must |
||||
include a readable copy of the attribution notices contained |
||||
within such NOTICE file, excluding those notices that do not |
||||
pertain to any part of the Derivative Works, in at least one |
||||
of the following places: within a NOTICE text file distributed |
||||
as part of the Derivative Works; within the Source form or |
||||
documentation, if provided along with the Derivative Works; or, |
||||
within a display generated by the Derivative Works, if and |
||||
wherever such third-party notices normally appear. The contents |
||||
of the NOTICE file are for informational purposes only and |
||||
do not modify the License. You may add Your own attribution |
||||
notices within Derivative Works that You distribute, alongside |
||||
or as an addendum to the NOTICE text from the Work, provided |
||||
that such additional attribution notices cannot be construed |
||||
as modifying the License. |
||||
|
||||
You may add Your own copyright statement to Your modifications and |
||||
may provide additional or different license terms and conditions |
||||
for use, reproduction, or distribution of Your modifications, or |
||||
for any such Derivative Works as a whole, provided Your use, |
||||
reproduction, and distribution of the Work otherwise complies with |
||||
the conditions stated in this License. |
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, |
||||
any Contribution intentionally submitted for inclusion in the Work |
||||
by You to the Licensor shall be under the terms and conditions of |
||||
this License, without any additional terms or conditions. |
||||
Notwithstanding the above, nothing herein shall supersede or modify |
||||
the terms of any separate license agreement you may have executed |
||||
with Licensor regarding such Contributions. |
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade |
||||
names, trademarks, service marks, or product names of the Licensor, |
||||
except as required for reasonable and customary use in describing the |
||||
origin of the Work and reproducing the content of the NOTICE file. |
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or |
||||
agreed to in writing, Licensor provides the Work (and each |
||||
Contributor provides its Contributions) on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
||||
implied, including, without limitation, any warranties or conditions |
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |
||||
PARTICULAR PURPOSE. You are solely responsible for determining the |
||||
appropriateness of using or redistributing the Work and assume any |
||||
risks associated with Your exercise of permissions under this License. |
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, |
||||
whether in tort (including negligence), contract, or otherwise, |
||||
unless required by applicable law (such as deliberate and grossly |
||||
negligent acts) or agreed to in writing, shall any Contributor be |
||||
liable to You for damages, including any direct, indirect, special, |
||||
incidental, or consequential damages of any character arising as a |
||||
result of this License or out of the use or inability to use the |
||||
Work (including but not limited to damages for loss of goodwill, |
||||
work stoppage, computer failure or malfunction, or any and all |
||||
other commercial damages or losses), even if such Contributor |
||||
has been advised of the possibility of such damages. |
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing |
||||
the Work or Derivative Works thereof, You may choose to offer, |
||||
and charge a fee for, acceptance of support, warranty, indemnity, |
||||
or other liability obligations and/or rights consistent with this |
||||
License. However, in accepting such obligations, You may act only |
||||
on Your own behalf and on Your sole responsibility, not on behalf |
||||
of any other Contributor, and only if You agree to indemnify, |
||||
defend, and hold each Contributor harmless for any liability |
||||
incurred by, or claims asserted against, such Contributor by reason |
||||
of your accepting any such warranty or additional liability. |
||||
|
@ -0,0 +1,6 @@
|
||||
include AUTHORS |
||||
include ChangeLog |
||||
exclude .gitignore |
||||
exclude .gitreview |
||||
|
||||
global-exclude *.pyc |
@ -0,0 +1,4 @@
|
||||
Ironic |
||||
====== |
||||
|
||||
Provision Bare Metal machines with Nova. |
@ -0,0 +1,270 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4 |
||||
|
||||
# Copyright 2010 United States Government as represented by the |
||||
# Administrator of the National Aeronautics and Space Administration. |
||||
# All Rights Reserved. |
||||
# |
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may |
||||
# not use this file except in compliance with the License. You may obtain |
||||
# a copy of the License at |
||||
# |
||||
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
# |
||||
# Unless required by applicable law or agreed to in writing, software |
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
||||
# License for the specific language governing permissions and limitations |
||||
# under the License. |
||||
|
||||
"""Base classes for our unit tests. |
||||
|
||||
Allows overriding of flags for use of fakes, and some black magic for |
||||
inline callbacks. |
||||
|
||||
""" |
||||
|
||||
import eventlet |
||||
eventlet.monkey_patch(os=False) |
||||
|
||||
import os |
||||
import shutil |
||||
import sys |
||||
import uuid |
||||
|
||||
import fixtures |
||||
import mox |
||||
from oslo.config import cfg |
||||
import stubout |
||||
import testtools |
||||
|
||||
from nova import context |
||||
from nova import db |
||||
from nova.db import migration |
||||
from nova.network import manager as network_manager |
||||
from nova.openstack.common.db.sqlalchemy import session |
||||
from nova.openstack.common import log as logging |
||||
from nova.openstack.common import timeutils |
||||
from nova import paths |
||||
from nova import service |
||||
from nova.tests import conf_fixture |
||||
from nova.tests import policy_fixture |
||||
|
||||
|
||||
test_opts = [ |
||||
cfg.StrOpt('sqlite_clean_db', |
||||
default='clean.sqlite', |
||||
help='File name of clean sqlite db'), |
||||
] |
||||
|
||||
CONF = cfg.CONF |
||||
CONF.register_opts(test_opts) |
||||
CONF.import_opt('sql_connection', |
||||
'nova.openstack.common.db.sqlalchemy.session') |
||||
CONF.import_opt('sqlite_db', 'nova.openstack.common.db.sqlalchemy.session') |
||||
CONF.set_override('use_stderr', False) |
||||
|
||||
logging.setup('nova') |
||||
|
||||
_DB_CACHE = None |
||||
|
||||
|
||||
class Database(fixtures.Fixture): |
||||
|
||||
def __init__(self, db_session, db_migrate, sql_connection, |
||||
sqlite_db, sqlite_clean_db): |
||||
self.sql_connection = sql_connection |
||||
self.sqlite_db = sqlite_db |
||||
self.sqlite_clean_db = sqlite_clean_db |
||||
|
||||
self.engine = db_session.get_engine() |
||||
self.engine.dispose() |
||||
conn = self.engine.connect() |
||||
if sql_connection == "sqlite://": |
||||
if db_migrate.db_version() > db_migrate.INIT_VERSION: |
||||
return |
||||
else: |
||||
testdb = paths.state_path_rel(sqlite_db) |
||||
if os.path.exists(testdb): |
||||
return |
||||
db_migrate.db_sync() |
||||
self.post_migrations() |
||||
if sql_connection == "sqlite://": |
||||
conn = self.engine.connect() |
||||
self._DB = "".join(line for line in conn.connection.iterdump()) |
||||
self.engine.dispose() |
||||
else: |
||||
cleandb = paths.state_path_rel(sqlite_clean_db) |
||||
shutil.copyfile(testdb, cleandb) |
||||
|
||||
def setUp(self): |
||||
super(Database, self).setUp() |
||||
|
||||
if self.sql_connection == "sqlite://": |
||||
conn = self.engine.connect() |
||||
conn.connection.executescript(self._DB) |
||||
self.addCleanup(self.engine.dispose) |
||||
else: |
||||
shutil.copyfile(paths.state_path_rel(self.sqlite_clean_db), |
||||
paths.state_path_rel(self.sqlite_db)) |
||||
|
||||
def post_migrations(self): |
||||
"""Any addition steps that are needed outside of the migrations.""" |
||||
ctxt = context.get_admin_context() |
||||
network = network_manager.VlanManager() |
||||
bridge_interface = CONF.flat_interface or CONF.vlan_interface |
||||
network.create_networks(ctxt, |
||||
label='test', |
||||
cidr=CONF.fixed_range, |
||||
multi_host=CONF.multi_host, |
||||
num_networks=CONF.num_networks, |
||||
network_size=CONF.network_size, |
||||
cidr_v6=CONF.fixed_range_v6, |
||||
gateway=CONF.gateway, |
||||
gateway_v6=CONF.gateway_v6, |
||||
bridge=CONF.flat_network_bridge, |
||||
bridge_interface=bridge_interface, |
||||
vpn_start=CONF.vpn_start, |
||||
vlan_start=CONF.vlan_start, |
||||
dns1=CONF.flat_network_dns) |
||||
for net in db.network_get_all(ctxt): |
||||
network.set_network_host(ctxt, net) |
||||
|
||||
|
||||
class ReplaceModule(fixtures.Fixture): |
||||
"""Replace a module with a fake module.""" |
||||
|
||||
def __init__(self, name, new_value): |
||||
self.name = name |
||||
self.new_value = new_value |
||||
|
||||
def _restore(self, old_value): |
||||
sys.modules[self.name] = old_value |
||||
|
||||
def setUp(self): |
||||
super(ReplaceModule, self).setUp() |
||||
old_value = sys.modules.get(self.name) |
||||
sys.modules[self.name] = self.new_value |
||||
self.addCleanup(self._restore, old_value) |
||||
|
||||
|
||||
class ServiceFixture(fixtures.Fixture): |
||||
"""Run a service as a test fixture.""" |
||||
|
||||
def __init__(self, name, host=None, **kwargs): |
||||
name = name |
||||
host = host and host or uuid.uuid4().hex |
||||
kwargs.setdefault('host', host) |
||||
kwargs.setdefault('binary', 'nova-%s' % name) |
||||
self.kwargs = kwargs |
||||
|
||||
def setUp(self): |
||||
super(ServiceFixture, self).setUp() |
||||
self.service = service.Service.create(**self.kwargs) |
||||
self.service.start() |
||||
self.addCleanup(self.service.kill) |
||||
|
||||
|
||||
class MoxStubout(fixtures.Fixture): |
||||
"""Deal with code around mox and stubout as a fixture.""" |
||||
|
||||
def setUp(self): |
||||
super(MoxStubout, self).setUp() |
||||
# emulate some of the mox stuff, we can't use the metaclass |
||||
# because it screws with our generators |
||||
self.mox = mox.Mox() |
||||
self.stubs = stubout.StubOutForTesting() |
||||
self.addCleanup(self.mox.UnsetStubs) |
||||
self.addCleanup(self.stubs.UnsetAll) |
||||
self.addCleanup(self.stubs.SmartUnsetAll) |
||||
self.addCleanup(self.mox.VerifyAll) |
||||
|
||||
|
||||
class TestingException(Exception): |
||||
pass |
||||
|
||||
|
||||
class TestCase(testtools.TestCase): |
||||
"""Test case base class for all unit tests.""" |
||||
|
||||
def setUp(self): |
||||
"""Run before each test method to initialize test environment.""" |
||||
super(TestCase, self).setUp() |
||||
test_timeout = os.environ.get('OS_TEST_TIMEOUT', 0) |
||||
try: |
||||
test_timeout = int(test_timeout) |
||||
except ValueError: |
||||
# If timeout value is invalid do not set a timeout. |
||||
test_timeout = 0 |
||||
if test_timeout > 0: |
||||
self.useFixture(fixtures.Timeout(test_timeout, gentle=True)) |
||||
self.useFixture(fixtures.NestedTempfile()) |
||||
self.useFixture(fixtures.TempHomeDir()) |
||||
|
||||
if (os.environ.get('OS_STDOUT_CAPTURE') == 'True' or |
||||
os.environ.get('OS_STDOUT_CAPTURE') == '1'): |
||||
stdout = self.useFixture(fixtures.StringStream('stdout')).stream |
||||
self.useFixture(fixtures.MonkeyPatch('sys.stdout', stdout)) |
||||
if (os.environ.get('OS_STDERR_CAPTURE') == 'True' or |
||||
os.environ.get('OS_STDERR_CAPTURE') == '1'): |
||||
stderr = self.useFixture(fixtures.StringStream('stderr')).stream |
||||
self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr)) |
||||
|
||||
self.log_fixture = self.useFixture(fixtures.FakeLogger()) |
||||
self.useFixture(conf_fixture.ConfFixture(CONF)) |
||||
|
||||
global _DB_CACHE |
||||
if not _DB_CACHE: |
||||
_DB_CACHE = Database(session, migration, |
||||
sql_connection=CONF.sql_connection, |
||||
sqlite_db=CONF.sqlite_db, |
||||
sqlite_clean_db=CONF.sqlite_clean_db) |
||||
self.useFixture(_DB_CACHE) |
||||
|
||||
mox_fixture = self.useFixture(MoxStubout()) |
||||
self.mox = mox_fixture.mox |
||||
self.stubs = mox_fixture.stubs |
||||
self.addCleanup(self._clear_attrs) |
||||
self.useFixture(fixtures.EnvironmentVariable('http_proxy')) |
||||
self.policy = self.useFixture(policy_fixture.PolicyFixture()) |
||||
CONF.set_override('fatal_exception_format_errors', True) |
||||
|
||||
def _clear_attrs(self): |
||||
# Delete attributes that don't start with _ so they don't pin |
||||
# memory around unnecessarily for the duration of the test |
||||
# suite |
||||
for key in [k for k in self.__dict__.keys() if k[0] != '_']: |
||||
del self.__dict__[key] |
||||
|
||||
def flags(self, **kw): |
||||
"""Override flag variables for a test.""" |
||||
group = kw.pop('group', None) |
||||
for k, v in kw.iteritems(): |
||||
CONF.set_override(k, v, group) |
||||
|
||||
def start_service(self, name, host=None, **kwargs): |
||||
svc = self.useFixture(ServiceFixture(name, host, **kwargs)) |
||||
return svc.service |
||||
|
||||
|
||||
class APICoverage(object): |
||||
|
||||
cover_api = None |
||||
|
||||
def test_api_methods(self): |
||||
self.assertTrue(self.cover_api is not None) |
||||
api_methods = [x for x in dir(self.cover_api) |
||||
if not x.startswith('_')] |
||||
test_methods = [x[5:] for x in dir(self) |
||||
if x.startswith('test_')] |
||||
self.assertThat( |
||||
test_methods, |
||||
testtools.matchers.ContainsAll(api_methods)) |
||||
|
||||
|
||||
class TimeOverride(fixtures.Fixture): |
||||
"""Fixture to start and remove time override.""" |
||||
|
||||
def setUp(self): |
||||
super(TimeOverride, self).setUp() |
||||
timeutils.set_time_override() |
||||
self.addCleanup(timeutils.clear_time_override) |
@ -0,0 +1,31 @@
|
||||
d2to1>=0.2.10,<0.3 |
||||
pbr>=0.5,<0.6 |
||||
SQLAlchemy>=0.7.8,<0.7.99 |
||||
Cheetah>=2.4.4 |
||||
amqplib>=0.6.1 |
||||
anyjson>=0.2.4 |
||||
argparse |
||||
boto |
||||
eventlet>=0.9.17 |
||||
kombu>=1.0.4 |
||||
lxml>=2.3 |
||||
routes>=1.12.3 |
||||
WebOb==1.2.3 |
||||
greenlet>=0.3.1 |
||||
PasteDeploy>=1.5.0 |
||||
paste |
||||
sqlalchemy-migrate>=0.7.2 |
||||
netaddr>=0.7.6 |
||||
suds>=0.4 |
||||
paramiko |
||||
pyasn1 |
||||
Babel>=0.9.6 |
||||
iso8601>=0.1.4 |
||||
httplib2 |
||||
python-cinderclient>=1.0.1 |
||||
python-quantumclient>=2.2.0,<3.0.0 |
||||
python-glanceclient>=0.5.0,<2 |
||||
python-keystoneclient>=0.2.0 |
||||
stevedore>=0.7 |
||||
websockify<0.4 |
||||
oslo.config>=1.1.0 |
@ -0,0 +1,56 @@
|
||||
[metadata] |
||||
name = ironic |
||||
version = 2013.2 |
||||
summary = OpenStack Bare Metal Provisioning |
||||
description-file = |
||||
README.rst |
||||
author = OpenStack |
||||
author-email = openstack-dev@lists.openstack.org |
||||
home-page = http://www.openstack.org/ |
||||
classifier = |
||||
Environment :: OpenStack |
||||
Intended Audience :: Information Technology |
||||
Intended Audience :: System Administrators |
||||
License :: OSI Approved :: Apache Software License |
||||
Operating System :: POSIX :: Linux |
||||
Programming Language :: Python |
||||
Programming Language :: Python :: 2 |
||||
Programming Language :: Python :: 2.7 |
||||
Programming Language :: Python :: 2.6 |
||||
|
||||
[global] |
||||
setup-hooks = |
||||
pbr.hooks.setup_hook |
||||
|
||||
[files] |
||||
packages = |
||||
ironic |
||||
|
||||
[entry_points] |
||||
console_scripts = |
||||
nova-baremetal-deploy-helper = nova.cmd.baremetal_deploy_helper:main |
||||
nova-baremetal-manage = nova.cmd.baremetal_manage:main |
||||
|
||||
[build_sphinx] |
||||
all_files = 1 |
||||
build-dir = doc/build |
||||
source-dir = doc/source |
||||
|
||||
[egg_info] |
||||
tag_build = |
||||
tag_date = 0 |
||||
tag_svn_revision = 0 |
||||
|
||||
[compile_catalog] |
||||
directory = ironic/locale |
||||
domain = ironic |
||||
|
||||
[update_catalog] |
||||
domain = ironic |
||||
output_dir = ironic/locale |
||||
input_file = ironic/locale/ironic.pot |
||||
|
||||
[extract_messages] |
||||
keywords = _ gettext ngettext l_ lazy_gettext |
||||
mapping_file = babel.cfg |
||||
output_file = ironic/locale/nova.pot |
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env python |
||||
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. |
||||
# |
||||
# Licensed under the Apache License, Version 2.0 (the "License"); |
||||
# you may not use this file except in compliance with the License. |
||||
# You may obtain a copy of the License at |
||||
# |
||||
# 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. |
||||
|
||||
import setuptools |
||||
|
||||
setuptools.setup( |
||||
setup_requires=['d2to1>=0.2.10,<0.3', 'pbr>=0.5,<0.6'], |
||||
d2to1=True) |
@ -0,0 +1,18 @@
|
||||
# Packages needed for dev testing |
||||
distribute>=0.6.24 |
||||
|
||||
# Install bounded pep8/pyflakes first, then let flake8 install |
||||
pep8==1.4.5 |
||||
pyflakes==0.7.2 |
||||
flake8==2.0 |
||||
hacking>=0.5.3,<0.6 |
||||
|
||||
coverage>=3.6 |
||||
discover |
||||
fixtures>=0.3.12 |
||||
mox==0.5.3 |
||||
MySQL-python |
||||
python-subunit |
||||
sphinx>=1.1.2 |
||||
testrepository>=0.0.13 |
||||
testtools>=0.9.27 |
@ -0,0 +1,216 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4 |
||||
|
||||
# Copyright 2013 OpenStack Foundation |
||||
# Copyright 2013 IBM Corp. |
||||
# |
||||
# 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. |
||||
|
||||
"""Provides methods needed by installation script for OpenStack development |
||||
virtual environments. |
||||
|
||||
Synced in from openstack-common |
||||
""" |
||||
|
||||
import argparse |
||||
import os |
||||
import subprocess |
||||
import sys |
||||
|
||||
|
||||
class InstallVenv(object): |
||||
|
||||
def __init__(self, root, venv, pip_requires, test_requires, py_version, |
||||
project): |
||||
self.root = root |
||||
self.venv = venv |
||||
self.pip_requires = pip_requires |
||||
self.test_requires = test_requires |
||||
self.py_version = py_version |
||||
self.project = project |
||||
|
||||
def die(self, message, *args): |
||||
print >> sys.stderr, message % args |
||||
sys.exit(1) |
||||
|
||||
def check_python_version(self): |
||||
if sys.version_info < (2, 6): |
||||
self.die("Need Python Version >= 2.6") |
||||
|
||||
def run_command_with_code(self, cmd, redirect_output=True, |
||||
check_exit_code=True): |
||||
"""Runs a command in an out-of-process shell. |
||||
|
||||
Returns the output of that command. Working directory is self.root. |
||||
""" |
||||
if redirect_output: |
||||
stdout = subprocess.PIPE |
||||
else: |
||||
stdout = None |
||||
|
||||
proc = subprocess.Popen(cmd, cwd=self.root, stdout=stdout) |
||||
output = proc.communicate()[0] |
||||
if check_exit_code and proc.returncode != 0: |
||||
self.die('Command "%s" failed.\n%s', ' '.join(cmd), output) |
||||
return (output, proc.returncode) |
||||
|
||||
def run_command(self, cmd, redirect_output=True, check_exit_code=True): |
||||
return self.run_command_with_code(cmd, redirect_output, |
||||
check_exit_code)[0] |
||||
|
||||
def get_distro(self): |
||||
if (os.path.exists('/etc/fedora-release') or |
||||
os.path.exists('/etc/redhat-release')): |
||||
return Fedora(self.root, self.venv, self.pip_requires, |
||||
self.test_requires, self.py_version, self.project) |
||||
else: |
||||
return Distro(self.root, self.venv, self.pip_requires, |
||||
self.test_requires, self.py_version, self.project) |
||||
|
||||
def check_dependencies(self): |
||||
self.get_distro().install_virtualenv() |
||||
|
||||
def create_virtualenv(self, no_site_packages=True): |
||||
"""Creates the virtual environment and installs PIP. |
||||
|
||||
Creates the virtual environment and installs PIP only into the |
||||
virtual environment. |
||||
""" |
||||
if not os.path.isdir(self.venv): |
||||
print 'Creating venv...', |
||||
if no_site_packages: |
||||
self.run_command(['virtualenv', '-q', '--no-site-packages', |
||||
self.venv]) |
||||
else: |
||||
self.run_command(['virtualenv', '-q', self.venv]) |
||||
print 'done.' |
||||
print 'Installing pip in venv...', |
||||
if not self.run_command(['tools/with_venv.sh', 'easy_install', |
||||
'pip>1.0']).strip(): |
||||
self.die("Failed to install pip.") |
||||
print 'done.' |
||||
else: |
||||
print "venv already exists..." |
||||
pass |
||||
|
||||
def pip_install(self, *args): |
||||
self.run_command(['tools/with_venv.sh', |
||||
'pip', 'install', '--upgrade'] + list(args), |
||||
redirect_output=False) |
||||
|
||||
def install_dependencies(self): |
||||
print 'Installing dependencies with pip (this can take a while)...' |
||||
|
||||
# First things first, make sure our venv has the latest pip and |
||||
# distribute. |
||||
# NOTE: we keep pip at version 1.1 since the most recent version causes |
||||
# the .venv creation to fail. See: |
||||
# https://bugs.launchpad.net/nova/+bug/1047120 |
||||
self.pip_install('pip==1.1') |
||||
self.pip_install('distribute') |
||||
|
||||
# Install greenlet by hand - just listing it in the requires file does |
||||
# not |
||||
# get it installed in the right order |
||||
self.pip_install('greenlet') |
||||
|
||||
self.pip_install('-r', self.pip_requires) |
||||
self.pip_install('-r', self.test_requires) |
||||
|
||||
def post_process(self): |
||||
self.get_distro().post_process() |
||||
|
||||
def parse_args(self, argv): |
||||
"""Parses command-line arguments.""" |
||||
parser = argparse.ArgumentParser() |
||||
parser.add_argument('-n', '--no-site-packages', |
||||
action='store_true', |
||||
help="Do not inherit packages from global Python " |
||||
"install") |
||||
return parser.parse_args(argv[1:]) |
||||
|
||||
|
||||
class Distro(InstallVenv): |
||||
|
||||
def check_cmd(self, cmd): |
||||
return bool(self.run_command(['which', cmd], |
||||
check_exit_code=False).strip()) |
||||
|
||||
def install_virtualenv(self): |
||||
if self.check_cmd('virtualenv'): |
||||
return |
||||
|
||||
if self.check_cmd('easy_install'): |
||||
print 'Installing virtualenv via easy_install...', |
||||
if self.run_command(['easy_install', 'virtualenv']): |
||||
print 'Succeeded' |
||||
return |
||||
else: |
||||
print 'Failed' |
||||
|
||||
self.die('ERROR: virtualenv not found.\n\n%s development' |
||||
' requires virtualenv, please install it using your' |
||||
' favorite package management tool' % self.project) |
||||
|
||||
def post_process(self): |
||||
"""Any distribution-specific post-processing gets done here. |
||||
|
||||
In particular, this is useful for applying patches to code inside |
||||
the venv. |
||||
""" |
||||
pass |
||||
|
||||
|
||||
class Fedora(Distro): |
||||
"""This covers all Fedora-based distributions. |
||||
|
||||
Includes: Fedora, RHEL, CentOS, Scientific Linux |
||||
""" |
||||
|
||||
def check_pkg(self, pkg): |
||||
return self.run_command_with_code(['rpm', '-q', pkg], |
||||
check_exit_code=False)[1] == 0 |
||||
|
||||
def apply_patch(self, originalfile, patchfile): |
||||
self.run_command(['patch', '-N', originalfile, patchfile], |
||||
check_exit_code=False) |
||||
|
||||
def install_virtualenv(self): |
||||
if self.check_cmd('virtualenv'): |
||||
return |
||||
|
||||
if not self.check_pkg('python-virtualenv'): |
||||
self.die("Please install 'python-virtualenv'.") |
||||
|
||||
super(Fedora, self).install_virtualenv() |
||||
|
||||
def post_process(self): |
||||
"""Workaround for a bug in eventlet. |
||||
|
||||
This currently affects RHEL6.1, but the fix can safely be |
||||
applied to all RHEL and Fedora distributions. |
||||
|
||||
This can be removed when the fix is applied upstream. |
||||
|
||||
Nova: https://bugs.launchpad.net/nova/+bug/884915 |
||||
Upstream: https://bitbucket.org/which_linden/eventlet/issue/89 |
||||
""" |
||||
|
||||
# Install "patch" program if it's not there |
||||
if not self.check_pkg('patch'): |
||||
self.die("Please install 'patch'.") |
||||
|
||||
# Apply the eventlet patch |
||||
self.apply_patch(os.path.join(self.venv, 'lib', self.py_version, |
||||
'site-packages', |
||||
'eventlet/green/subprocess.py'), |
||||
'contrib/redhat-eventlet.patch') |
@ -0,0 +1,38 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4 |
||||
|
||||
# Copyright 2013 Red Hat, Inc. |
||||
# |
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may |
||||
# not use this file except in compliance with the License. You may obtain |
||||
# a copy of the License at |
||||
# |
||||
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
# |
||||
# Unless required by applicable law or agreed to in writing, software |
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
||||
# License for the specific language governing permissions and limitations |
||||
# under the License. |
||||
|
||||
import os |
||||
import sys |
||||
|
||||
import tools.install_venv_common as install_venv |
||||
|
||||
|
||||
def main(argv): |
||||
root = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) |
||||
|
||||
venv = os.environ['VIRTUAL_ENV'] |
||||
|
||||
pip_requires = os.path.join(root, 'requirements.txt') |
||||
test_requires = os.path.join(root, 'test-requirements.txt') |
||||
py_version = "python%s.%s" % (sys.version_info[0], sys.version_info[1]) |
||||
project = 'Nova' |
||||
install = install_venv.InstallVenv(root, venv, pip_requires, test_requires, |
||||
py_version, project) |
||||
#NOTE(dprince): For Tox we only run post_process (which patches files, etc) |
||||
install.post_process() |
||||
|
||||
if __name__ == '__main__': |
||||
main(sys.argv) |
@ -0,0 +1,34 @@
|
||||
[tox] |
||||
envlist = py26,py27,pep8 |
||||
|
||||
[testenv] |
||||
setenv = VIRTUAL_ENV={envdir} |
||||
LANG=en_US.UTF-8 |
||||
LANGUAGE=en_US:en |
||||
LC_ALL=C |
||||
deps = -r{toxinidir}/requirements.txt |
||||
-r{toxinidir}/test-requirements.txt |
||||
commands = |
||||
python tools/patch_tox_venv.py |
||||
python setup.py testr --slowest --testr-args='{posargs}' |
||||
|
||||
[tox:jenkins] |
||||
downloadcache = ~/cache/pip |
||||
|
||||
[testenv:pep8] |
||||
commands = |
||||
flake8 |
||||
|
||||
[testenv:cover] |
||||
setenv = VIRTUAL_ENV={envdir} |
||||
commands = |
||||
python tools/patch_tox_venv.py |
||||
python setup.py testr --coverage {posargs} |
||||
|
||||
[testenv:venv] |
||||
commands = {posargs} |
||||
|
||||
[flake8] |
||||
ignore = E12,E711,E721,E712,H302,H303,H403,H404,F |
||||
builtins = _ |
||||
exclude = .venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build |
Loading…
Reference in new issue