Initial fork out of Nova.

This commit is contained in:
Jenkins 2012-05-03 10:48:26 -07:00 committed by Monty Taylor
commit c53d8e343e
468 changed files with 247534 additions and 0 deletions

24
.gitignore vendored Normal file
View File

@ -0,0 +1,24 @@
*.pyc
*.DS_Store
local_settings.py
CA/
keeper
instances
keys
build/*
build-stamp
cinder.egg-info
nova.egg-info
.cinder-venv
.nova-venv
.venv
.tox
*.sqlite
*.log
*.mo
tools/conf/cinder.conf*
tools/conf/nova.conf*
cover/*
dist/*
.coverage
covhtml

4
.gitreview Normal file
View File

@ -0,0 +1,4 @@
[gerrit]
host=review.openstack.org
port=29418
project=openstack/cinder.git

81
.mailmap Normal file
View File

@ -0,0 +1,81 @@
# Format is:
# <preferred e-mail> <other e-mail 1>
# <preferred e-mail> <other e-mail 2>
<aaron.lee@rackspace.com> <wwkeyboard@gmail.com>
<anotherjesse@gmail.com> <jesse@dancelamb>
<anotherjesse@gmail.com> <jesse@gigantor.local>
<anotherjesse@gmail.com> <jesse@ubuntu>
<anotherjesse@gmail.com> <jesse@aire.local>
<ant@openstack.org> <amesserl@rackspace.com>
<Armando.Migliaccio@eu.citrix.com> <armando.migliaccio@citrix.com>
<brian.lamar@rackspace.com> <brian.lamar@gmail.com>
<brian.waldon@rackspace.com> <bcwaldon@gmail.com>
<bschott@isi.edu> <bfschott@gmail.com>
<cbehrens@codestud.com> <chris.behrens@rackspace.com>
<chiradeep@cloud.com> <chiradeep@chiradeep-lt2>
<code@term.ie> <github@anarkystic.com>
<code@term.ie> <termie@preciousroy.local>
<corywright@gmail.com> <cory.wright@rackspace.com>
<dan@nicira.com> <danwent@dan-xs3-cs>
<dan@nicira.com> <danwent@gmail.com>
<dtroyer@gmail.com> <dt-github@xr7.org>
<Dave.Walker@canonical.com> <DaveWalker@ubuntu.com>
<derekh@redhat.com> <higginsd@gmail.com>
<devin.carlen@gmail.com> <devcamcar@illian.local>
<doug.hellmann@dreamhost.com> <doug.hellmann@gmail.com>
<dprince@redhat.com> <dan.prince@rackspace.com>
<edouard1.thuleau@orange.com> <thuleau@gmail.com>
<ewan.mellor@citrix.com> <emellor@silver>
<ghe@debian.org> <ghe.rivero@gmail.com>
<itoumsn@nttdata.co.jp> <itoumsn@shayol>
<jake@ansolabs.com> <jake@markupisart.com>
<jake@ansolabs.com> <admin@jakedahn.com>
<jaypipes@gmail.com> <jpipes@serialcoder>
<jeblair@hp.com> <james.blair@rackspace.com>
<jeblair@hp.com> <corvus@inaugust.com>
<jmckenty@gmail.com> <jmckenty@joshua-mckentys-macbook-pro.local>
<jmckenty@gmail.com> <jmckenty@yyj-dhcp171.corp.flock.com>
<jmckenty@gmail.com> <joshua.mckenty@nasa.gov>
<johannes.erdfelt@rackspace.com> <johannes@compute3.221.st>
<john.griffith@solidfire.com> <john.griffith8@gmail.com>
<josh@jk0.org> <josh.kearney@rackspace.com>
<justin@fathomdb.com> <justinsb@justinsb-desktop>
<justin@fathomdb.com> <superstack@superstack.org>
<lorin@nimbisservices.com> <lorin@isi.edu>
<masumotok@nttdata.co.jp> Masumoto<masumotok@nttdata.co.jp>
<masumotok@nttdata.co.jp> <root@openstack2-api>
<matt.dietz@rackspace.com> <matthewdietz@Matthew-Dietzs-MacBook-Pro.local>
<matt.dietz@rackspace.com> <mdietz@openstack>
<mikal@stillhq.com> <michael.still@canonical.com>
<mordred@inaugust.com> <mordred@hudson>
<naveedm9@gmail.com> <naveed.massjouni@rackspace.com>
<rnirmal@gmail.com> <nirmal.ranganathan@rackspace.com>
<rnirmal@gmail.com> <nirmal.ranganathan@rackspace.coom>
<paul@openstack.org> <paul.voccio@rackspace.com>
<paul@openstack.org> <pvoccio@castor.local>
<paul@openstack.org> <paul@substation9.com>
<rconradharris@gmail.com> <rick.harris@rackspace.com>
<rlane@wikimedia.org> <laner@controller>
<sandy.walsh@rackspace.com> <sandy@sandywalsh.com>
<sleepsonthefloor@gmail.com> <root@tonbuntu>
<soren.hansen@rackspace.com> <soren@linux2go.dk>
<throughnothing@gmail.com> <will.wolf@rackspace.com>
<tim.simpson@rackspace.com> <tim.simpson4@gmail.com>
<todd@ansolabs.com> <todd@lapex>
<todd@ansolabs.com> <todd@rubidine.com>
<todd@ansolabs.com> <xtoddx@gmail.com>
<trey.morris@rackspace.com> <treyemorris@gmail.com>
<tushar.vitthal.patil@gmail.com> <tpatil@vertex.co.in>
<ueno.nachi@lab.ntt.co.jp> <nati.ueno@gmail.com>
<ueno.nachi@lab.ntt.co.jp> <nova@u4>
<ueno.nachi@lab.ntt.co.jp> <openstack@lab.ntt.co.jp>
<vishvananda@gmail.com> <root@mirror.nasanebula.net>
<vishvananda@gmail.com> <root@ubuntu>
<vishvananda@gmail.com> <vishvananda@yahoo.com>
<ilyaalekseyev@acm.org> <ialekseev@griddynamics.com>
<ilyaalekseyev@acm.org> <ilya@oscloud.ru>
<reldan@oscloud.ru> <enugaev@griddynamics.com>
<kshileev@gmail.com> <kshileev@griddynamics.com>
<nsokolov@griddynamics.com> <nsokolov@griddynamics.net>
<troy.toman@rackspace.com> <ttcl@mac.com>
<zulcss@ubuntu.com> <chuck.short@canonical.com>

211
Authors Normal file
View File

@ -0,0 +1,211 @@
Aaron Lee <aaron.lee@rackspace.com>
Adam Gandelman <adamg@canonical.com>
Adam Johnson <adjohn@gmail.com>
Adrian Smith <adrian_f_smith@dell.com>
Ahmad Hassan <ahmad.hassan@hp.com>
Alex Meade <alex.meade@rackspace.com>
Alexander Sakhnov <asakhnov@mirantis.com>
Alexander Kovalev <akovalev@mirantis.com>
Alvaro Lopez Garcia <aloga@ifca.unican.es>
Andrew Bogott <abogott@wikimedia.org>
Andrew Clay Shafer <acs@parvuscaptus.com>
Andrey Brindeyev <abrindeyev@griddynamics.com>
Andy Smith <code@term.ie>
Andy Southgate <andy.southgate@citrix.com>
Anne Gentle <anne@openstack.org>
Ante Karamatić <ivoks@ubuntu.com>
Anthony Young <sleepsonthefloor@gmail.com>
Antony Messerli <ant@openstack.org>
Armando Migliaccio <Armando.Migliaccio@eu.citrix.com>
Arvind Somya <asomya@cisco.com>
Asbjørn Sannes <asbjorn.sannes@interhost.no>
Ben McGraw <ben@pistoncloud.com>
Ben Swartzlander <bswartz@netapp.com>
Bilal Akhtar <bilalakhtar@ubuntu.com>
Brad Hall <brad@nicira.com>
Brad McConnell <bmcconne@rackspace.com>
Brendan Maguire <B_Maguire@Dell.com>
Brian Elliott <brian.elliott@rackspace.com>
Brian Lamar <brian.lamar@rackspace.com>
Brian Schott <bschott@isi.edu>
Brian Waldon <brian.waldon@rackspace.com>
Chiradeep Vittal <chiradeep@cloud.com>
Chmouel Boudjnah <chmouel@chmouel.com>
Chris Behrens <cbehrens@codestud.com>
Christian Berendt <berendt@b1-systems.de>
Chris Fattarsi <chris.fattarsi@pistoncloud.com>
Christopher MacGown <chris@pistoncloud.com>
Chuck Short <zulcss@ubuntu.com>
Cole Robinson <crobinso@redhat.com>
Cor Cornelisse <cor@hyves.nl>
Cory Wright <corywright@gmail.com>
Dan Prince <dprince@redhat.com>
Dan Wendlandt <dan@nicira.com>
Daniel P. Berrange <berrange@redhat.com>
Dave Lapsley <dlapsley@nicira.com>
Dave Walker <Dave.Walker@canonical.com>
David Pravec <David.Pravec@danix.org>
David Subiros <david.perez5@hp.com>
Dean Troyer <dtroyer@gmail.com>
Deepak Garg <deepak.garg@citrix.com>
Derek Higgins <derekh@redhat.com>
Devdeep Singh <devdeep.singh@citrix.com>
Devendra Modium <dmodium@isi.edu>
Devin Carlen <devin.carlen@gmail.com>
Dina Belova <dbelova@mirantis.com>
Donal Lafferty <donal.lafferty@citrix.com>
Dong-In David Kang <dkang@isi.edu>
Doug Hellmann <doug.hellmann@dreamhost.com>
Duncan McGreggor <duncan@dreamhost.com>
Ed Leafe <ed@leafe.com>
Edouard Thuleau <edouard1.thuleau@orange.com>
Eldar Nugaev <reldan@oscloud.ru>
Eoghan Glynn <eglynn@redhat.com>
Eric Day <eday@oddments.org>
Eric Windisch <eric@cloudscaling.com>
Evan Callicoat <diopter@gmail.com>
Ewan Mellor <ewan.mellor@citrix.com>
François Charlier <francois.charlier@ecindernce.com>
Gabe Westmaas <gabe.westmaas@rackspace.com>
Gabriel Hurley <gabriel@strikeawe.com>
Gary Kotton <garyk@radware.com>
Gaurav Gupta <gaurav@denali-systems.com>
Greg Althaus <galthaus@austin.rr.com>
Hengqing Hu <hudayou@hotmail.com>
Hisaharu Ishii <ishii.hisaharu@lab.ntt.co.jp>
Hisaki Ohara <hisaki.ohara@intel.com>
Ilya Alekseyev <ilyaalekseyev@acm.org>
Ionuț Arțăriși <iartarisi@suse.cz>
Isaku Yamahata <yamahata@valinux.co.jp>
Ivan Kolodyazhny <e0ne@e0ne.info>
J. Daniel Schmidt <jdsn@suse.de>
Jake Dahn <jake@ansolabs.com>
James E. Blair <jeblair@hp.com>
Jason Cannavale <jason.cannavale@rackspace.com>
Jason Koelker <jason@koelker.net>
Jay Pipes <jaypipes@gmail.com>
JC Martin <jcmartin@ebaysf.com>
Jesse Andrews <anotherjesse@gmail.com>
Jimmy Bergman <jimmy@sigint.se>
Joe Gordon <jogo@cloudscaling.com>
Joe Heck <heckj@mac.com>
Joel Moore <joelbm24@gmail.com>
Johannes Erdfelt <johannes.erdfelt@rackspace.com>
John Dewey <john@dewey.ws>
John Garbutt <john.garbutt@citrix.com>
John Griffith <john.griffith@solidfire.com>
John Kennedy <john.m.kennedy@intel.com>
John Tran <jtran@attinteractive.com>
Jonathan Bryce <jbryce@jbryce.com>
Jordan Rinke <jordan@openstack.org>
Joseph Suh <jsuh@isi.edu>
Joseph W. Breu <breu@breu.org>
Josh Durgin <joshd@hq.newdream.net>
Josh Kearney <josh@jk0.org>
Josh Kleinpeter <josh@kleinpeter.org>
Joshua Harlow <harlowja@yahoo-inc.com>
Joshua McKenty <jmckenty@gmail.com>
Juan G. Hernando Rivero <ghe@debian.org>
Julien Danjou <julien.danjou@ecindernce.com>
Justin Santa Barbara <justin@fathomdb.com>
Justin Shepherd <jshepher@rackspace.com>
Kei Masumoto <masumotok@nttdata.co.jp>
Keisuke Tagami <tagami.keisuke@lab.ntt.co.jp>
masumoto<masumotok@nttdata.co.jp>
masukotm<masukotm@nttdata.co.jp>
Ken Pepple <ken.pepple@gmail.com>
Kevin Bringard <kbringard@attinteractive.com>
Kevin L. Mitchell <kevin.mitchell@rackspace.com>
Kiall Mac Innes <kiall@managedit.ie>
Kirill Shileev <kshileev@gmail.com>
Koji Iida <iida.koji@lab.ntt.co.jp>
Liam Kelleher <liam.kelleher@hp.com>
Likitha Shetty <likitha.shetty@citrix.com>
Loganathan Parthipan <parthipan@hp.com>
Lorin Hochstein <lorin@nimbisservices.com>
Lvov Maxim <usrleon@gmail.com>
Mandar Vaze <mandar.vaze@vertex.co.in>
Mandell Degerness <mdegerne@gmail.com>
Mark McClain <mark.mcclain@dreamhost.com>
Mark McLoughlin <markmc@redhat.com>
Mark Washenberger <mark.washenberger@rackspace.com>
Maru Newby <mnewby@internap.com>
Masanori Itoh <itoumsn@nttdata.co.jp>
Matt Dietz <matt.dietz@rackspace.com>
Matt Stephenson <mattstep@mattstep.net>
Matthew Hooker <matt@cloudscaling.com>
Michael Basnight <mbasnigh@rackspace.com>
Michael Gundlach <michael.gundlach@rackspace.com>
Michael Still <mikal@stillhq.com>
Mike Lundy <mike@pistoncloud.com>
Mike Milner <mike.milner@canonical.com>
Mike Pittaro <mikeyp@lahondaresearch.org>
Mike Scherbakov <mihgen@gmail.com>
Mikyung Kang <mkkang@isi.edu>
Mohammed Naser <mnaser@vexxhost.com>
Monsyne Dragon <mdragon@rackspace.com>
Monty Taylor <mordred@inaugust.com>
MORITA Kazutaka <morita.kazutaka@gmail.com>
MotoKen <motokentsai@gmail.com>
Muneyuki Noguchi <noguchimn@nttdata.co.jp>
Nachi Ueno <ueno.nachi@lab.ntt.co.jp>
Naveed Massjouni <naveedm9@gmail.com>
Nick Bartos <nick@pistoncloud.com>
Nikhil Komawar <nikhil.komawar@rackspace.com>
Nikolay Sokolov <nsokolov@griddynamics.com>
Nirmal Ranganathan <rnirmal@gmail.com>
Ollie Leahy <oliver.leahy@hp.com>
Pádraig Brady <pbrady@redhat.com>
Paul McMillan <paul.mcmillan@nebula.com>
Paul Voccio <paul@openstack.org>
Peng Yong <ppyy@pubyun.com>
Philip Knouff <philip.knouff@mailtrust.com>
Renier Morales <renierm@us.ibm.com>
Renuka Apte <renuka.apte@citrix.com>
Ricardo Carrillo Cruz <emaildericky@gmail.com>
Rick Clark <rick@openstack.org>
Rick Harris <rconradharris@gmail.com>
Rob Kost <kost@isi.edu>
Robert Esker <esker@netapp.com>
Russell Bryant <rbryant@redhat.com>
Russell Sim <russell.sim@gmail.com>
Ryan Lane <rlane@wikimedia.org>
Ryan Lucio <rlucio@internap.com>
Ryu Ishimoto <ryu@midokura.jp>
Salvatore Orlando <salvatore.orlando@eu.citrix.com>
Sandy Walsh <sandy.walsh@rackspace.com>
Sateesh Chodapuneedi <sateesh.chodapuneedi@citrix.com>
Scott Moser <smoser@ubuntu.com>
Sean Dague <sdague@linux.vnet.ibm.com>
Soren Hansen <soren.hansen@rackspace.com>
Stanislaw Pitucha <stanislaw.pitucha@hp.com>
Stephanie Reese <reese.sm@gmail.com>
Sumit Naiksatam <snaiksat@cisco.com>
Thierry Carrez <thierry@openstack.org>
Tim Simpson <tim.simpson@rackspace.com>
Todd Willey <todd@ansolabs.com>
Tomoe Sugihara <tomoe@midokura.com>
Tomoya Masuko<masukotm@nttdata.co.jp>
Thorsten Tarrach <thorsten@atomia.com>
Trey Morris <trey.morris@rackspace.com>
Troy Toman <troy.toman@rackspace.com>
Tushar Patil <tushar.vitthal.patil@gmail.com>
Unmesh Gurjar <unmesh.gurjar@vertex.co.in>
Vasiliy Shlykov <vash@vasiliyshlykov.org>
Vishvananda Ishaya <vishvananda@gmail.com>
Vivek Y S <vivek.ys@gmail.com>
Vladimir Popovski <vladimir@zadarastorage.com>
Vaddi kiran <vaddi_kiran@persistent.co.in>
William Henry <whenry@redhat.com>
William Kelly <william.kelly@rackspace.com>
William Wolf <throughnothing@gmail.com>
Yaguang Tang <heut2008@gmail.com>
Yoshiaki Tamura <yoshi@midokura.jp>
Youcef Laribi <Youcef.Laribi@eu.citrix.com>
Yun Mao <yunmao@gmail.com>
Yun Shen <Yun.Shen@hp.com>
Yuriy Taraday <yorik.sar@gmail.com>
Zed Shaw <zedshaw@zedshaw.com>
Zhixue Wu <Zhixue.Wu@citrix.com>
Zhongyue Luo <lzyeval@gmail.com>
Ziad Sawalha <github@highbridgellc.com>

213
HACKING.rst Normal file
View File

@ -0,0 +1,213 @@
Cinder Style Commandments
=======================
- Step 1: Read http://www.python.org/dev/peps/pep-0008/
- Step 2: Read http://www.python.org/dev/peps/pep-0008/ again
- Step 3: Read on
General
-------
- Put two newlines between top-level code (funcs, classes, etc)
- Put one newline between methods in classes and anywhere else
- Do not write "except:", use "except Exception:" at the very least
- Include your name with TODOs as in "#TODO(termie)"
- Do not shadow a built-in or reserved word. Example::
def list():
return [1, 2, 3]
mylist = list() # BAD, shadows `list` built-in
class Foo(object):
def list(self):
return [1, 2, 3]
mylist = Foo().list() # OKAY, does not shadow built-in
Imports
-------
- Do not import objects, only modules (*)
- Do not import more than one module per line (*)
- Do not make relative imports
- Order your imports by the full module path
- Organize your imports according to the following template
(*) exceptions are:
- imports from ``migrate`` package
- imports from ``sqlalchemy`` package
- imports from ``cinder.db.sqlalchemy.session`` module
Example::
# vim: tabstop=4 shiftwidth=4 softtabstop=4
{{stdlib imports in human alphabetical order}}
\n
{{third-party lib imports in human alphabetical order}}
\n
{{cinder imports in human alphabetical order}}
\n
\n
{{begin your code}}
Human Alphabetical Order Examples
---------------------------------
Example::
import httplib
import logging
import random
import StringIO
import time
import unittest
import eventlet
import webob.exc
import cinder.api.ec2
from cinder.api import openstack
from cinder.auth import users
from cinder.endpoint import cloud
import cinder.flags
from cinder import test
Docstrings
----------
Example::
"""A one line docstring looks like this and ends in a period."""
"""A multi line docstring has a one-line summary, less than 80 characters.
Then a new paragraph after a newline that explains in more detail any
general information about the function, class or method. Example usages
are also great to have here if it is a complex class for function.
When writing the docstring for a class, an extra line should be placed
after the closing quotations. For more in-depth explanations for these
decisions see http://www.python.org/dev/peps/pep-0257/
If you are going to describe parameters and return values, use Sphinx, the
appropriate syntax is as follows.
:param foo: the foo parameter
:param bar: the bar parameter
:returns: return_type -- description of the return value
:returns: description of the return value
:raises: AttributeError, KeyError
"""
Dictionaries/Lists
------------------
If a dictionary (dict) or list object is longer than 80 characters, its items
should be split with newlines. Embedded iterables should have their items
indented. Additionally, the last item in the dictionary should have a trailing
comma. This increases readability and simplifies future diffs.
Example::
my_dictionary = {
"image": {
"name": "Just a Snapshot",
"size": 2749573,
"properties": {
"user_id": 12,
"arch": "x86_64",
},
"things": [
"thing_one",
"thing_two",
],
"status": "ACTIVE",
},
}
Calling Methods
---------------
Calls to methods 80 characters or longer should format each argument with
newlines. This is not a requirement, but a guideline::
unnecessarily_long_function_name('string one',
'string two',
kwarg1=constants.ACTIVE,
kwarg2=['a', 'b', 'c'])
Rather than constructing parameters inline, it is better to break things up::
list_of_strings = [
'what_a_long_string',
'not as long',
]
dict_of_numbers = {
'one': 1,
'two': 2,
'twenty four': 24,
}
object_one.call_a_method('string three',
'string four',
kwarg1=list_of_strings,
kwarg2=dict_of_numbers)
Internationalization (i18n) Strings
-----------------------------------
In order to support multiple languages, we have a mechanism to support
automatic translations of exception and log strings.
Example::
msg = _("An error occurred")
raise HTTPBadRequest(explanation=msg)
If you have a variable to place within the string, first internationalize the
template string then do the replacement.
Example::
msg = _("Missing parameter: %s") % ("flavor",)
LOG.error(msg)
If you have multiple variables to place in the string, use keyword parameters.
This helps our translators reorder parameters when needed.
Example::
msg = _("The server with id %(s_id)s has no key %(m_key)s")
LOG.error(msg % {"s_id": "1234", "m_key": "imageId"})
Creating Unit Tests
-------------------
For every new feature, unit tests should be created that both test and
(implicitly) document the usage of said feature. If submitting a patch for a
bug that had no unit test, a new passing unit test should be added. If a
submitted bug fix does have a unit test, be sure to add a new one that fails
without the patch and passes with the patch.
For more information on creating unit tests and utilizing the testing
infrastructure in OpenStack Cinder, please read cinder/testing/README.rst.
openstack-common
----------------
A number of modules from openstack-common are imported into the project.
These modules are "incubating" in openstack-common and are kept in sync
with the help of openstack-common's update.py script. See:
http://wiki.openstack.org/CommonLibrary#Incubation
The copy of the code should never be directly modified here. Please
always update openstack-common first and then run the script to copy
the changes across.

176
LICENSE Normal file
View File

@ -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.

37
MANIFEST.in Normal file
View File

@ -0,0 +1,37 @@
include HACKING.rst
include LICENSE run_tests.sh
include README.rst
include MANIFEST.in pylintrc Authors
include openstack-common.conf
include babel.cfg tox.ini
graft cinder/CA
graft doc
graft smoketests
graft tools
graft etc
graft contrib
graft plugins
graft cinder/api/openstack/*/schemas
include cinder/auth/*.schema
include cinder/auth/cinderrc.template
include cinder/auth/opendj.sh
include cinder/auth/slap.sh
include cinder/db/sqlalchemy/migrate_repo/migrate.cfg
include cinder/db/sqlalchemy/migrate_repo/README
include cinder/db/sqlalchemy/migrate_repo/versions/*.sql
include cinder/openstack/common/README
include cinder/virt/interfaces.template
include cinder/virt/libvirt*.xml.template
include cinder/virt/cpuinfo.xml.template
include cinder/testing/README.rst
include cinder/tests/db/cinder.austin.sqlite
include cinder/tests/image/*.tar.gz
include cinder/tests/policy.json
include cinder/tests/test_migrations.conf
include cinder/tests/xenapi/vm_rrd.xml
include plugins/xenapi/README
include plugins/xenapi/etc/xapi.d/plugins/objectstore
include plugins/xenapi/etc/xapi.d/plugins/pluginlib_cinder.py
global-exclude *.pyc
recursive-include cinder/locale *

21
README.rst Normal file
View File

@ -0,0 +1,21 @@
The Choose Your Own Adventure README for Cinder
===============================================
You have come across a storage service for an open cloud computing service.
It has identified itself as "Cinder." It was abstracted from the Nova project.
To monitor it from a distance: follow `@openstack <http://twitter.com/openstack>`_ on twitter.
To tame it for use in your own cloud: read http://docs.openstack.org
To study its anatomy: read http://cinder.openstack.org
To dissect it in detail: visit http://github.com/openstack/cinder
To taunt it with its weaknesses: use http://bugs.launchpad.net/cinder
To watch it: http://jenkins.openstack.org
To hack at it: read HACKING
To cry over its pylint problems: http://jenkins.openstack.org/job/cinder-pylint/violations

2
babel.cfg Normal file
View File

@ -0,0 +1,2 @@
[python: **.py]

70
bin/cinder-all Executable file
View File

@ -0,0 +1,70 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011 OpenStack, LLC
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Starter script for All cinder services.
This script attempts to start all the cinder services in one process. Each
service is started in its own greenthread. Please note that exceptions and
sys.exit() on the starting of a service are logged and the script will
continue attempting to launch the rest of the services.
"""
import eventlet
eventlet.monkey_patch()
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, "cinder", "__init__.py")):
sys.path.insert(0, possible_topdir)
from cinder import flags
from cinder import log as logging
from cinder import service
from cinder import utils
LOG = logging.getLogger('cinder.all')
if __name__ == '__main__':
utils.default_flagfile()
flags.FLAGS(sys.argv)
logging.setup()
utils.monkey_patch()
servers = []
# cinder-api
for api in flags.FLAGS.enabled_apis:
try:
servers.append(service.WSGIService(api))
except (Exception, SystemExit):
logging.exception(_('Failed to load %s') % '%s-api' % api)
for binary in ['cinder-volume', 'cinder-scheduler']:
try:
servers.append(service.Service.create(binary=binary))
except (Exception, SystemExit):
LOG.exception(_('Failed to load %s'), binary)
service.serve(*servers)
service.wait()

47
bin/cinder-api Executable file
View File

@ -0,0 +1,47 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Starter script for Cinder OS API."""
import eventlet
eventlet.monkey_patch()
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, "cinder", "__init__.py")):
sys.path.insert(0, possible_topdir)
from cinder import flags
from cinder import log as logging
from cinder import service
from cinder import utils
if __name__ == '__main__':
utils.default_flagfile()
flags.FLAGS(sys.argv)
logging.setup()
utils.monkey_patch()
server = service.WSGIService('osapi_volume')
service.serve(server)
service.wait()

635
bin/cinder-manage Executable file
View File

@ -0,0 +1,635 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2011 X.commerce, a business unit of eBay Inc.
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# 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.
# Interactive shell based on Django:
#
# Copyright (c) 2005, the Lawrence Journal-World
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of Django nor the names of its contributors may be
# used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
CLI interface for cinder management.
"""
import ast
import errno
import gettext
import json
import math
import netaddr
import optparse
import os
import StringIO
import sys
# If ../cinder/__init__.py exists, add ../ to Python search path, so that
# it will override what happens to be installed in /usr/(local/)lib/python...
POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
os.pardir,
os.pardir))
if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'cinder', '__init__.py')):
sys.path.insert(0, POSSIBLE_TOPDIR)
gettext.install('cinder', unicode=1)
from cinder.compat import flagfile
from cinder import context
from cinder import db
from cinder.db import migration
from cinder import exception
from cinder import flags
from cinder import log as logging
from cinder.openstack.common import importutils
from cinder import quota
from cinder import rpc
from cinder import utils
from cinder import version
from cinder.volume import volume_types
FLAGS = flags.FLAGS
# Decorators for actions
def args(*args, **kwargs):
def _decorator(func):
func.__dict__.setdefault('options', []).insert(0, (args, kwargs))
return func
return _decorator
def param2id(object_id):
"""Helper function to convert various id types to internal id.
args: [object_id], e.g. 'vol-0000000a' or 'volume-0000000a' or '10'
"""
if '-' in object_id:
# FIXME(ja): mapping occurs in nova?
pass
else:
return int(object_id)
class ShellCommands(object):
def bpython(self):
"""Runs a bpython shell.
Falls back to Ipython/python shell if unavailable"""
self.run('bpython')
def ipython(self):
"""Runs an Ipython shell.
Falls back to Python shell if unavailable"""
self.run('ipython')
def python(self):
"""Runs a python shell.
Falls back to Python shell if unavailable"""
self.run('python')
@args('--shell', dest="shell", metavar='<bpython|ipython|python >',
help='Python shell')
def run(self, shell=None):
"""Runs a Python interactive interpreter."""
if not shell:
shell = 'bpython'
if shell == 'bpython':
try:
import bpython
bpython.embed()
except ImportError:
shell = 'ipython'
if shell == 'ipython':
try:
import IPython
# Explicitly pass an empty list as arguments, because
# otherwise IPython would use sys.argv from this script.
shell = IPython.Shell.IPShell(argv=[])
shell.mainloop()
except ImportError:
shell = 'python'
if shell == 'python':
import code
try:
# Try activating rlcompleter, because it's handy.
import readline
except ImportError:
pass
else:
# We don't have to wrap the following import in a 'try',
# because we already know 'readline' was imported successfully.
import rlcompleter
readline.parse_and_bind("tab:complete")
code.interact()
@args('--path', dest='path', metavar='<path>', help='Script path')
def script(self, path):
"""Runs the script from the specifed path with flags set properly.
arguments: path"""
exec(compile(open(path).read(), path, 'exec'), locals(), globals())
def _db_error(caught_exception):
print caught_exception
print _("The above error may show that the database has not "
"been created.\nPlease create a database using "
"'cinder-manage db sync' before running this command.")
exit(1)
class HostCommands(object):
"""List hosts"""
def list(self, zone=None):
"""Show a list of all physical hosts. Filter by zone.
args: [zone]"""
print "%-25s\t%-15s" % (_('host'),
_('zone'))
ctxt = context.get_admin_context()
now = utils.utcnow()
services = db.service_get_all(ctxt)
if zone:
services = [s for s in services if s['availability_zone'] == zone]
hosts = []
for srv in services:
if not [h for h in hosts if h['host'] == srv['host']]:
hosts.append(srv)
for h in hosts:
print "%-25s\t%-15s" % (h['host'], h['availability_zone'])
class DbCommands(object):
"""Class for managing the database."""
def __init__(self):
pass
@args('--version', dest='version', metavar='<version>',
help='Database version')
def sync(self, version=None):
"""Sync the database up to the most recent version."""
return migration.db_sync(version)
def version(self):
"""Print the current database version."""
print migration.db_version()
class VersionCommands(object):
"""Class for exposing the codebase version."""
def __init__(self):
pass
def list(self):
print _("%(version)s (%(vcs)s)") % \
{'version': version.version_string(),
'vcs': version.version_string_with_vcs()}
def __call__(self):
self.list()
class VolumeCommands(object):
"""Methods for dealing with a cloud in an odd state"""
@args('--volume', dest='volume_id', metavar='<volume id>',
help='Volume ID')
def delete(self, volume_id):
"""Delete a volume, bypassing the check that it
must be available."""
ctxt = context.get_admin_context()
volume = db.volume_get(ctxt, param2id(volume_id))
host = volume['host']
if not host:
print "Volume not yet assigned to host."
print "Deleting volume from database and skipping rpc."
db.volume_destroy(ctxt, param2id(volume_id))
return
if volume['status'] == 'in-use':
print "Volume is in-use."
print "Detach volume from instance and then try again."
return
rpc.cast(ctxt,
db.queue_get_for(ctxt, FLAGS.volume_topic, host),
{"method": "delete_volume",
"args": {"volume_id": volume['id']}})
@args('--volume', dest='volume_id', metavar='<volume id>',
help='Volume ID')
def reattach(self, volume_id):
"""Re-attach a volume that has previously been attached
to an instance. Typically called after a compute host
has been rebooted."""
ctxt = context.get_admin_context()
volume = db.volume_get(ctxt, param2id(volume_id))
if not volume['instance_id']:
print "volume is not attached to an instance"
return
instance = db.instance_get(ctxt, volume['instance_id'])
host = instance['host']
rpc.cast(ctxt,
db.queue_get_for(ctxt, FLAGS.compute_topic, host),
{"method": "attach_volume",
"args": {"instance_id": instance['id'],
"volume_id": volume['id'],
"mountpoint": volume['mountpoint']}})
class StorageManagerCommands(object):
"""Class for mangaging Storage Backends and Flavors"""
def flavor_list(self, flavor=None):
ctxt = context.get_admin_context()
try:
if flavor is None:
flavors = db.sm_flavor_get_all(ctxt)
else:
flavors = db.sm_flavor_get(ctxt, flavor)
except exception.NotFound as ex:
print "error: %s" % ex
sys.exit(2)
print "%-18s\t%-20s\t%s" % (_('id'),
_('Label'),
_('Description'))
for flav in flavors:
print "%-18s\t%-20s\t%s" % (
flav['id'],
flav['label'],
flav['description'])
def flavor_create(self, label, desc):
# TODO(renukaapte) flavor name must be unique
try:
db.sm_flavor_create(context.get_admin_context(),
dict(label=label,
description=desc))
except exception.DBError, e:
_db_error(e)
def flavor_delete(self, label):
try:
db.sm_flavor_delete(context.get_admin_context(), label)
except exception.DBError, e:
_db_error(e)
def _splitfun(self, item):
i = item.split("=")
return i[0:2]
def backend_list(self, backend_conf_id=None):
ctxt = context.get_admin_context()
try:
if backend_conf_id is None:
backends = db.sm_backend_conf_get_all(ctxt)
else:
backends = db.sm_backend_conf_get(ctxt, backend_conf_id)
except exception.NotFound as ex:
print "error: %s" % ex
sys.exit(2)
print "%-5s\t%-10s\t%-40s\t%-10s\t%s" % (_('id'),
_('Flavor id'),
_('SR UUID'),
_('SR Type'),
_('Config Parameters'),)
for b in backends:
print "%-5s\t%-10s\t%-40s\t%-10s\t%s" % (b['id'],
b['flavor_id'],
b['sr_uuid'],
b['sr_type'],
b['config_params'],)
def backend_add(self, flavor_label, sr_type, *args):
# TODO(renukaapte) Add backend_introduce.
ctxt = context.get_admin_context()
params = dict(map(self._splitfun, args))
sr_uuid = utils.gen_uuid()
if flavor_label is None:
print "error: backend needs to be associated with flavor"
sys.exit(2)
try:
flavors = db.sm_flavor_get(ctxt, flavor_label)
except exception.NotFound as ex:
print "error: %s" % ex
sys.exit(2)
config_params = " ".join(['%s=%s' %
(key, params[key]) for key in params])
if 'sr_uuid' in params:
sr_uuid = params['sr_uuid']
try:
backend = db.sm_backend_conf_get_by_sr(ctxt, sr_uuid)
except exception.DBError, e:
_db_error(e)
if backend:
print 'Backend config found. Would you like to recreate this?'
print '(WARNING:Recreating will destroy all VDIs on backend!!)'
c = raw_input('Proceed? (y/n) ')
if c == 'y' or c == 'Y':
try:
db.sm_backend_conf_update(ctxt, backend['id'],
dict(created=False,
flavor_id=flavors['id'],
sr_type=sr_type,
config_params=config_params))
except exception.DBError, e:
_db_error(e)
return
else:
print 'Backend config not found. Would you like to create it?'
print '(WARNING: Creating will destroy all data on backend!!!)'
c = raw_input('Proceed? (y/n) ')
if c == 'y' or c == 'Y':
try:
db.sm_backend_conf_create(ctxt,
dict(flavor_id=flavors['id'],
sr_uuid=sr_uuid,
sr_type=sr_type,
config_params=config_params))
except exception.DBError, e:
_db_error(e)
def backend_remove(self, backend_conf_id):
try:
db.sm_backend_conf_delete(context.get_admin_context(),
backend_conf_id)
except exception.DBError, e:
_db_error(e)
class ConfigCommands(object):
"""Class for exposing the flags defined by flag_file(s)."""
def __init__(self):
pass
def list(self):
for key, value in FLAGS.iteritems():
if value is not None:
print '%s = %s' % (key, value)
@args('--infile', dest='infile', metavar='<path>',
help='old-style flagfile to convert to config')
@args('--outfile', dest='outfile', metavar='<path>',
help='path for output file. Writes config'
'to stdout if not specified.')
def convert(self, infile, outfile=None):
"""Converts a flagfile and prints results to stdout."""
arg = '--flagfile=%s' % infile
with flagfile.handle_flagfiles_managed([arg]) as newargs:
with open(newargs[0].split('=')[1]) as configfile:
config = configfile.read()
if outfile:
with open(outfile, 'w') as configfile:
configfile.write(config)
else:
print config,
class GetLogCommands(object):
"""Get logging information"""
def errors(self):
"""Get all of the errors from the log files"""
error_found = 0
if FLAGS.logdir:
logs = [x for x in os.listdir(FLAGS.logdir) if x.endswith('.log')]
for file in logs:
log_file = os.path.join(FLAGS.logdir, file)
lines = [line.strip() for line in open(log_file, "r")]
lines.reverse()
print_name = 0
for index, line in enumerate(lines):
if line.find(" ERROR ") > 0:
error_found += 1
if print_name == 0:
print log_file + ":-"
print_name = 1
print "Line %d : %s" % (len(lines) - index, line)
if error_found == 0:
print "No errors in logfiles!"
def syslog(self, num_entries=10):
"""Get <num_entries> of the cinder syslog events"""
entries = int(num_entries)
count = 0
log_file = ''
if os.path.exists('/var/log/syslog'):
log_file = '/var/log/syslog'
elif os.path.exists('/var/log/messages'):
log_file = '/var/log/messages'
else:
print "Unable to find system log file!"
sys.exit(1)
lines = [line.strip() for line in open(log_file, "r")]
lines.reverse()
print "Last %s cinder syslog entries:-" % (entries)
for line in lines:
if line.find("cinder") > 0:
count += 1
print "%s" % (line)
if count == entries:
break
if count == 0:
print "No cinder entries in syslog!"
CATEGORIES = [
('config', ConfigCommands),
('db', DbCommands),
('host', HostCommands),
('logs', GetLogCommands),
('shell', ShellCommands),
('sm', StorageManagerCommands),
('version', VersionCommands),
('volume', VolumeCommands),
]
def lazy_match(name, key_value_tuples):
"""Finds all objects that have a key that case insensitively contains
[name] key_value_tuples is a list of tuples of the form (key, value)
returns a list of tuples of the form (key, value)"""
result = []
for (k, v) in key_value_tuples:
if k.lower().find(name.lower()) == 0:
result.append((k, v))
if len(result) == 0:
print "%s does not match any options:" % name
for k, _v in key_value_tuples:
print "\t%s" % k
sys.exit(2)
if len(result) > 1:
print "%s matched multiple options:" % name
for k, _v in result:
print "\t%s" % k
sys.exit(2)
return result
def methods_of(obj):
"""Get all callable methods of an object that don't start with underscore
returns a list of tuples of the form (method_name, method)"""
result = []
for i in dir(obj):
if callable(getattr(obj, i)) and not i.startswith('_'):
result.append((i, getattr(obj, i)))
return result
def main():
"""Parse options and call the appropriate class/method."""
flagfile = utils.default_flagfile()
if flagfile and not os.access(flagfile, os.R_OK):
st = os.stat(flagfile)
print "Could not read %s. Re-running with sudo" % flagfile
try:
os.execvp('sudo', ['sudo', '-u', '#%s' % st.st_uid] + sys.argv)
except Exception:
print 'sudo failed, continuing as if nothing happened'
rpc.register_opts(FLAGS)
try:
argv = FLAGS(sys.argv)
logging.setup()
except IOError, e:
if e.errno == errno.EACCES:
print _('Please re-run cinder-manage as root.')
sys.exit(2)
raise
script_name = argv.pop(0)
if len(argv) < 1:
print _("\nOpenStack Cinder version: %(version)s (%(vcs)s)\n") % \
{'version': version.version_string(),
'vcs': version.version_string_with_vcs()}
print script_name + " category action [<args>]"
print _("Available categories:")
for k, _v in CATEGORIES:
print "\t%s" % k
sys.exit(2)
category = argv.pop(0)
matches = lazy_match(category, CATEGORIES)
# instantiate the command group object
category, fn = matches[0]
command_object = fn()
actions = methods_of(command_object)
if len(argv) < 1:
if hasattr(command_object, '__call__'):
action = ''
fn = command_object.__call__
else:
print script_name + " category action [<args>]"
print _("Available actions for %s category:") % category
for k, _v in actions:
print "\t%s" % k
sys.exit(2)
else:
action = argv.pop(0)
matches = lazy_match(action, actions)
action, fn = matches[0]
# For not decorated methods
options = getattr(fn, 'options', [])
usage = "%%prog %s %s <args> [options]" % (category, action)
parser = optparse.OptionParser(usage=usage)
for ar, kw in options:
parser.add_option(*ar, **kw)
(opts, fn_args) = parser.parse_args(argv)
fn_kwargs = vars(opts)
for k, v in fn_kwargs.items():
if v is None:
del fn_kwargs[k]
elif isinstance(v, basestring):
fn_kwargs[k] = v.decode('utf-8')
else:
fn_kwargs[k] = v
fn_args = [arg.decode('utf-8') for arg in fn_args]
# call the action with the remaining arguments
try:
fn(*fn_args, **fn_kwargs)
rpc.cleanup()
sys.exit(0)
except TypeError:
print _("Possible wrong number of arguments supplied")
print fn.__doc__
parser.print_help()
raise
except Exception:
print _("Command failed, please check log for more info")
raise
if __name__ == '__main__':
main()

74
bin/cinder-rootwrap Executable file
View File

@ -0,0 +1,74 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 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.
"""Root wrapper for Cinder
Uses modules in cinder.rootwrap containing filters for commands
that cinder is allowed to run as another user.
To switch to using this, you should:
* Set "--root_helper=sudo cinder-rootwrap" in cinder.conf
* Allow cinder to run cinder-rootwrap as root in cinder_sudoers:
cinder ALL = (root) NOPASSWD: /usr/bin/cinder-rootwrap
(all other commands can be removed from this file)
To make allowed commands node-specific, your packaging should only
install cinder/rootwrap/{compute,network,volume}.py respectively on
compute, network and volume nodes (i.e. cinder-api nodes should not
have any of those files installed).
"""
import os
import subprocess
import sys
RC_UNAUTHORIZED = 99
RC_NOCOMMAND = 98
if __name__ == '__main__':
# Split arguments, require at least a command
execname = sys.argv.pop(0)
if len(sys.argv) == 0:
print "%s: %s" % (execname, "No command specified")
sys.exit(RC_NOCOMMAND)
userargs = sys.argv[:]
# Add ../ to sys.path to allow running from branch
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(execname),
os.pardir, os.pardir))
if os.path.exists(os.path.join(possible_topdir, "cinder", "__init__.py")):
sys.path.insert(0, possible_topdir)
from cinder.rootwrap import wrapper
# Execute command if it matches any of the loaded filters
filters = wrapper.load_filters()
filtermatch = wrapper.match_filter(filters, userargs)
if filtermatch:
obj = subprocess.Popen(filtermatch.get_command(userargs),
stdin=sys.stdin,
stdout=sys.stdout,
stderr=sys.stderr,
env=filtermatch.get_environment(userargs))
obj.wait()
sys.exit(obj.returncode)
print "Unauthorized command: %s" % ' '.join(userargs)
sys.exit(RC_UNAUTHORIZED)

51
bin/cinder-scheduler Executable file
View File

@ -0,0 +1,51 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Starter script for Cinder Scheduler."""
import eventlet
eventlet.monkey_patch()
import gettext
import os
import sys
# If ../cinder/__init__.py exists, add ../ to Python search path, so that
# it will override what happens to be installed in /usr/(local/)lib/python...
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
os.pardir,
os.pardir))
if os.path.exists(os.path.join(possible_topdir, 'cinder', '__init__.py')):
sys.path.insert(0, possible_topdir)
gettext.install('cinder', unicode=1)
from cinder import flags
from cinder import log as logging
from cinder import service
from cinder import utils
if __name__ == '__main__':
utils.default_flagfile()
flags.FLAGS(sys.argv)
logging.setup()
utils.monkey_patch()
server = service.Service.create(binary='cinder-scheduler')
service.serve(server)
service.wait()

49
bin/cinder-volume Executable file
View File

@ -0,0 +1,49 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Starter script for Cinder Volume."""
import eventlet
eventlet.monkey_patch()
import os
import sys
# If ../cinder/__init__.py exists, add ../ to Python search path, so that
# it will override what happens to be installed in /usr/(local/)lib/python...
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
os.pardir,
os.pardir))
if os.path.exists(os.path.join(possible_topdir, 'cinder', '__init__.py')):
sys.path.insert(0, possible_topdir)
from cinder import flags
from cinder import log as logging
from cinder import service
from cinder import utils
if __name__ == '__main__':
utils.default_flagfile()
flags.FLAGS(sys.argv)
logging.setup()
utils.monkey_patch()
server = service.Service.create(binary='cinder-volume')
service.serve(server)
service.wait()

80
bin/clear_rabbit_queues Executable file
View File

@ -0,0 +1,80 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 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.
"""Admin/debug script to wipe rabbitMQ (AMQP) queues cinder uses.
This can be used if you need to change durable options on queues,
or to wipe all messages in the queue system if things are in a
serious bad way.
"""
import datetime
import gettext
import os
import sys
import time
# If ../cinder/__init__.py exists, add ../ to Python search path, so that