-From 2a3566b8f56014f3e39f3e5823fb45dd202a8bd5 Mon Sep 17 00:00:00 2001
+From daa9d9720b5bada99c6a7970c903e6643ab52249 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
Date: Fri, 21 Sep 2012 13:33:26 +0100
-Subject: [PATCH 1/4] Ensure we don't access the net when building docs
+Subject: [PATCH] Ensure we don't access the net when building docs
(Note, this has not been sent upstream)
---
- doc/source/conf.py | 1 -
+ doc/source/conf.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/doc/source/conf.py b/doc/source/conf.py
'ext.cinder_todo',
'sphinx.ext.coverage',
'sphinx.ext.pngmath',
---
-1.7.9.5
-
-From 1c75890c8f0ae702abbd880881b57f103f1c94e2 Mon Sep 17 00:00:00 2001
+From 302c285b0193bcae47aaaaec49f51340b4fbe6e7 Mon Sep 17 00:00:00 2001
From: Eric Harney <eharney@redhat.com>
Date: Thu, 13 Jun 2013 17:50:12 -0400
-Subject: [PATCH 3/4] Remove runtime dep on python-pbr, python-d2to1
+Subject: [PATCH] Remove runtime dep on python-pbr, python-d2to1
Requires RPM spec to fill in REDHATCINDERVERSION.
---
- cinder/version.py | 16 +++++++++++++---
+ cinder/version.py | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/cinder/version.py b/cinder/version.py
+
+version_info = VersionInfo()
version_string = version_info.version_string
---
-1.7.9.5
-
+++ /dev/null
-From 433133a658c36ae5f7fc16f1679908c13205fcff Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
-Date: Wed, 24 Oct 2012 13:44:37 +0100
-Subject: [PATCH 2/4] Use updated parallel install versions of epel package
-
-Use sqlalchemy >= 0.6.3 WebOb >= 1.2 Routes >= 1.12.3 PasteDeploy >= 1.5.0
-and depend on the parallel installable
-versions of these packages to satisfy those requirements.
-
-Delve into pkg_resources a little to get it to modify sys.path,
-so that our parallel installed egg takes precedence over the
-system default module versions.
-
-Conflicts:
- cinder/db/sqlalchemy/migration.py
----
- bin/cinder-manage | 3 +++
- cinder/__init__.py | 30 +++++++++++++++++++++++++
- cinder/db/sqlalchemy/migration.py | 44 ++++++++++++++++++++++++++++++++++++-
- 3 files changed, 76 insertions(+), 1 deletion(-)
-
-diff --git a/bin/cinder-manage b/bin/cinder-manage
-index c9eec4a..ef7329c 100755
---- a/bin/cinder-manage
-+++ b/bin/cinder-manage
-@@ -83,6 +83,9 @@ from cinder import rpc
- from cinder import utils
- from cinder import version
-
-+from sqlalchemy import create_engine, MetaData, Table
-+from sqlalchemy.ext.declarative import declarative_base
-+from sqlalchemy.orm import sessionmaker
-
- CONF = cfg.CONF
-
-diff --git a/cinder/__init__.py b/cinder/__init__.py
-index 2b43c2f..da4fb0a 100644
---- a/cinder/__init__.py
-+++ b/cinder/__init__.py
-@@ -28,3 +28,33 @@
- .. moduleauthor:: Manish Singh <yosh@gimp.org>
- .. moduleauthor:: Andy Smith <andy@anarkystic.com>
- """
-+
-+import sys
-+import pkg_resources
-+
-+# If there is a conflicting non egg module,
-+# i.e. an older standard system module installed,
-+# then replace it with this requirement
-+def replace_dist(requirement):
-+ try:
-+ return pkg_resources.require(requirement)
-+ except pkg_resources.VersionConflict:
-+ e = sys.exc_info()[1]
-+ dist=e.args[0]
-+ req=e.args[1]
-+ if dist.key == req.key and not dist.location.endswith('.egg'):
-+ del pkg_resources.working_set.by_key[dist.key]
-+ # We assume there is no need to adjust sys.path
-+ # and the associated pkg_resources.working_set.entries
-+ return pkg_resources.require(requirement)
-+
-+replace_dist("WebOb >= 1.2")
-+replace_dist("SQLAlchemy >= 0.6.3")
-+replace_dist("Routes >= 1.12.3")
-+
-+replace_dist("PasteDeploy >= 1.5.0")
-+# This hack is needed because replace_dist() results in
-+# the standard paste module path being at the start of __path__.
-+# TODO: See can we get pkg_resources to do the right thing directly
-+import paste
-+paste.__path__.insert(0, paste.__path__.pop(-1))
-diff --git a/cinder/db/sqlalchemy/migration.py b/cinder/db/sqlalchemy/migration.py
-index ebfdff8..9b3acd5 100644
---- a/cinder/db/sqlalchemy/migration.py
-+++ b/cinder/db/sqlalchemy/migration.py
-@@ -17,7 +17,49 @@
-
- import os
-
--from migrate import exceptions as versioning_exceptions
-+import distutils.version as dist_version
-+import migrate
-+from migrate.versioning import util as migrate_util
-+import sqlalchemy
-+
-+from cinder.db import migration
-+from cinder.db.sqlalchemy.api import get_engine
-+from cinder import exception
-+from cinder.openstack.common import log as logging
-+
-+
-+LOG = logging.getLogger(__name__)
-+
-+
-+@migrate_util.decorator
-+def patched_with_engine(f, *a, **kw):
-+ url = a[0]
-+ engine = migrate_util.construct_engine(url, **kw)
-+
-+ try:
-+ kw['engine'] = engine
-+ return f(*a, **kw)
-+ finally:
-+ if isinstance(engine, migrate_util.Engine) and engine is not url:
-+ migrate_util.log.debug('Disposing SQLAlchemy engine %s', engine)
-+ engine.dispose()
-+
-+
-+# TODO(jkoelker) When migrate 0.7.3 is released and cinder depends
-+# on that version or higher, this can be removed
-+MIN_PKG_VERSION = dist_version.StrictVersion('0.7.3')
-+if (not hasattr(migrate, '__version__') or
-+ dist_version.StrictVersion(migrate.__version__) < MIN_PKG_VERSION):
-+ migrate_util.with_engine = patched_with_engine
-+
-+
-+# NOTE(jkoelker) Delay importing migrate until we are patched
-+try:
-+ # Try the more specific path first (migrate <= 0.6)
-+ from migrate.versioning import exceptions as versioning_exceptions
-+except ImportError:
-+ # Use the newer path (migrate >= 0.7)
-+ from migrate import exceptions as versioning_exceptions
- from migrate.versioning import api as versioning_api
- from migrate.versioning.repository import Repository
- import sqlalchemy
---
-1.7.9.5
-
--- /dev/null
+From 15cc208adf811d9a83e8f820fb4be775c5db9a00 Mon Sep 17 00:00:00 2001
+From: Eric Harney <eharney@redhat.com>
+Date: Thu, 27 Mar 2014 14:24:57 -0400
+Subject: [PATCH] Revert "Switch over to oslosphinx"
+
+This reverts commit ea7d4a599224b5d0c7674d03993bbe72c49f0d51.
+---
+ doc/source/conf.py | 2 +-
+ test-requirements.txt | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/doc/source/conf.py b/doc/source/conf.py
+index ac2eadc..238a922 100644
+--- a/doc/source/conf.py
++++ b/doc/source/conf.py
+@@ -34,7 +34,7 @@ extensions = ['sphinx.ext.autodoc',
+ 'sphinx.ext.pngmath',
+ 'sphinx.ext.ifconfig',
+ 'sphinx.ext.graphviz',
+- 'oslosphinx',
++ 'oslo.sphinx',
+ ]
+
+ # autodoc generation is a bit aggressive and a nuisance
+diff --git a/test-requirements.txt b/test-requirements.txt
+index 56746da..15308b9 100644
+--- a/test-requirements.txt
++++ b/test-requirements.txt
+@@ -13,4 +13,4 @@ sphinx>=1.1.2,<1.2
+ python-subunit>=0.0.18
+ testtools>=0.9.34
+ testrepository>=0.0.18
+-oslosphinx
++oslo.sphinx
+++ /dev/null
-From 4cb3cf87312a5f351f264f20d7bcd998d2c1f075 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
-Date: Mon, 22 Jul 2013 03:14:27 +0100
-Subject: [PATCH 4/4] Revert "Use oslo.sphinx and remove local copy of doc
- theme"
-
-This reverts commit 8b1ae18ba95f04fedc04592b419401d75d448543.
-
-Conflicts:
-
- test-requirements.txt
----
- doc/source/_static/basic.css | 416 ++++++++++++++++++++++++++++++++++++
- doc/source/_static/default.css | 230 ++++++++++++++++++++
- doc/source/_static/jquery.tweet.js | 154 +++++++++++++
- doc/source/_static/tweaks.css | 218 +++++++++++++++++++
- doc/source/_theme/layout.html | 95 ++++++++
- doc/source/_theme/theme.conf | 5 +
- doc/source/conf.py | 8 +-
- test-requirements.txt | 1 -
- 8 files changed, 1121 insertions(+), 6 deletions(-)
- create mode 100644 doc/source/_static/.gitignore
- create mode 100644 doc/source/_static/.placeholder
- create mode 100644 doc/source/_static/basic.css
- create mode 100644 doc/source/_static/default.css
- create mode 100644 doc/source/_static/jquery.tweet.js
- create mode 100644 doc/source/_static/tweaks.css
- create mode 100644 doc/source/_templates/.gitignore
- create mode 100644 doc/source/_templates/.placeholder
- create mode 100644 doc/source/_theme/layout.html
- create mode 100644 doc/source/_theme/theme.conf
-
-diff --git a/doc/source/_static/.gitignore b/doc/source/_static/.gitignore
-new file mode 100644
-index 0000000..e69de29
-diff --git a/doc/source/_static/.placeholder b/doc/source/_static/.placeholder
-new file mode 100644
-index 0000000..e69de29
-diff --git a/doc/source/_static/basic.css b/doc/source/_static/basic.css
-new file mode 100644
-index 0000000..d909ce3
---- /dev/null
-+++ b/doc/source/_static/basic.css
-@@ -0,0 +1,416 @@
-+/**
-+ * Sphinx stylesheet -- basic theme
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ */
-+
-+/* -- main layout ----------------------------------------------------------- */
-+
-+div.clearer {
-+ clear: both;
-+}
-+
-+/* -- relbar ---------------------------------------------------------------- */
-+
-+div.related {
-+ width: 100%;
-+ font-size: 90%;
-+}
-+
-+div.related h3 {
-+ display: none;
-+}
-+
-+div.related ul {
-+ margin: 0;
-+ padding: 0 0 0 10px;
-+ list-style: none;
-+}
-+
-+div.related li {
-+ display: inline;
-+}
-+
-+div.related li.right {
-+ float: right;
-+ margin-right: 5px;
-+}
-+
-+/* -- sidebar --------------------------------------------------------------- */
-+
-+div.sphinxsidebarwrapper {
-+ padding: 10px 5px 0 10px;
-+}
-+
-+div.sphinxsidebar {
-+ float: left;
-+ width: 230px;
-+ margin-left: -100%;
-+ font-size: 90%;
-+}
-+
-+div.sphinxsidebar ul {
-+ list-style: none;
-+}
-+
-+div.sphinxsidebar ul ul,
-+div.sphinxsidebar ul.want-points {
-+ margin-left: 20px;
-+ list-style: square;
-+}
-+
-+div.sphinxsidebar ul ul {
-+ margin-top: 0;
-+ margin-bottom: 0;
-+}
-+
-+div.sphinxsidebar form {
-+ margin-top: 10px;
-+}
-+
-+div.sphinxsidebar input {
-+ border: 1px solid #98dbcc;
-+ font-family: sans-serif;
-+ font-size: 1em;
-+}
-+
-+img {
-+ border: 0;
-+}
-+
-+/* -- search page ----------------------------------------------------------- */
-+
-+ul.search {
-+ margin: 10px 0 0 20px;
-+ padding: 0;
-+}
-+
-+ul.search li {
-+ padding: 5px 0 5px 20px;
-+ background-image: url(file.png);
-+ background-repeat: no-repeat;
-+ background-position: 0 7px;
-+}
-+
-+ul.search li a {
-+ font-weight: bold;
-+}
-+
-+ul.search li div.context {
-+ color: #888;
-+ margin: 2px 0 0 30px;
-+ text-align: left;
-+}
-+
-+ul.keywordmatches li.goodmatch a {
-+ font-weight: bold;
-+}
-+
-+/* -- index page ------------------------------------------------------------ */
-+
-+table.contentstable {
-+ width: 90%;
-+}
-+
-+table.contentstable p.biglink {
-+ line-height: 150%;
-+}
-+
-+a.biglink {
-+ font-size: 1.3em;
-+}
-+
-+span.linkdescr {
-+ font-style: italic;
-+ padding-top: 5px;
-+ font-size: 90%;
-+}
-+
-+/* -- general index --------------------------------------------------------- */
-+
-+table.indextable td {
-+ text-align: left;
-+ vertical-align: top;
-+}
-+
-+table.indextable dl, table.indextable dd {
-+ margin-top: 0;
-+ margin-bottom: 0;
-+}
-+
-+table.indextable tr.pcap {
-+ height: 10px;
-+}
-+
-+table.indextable tr.cap {
-+ margin-top: 10px;
-+ background-color: #f2f2f2;
-+}
-+
-+img.toggler {
-+ margin-right: 3px;
-+ margin-top: 3px;
-+ cursor: pointer;
-+}
-+
-+/* -- general body styles --------------------------------------------------- */
-+
-+a.headerlink {
-+ visibility: hidden;
-+}
-+
-+h1:hover > a.headerlink,
-+h2:hover > a.headerlink,
-+h3:hover > a.headerlink,
-+h4:hover > a.headerlink,
-+h5:hover > a.headerlink,
-+h6:hover > a.headerlink,
-+dt:hover > a.headerlink {
-+ visibility: visible;
-+}
-+
-+div.body p.caption {
-+ text-align: inherit;
-+}
-+
-+div.body td {
-+ text-align: left;
-+}
-+
-+.field-list ul {
-+ padding-left: 1em;
-+}
-+
-+.first {
-+}
-+
-+p.rubric {
-+ margin-top: 30px;
-+ font-weight: bold;
-+}
-+
-+/* -- sidebars -------------------------------------------------------------- */
-+
-+div.sidebar {
-+ margin: 0 0 0.5em 1em;
-+ border: 1px solid #ddb;
-+ padding: 7px 7px 0 7px;
-+ background-color: #ffe;
-+ width: 40%;
-+ float: right;
-+}
-+
-+p.sidebar-title {
-+ font-weight: bold;
-+}
-+
-+/* -- topics ---------------------------------------------------------------- */
-+
-+div.topic {
-+ border: 1px solid #ccc;
-+ padding: 7px 7px 0 7px;
-+ margin: 10px 0 10px 0;
-+}
-+
-+p.topic-title {
-+ font-size: 1.1em;
-+ font-weight: bold;
-+ margin-top: 10px;
-+}
-+
-+/* -- admonitions ----------------------------------------------------------- */
-+
-+div.admonition {
-+ margin-top: 10px;
-+ margin-bottom: 10px;
-+ padding: 7px;
-+}
-+
-+div.admonition dt {
-+ font-weight: bold;
-+}
-+
-+div.admonition dl {
-+ margin-bottom: 0;
-+}
-+
-+p.admonition-title {
-+ margin: 0px 10px 5px 0px;
-+ font-weight: bold;
-+}
-+
-+div.body p.centered {
-+ text-align: center;
-+ margin-top: 25px;
-+}
-+
-+/* -- tables ---------------------------------------------------------------- */
-+
-+table.docutils {
-+ border: 0;
-+ border-collapse: collapse;
-+}
-+
-+table.docutils td, table.docutils th {
-+ padding: 1px 8px 1px 0;
-+ border-top: 0;
-+ border-left: 0;
-+ border-right: 0;
-+ border-bottom: 1px solid #aaa;
-+}
-+
-+table.field-list td, table.field-list th {
-+ border: 0 !important;
-+}
-+
-+table.footnote td, table.footnote th {
-+ border: 0 !important;
-+}
-+
-+th {
-+ text-align: left;
-+ padding-right: 5px;
-+}
-+
-+/* -- other body styles ----------------------------------------------------- */
-+
-+dl {
-+ margin-bottom: 15px;
-+}
-+
-+dd p {
-+ margin-top: 0px;
-+}
-+
-+dd ul, dd table {
-+ margin-bottom: 10px;
-+}
-+
-+dd {
-+ margin-top: 3px;
-+ margin-bottom: 10px;
-+ margin-left: 30px;
-+}
-+
-+dt:target, .highlight {
-+ background-color: #fbe54e;
-+}
-+
-+dl.glossary dt {
-+ font-weight: bold;
-+ font-size: 1.1em;
-+}
-+
-+.field-list ul {
-+ margin: 0;
-+ padding-left: 1em;
-+}
-+
-+.field-list p {
-+ margin: 0;
-+}
-+
-+.refcount {
-+ color: #060;
-+}
-+
-+.optional {
-+ font-size: 1.3em;
-+}
-+
-+.versionmodified {
-+ font-style: italic;
-+}
-+
-+.system-message {
-+ background-color: #fda;
-+ padding: 5px;
-+ border: 3px solid red;
-+}
-+
-+.footnote:target {
-+ background-color: #ffa
-+}
-+
-+.line-block {
-+ display: block;
-+ margin-top: 1em;
-+ margin-bottom: 1em;
-+}
-+
-+.line-block .line-block {
-+ margin-top: 0;
-+ margin-bottom: 0;
-+ margin-left: 1.5em;
-+}
-+
-+/* -- code displays --------------------------------------------------------- */
-+
-+pre {
-+ overflow: auto;
-+}
-+
-+td.linenos pre {
-+ padding: 5px 0px;
-+ border: 0;
-+ background-color: transparent;
-+ color: #aaa;
-+}
-+
-+table.highlighttable {
-+ margin-left: 0.5em;
-+}
-+
-+table.highlighttable td {
-+ padding: 0 0.5em 0 0.5em;
-+}
-+
-+tt.descname {
-+ background-color: transparent;
-+ font-weight: bold;
-+ font-size: 1.2em;
-+}
-+
-+tt.descclassname {
-+ background-color: transparent;
-+}
-+
-+tt.xref, a tt {
-+ background-color: transparent;
-+ font-weight: bold;
-+}
-+
-+h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
-+ background-color: transparent;
-+}
-+
-+/* -- math display ---------------------------------------------------------- */
-+
-+img.math {
-+ vertical-align: middle;
-+}
-+
-+div.body div.math p {
-+ text-align: center;
-+}
-+
-+span.eqno {
-+ float: right;
-+}
-+
-+/* -- printout stylesheet --------------------------------------------------- */
-+
-+@media print {
-+ div.document,
-+ div.documentwrapper,
-+ div.bodywrapper {
-+ margin: 0 !important;
-+ width: 100%;
-+ }
-+
-+ div.sphinxsidebar,
-+ div.related,
-+ div.footer,
-+ #top-link {
-+ display: none;
-+ }
-+}
-diff --git a/doc/source/_static/default.css b/doc/source/_static/default.css
-new file mode 100644
-index 0000000..c8091ec
---- /dev/null
-+++ b/doc/source/_static/default.css
-@@ -0,0 +1,230 @@
-+/**
-+ * Sphinx stylesheet -- default theme
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ */
-+
-+@import url("basic.css");
-+
-+/* -- page layout ----------------------------------------------------------- */
-+
-+body {
-+ font-family: sans-serif;
-+ font-size: 100%;
-+ background-color: #11303d;
-+ color: #000;
-+ margin: 0;
-+ padding: 0;
-+}
-+
-+div.document {
-+ background-color: #1c4e63;
-+}
-+
-+div.documentwrapper {
-+ float: left;
-+ width: 100%;
-+}
-+
-+div.bodywrapper {
-+ margin: 0 0 0 230px;
-+}
-+
-+div.body {
-+ background-color: #ffffff;
-+ color: #000000;
-+ padding: 0 20px 30px 20px;
-+}
-+
-+div.footer {
-+ color: #ffffff;
-+ width: 100%;
-+ padding: 9px 0 9px 0;
-+ text-align: center;
-+ font-size: 75%;
-+}
-+
-+div.footer a {
-+ color: #ffffff;
-+ text-decoration: underline;
-+}
-+
-+div.related {
-+ background-color: #133f52;
-+ line-height: 30px;
-+ color: #ffffff;
-+}
-+
-+div.related a {
-+ color: #ffffff;
-+}
-+
-+div.sphinxsidebar {
-+}
-+
-+div.sphinxsidebar h3 {
-+ font-family: 'Trebuchet MS', sans-serif;
-+ color: #ffffff;
-+ font-size: 1.4em;
-+ font-weight: normal;
-+ margin: 0;
-+ padding: 0;
-+}
-+
-+div.sphinxsidebar h3 a {
-+ color: #ffffff;
-+}
-+
-+div.sphinxsidebar h4 {
-+ font-family: 'Trebuchet MS', sans-serif;
-+ color: #ffffff;
-+ font-size: 1.3em;
-+ font-weight: normal;
-+ margin: 5px 0 0 0;
-+ padding: 0;
-+}
-+
-+div.sphinxsidebar p {
-+ color: #ffffff;
-+}
-+
-+div.sphinxsidebar p.topless {
-+ margin: 5px 10px 10px 10px;
-+}
-+
-+div.sphinxsidebar ul {
-+ margin: 10px;
-+ padding: 0;
-+ color: #ffffff;
-+}
-+
-+div.sphinxsidebar a {
-+ color: #98dbcc;
-+}
-+
-+div.sphinxsidebar input {
-+ border: 1px solid #98dbcc;
-+ font-family: sans-serif;
-+ font-size: 1em;
-+}
-+
-+/* -- body styles ----------------------------------------------------------- */
-+
-+a {
-+ color: #355f7c;
-+ text-decoration: none;
-+}
-+
-+a:hover {
-+ text-decoration: underline;
-+}
-+
-+div.body p, div.body dd, div.body li {
-+ text-align: left;
-+ line-height: 130%;
-+}
-+
-+div.body h1,
-+div.body h2,
-+div.body h3,
-+div.body h4,
-+div.body h5,
-+div.body h6 {
-+ font-family: 'Trebuchet MS', sans-serif;
-+ background-color: #f2f2f2;
-+ font-weight: normal;
-+ color: #20435c;
-+ border-bottom: 1px solid #ccc;
-+ margin: 20px -20px 10px -20px;
-+ padding: 3px 0 3px 10px;
-+}
-+
-+div.body h1 { margin-top: 0; font-size: 200%; }
-+div.body h2 { font-size: 160%; }
-+div.body h3 { font-size: 140%; }
-+div.body h4 { font-size: 120%; }
-+div.body h5 { font-size: 110%; }
-+div.body h6 { font-size: 100%; }
-+
-+a.headerlink {
-+ color: #c60f0f;
-+ font-size: 0.8em;
-+ padding: 0 4px 0 4px;
-+ text-decoration: none;
-+}
-+
-+a.headerlink:hover {
-+ background-color: #c60f0f;
-+ color: white;
-+}
-+
-+div.body p, div.body dd, div.body li {
-+ text-align: left;
-+ line-height: 130%;
-+}
-+
-+div.admonition p.admonition-title + p {
-+ display: inline;
-+}
-+
-+div.admonition p {
-+ margin-bottom: 5px;
-+}
-+
-+div.admonition pre {
-+ margin-bottom: 5px;
-+}
-+
-+div.admonition ul, div.admonition ol {
-+ margin-bottom: 5px;
-+}
-+
-+div.note {
-+ background-color: #eee;
-+ border: 1px solid #ccc;
-+}
-+
-+div.seealso {
-+ background-color: #ffc;
-+ border: 1px solid #ff6;
-+}
-+
-+div.topic {
-+ background-color: #eee;
-+}
-+
-+div.warning {
-+ background-color: #ffe4e4;
-+ border: 1px solid #f66;
-+}
-+
-+p.admonition-title {
-+ display: inline;
-+}
-+
-+p.admonition-title:after {
-+ content: ":";
-+}
-+
-+pre {
-+ padding: 5px;
-+ background-color: #eeffcc;
-+ color: #333333;
-+ line-height: 120%;
-+ border: 1px solid #ac9;
-+ border-left: none;
-+ border-right: none;
-+}
-+
-+tt {
-+ background-color: #ecf0f3;
-+ padding: 0 1px 0 1px;
-+ font-size: 0.95em;
-+}
-+
-+.warning tt {
-+ background: #efc2c2;
-+}
-+
-+.note tt {
-+ background: #d6d6d6;
-+}
-diff --git a/doc/source/_static/jquery.tweet.js b/doc/source/_static/jquery.tweet.js
-new file mode 100644
-index 0000000..79bf0bd
---- /dev/null
-+++ b/doc/source/_static/jquery.tweet.js
-@@ -0,0 +1,154 @@
-+(function($) {
-+
-+ $.fn.tweet = function(o){
-+ var s = {
-+ username: ["seaofclouds"], // [string] required, unless you want to display our tweets. :) it can be an array, just do ["username1","username2","etc"]
-+ list: null, //[string] optional name of list belonging to username
-+ avatar_size: null, // [integer] height and width of avatar if displayed (48px max)
-+ count: 3, // [integer] how many tweets to display?
-+ intro_text: null, // [string] do you want text BEFORE your your tweets?
-+ outro_text: null, // [string] do you want text AFTER your tweets?
-+ join_text: null, // [string] optional text in between date and tweet, try setting to "auto"
-+ auto_join_text_default: "i said,", // [string] auto text for non verb: "i said" bullocks
-+ auto_join_text_ed: "i", // [string] auto text for past tense: "i" surfed
-+ auto_join_text_ing: "i am", // [string] auto tense for present tense: "i was" surfing
-+ auto_join_text_reply: "i replied to", // [string] auto tense for replies: "i replied to" @someone "with"
-+ auto_join_text_url: "i was looking at", // [string] auto tense for urls: "i was looking at" http:...
-+ loading_text: null, // [string] optional loading text, displayed while tweets load
-+ query: null // [string] optional search query
-+ };
-+
-+ if(o) $.extend(s, o);
-+
-+ $.fn.extend({
-+ linkUrl: function() {
-+ var returning = [];
-+ var regexp = /((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/gi;
-+ this.each(function() {
-+ returning.push(this.replace(regexp,"<a href=\"$1\">$1</a>"));
-+ });
-+ return $(returning);
-+ },
-+ linkUser: function() {
-+ var returning = [];
-+ var regexp = /[\@]+([A-Za-z0-9-_]+)/gi;
-+ this.each(function() {
-+ returning.push(this.replace(regexp,"<a href=\"http://twitter.com/$1\">@$1</a>"));
-+ });
-+ return $(returning);
-+ },
-+ linkHash: function() {
-+ var returning = [];
-+ var regexp = / [\#]+([A-Za-z0-9-_]+)/gi;
-+ this.each(function() {
-+ returning.push(this.replace(regexp, ' <a href="http://search.twitter.com/search?q=&tag=$1&lang=all&from='+s.username.join("%2BOR%2B")+'">#$1</a>'));
-+ });
-+ return $(returning);
-+ },
-+ capAwesome: function() {
-+ var returning = [];
-+ this.each(function() {
-+ returning.push(this.replace(/\b(awesome)\b/gi, '<span class="awesome">$1</span>'));
-+ });
-+ return $(returning);
-+ },
-+ capEpic: function() {
-+ var returning = [];
-+ this.each(function() {
-+ returning.push(this.replace(/\b(epic)\b/gi, '<span class="epic">$1</span>'));
-+ });
-+ return $(returning);
-+ },
-+ makeHeart: function() {
-+ var returning = [];
-+ this.each(function() {
-+ returning.push(this.replace(/(<)+[3]/gi, "<tt class='heart'>♥</tt>"));
-+ });
-+ return $(returning);
-+ }
-+ });
-+
-+ function relative_time(time_value) {
-+ var parsed_date = Date.parse(time_value);
-+ var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
-+ var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
-+ var pluralize = function (singular, n) {
-+ return '' + n + ' ' + singular + (n == 1 ? '' : 's');
-+ };
-+ if(delta < 60) {
-+ return 'less than a minute ago';
-+ } else if(delta < (45*60)) {
-+ return 'about ' + pluralize("minute", parseInt(delta / 60)) + ' ago';
-+ } else if(delta < (24*60*60)) {
-+ return 'about ' + pluralize("hour", parseInt(delta / 3600)) + ' ago';
-+ } else {
-+ return 'about ' + pluralize("day", parseInt(delta / 86400)) + ' ago';
-+ }
-+ }
-+
-+ function build_url() {
-+ var proto = ('https:' == document.location.protocol ? 'https:' : 'http:');
-+ if (s.list) {
-+ return proto+"//api.twitter.com/1/"+s.username[0]+"/lists/"+s.list+"/statuses.json?per_page="+s.count+"&callback=?";
-+ } else if (s.query == null && s.username.length == 1) {
-+ return proto+'//twitter.com/status/user_timeline/'+s.username[0]+'.json?count='+s.count+'&callback=?';
-+ } else {
-+ var query = (s.query || 'from:'+s.username.join('%20OR%20from:'));
-+ return proto+'//search.twitter.com/search.json?&q='+query+'&rpp='+s.count+'&callback=?';
-+ }
-+ }
-+
-+ return this.each(function(){
-+ var list = $('<ul class="tweet_list">').appendTo(this);
-+ var intro = '<p class="tweet_intro">'+s.intro_text+'</p>';
-+ var outro = '<p class="tweet_outro">'+s.outro_text+'</p>';
-+ var loading = $('<p class="loading">'+s.loading_text+'</p>');
-+
-+ if(typeof(s.username) == "string"){
-+ s.username = [s.username];
-+ }
-+
-+ if (s.loading_text) $(this).append(loading);
-+ $.getJSON(build_url(), function(data){
-+ if (s.loading_text) loading.remove();
-+ if (s.intro_text) list.before(intro);
-+ $.each((data.results || data), function(i,item){
-+ // auto join text based on verb tense and content
-+ if (s.join_text == "auto") {
-+ if (item.text.match(/^(@([A-Za-z0-9-_]+)) .*/i)) {
-+ var join_text = s.auto_join_text_reply;
-+ } else if (item.text.match(/(^\w+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+) .*/i)) {
-+ var join_text = s.auto_join_text_url;
-+ } else if (item.text.match(/^((\w+ed)|just) .*/im)) {
-+ var join_text = s.auto_join_text_ed;
-+ } else if (item.text.match(/^(\w*ing) .*/i)) {
-+ var join_text = s.auto_join_text_ing;
-+ } else {
-+ var join_text = s.auto_join_text_default;
-+ }
-+ } else {
-+ var join_text = s.join_text;
-+ };
-+
-+ var from_user = item.from_user || item.user.screen_name;
-+ var profile_image_url = item.profile_image_url || item.user.profile_image_url;
-+ var join_template = '<span class="tweet_join"> '+join_text+' </span>';
-+ var join = ((s.join_text) ? join_template : ' ');
-+ var avatar_template = '<a class="tweet_avatar" href="http://twitter.com/'+from_user+'"><img src="'+profile_image_url+'" height="'+s.avatar_size+'" width="'+s.avatar_size+'" alt="'+from_user+'\'s avatar" title="'+from_user+'\'s avatar" border="0"/></a>';
-+ var avatar = (s.avatar_size ? avatar_template : '');
-+ var date = '<a href="http://twitter.com/'+from_user+'/statuses/'+item.id+'" title="view tweet on twitter">'+relative_time(item.created_at)+'</a>';
-+ var text = '<span class="tweet_text">' +$([item.text]).linkUrl().linkUser().linkHash().makeHeart().capAwesome().capEpic()[0]+ '</span>';
-+
-+ // until we create a template option, arrange the items below to alter a tweet's display.
-+ list.append('<li>' + avatar + date + join + text + '</li>');
-+
-+ list.children('li:first').addClass('tweet_first');
-+ list.children('li:odd').addClass('tweet_even');
-+ list.children('li:even').addClass('tweet_odd');
-+ });
-+ if (s.outro_text) list.after(outro);
-+ });
-+
-+ });
-+ };
-+})(jQuery);
-\ No newline at end of file
-diff --git a/doc/source/_static/tweaks.css b/doc/source/_static/tweaks.css
-new file mode 100644
-index 0000000..046ead8
---- /dev/null
-+++ b/doc/source/_static/tweaks.css
-@@ -0,0 +1,218 @@
-+ul.todo_list {
-+ list-style-type: none;
-+ margin: 0;
-+ padding: 0;
-+}
-+
-+ul.todo_list li {
-+ display: block;
-+ margin: 0;
-+ padding: 7px 0;
-+ border-top: 1px solid #eee;
-+}
-+
-+ul.todo_list li p {
-+ display: inline;
-+}
-+
-+ul.todo_list li p.link {
-+ font-weight: bold;
-+}
-+
-+ul.todo_list li p.details {
-+ font-style: italic;
-+}
-+
-+ul.todo_list li {
-+}
-+
-+div.admonition {
-+ border: 1px solid #8F1000;
-+}
-+
-+div.admonition p.admonition-title {
-+ background-color: #8F1000;
-+ border-bottom: 1px solid #8E8E8E;
-+}
-+
-+a {
-+ color: #CF2F19;
-+}
-+
-+div.related ul li a {
-+ color: #CF2F19;
-+}
-+
-+div.sphinxsidebar h4 {
-+ background-color:#8E8E8E;
-+ border:1px solid #255E6E;
-+ color:white;
-+ font-size:1em;
-+ margin:1em 0 0.5em;
-+ padding:0.1em 0 0.1em 0.5em;
-+}
-+
-+em {
-+ font-style: normal;
-+}
-+
-+table.docutils {
-+ font-size: 11px;
-+}
-+
-+.tweet_list li {
-+ font-size: 0.9em;
-+ border-bottom: 1px solid #eee;
-+ padding: 5px 0;
-+}
-+
-+.tweet_list li .tweet_avatar {
-+ float: left;
-+}
-+
-+/* ------------------------------------------
-+PURE CSS SPEECH BUBBLES
-+by Nicolas Gallagher
-+- http://nicolasgallagher.com/pure-css-speech-bubbles/
-+
-+http://nicolasgallagher.com
-+http://twitter.com/necolas
-+
-+Created: 02 March 2010
-+Version: 1.1 (21 October 2010)
-+
-+Dual licensed under MIT and GNU GPLv2 © Nicolas Gallagher
-+------------------------------------------ */
-+/* THE SPEECH BUBBLE
-+------------------------------------------------------------------------------------------------------------------------------- */
-+
-+/* THE SPEECH BUBBLE
-+------------------------------------------------------------------------------------------------------------------------------- */
-+
-+.triangle-border {
-+ position:relative;
-+ padding:15px;
-+ margin:1em 0 3em;
-+ border:5px solid #BC1518;
-+ color:#333;
-+ background:#fff;
-+
-+ /* css3 */
-+ -moz-border-radius:10px;
-+ -webkit-border-radius:10px;
-+ border-radius:10px;
-+}
-+
-+/* Variant : for left positioned triangle
-+------------------------------------------ */
-+
-+.triangle-border.left {
-+ margin-left:30px;
-+}
-+
-+/* Variant : for right positioned triangle
-+------------------------------------------ */
-+
-+.triangle-border.right {
-+ margin-right:30px;
-+}
-+
-+/* THE TRIANGLE
-+------------------------------------------------------------------------------------------------------------------------------- */
-+
-+.triangle-border:before {
-+ content:"";
-+ display:block; /* reduce the damage in FF3.0 */
-+ position:absolute;
-+ bottom:-40px; /* value = - border-top-width - border-bottom-width */
-+ left:40px; /* controls horizontal position */
-+ width:0;
-+ height:0;
-+ border:20px solid transparent;
-+ border-top-color:#BC1518;
-+}
-+
-+/* creates the smaller triangle */
-+.triangle-border:after {
-+ content:"";
-+ display:block; /* reduce the damage in FF3.0 */
-+ position:absolute;
-+ bottom:-26px; /* value = - border-top-width - border-bottom-width */
-+ left:47px; /* value = (:before left) + (:before border-left) - (:after border-left) */
-+ width:0;
-+ height:0;
-+ border:13px solid transparent;
-+ border-top-color:#fff;
-+}
-+
-+/* Variant : top
-+------------------------------------------ */
-+
-+/* creates the larger triangle */
-+.triangle-border.top:before {
-+ top:-40px; /* value = - border-top-width - border-bottom-width */
-+ right:40px; /* controls horizontal position */
-+ bottom:auto;
-+ left:auto;
-+ border:20px solid transparent;
-+ border-bottom-color:#BC1518;
-+}
-+
-+/* creates the smaller triangle */
-+.triangle-border.top:after {
-+ top:-26px; /* value = - border-top-width - border-bottom-width */
-+ right:47px; /* value = (:before right) + (:before border-right) - (:after border-right) */
-+ bottom:auto;
-+ left:auto;
-+ border:13px solid transparent;
-+ border-bottom-color:#fff;
-+}
-+
-+/* Variant : left
-+------------------------------------------ */
-+
-+/* creates the larger triangle */
-+.triangle-border.left:before {
-+ top:10px; /* controls vertical position */
-+ left:-30px; /* value = - border-left-width - border-right-width */
-+ bottom:auto;
-+ border-width:15px 30px 15px 0;
-+ border-style:solid;
-+ border-color:transparent #BC1518;
-+}
-+
-+/* creates the smaller triangle */
-+.triangle-border.left:after {
-+ top:16px; /* value = (:before top) + (:before border-top) - (:after border-top) */
-+ left:-21px; /* value = - border-left-width - border-right-width */
-+ bottom:auto;
-+ border-width:9px 21px 9px 0;
-+ border-style:solid;
-+ border-color:transparent #fff;
-+}
-+
-+/* Variant : right
-+------------------------------------------ */
-+
-+/* creates the larger triangle */
-+.triangle-border.right:before {
-+ top:10px; /* controls vertical position */
-+ right:-30px; /* value = - border-left-width - border-right-width */
-+ bottom:auto;
-+ left:auto;
-+ border-width:15px 0 15px 30px;
-+ border-style:solid;
-+ border-color:transparent #BC1518;
-+}
-+
-+/* creates the smaller triangle */
-+.triangle-border.right:after {
-+ top:16px; /* value = (:before top) + (:before border-top) - (:after border-top) */
-+ right:-21px; /* value = - border-left-width - border-right-width */
-+ bottom:auto;
-+ left:auto;
-+ border-width:9px 0 9px 21px;
-+ border-style:solid;
-+ border-color:transparent #fff;
-+}
-+
-diff --git a/doc/source/_templates/.gitignore b/doc/source/_templates/.gitignore
-new file mode 100644
-index 0000000..e69de29
-diff --git a/doc/source/_templates/.placeholder b/doc/source/_templates/.placeholder
-new file mode 100644
-index 0000000..e69de29
-diff --git a/doc/source/_theme/layout.html b/doc/source/_theme/layout.html
-new file mode 100644
-index 0000000..f5b388c
---- /dev/null
-+++ b/doc/source/_theme/layout.html
-@@ -0,0 +1,95 @@
-+{% extends "sphinxdoc/layout.html" %}
-+{% set css_files = css_files + ['_static/tweaks.css'] %}
-+{% set script_files = script_files + ['_static/jquery.tweet.js'] %}
-+{% block extrahead %}
-+ <script type='text/javascript'>
-+ $(document).ready(function(){
-+ $("#twitter_feed").tweet({
-+ username: "openstack",
-+ query: "from:openstack",
-+ avatar_size: 32,
-+ count: 10,
-+ loading_text: "loading tweets..."
-+ });
-+ });
-+ </script>
-+{% endblock %}
-+
-+{%- macro sidebar() %}
-+ {%- if not embedded %}{% if not theme_nosidebar|tobool %}
-+ <div class="sphinxsidebar">
-+ <div class="sphinxsidebarwrapper">
-+ {%- block sidebarlogo %}
-+ {%- if logo %}
-+ <p class="logo"><a href="{{ pathto(master_doc) }}">
-+ <img class="logo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/>
-+ </a></p>
-+ {%- endif %}
-+ {%- endblock %}
-+ {%- block sidebartoc %}
-+ {%- if display_toc %}
-+ <h3><a href="{{ pathto(master_doc) }}">{{ _('Table Of Contents') }}</a></h3>
-+ {{ toc }}
-+ {%- endif %}
-+ {%- endblock %}
-+ {%- block sidebarrel %}
-+ {%- if prev %}
-+ <h4>{{ _('Previous topic') }}</h4>
-+ <p class="topless"><a href="{{ prev.link|e }}"
-+ title="{{ _('previous chapter') }}">{{ prev.title }}</a></p>
-+ {%- endif %}
-+ {%- if next %}
-+ <h4>{{ _('Next topic') }}</h4>
-+ <p class="topless"><a href="{{ next.link|e }}"
-+ title="{{ _('next chapter') }}">{{ next.title }}</a></p>
-+ {%- endif %}
-+ {%- endblock %}
-+ {%- block sidebarsourcelink %}
-+ {%- if show_source and has_source and sourcename %}
-+ <h3>{{ _('This Page') }}</h3>
-+ <ul class="this-page-menu">
-+ <li><a href="{{ pathto('_sources/' + sourcename, true)|e }}"
-+ rel="nofollow">{{ _('Show Source') }}</a></li>
-+ </ul>
-+ {%- endif %}
-+ {%- endblock %}
-+ {%- if customsidebar %}
-+ {% include customsidebar %}
-+ {%- endif %}
-+ {%- block sidebarsearch %}
-+ {%- if pagename != "search" %}
-+ <div id="searchbox" style="display: none">
-+ <h3>{{ _('Quick search') }}</h3>
-+ <form class="search" action="{{ pathto('search') }}" method="get">
-+ <input type="text" name="q" size="18" />
-+ <input type="submit" value="{{ _('Go') }}" />
-+ <input type="hidden" name="check_keywords" value="yes" />
-+ <input type="hidden" name="area" value="default" />
-+ </form>
-+ <p class="searchtip" style="font-size: 90%">
-+ {{ _('Enter search terms or a module, class or function name.') }}
-+ </p>
-+ </div>
-+ <script type="text/javascript">$('#searchbox').show(0);</script>
-+
-+ <p class="triangle-border right">
-+ Psst... hey. You're reading the latest content, but it's for the Block Storage project only. You can read <a href="http://docs.openstack.org">all OpenStack docs</a> too.
-+ </p>
-+
-+ {%- endif %}
-+
-+ {%- if pagename == "index" %}
-+
-+
-+ <h3>{{ _('Twitter Feed') }}</h3>
-+ <div id="twitter_feed" class='twitter_feed'></div>
-+ {%- endif %}
-+
-+
-+
-+
-+ {%- endblock %}
-+ </div>
-+ </div>
-+ {%- endif %}{% endif %}
-+{%- endmacro %}
-diff --git a/doc/source/_theme/theme.conf b/doc/source/_theme/theme.conf
-new file mode 100644
-index 0000000..e039fe0
---- /dev/null
-+++ b/doc/source/_theme/theme.conf
-@@ -0,0 +1,5 @@
-+[theme]
-+inherit = sphinxdoc
-+stylesheet = sphinxdoc.css
-+pygments_style = friendly
-+
-diff --git a/doc/source/conf.py b/doc/source/conf.py
-index ac2eadc..58fc367 100644
---- a/doc/source/conf.py
-+++ b/doc/source/conf.py
-@@ -33,9 +33,7 @@ extensions = ['sphinx.ext.autodoc',
- 'sphinx.ext.coverage',
- 'sphinx.ext.pngmath',
- 'sphinx.ext.ifconfig',
-- 'sphinx.ext.graphviz',
-- 'oslosphinx',
-- ]
-+ 'sphinx.ext.graphviz']
-
- # autodoc generation is a bit aggressive and a nuisance
- # when doing heavy text edit cycles. Execute "export SPHINX_DEBUG=1"
-@@ -133,8 +131,8 @@ man_pages = [
-
- # The theme to use for HTML and HTML Help pages. Major themes that come with
- # Sphinx are currently 'default' and 'sphinxdoc'.
--# html_theme_path = ["."]
--# html_theme = '_theme'
-+html_theme_path = ["."]
-+html_theme = '_theme'
-
- # Theme options are theme-specific and customize the look and feel of a theme
- # further. For a list of options available for each theme, see the
-diff --git a/test-requirements.txt b/test-requirements.txt
-index 56746da..cabe88a 100644
---- a/test-requirements.txt
-+++ b/test-requirements.txt
-@@ -13,4 +13,3 @@ sphinx>=1.1.2,<1.2
- python-subunit>=0.0.18
- testtools>=0.9.34
- testrepository>=0.0.18
--oslosphinx
---
-1.7.9.5
-
--- /dev/null
+From 5c26d073f2a95b252928cee902ed53e606a7c20d Mon Sep 17 00:00:00 2001
+From: Alan Pevec <apevec@redhat.com>
+Date: Tue, 11 Feb 2014 22:36:00 +0100
+Subject: [PATCH] notify calling process we are ready to serve
+
+Systemd notification should be sent in-process, otherwise systemd might
+miss the subprocess sending notification.
+See systemd bug https://bugzilla.redhat.com/show_bug.cgi?id=820448
+
+Taken from keystone project commit
+abc06716d027d68f0da3b0f559fa7c85a21804d5
+
+Improvements from Keystone version:
+
+ * add unset_environment parameter
+ New parameter unset_environment was added to sd_notify
+ http://www.freedesktop.org/software/systemd/man/sd_notify.html
+ to ensure service readiness is sent only once.
+
+ * add onready() method to simulate systemd environment
+ For testing purposes and optional use with SysV initscripts.
+
+ * unit test added
+
+ * docstrings for notification methods
+
+Patch includes deployment in openstack.common.service.
+It does not have an effect when running the service outside
+the systemd environment.
+
+Implements: blueprint service-readiness
+Change-Id: I80f325c9be9c171c2dc8d5526570bf64f0f87c78
+---
+ cinder/openstack/common/service.py | 2 +
+ cinder/openstack/common/systemd.py | 104 +++++++++++++++++++++++++++++++++++++
+ 2 files changed, 106 insertions(+)
+ create mode 100644 cinder/openstack/common/systemd.py
+
+diff --git a/cinder/openstack/common/service.py b/cinder/openstack/common/service.py
+index 7632625..128d113 100644
+--- a/cinder/openstack/common/service.py
++++ b/cinder/openstack/common/service.py
+@@ -41,6 +41,7 @@ from cinder.openstack.common import eventlet_backdoor
+ from cinder.openstack.common.gettextutils import _
+ from cinder.openstack.common import importutils
+ from cinder.openstack.common import log as logging
++from cinder.openstack.common import systemd
+ from cinder.openstack.common import threadgroup
+
+
+@@ -481,6 +482,7 @@ class Services(object):
+
+ """
+ service.start()
++ systemd.notify_once()
+ done.wait()
+
+
+diff --git a/cinder/openstack/common/systemd.py b/cinder/openstack/common/systemd.py
+new file mode 100644
+index 0000000..d9fd0b7
+--- /dev/null
++++ b/cinder/openstack/common/systemd.py
+@@ -0,0 +1,104 @@
++# Copyright 2012-2014 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.
++
++"""
++Helper module for systemd service readiness notification.
++"""
++
++import os
++import socket
++import sys
++
++from cinder.openstack.common import log as logging
++
++
++LOG = logging.getLogger(__name__)
++
++
++def _abstractify(socket_name):
++ if socket_name.startswith('@'):
++ # abstract namespace socket
++ socket_name = '\0%s' % socket_name[1:]
++ return socket_name
++
++
++def _sd_notify(unset_env, msg):
++ notify_socket = os.getenv('NOTIFY_SOCKET')
++ if notify_socket:
++ sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
++ try:
++ sock.connect(_abstractify(notify_socket))
++ sock.sendall(msg)
++ if unset_env:
++ del os.environ['NOTIFY_SOCKET']
++ except EnvironmentError:
++ LOG.debug("Systemd notification failed", exc_info=True)
++ finally:
++ sock.close()
++
++
++def notify():
++ """Send notification to Systemd that service is ready.
++ For details see
++ http://www.freedesktop.org/software/systemd/man/sd_notify.html
++ """
++ _sd_notify(False, 'READY=1')
++
++
++def notify_once():
++ """Send notification once to Systemd that service is ready.
++ Systemd sets NOTIFY_SOCKET environment variable with the name of the
++ socket listening for notifications from services.
++ This method removes the NOTIFY_SOCKET environment variable to ensure
++ notification is sent only once.
++ """
++ _sd_notify(True, 'READY=1')
++
++
++def onready(notify_socket, timeout):
++ """Wait for systemd style notification on the socket.
++
++ :param notify_socket: local socket address
++ :type notify_socket: string
++ :param timeout: socket timeout
++ :type timeout: float
++ :returns: 0 service ready
++ 1 service not ready
++ 2 timeout occured
++ """
++ sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
++ sock.settimeout(timeout)
++ sock.bind(_abstractify(notify_socket))
++ try:
++ msg = sock.recv(512)
++ except socket.timeout:
++ return 2
++ finally:
++ sock.close()
++ if 'READY=1' in msg:
++ return 0
++ else:
++ return 1
++
++
++if __name__ == '__main__':
++ # simple CLI for testing
++ if len(sys.argv) == 1:
++ notify()
++ elif len(sys.argv) >= 2:
++ timeout = float(sys.argv[1])
++ notify_socket = os.getenv('NOTIFY_SOCKET')
++ if notify_socket:
++ retval = onready(notify_socket, timeout)
++ sys.exit(retval)
--- /dev/null
+From 3a494224142ed9d59ad86e32c5c5565a5b9ebca8 Mon Sep 17 00:00:00 2001
+From: Alan Pevec <apevec@redhat.com>
+Date: Mon, 14 Apr 2014 18:11:04 +0200
+Subject: [PATCH] Move notification point to a better place
+
+Follow-up for I80f325c9be9c171c2dc8d5526570bf64f0f87c78
+"notify calling process we are ready to serve"
+
+Xavier Queralt found issue with sending readiness notification from inside
+run_service: it returns premature OK in case of multiple service endpoints
+in one systemd service like nova-api which by default provides osapi, ec2 and
+metadata services.
+
+Instead, send readiness notification before entering wait loop for each
+Launcher type.
+
+Change-Id: I69bf10f353f5fecaaf89e537c2d3c46b73e39d36
+Implements: blueprint service-readiness
+---
+ cinder/openstack/common/service.py | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/cinder/openstack/common/service.py b/cinder/openstack/common/service.py
+index 128d113..cb4fee7 100644
+--- a/cinder/openstack/common/service.py
++++ b/cinder/openstack/common/service.py
+@@ -190,6 +190,7 @@ class ServiceLauncher(Launcher):
+ return status, signo
+
+ def wait(self, ready_callback=None):
++ systemd.notify_once()
+ while True:
+ self.handle_signal()
+ status, signo = self._wait_for_exit_or_signal(ready_callback)
+@@ -382,6 +383,7 @@ class ProcessLauncher(object):
+ def wait(self):
+ """Loop waiting on children to die and respawning as necessary."""
+
++ systemd.notify_once()
+ LOG.debug(_('Full set of CONF:'))
+ CONF.log_opt_values(LOG, std_logging.DEBUG)
+
+@@ -482,7 +484,6 @@ class Services(object):
+
+ """
+ service.start()
+- systemd.notify_once()
+ done.wait()
+
+
state_path = /var/lib/cinder
lock_path = /var/lib/cinder/tmp
volumes_dir = /etc/cinder/volumes
-iscsi_helper = tgtadm
+iscsi_helper = lioadm
sql_connection = mysql://cinder:cinder@localhost/cinder
-rpc_backend = cinder.openstack.common.rpc.impl_qpid
rootwrap_config = /etc/cinder/rootwrap.conf
auth_strategy = keystone
-# Note this config mode is not supported by scsi-target-utils in RHEL <= 6.4
-# include /etc/cinder/volumes/
-# So instead please add the following line (without the leading comment char)
-# to the top of /etc/tgt/targets.conf
-# include /etc/cinder/volumes/*
+include /etc/cinder/volumes/
+++ /dev/null
-description "OpenStack Cinder API Server"
-
-start on stopped rc RUNLEVEL=[2345]
-stop on runlevel [S016]
-
-respawn
-
-exec su -s /bin/sh -c "exec /usr/bin/cinder-api --config-file /usr/share/cinder/cinder-dist.conf --config-file /etc/cinder/cinder.conf --logfile /var/log/cinder/api.log" cinder
+++ /dev/null
-description "OpenStack Cinder Backup Server"
-
-start on stopped rc RUNLEVEL=[2345]
-stop on runlevel [S016]
-
-respawn
-
-exec su -s /bin/sh -c "exec /usr/bin/cinder-backup --config-file /usr/share/cinder/cinder-dist.conf --config-file /etc/cinder/cinder.conf --logfile /var/log/cinder/backup.log" cinder
+++ /dev/null
-description "OpenStack Cinder Scheduler Server"
-
-start on stopped rc RUNLEVEL=[2345]
-stop on runlevel [S016]
-
-respawn
-
-exec su -s /bin/sh -c "exec /usr/bin/cinder-scheduler --config-file /usr/share/cinder/cinder-dist.conf --config-file /etc/cinder/cinder.conf --logfile /var/log/cinder/scheduler.log" cinder
+++ /dev/null
-description "OpenStack Cinder Volume Server"
-
-start on stopped rc RUNLEVEL=[2345]
-stop on runlevel [S016]
-
-respawn
-
-exec su -s /bin/sh -c "exec /usr/bin/cinder-volume --config-file /usr/share/cinder/cinder-dist.conf --config-file /etc/cinder/cinder.conf --logfile /var/log/cinder/volume.log" cinder
%global with_doc %{!?_without_doc:1}%{?_without_doc:0}
Name: openstack-cinder
-Version: 2014.1
-Release: 0.2.rc1%{?dist}
+Version: 2014.1.1
+Release: 2%{?dist}
Summary: OpenStack Volume service
Group: Applications/System
License: ASL 2.0
URL: http://www.openstack.org/software/openstack-storage/
-Source0: https://launchpad.net/cinder/icehouse/icehouse-1/+download/cinder-%{version}.b1.tar.gz
+Source0: https://launchpad.net/cinder/icehouse/2014.1/+download/cinder-%{version}.tar.gz
Source1: cinder-dist.conf
Source2: cinder.logrotate
Source3: cinder-tgt.conf
Source10: openstack-cinder-api.init
-Source100: openstack-cinder-api.upstart
Source11: openstack-cinder-scheduler.init
-Source110: openstack-cinder-scheduler.upstart
Source12: openstack-cinder-volume.init
-Source120: openstack-cinder-volume.upstart
Source13: openstack-cinder-backup.init
-Source130: openstack-cinder-backup.upstart
Source20: cinder-sudoers
#
-# patches_base=2014.1.b1
+# patches_base=2014.1.1
#
Patch0001: 0001-Ensure-we-don-t-access-the-net-when-building-docs.patch
-Patch0002: 0002-Use-updated-parallel-install-versions-of-epel-packag.patch
-Patch0003: 0003-Remove-runtime-dep-on-python-pbr-python-d2to1.patch
-Patch0004: 0004-Revert-Use-oslo.sphinx-and-remove-local-copy-of-doc-.patch
+Patch0002: 0002-Remove-runtime-dep-on-python-pbr-python-d2to1.patch
+Patch0003: 0003-Revert-Switch-over-to-oslosphinx.patch
+Patch0004: 0004-notify-calling-process-we-are-ready-to-serve.patch
+Patch0005: 0005-Move-notification-point-to-a-better-place.patch
BuildArch: noarch
BuildRequires: intltool
BuildRequires: python-d2to1
+BuildRequires: python-oslo-sphinx
BuildRequires: python-pbr
-BuildRequires: python-sphinx10
+BuildRequires: python-sphinx
BuildRequires: python-setuptools
BuildRequires: python-netaddr
-BuildRequires: openstack-utils
-BuildRequires: python-paste-deploy1.5
-BuildRequires: python-routes1.12
-BuildRequires: python-sqlalchemy0.7
-BuildRequires: python-webob1.2
Requires: openstack-utils
Requires: python-cinder = %{version}-%{release}
Requires: python-stevedore
Requires: python-suds
-Requires: python-sqlalchemy0.7
+Requires: python-sqlalchemy
Requires: python-migrate
-Requires: python-paste-deploy1.5
-Requires: python-routes1.12
-Requires: python-webob1.2
+Requires: python-paste-deploy
+Requires: python-routes
+Requires: python-webob
Requires: python-glanceclient >= 1:0
Requires: python-swiftclient >= 1.2
Requires: python-novaclient >= 1:2.15
Requires: python-oslo-config >= 1:1.2.0
-Requires: python-six >= 1.4.1
+Requires: python-six >= 1.5.0
Requires: python-babel
Requires: python-lockfile
Requires: python-oslo-rootwrap
Requires: python-taskflow
+Requires: python-oslo-messaging >= 1.3.0-0.1.a9
Requires: python-ceph
+#Requires: iscsi-initiator-utils
%description -n python-cinder
OpenStack Volume (codename Cinder) provides services to manage and
# Required to build module documents
BuildRequires: python-eventlet
-BuildRequires: python-routes1.12
-BuildRequires: python-sqlalchemy0.7
-BuildRequires: python-webob1.2
+BuildRequires: python-routes
+BuildRequires: python-sqlalchemy
+BuildRequires: python-webob
# while not strictly required, quiets the build down when building docs.
BuildRequires: python-migrate, python-iso8601
%patch0002 -p1
%patch0003 -p1
%patch0004 -p1
+%patch0005 -p1
find . \( -name .gitignore -o -name .placeholder \) -delete
sed -i s/REDHATCINDERRELEASE/%{release}/ cinder/version.py
%build
-
-# Move authtoken configuration out of paste.ini
-openstack-config --del etc/cinder/api-paste.ini filter:authtoken admin_tenant_name
-openstack-config --del etc/cinder/api-paste.ini filter:authtoken admin_user
-openstack-config --del etc/cinder/api-paste.ini filter:authtoken admin_password
-openstack-config --del etc/cinder/api-paste.ini filter:authtoken auth_host
-openstack-config --del etc/cinder/api-paste.ini filter:authtoken auth_port
-openstack-config --del etc/cinder/api-paste.ini filter:authtoken auth_protocol
-
%{__python} setup.py build
%install
pushd doc
%if 0%{?with_doc}
-SPHINX_DEBUG=1 sphinx-1.0-build -b html source build/html
+SPHINX_DEBUG=1 sphinx-build -b html source build/html
# Fix hidden-file-or-dir warnings
rm -fr build/html/.doctrees build/html/.buildinfo
%endif
# Create dir link to avoid a sphinx-build exception
mkdir -p build/man/.doctrees/
ln -s . build/man/.doctrees/man
-SPHINX_DEBUG=1 sphinx-1.0-build -b man -c source source/man build/man
+SPHINX_DEBUG=1 sphinx-build -b man -c source source/man build/man
mkdir -p %{buildroot}%{_mandir}/man1
install -p -D -m 644 build/man/*.1 %{buildroot}%{_mandir}/man1/
# Install pid directory
install -d -m 755 %{buildroot}%{_localstatedir}/run/cinder
-# Install upstart jobs examples
-install -d -m 755 %{buildroot}%{_datadir}/cinder
-install -p -m 644 %{SOURCE100} %{buildroot}%{_datadir}/cinder/
-install -p -m 644 %{SOURCE110} %{buildroot}%{_datadir}/cinder/
-install -p -m 644 %{SOURCE120} %{buildroot}%{_datadir}/cinder/
-install -p -m 644 %{SOURCE130} %{buildroot}%{_datadir}/cinder/
-
# Install rootwrap files in /usr/share/cinder/rootwrap
mkdir -p %{buildroot}%{_datarootdir}/cinder/rootwrap/
install -p -D -m 644 etc/cinder/rootwrap.d/* %{buildroot}%{_datarootdir}/cinder/rootwrap/
%endif
%changelog
+* Wed Jun 11 2014 Eric Harney <eharney@redhat.com> - 2014.1.1-2
+- Add dependency on iscsi-initiator-utils
+
+* Mon Jun 09 2014 Eric Harney <eharney@redhat.com> - 2014.1.1-1
+- Update to Icehouse stable release 1
+
+* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2014.1-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
+
+* Tue Apr 29 2014 Alan Pevec <apevec@redhat.com> - 2014.1-3
+- drop crudini build dependency
+
+* Mon Apr 21 2014 Eric Harney <eharney@redhat.com> - 2014.1-2
+- Remove qpid settings from cinder-dist.conf
+
+* Thu Apr 17 2014 Eric Harney <eharney@redhat.com> - 2014.1-1
+- Update to 2014.1 (Icehouse)
+
+* Tue Apr 15 2014 Eric Harney <eharney@redhat.com> - 2014.1-0.10.rc3
+- Add python-oslo-messaging requirement
+- Add GlusterFS delete patch
+- Add systemd patches (not used yet)
+
+* Tue Apr 15 2014 Eric Harney <eharney@redhat.com> - 2014.1-0.9.rc3
+- Update to Icehouse RC3
+
+* Mon Apr 07 2014 Eric Harney <eharney@redhat.com> - 2014.1-0.8.rc2
+- Update to Icehouse RC2
+- Icehouse requires newer version of python-six
+
+* Thu Mar 27 2014 Eric Harney <eharney@redhat.com> - 2014.1-0.7.rc1
+- Update to Icehouse RC1
+
+* Tue Mar 25 2014 Pádraig Brady <pbrady@redhat.com> - 2014.1-0.6.b3
+- Depend on python-rtslib and targetcli rather than scsi-target-utils
+
+* Fri Mar 21 2014 Pádraig Brady <pbrady@redhat.com> - 2014.1-0.5.b3
+- Use lioadm iSCSI helper rather than tgtadm
+
+* Sun Mar 16 2014 Eric Harney <eharney@redhat.com> - 2014.1-0.4.b3
+- Update to Icehouse milestone 3
+- Add deps on python-oslo-rootwrap, python-taskflow
+
+* Mon Jan 27 2014 Eric Harney <eharney@redhat.com> - 2014.1-0.3.b2
+- Update to Icehouse milestone 2
+
* Mon Jan 06 2014 Pádraig Brady <pbrady@redhat.com> - 2014.1-0.2.b1
- Set python-six min version to ensure updated
* Thu Dec 19 2013 Eric Harney <eharney@redhat.com> - 2014.1-0.1.b1
- Update to Icehouse milestone 1
-* Tue Dec 17 2013 Eric Harney <eharney@redhat.com> - 2013.2.1-1
-- Update to Havana stable release 1
-
* Mon Oct 28 2013 Eric Harney <eharney@redhat.com> - 2013.2-2
- Fix GlusterFS volume driver clone operations
* Thu Oct 17 2013 Eric Harney <eharney@redhat.com> - 2013.2-1
- Update to 2013.2 (Havana)
-- Handle cinder-backup service registration/restart/removal
+- Restart/remove cinder-backup service during upgrade/uninstallation
* Wed Oct 16 2013 Eric Harney <eharney@redhat.com> - 2013.2-0.13.rc3
- Update to Havana RC3
-* Tue Oct 15 2013 Eric Harney <eharney@redhat.com> - 2013.2-0.12.rc2
+* Fri Oct 11 2013 Eric Harney <eharney@redhat.com> - 2013.2-0.12.rc2
- Update to Havana RC2
* Tue Oct 08 2013 Eric Harney <eharney@redhat.com> - 2013.2-0.11.rc1
* Thu Aug 29 2013 Pádraig Brady <pbrady@redhat.com> - 2013.2-0.7.b2
- Add dependency on sysfsutils to support the fiber channel driver
-* Mon Aug 26 2013 Eric Harney <eharney@redhat.com> - 2013.2-0.5.b2
+* Mon Aug 26 2013 Eric Harney <eharney@redhat.com> - 2013.2-0.6.b2
- Add cinder-backup service init script
+* Sat Aug 03 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2013.2-0.5.b2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
+
* Mon Jul 22 2013 Pádraig Brady <pbrady@redhat.com> - 2013.2-0.4.b2
- Add dependency on python-suds to support the netapp driver
- Add dependency on python-keystoneclient for auth token middleware
* Thu Jun 13 2013 Eric Harney <eharney@redhat.com> - 2013.2-0.2.b1
- Update to Havana milestone 1
-* Fri May 10 2013 Eric Harney <eharney@redhat.com> - 2013.1.1-1
-- Update to Grizzly stable release 1
+* Mon May 13 2013 Eric Harney <eharney@redhat.com> - 2013.1.1-1
+- Update to Grizzly stable release 1, 2013.1.1
* Mon Apr 08 2013 Eric Harney <eharney@redhat.com> - 2013.1-2
- Backport fix for GlusterFS driver get_volume_stats
-- Adjust to support sqlalchemy-0.8.0
* Thu Apr 04 2013 Eric Harney <eharney@redhat.com> - 2013.1-1
- Update to Grizzly final release
+* Tue Apr 2 2013 Pádraig Brady <pbrady@redhat.com> - 2013.1-0.6.rc3
+- Adjust to support sqlalchemy-0.8.0
+
* Wed Mar 27 2013 Eric Harney <eharney@redhat.com> - 2013.1-0.5.rc3
- Update to Grizzly RC3 release
* Tue Mar 05 2013 Pádraig Brady <P@draigBrady.com> - 2013.1-0.4.g3
- Add dependency on python-stevedore
-* Wed Feb 27 2013 Eric Harney <eharney@redhat.com> - 2013.1-0.2.g3
+* Mon Feb 25 2013 Eric Harney <eharney@redhat.com> - 2013.1-0.3.g3
+- Fix build issues with G-3 update
+
+* Mon Feb 25 2013 Eric Harney <eharney@redhat.com> - 2013.1-0.2.g3
- Update to Grizzly milestone 3
+* Thu Feb 14 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2013.1-0.2.g2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
+
* Thu Jan 10 2013 Eric Harney <eharney@redhat.com> - 2013.1-0.1.g2
- Update to Grizzly milestone 2
-* Thu Dec 20 2012 Eric Harney <eharney@redhat.com> - 2013.1-0.1.g1
+* Thu Nov 29 2012 Eric Harney <eharney@redhat.com> - 2013.1-0.1.g1
- Update to Grizzly milestone 1
-* Mon Dec 03 2012 Eric Harney <eharney@redhat.com> - 2012.2.1-1
-- Update to Folsom stable release 1
-
-* Wed Nov 14 2012 Eric Harney <eharney@redhat.com> - 2012.2-4
+* Wed Nov 14 2012 Eric Harney <eharney@redhat.com> - 2012.2-2
- Remove unused dependency on python-daemon
-* Wed Oct 31 2012 Pádraig Brady <P@draigBrady.com> - 2012.2-3
-- Adjust to be compatible with python-migrate-0.6
+* Thu Sep 27 2012 Pádraig Brady <P@draigBrady.com> - 2012.2-1
+- Update to Folsom final
+
+* Fri Sep 21 2012 Pádraig Brady <P@draigBrady.com> - 2012.2-0.5.rc1
+- Update to Folsom RC1
+
+* Fri Sep 21 2012 Pádraig Brady <P@draigBrady.com> - 2012.2-0.4.f3
+- Fix to ensure that tgt configuration is honored
+
+* Mon Sep 17 2012 Pádraig Brady <P@draigBrady.com> - 2012.2-0.3.f3
+- Move user config out of /etc/cinder/api-paste.ini
+- Require python-cinderclient
-* Wed Oct 24 2012 Pádraig Brady <P@draigBrady.com> - 2012.2-2
-- Initial Folsom release
+* Mon Sep 3 2012 Pádraig Brady <P@draigBrady.com> - 2012.2-0.2.f3
+- Initial release