summaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorJoe Heck <heckj@mac.com>2012-01-19 17:30:27 -0800
committerJoe Heck <heckj@mac.com>2012-01-19 17:30:40 -0800
commitf40198dece0b3729e6eb70abaa972bd73ee827da (patch)
tree737b41d3e0867134b143644f30bed12ddab4491f /docs
parentffeb0e558ca1108df02c53c9170e73020e57e67c (diff)
downloadkeystone-f40198dece0b3729e6eb70abaa972bd73ee827da.tar.gz
keystone-f40198dece0b3729e6eb70abaa972bd73ee827da.tar.xz
keystone-f40198dece0b3729e6eb70abaa972bd73ee827da.zip
shimming in basics from original keystone
Diffstat (limited to 'docs')
-rwxr-xr-xdocs/generate_autodoc_index.py76
-rw-r--r--docs/source/_static/basic.css416
-rw-r--r--docs/source/_static/default.css230
-rw-r--r--docs/source/_static/jquery.tweet.js154
-rw-r--r--docs/source/_static/tweaks.css65
-rw-r--r--docs/source/_templates/.placeholder0
-rw-r--r--docs/source/_theme/layout.html86
-rw-r--r--docs/source/_theme/theme.conf5
-rw-r--r--docs/source/community.rst93
-rw-r--r--docs/source/conf.py12
-rw-r--r--docs/source/developing.rst135
-rw-r--r--docs/source/index.rst58
-rw-r--r--docs/source/man/keystone-manage.rst192
-rw-r--r--docs/source/man/keystone.rst90
-rw-r--r--docs/source/setup.rst151
-rw-r--r--docs/source/testing.rst77
16 files changed, 1832 insertions, 8 deletions
diff --git a/docs/generate_autodoc_index.py b/docs/generate_autodoc_index.py
new file mode 100755
index 00000000..993369b0
--- /dev/null
+++ b/docs/generate_autodoc_index.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python
+"""Generates files for sphinx documentation using a simple Autodoc based
+template.
+
+To use, just run as a script:
+ $ python doc/generate_autodoc_index.py
+"""
+
+import os
+
+
+base_dir = os.path.dirname(os.path.abspath(__file__))
+RSTDIR=os.path.join(base_dir, "source", "sourcecode")
+SOURCEDIR=os.path.join(base_dir, "..")
+
+# Exclude these modules from the autodoc results
+EXCLUDE_MODULES = ['keystone.backends.sqlalchemy.migrate_repo']
+
+def in_exclude_list(module_name):
+ """Compares a module to the list of excluded modules
+
+ Returns true if the provided module resides in or matches
+ an excluded module, false otherwise.
+ """
+ for excluded_module in EXCLUDE_MODULES:
+ if module_name.startswith(excluded_module):
+ return True
+ return False
+
+def find_autodoc_modules(module_name, sourcedir):
+ """returns a list of modules in the SOURCE directory"""
+ modlist = []
+ os.chdir(os.path.join(sourcedir, module_name))
+ for root, dirs, files in os.walk("."):
+ for filename in files:
+ if filename.endswith(".py"):
+ # root = ./keystone/test/unit
+ # filename = base.py
+ elements = root.split(os.path.sep)
+ # replace the leading "." with the module name
+ elements[0] = module_name
+ # and get the base module name
+ base, extension = os.path.splitext(filename)
+ if not (base == "__init__"):
+ elements.append(base)
+ result = (".".join(elements))
+ if not in_exclude_list(result):
+ modlist.append(result)
+ return modlist
+
+if not(os.path.exists(RSTDIR)):
+ os.mkdir(RSTDIR)
+
+INDEXOUT = open("%s/autoindex.rst" % RSTDIR, "w")
+INDEXOUT.write("Source Code Index\n")
+INDEXOUT.write("=================\n")
+INDEXOUT.write(".. toctree::\n")
+INDEXOUT.write(" :maxdepth: 1\n")
+INDEXOUT.write("\n")
+
+for module in find_autodoc_modules('keystone', SOURCEDIR):
+ generated_file = "%s/%s.rst" % (RSTDIR, module)
+
+ INDEXOUT.write(" %s\n" % module)
+ FILEOUT = open(generated_file, "w")
+ FILEOUT.write("The :mod:`%s` Module\n" % module)
+ FILEOUT.write("=============================="
+ "=============================="
+ "==============================\n")
+ FILEOUT.write(".. automodule:: %s\n" % module)
+ FILEOUT.write(" :members:\n")
+ FILEOUT.write(" :undoc-members:\n")
+ FILEOUT.write(" :show-inheritance:\n")
+ FILEOUT.close()
+
+INDEXOUT.close()
diff --git a/docs/source/_static/basic.css b/docs/source/_static/basic.css
new file mode 100644
index 00000000..d909ce37
--- /dev/null
+++ b/docs/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/docs/source/_static/default.css b/docs/source/_static/default.css
new file mode 100644
index 00000000..c8091ecb
--- /dev/null
+++ b/docs/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/docs/source/_static/jquery.tweet.js b/docs/source/_static/jquery.tweet.js
new file mode 100644
index 00000000..c93fea87
--- /dev/null
+++ b/docs/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(/(&lt;)+[3]/gi, "<tt class='heart'>&#x2665;</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/docs/source/_static/tweaks.css b/docs/source/_static/tweaks.css
new file mode 100644
index 00000000..16cd6e76
--- /dev/null
+++ b/docs/source/_static/tweaks.css
@@ -0,0 +1,65 @@
+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;
+}
+
+a tt {
+ color:#CF2F19;
+} \ No newline at end of file
diff --git a/docs/source/_templates/.placeholder b/docs/source/_templates/.placeholder
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/docs/source/_templates/.placeholder
diff --git a/docs/source/_theme/layout.html b/docs/source/_theme/layout.html
new file mode 100644
index 00000000..e3eb54b7
--- /dev/null
+++ b/docs/source/_theme/layout.html
@@ -0,0 +1,86 @@
+{% 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>
+ {%- 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/docs/source/_theme/theme.conf b/docs/source/_theme/theme.conf
new file mode 100644
index 00000000..e039fe01
--- /dev/null
+++ b/docs/source/_theme/theme.conf
@@ -0,0 +1,5 @@
+[theme]
+inherit = sphinxdoc
+stylesheet = sphinxdoc.css
+pygments_style = friendly
+
diff --git a/docs/source/community.rst b/docs/source/community.rst
new file mode 100644
index 00000000..bbad2421
--- /dev/null
+++ b/docs/source/community.rst
@@ -0,0 +1,93 @@
+..
+ Copyright 2011 OpenStack, LLC
+ All Rights Reserved.
+
+ Licensed under the Apache License, Version 2.0 (the "License"); you may
+ not use this file except in compliance with the License. You may obtain
+ a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ License for the specific language governing permissions and limitations
+ under the License.
+
+================
+Getting Involved
+================
+
+The OpenStack community is a very friendly group and there are places online to join in with the
+community. Feel free to ask questions. This document points you to some of the places where you can
+communicate with people.
+
+How to Join the Community
+=========================
+
+Our community welcomes all people interested in open source cloud computing, and there are no formal
+membership requirements. The best way to join the community is to talk with others online or at a meetup
+and offer contributions through Launchpad_, the wiki_, or blogs. We welcome all types of contributions,
+from blueprint designs to documentation to testing to deployment scripts.
+
+.. _Launchpad: https://launchpad.net/keystone
+.. _wiki: http://wiki.openstack.org/
+
+
+
+Contributing Code
+-----------------
+
+To contribute code, sign up for a Launchpad account and sign a contributor license agreement,
+available on the `<http://wiki.openstack.org/CLA>`_. Once the CLA is signed you
+can contribute code through the Gerrit version control system which is related to your Launchpad account.
+
+To contribute tests, docs, code, etc, refer to our `Gerrit-Jenkins-Github Workflow`_.
+
+.. _`Gerrit-Jenkins-Github Workflow`: http://wiki.openstack.org/GerritJenkinsGithub
+
+
+#openstack on Freenode IRC Network
+----------------------------------
+
+There is a very active chat channel at `<irc://freenode.net/#openstack>`_. This
+is usually the best place to ask questions and find your way around. IRC stands for Internet Relay
+Chat and it is a way to chat online in real time. You can also ask a question and come back to the
+log files to read the answer later. Logs for the #openstack IRC channel are stored at
+`<http://eavesdrop.openstack.org/irclogs/>`_.
+
+OpenStack Wiki
+--------------
+
+The wiki is a living source of knowledge. It is edited by the community, and
+has collections of links and other sources of information. Typically the pages are a good place
+to write drafts for specs or documentation, describe a blueprint, or collaborate with others.
+
+`OpenStack Wiki <http://wiki.openstack.org/>`_
+
+Keystone on Launchpad
+---------------------
+
+Launchpad is a code hosting service that hosts the Keystone source code. From
+Launchpad you can report bugs, ask questions, and register blueprints (feature requests).
+
+* `Launchpad Keystone Page <http://launchpad.net/keystone>`_
+
+OpenStack Blog
+--------------
+
+The OpenStack blog includes a weekly newsletter that aggregates OpenStack news
+from around the internet, as well as providing inside information on upcoming
+events and posts from OpenStack contributors.
+
+`OpenStack Blog <http://openstack.org/blog>`_
+
+See also: `Planet OpenStack <http://planet.openstack.org/>`_, aggregating blogs
+about OpenStack from around the internet into a single feed. If you'd like to contribute to this blog
+aggregation with your blog posts, there are instructions for `adding your blog <http://wiki.openstack.org/AddingYourBlog>`_.
+
+Twitter
+-------
+
+Because all the cool kids do it: `@openstack <http://twitter.com/openstack>`_. Also follow the
+`#openstack <http://search.twitter.com/search?q=%23openstack>`_ tag for relevant tweets.
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 11c8adb0..63515726 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -97,6 +97,18 @@ pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
modindex_common_prefix = ['keystone.']
+# -- Options for man page output --------------------------------------------
+
+# Grouping the document tree for man pages.
+# List of tuples 'sourcefile', 'target', u'title', u'Authors name', 'manual'
+
+man_pages = [
+ ('man/keystone-manage', 'keystone-manage', u'Keystone Management Utility',
+ [u'OpenStack'], 1),
+ ('man/keystone', 'keystone', u'Keystone Startup Command',
+ [u'OpenStack'], 1),
+ ]
+
# -- Options for HTML output ---------------------------------------------------
diff --git a/docs/source/developing.rst b/docs/source/developing.rst
new file mode 100644
index 00000000..acd22730
--- /dev/null
+++ b/docs/source/developing.rst
@@ -0,0 +1,135 @@
+..
+ Copyright 2011 OpenStack, LLC
+ All Rights Reserved.
+
+ Licensed under the Apache License, Version 2.0 (the "License"); you may
+ not use this file except in compliance with the License. You may obtain
+ a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ License for the specific language governing permissions and limitations
+ under the License.
+
+========================
+Developing with Keystone
+========================
+
+Get your development environment set up according to :doc:`setup`.
+
+Running a development instance
+==============================
+
+Setting up a virtualenv
+-----------------------
+
+We recommend establishing a virtualenv to run keystone within. To establish
+this environment, use the command::
+
+ $ python tools/install_venv.py
+
+This will create a local virtual environment in the directory ``.venv``.
+Once created, you can activate this virtualenv for your current shell using::
+
+ $ source .venv/bin/activate
+
+The virtual environment can be disabled using the command::
+
+ $ deactivate
+
+You can also use ``tools\with_venv.sh`` to prefix commands so that they run
+within the virtual environment. For more information on virtual environments,
+see virtualenv_.
+
+.. _virtualenv: http://www.virtualenv.org/
+
+Running Keystone
+----------------
+
+To run the keystone Admin and API server instances, use::
+
+ $ tools/with_venv.sh bin/keystone
+
+Running a demo service that uses Keystone
+-----------------------------------------
+
+To run client demo (with all auth middleware running locally on sample service)::
+
+ $ tools/with_venv.sh examples/echo/bin/echod
+
+which spins up a simple "echo" service on port 8090. To use a simple echo client::
+
+ $ python examples/echo/echo_client.py
+
+Interacting with Keystone
+=========================
+
+You can interact with Keystone through the command line using :doc:`man/keystone-manage`
+which allows you to establish tenants, users, etc.
+
+You can also interact with Keystone through it's REST API. There is a python
+keystone client library python-keystoneclient_ which interacts exclusively through
+the REST API.
+
+.. _python-keystoneclient: https://github.com/4P/python-keystoneclient
+
+The easiest way to establish some base information in Keystone to interact with is
+to invoke::
+
+ $ tools/with_venv.sh bin/sampledata
+
+You can see the details of what that creates in ``keystone/test/sampledata.py``
+
+Enabling debugging middleware
+-----------------------------
+
+You can enable a huge amount of additional data (debugging information) about
+the request and repsonse objects flowing through Keystone using the debugging
+WSGI middleware.
+
+To enable this, just modify the pipelines in ``etc/keystone.conf``, from::
+
+ [pipeline:admin]
+ pipeline =
+ urlnormalizer
+ admin_api
+
+ [pipeline:keystone-legacy-auth]
+ pipeline =
+ urlnormalizer
+ legacy_auth
+ d5_compat
+ service_api
+
+... to::
+
+ [pipeline:admin]
+ pipeline =
+ debug
+ urlnormalizer
+ d5_compat
+ admin_api
+
+ [pipeline:keystone-legacy-auth]
+ pipeline =
+ debug
+ urlnormalizer
+ legacy_auth
+ d5_compat
+ service_api
+
+Two simple and easy debugging tools are using the ``-d`` when you start keystone::
+
+ $ ./keystone -d
+
+and the `--trace-calls` flag::
+
+ $ ./keystone -trace-calls
+
+The ``-d`` flag outputs debug information to the console. The ``--trace-calls`` flag
+outputs extensive, nested trace calls to the console and highlights any errors
+in red.
+
diff --git a/docs/source/index.rst b/docs/source/index.rst
index cd7c96a8..4270033a 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -1,17 +1,59 @@
-.. keystone documentation master file, created by
- sphinx-quickstart on Mon Jan 9 12:02:59 2012.
- You can adapt this file completely to your liking, but it should at least
- contain the root `toctree` directive.
+..
+ Copyright 2011 OpenStack, LLC
+ All Rights Reserved.
-Welcome to keystone's documentation!
-====================================
+ 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
-Contents:
+ 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.
+
+====================================================
+Welcome to Keystone, the OpenStack Identity Service!
+====================================================
+
+Keystone is a cloud identity service written in Python, which provides
+authentication, authorization, and an OpenStack service catalog. It
+implements `OpenStack's Identity API`_.
+
+This document describes Keystone for contributors of the project, and assumes
+that you are already familiar with Keystone from an `end-user perspective`_.
+
+.. _`OpenStack's Identity API`: http://docs.openstack.org/api/openstack-identity-service/2.0/content/
+.. _`end-user perspective`: http://docs.openstack.org/
+
+This documentation is generated by the Sphinx toolkit and lives in the source
+tree. Additional documentation on Keystone and other components of OpenStack can
+be found on the `OpenStack wiki`_. Also see the :doc:`community` page for
+other ways to interact with the community.
+
+.. _`OpenStack wiki`: http://wiki.openstack.org
+
+Getting Started
+===============
.. toctree::
- :maxdepth: 2
+ :maxdepth: 1
+
+ setup
+ community
+ testing
+Developers Documentation
+========================
+.. toctree::
+ :maxdepth: 1
+
+ developing
+ architecture
+ sourcecode/autoindex
Indices and tables
==================
diff --git a/docs/source/man/keystone-manage.rst b/docs/source/man/keystone-manage.rst
new file mode 100644
index 00000000..9e9304f0
--- /dev/null
+++ b/docs/source/man/keystone-manage.rst
@@ -0,0 +1,192 @@
+===============
+keystone-manage
+===============
+
+---------------------------
+Keystone Management Utility
+---------------------------
+
+:Author: keystone@lists.launchpad.net
+:Date: 2010-11-16
+:Copyright: OpenStack LLC
+:Version: 0.1.2
+:Manual section: 1
+:Manual group: cloud computing
+
+SYNOPSIS
+========
+
+ keystone-manage [options]
+
+DESCRIPTION
+===========
+
+keystone-manage is the command line tool that interacts with the keystone
+service to configure Keystone
+
+USAGE
+=====
+
+ ``keystone-manage [options] type action [additional args]``
+
+user
+----
+
+* **user add** [username] [password]
+
+ adds a user to Keystone's data store
+
+* **user list**
+
+ lists all users
+
+* **user disable** [username]
+
+ disables the user *username*
+
+tenant
+------
+
+* **tenant add** [tenant_name]
+
+ adds a tenant to Keystone's data store
+
+* **tenant list**
+
+ lists all users
+
+* **tenant disable** [tenant_name]
+
+role
+----
+
+Roles are used to associated users to tenants. Two roles are defined related
+to the Keystone service in it's configuration file :doc:`../keystone.conf`
+
+* **role add** [role_name]
+
+ adds a role
+
+* **role list** ([tenant_name])
+
+ lists all roles, or all roles for tenant, if tenant_name is provided
+
+* **role grant** [role_name] [username] ([tenant])
+
+ grants a role to a specific user. Granted globally if tenant_name is not
+ provided or granted for a specific tenant if tenant_name is provided.
+
+service
+-------
+
+* **service add** [name] [type] [description] [owner_id]
+
+ adds a service
+
+* **service list**
+
+ lists all services with id, name, and type
+
+endpointTemplate
+----------------
+
+* **endpointTemplate add** [region] [service_name] [public_url] [admin_url] [internal_url] [enabled] [is_global]
+
+ Add a service endpoint for keystone.
+
+ example::
+
+ keystone-manage endpointTemplates add RegionOne \
+ keystone \
+ http://keystone_host:5000/v2.0 \
+ http://keystone_host:35357/v2.0 \
+ http://keystone_host:5000/v2.0 \
+ 1 1
+
+* **endpointTemplate list** ([tenant_name])
+
+ lists endpoint templates with service, region, and public_url. Restricted to
+ tenant endpoints if tenant_name is provided.
+
+token
+-----
+
+* **token add** [token] [username] [tenant] [expiration]
+
+ adds a token for a given user and tenant with an expiration
+
+* **token list**
+
+ lists all tokens
+
+* **token delete** [token]
+
+ deletes the identified token
+
+endpoint
+--------
+
+* **endpoint add** [tenant_name] [endpoint_template]
+
+ adds a tenant-specific endpoint
+
+credentials
+-----------
+
+* **credentials add** [username] [type] [key] [password] ([tenant_name])
+
+OPTIONS
+=======
+
+ --version show program's version number and exit
+ -h, --help show this help message and exit
+ -v, --verbose Print more verbose output
+ -d, --debug Print debugging output to console
+ -c PATH, --config-file=PATH Path to the config file to use. When not
+ specified (the default), we generally look at
+ the first argument specified to be a config
+ file, and if that is also missing, we search
+ standard directories for a config file.
+ -p BIND_PORT, --port=BIND_PORT, --bind-port=BIND_PORT
+ specifies port to listen on (default is 5000)
+ --host=BIND_HOST, --bind-host=BIND_HOST
+ specifies host address to listen on (default
+ is all or 0.0.0.0)
+ -t, --trace-calls Turns on call tracing for troubleshooting
+ -a PORT, --admin-port=PORT Specifies port for Admin API to listen on
+ (default is 35357)
+
+Logging Options:
+================
+
+The following configuration options are specific to logging
+functionality for this program.
+
+ --log-config=PATH If this option is specified, the logging
+ configuration file specified is used and
+ overrides any other logging options specified.
+ Please see the Python logging module
+ documentation for details on logging
+ configuration files.
+ --log-date-format=FORMAT Format string for %(asctime)s in log records.
+ Default: %Y-%m-%d %H:%M:%S
+ --log-file=PATH (Optional) Name of log file to output to. If
+ not set, logging will go to stdout.
+ --log-dir=LOG_DIR (Optional) The directory to keep log files in
+ (will be prepended to --logfile)
+
+FILES
+=====
+
+None
+
+SEE ALSO
+========
+
+* `Keystone <http://github.com/openstack/keystone>`__
+
+SOURCE
+======
+
+* Keystone is sourced in GitHub `Keystone <http://github.com/openstack/keystone>`__
+* Keystone bugs are managed at Launchpad `Launchpad Keystone <https://bugs.launchpad.net/keystone>`__
diff --git a/docs/source/man/keystone.rst b/docs/source/man/keystone.rst
new file mode 100644
index 00000000..48e062e4
--- /dev/null
+++ b/docs/source/man/keystone.rst
@@ -0,0 +1,90 @@
+========
+keystone
+========
+
+---------------------------
+Keystone Management Utility
+---------------------------
+
+:Author: keystone@lists.launchpad.net
+:Date: 2010-11-16
+:Copyright: OpenStack LLC
+:Version: 0.1.2
+:Manual section: 1
+:Manual group: cloud computing
+
+SYNOPSIS
+========
+
+ keystone [options]
+
+DESCRIPTION
+===========
+
+keystone starts both the service and administrative API servers for Keystone.
+Use :doc:`keystone-control` to stop/start/restart and manage those services
+once started.
+
+USAGE
+=====
+
+ keystone ``keystone [options]``
+
+Common Options:
+^^^^^^^^^^^^^^^
+ --version show program's version number and exit
+ -h, --help show this help message and exit
+
+The following configuration options are common to all keystone
+programs.::
+
+ -v, --verbose Print more verbose output
+ -d, --debug Print debugging output to console
+ -c PATH, --config-file=PATH Path to the config file to use. When not
+ specified (the default), we generally look at
+ the first argument specified to be a config
+ file, and if that is also missing, we search
+ standard directories for a config file.
+ -p BIND_PORT, --port=BIND_PORT, --bind-port=BIND_PORT
+ specifies port to listen on (default is 5000)
+ --host=BIND_HOST, --bind-host=BIND_HOST
+ specifies host address to listen on (default
+ is all or 0.0.0.0)
+ -t, --trace-calls Turns on call tracing for troubleshooting
+ -a PORT, --admin-port=PORT Specifies port for Admin API to listen on
+ (default is 35357)
+
+Logging Options:
+^^^^^^^^^^^^^^^^
+
+The following configuration options are specific to logging
+functionality for this program.::
+
+ --log-config=PATH If this option is specified, the logging
+ configuration file specified is used and
+ overrides any other logging options specified.
+ Please see the Python logging module
+ documentation for details on logging
+ configuration files.
+ --log-date-format=FORMAT Format string for %(asctime)s in log records.
+ Default: %Y-%m-%d %H:%M:%S
+ --log-file=PATH (Optional) Name of log file to output to. If
+ not set, logging will go to stdout.
+ --log-dir=LOG_DIR (Optional) The directory to keep log files in
+ (will be prepended to --logfile)
+
+FILES
+=====
+
+None
+
+SEE ALSO
+========
+
+* `Keystone <http://github.com/openstack/keystone>`__
+
+SOURCE
+======
+
+* Keystone is sourced in GitHub `Keystone <http://github.com/openstack/keystone>`__
+* Keystone bugs are managed at Launchpad `Launchpad Keystone <https://bugs.launchpad.net/keystone>`__
diff --git a/docs/source/setup.rst b/docs/source/setup.rst
new file mode 100644
index 00000000..e608f09e
--- /dev/null
+++ b/docs/source/setup.rst
@@ -0,0 +1,151 @@
+..
+ Copyright 2011 OpenStack, LLC
+ All Rights Reserved.
+
+ Licensed under the Apache License, Version 2.0 (the "License"); you may
+ not use this file except in compliance with the License. You may obtain
+ a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ License for the specific language governing permissions and limitations
+ under the License.
+
+=============================================
+Setting up a Keystone development environment
+=============================================
+
+This document describes setting up keystone directly from GitHub_
+for development purposes.
+
+To install keystone from packaging, refer instead to Keystone's `User Documentation`_.
+
+.. _GitHub: http://github.com/openstack/keystone
+.. _`User Documentation`: http://docs.openstack.org/
+
+Prerequisites
+=============
+
+This document assumes you are using:
+
+- Ubuntu 11.10, Fedora 15, or Mac OS X Lion
+- `Python 2.7`_
+
+.. _`Python 2.7`: http://www.python.org/
+
+And that you have the following tools available on your system:
+
+- git_
+- setuptools_
+- pip_
+
+**Reminder**: If you're successfully using a different platform, or a
+different version of the above, please document your configuration here!
+
+.. _git: http://git-scm.com/
+.. _setuptools: http://pypi.python.org/pypi/setuptools
+
+Getting the latest code
+=======================
+
+You can clone our latest code from our `Github repository`::
+
+ $ git clone https://github.com/openstack/keystone.git
+
+When that is complete, you can::
+
+ $ cd keystone
+
+.. _`Github repository`: https://github.com/openstack/keystone
+
+Installing dependencies
+=======================
+
+Keystone maintains a list of PyPi_ dependencies, designed for use by
+pip_.
+
+.. _PyPi: http://pypi.python.org/
+.. _pip: http://pypi.python.org/pypi/pip
+
+However, your system *may* need additional dependencies that `pip` (and by
+extension, PyPi) cannot satisfy. These dependencies should be installed
+prior to using `pip`, and the installation method may vary depending on
+your platform.
+
+Ubuntu 11.10::
+
+ $ sudo apt-get install python-dev libxml2-dev libxslt1-dev libsasl2-dev libsqlite3-dev libssl-dev libldap2-dev
+
+Fedora 15::
+
+ $ sudo yum install python-sqlite2 python-lxml python-greenlet-devel python-ldap
+
+Mac OS X Lion (requires MacPorts_)::
+
+ $ sudo port install py-ldap
+
+.. _MacPorts: http://www.macports.org/
+
+PyPi Packages
+-------------
+
+Assuming you have any necessary binary packages & header files available
+on your system, you can then install PyPi dependencies.
+
+You may also need to prefix `pip install` with `sudo`, depending on your
+environment::
+
+ # Describe dependencies (including non-PyPi dependencies)
+ $ cat tools/pip-requires
+
+ # Install all PyPi dependencies (for production, testing, and development)
+ $ pip install -r tools/pip-requires
+
+Updating your PYTHONPATH
+========================
+
+There are a number of methods for getting Keystone into your PYTHON PATH,
+the easiest of which is::
+
+ # Fake-install the project by symlinking Keystone into your Python site-packages
+ $ python setup.py develop
+
+You should then be able to `import keystone` from your Python shell
+without issue::
+
+ >>> import keystone.version
+ >>>
+
+If you want to check the version of Keystone you are running:
+
+ >>> print keystone.version.version()
+ 2012.1-dev
+
+
+If you can import keystone successfully, you should be ready to move on to :doc:`testing`.
+
+Troubleshooting
+===============
+
+Eventlet segfaults on RedHat / Fedora
+-------------------------------------
+
+[*If this is no longer an issue, please remove this section, thanks!*]
+
+On some OSes, specifically Fedora 15, the current versions of
+greenlet/eventlet segfault when running keystone. To fix this, install
+the development versions of greenlet and eventlet::
+
+ $ pip uninstall greenlet eventlet
+ $ cd <appropriate working directory>
+ $ hg clone https://bitbucket.org/ambroff/greenlet
+ $ cd greenlet
+ $ sudo python setup.py install
+
+ $ cd <appropriate working directory>
+ $ hg clone https://bitbucket.org/which_linden/eventlet
+ $ cd greenlet
+ $ sudo python setup.py install
diff --git a/docs/source/testing.rst b/docs/source/testing.rst
new file mode 100644
index 00000000..82a33604
--- /dev/null
+++ b/docs/source/testing.rst
@@ -0,0 +1,77 @@
+================
+Testing Keystone
+================
+
+Keystone uses a number of testing methodologies to ensure correctness.
+
+Running Built-In Tests
+======================
+
+To run the full suites of tests maintained within Keystone, run::
+
+ $ ./run_tests.sh --with-progress
+
+This shows realtime feedback during test execution, and iterates over
+multiple configuration variations.
+
+This differs from how tests are executed from the continuous integration
+environment. Specifically, Jenkins doesn't care about realtime progress,
+and aborts after the first test failure (a fail-fast behavior)::
+
+ $ ./run_tests.sh
+
+Testing Schema Migrations
+=========================
+
+The application of schema migrations can be tested using SQLAlchemy Migrate’s built-in test runner, one migration at a time.
+
+.. WARNING::
+
+ This may leave your database in an inconsistent state; attempt this in non-production environments only!
+
+This is useful for testing the *next* migration in sequence (both forward & backward) in a database under version control::
+
+ $ python keystone/backends/sqlalchemy/migrate_repo/manage.py test --url=sqlite:///test.db --repository=keystone/backends/sqlalchemy/migrate_repo/
+
+This command refers to a SQLite database used for testing purposes. Depending on the migration, this command alone does not make assertions as to the integrity of your data during migration.
+
+Writing Tests
+=============
+
+Tests are maintained in the ``keystone.test`` module. Unit tests are
+isolated from functional tests.
+
+Functional Tests
+----------------
+
+The ``keystone.test.functional.common`` module provides a ``unittest``-based
+``httplib`` client which you can extend and use for your own tests.
+Generally, functional tests should serve to illustrate intended use cases
+and API behaviors. To help make your tests easier to read, the test client:
+
+- Authenticates with a known user name and password combination
+- Asserts 2xx HTTP status codes (unless told otherwise)
+- Abstracts keystone REST verbs & resources into single function calls
+
+Testing Multiple Configurations
+-------------------------------
+
+Several variations of the default configuration are iterated over to
+ensure test coverage of mutually exclusive featuresets, such as the
+various backend options.
+
+These configuration templates are maintained in ``keystone/test/etc`` and
+are iterated over by ``run_tests.py``.
+
+Further Testing
+===============
+
+devstack_ is the *best* way to quickly deploy keystone with the rest of the
+OpenStack universe and should be critical step in your development workflow!
+
+You may also be interested in either the `OpenStack Continuous Integration Project`_
+or the `OpenStack Integration Testing Project`_.
+
+.. _devstack: http://devstack.org/
+.. _OpenStack Continuous Integration Project: https://github.com/openstack/openstack-ci
+.. _OpenStack Integration Testing Project: https://github.com/openstack/openstack-integration-tests