add the plan to readme
Project: http://git-wip-us.apache.org/repos/asf/couchdb-setup/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-setup/commit/404692f5 Tree: http://git-wip-us.apache.org/repos/asf/couchdb-setup/tree/404692f5 Diff: http://git-wip-us.apache.org/repos/asf/couchdb-setup/diff/404692f5 Branch: refs/heads/master Commit: 404692f5f0c65e8604ab2c47078abe2c17301a7c Parents: a5213f7 Author: Jan Lehnardt <[email protected]> Authored: Fri Oct 31 17:14:43 2014 +0100 Committer: Jan Lehnardt <[email protected]> Committed: Fri Oct 31 17:14:43 2014 +0100 ---------------------------------------------------------------------- README.md | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-setup/blob/404692f5/README.md ---------------------------------------------------------------------- diff --git a/README.md b/README.md index 83758a5..c067d80 100644 --- a/README.md +++ b/README.md @@ -1 +1,145 @@ This module implements /_cluster_setup and manages the setting up, duh, of a CouchDB cluster. + +The Plan: + +N. End User Action +- What happens behind the scenes. + + +1. Launch CouchDB with `$ couchdb`, or init.d, or any other way, exactly +like it is done in 1.x.x. +- CouchDB launches and listens on 127.0.0.1:5984 + +From here on, there are two paths, one is via Fauxton (a) the other is +using a HTTP endpoint (b). Fauxton just uses the HTTP endpoint in (b). +(b) can be used to set up a cluster programmatically. + + +2.a. Go to Fauxton. There is a âCluster Setupâ tab in the sidebar. Go +to the tab and get presented with a form that asks you to enter an admin +username, admin password and optionally a bind_address and port to bind +to publicly. Submit the form with the [Enable Cluster] button. + +- POST to /_setup with + { + "action": "enable_cluster", + "admin": { + "user": "username", + "pass": "password" + }, + ["bind_address": "xxxx",] + ["port": yyyy] + } + +This sets up the admin user on the current node and binds to 0.0.0.0:5984 +or the specified ip:port. Logs admin user into Fauxton automatically. + +2.b. POST to /_setup as shown above. + +Repeat on all nodes. +- keep the same username/password everywhere. + + +3. Pick any one node, for simplicity use the first one, to be the +âsetup coordination nodeâ. +- this is a âmasterâ node that manages the setup and requires all + other nodes to be able to see it and vice versa. Setup wonât work + with unavailable nodes (duh). The notion of âmasterâ will be gone + once the setup is finished. At that point, the system has no + master node. Ignore I ever said âmasterâ. + +a. Go to Fauxton / Cluster Setup, once we have enabled the cluster, the +UI shows an âAdd Nodeâ interface with the fields admin, and node: +- POST to /_setup with + { + "action": "add_node", + "admin": { // should be auto-filled from Fauxton + "user": "username", + "pass": "password" + }, + "node": { + "host": "hostname", + ["port": 5984] + } + } + +b. as in a, but without the Fauxton bits, just POST to /_setup +- this request will do this: + - on the âsetup coordination nodeâ: + - check if we have an Erlang Cookie Secret. If not, generate + a UUID and set the erlang cookie to to that UUID. + // TBD: persist the cookie, so it survives restarts + - make a POST request to the node specified in the body above + using the admin credentials in the body above: + POST to http://username:password@node_b:5984/_setup with: + { + "action": "receive_cookie", + "cookie": "<secretcookie>", + } + // TBD: persist the cookie on node B, so it survives restarts + + - when the request to node B returns, we know the Erlang-level + inter-cluster communication is enabled and we can start adding + the node on the CouchDB level. To do that, the âsetup + coordination nodeâ does this to itâs own HTTP endpoint: + PUT /nodes/node_b:5984 or the same thing with internal APIs. + +- Repeat for all nodes. +- Fauxton keeps a list of all set up nodes for users to see. + + +4.a. When all nodes are added, click the [Finish Cluster Setup] button +in Fauxton. +- this does POST /_setup + { + "action": "finish_setup" + } + +b. Same as in a. + +- this manages the final setup bits, like creating the _users, + _replicator and _db_updates endpoints and whatever else is needed. + // TBD: collect what else is needed. + + +## The Setup Endpoint + +This is not a REST-y endpoint, it is a simple state machine operated +by HTTP POST with JSON bodies that have an `action` field. + +### State 1: No Cluster Enabled + +This is right after starting a node for the first time, and any time +before the cluster is enabled as outlined above. + +GET /_setup +{"state": "cluster_disabled"} + +POST /_setup {"action":"enable_cluster"...} -> Transition to State 2 +POST /_setup {"action":"enable_cluster"...} with empty admin user/pass or invalid host/post or host/port not available -> Error +POST /_setup {"action":"anything_but_enable_cluster"...} -> Error + + +### State 2: Cluster enabled, admin user set, waiting for nodes to be added. + +GET /_setup +{"state":"cluster_enabled","nodes":[]} + +POST /_setup {"action":"enable_cluster"...} -> Error +POST /_setup {"action":"add_node"...} -> Stay in State 2, but return "nodes":["node B"}] on GET +POST /_setup {"action":"add_node"...} -> if target node not available, Error +POST /_setup {"action":"finish_cluster"} with no nodes set up -> Error +POST /_setup {"action":"finish_cluster"} -> Transition to State 3 + + +### State 3: Cluster set up, all nodes operational + +GET /_setup +{"state":"cluster_finished","nodes":["node a", "node b", ...]} + +POST /_setup {"action":"enable_cluster"...} -> Error +POST /_setup {"action":"finish_cluster"...} -> Stay in State 3, do nothing +POST /_setup {"action":"add_node"...} -> Error +POST /_setup?i_know_what_i_am_doing=true {"action":"add_node"...} -> Add node, stay in State 3. + +// TBD: we need to persist the setup state somewhere. \ No newline at end of file
