commit | 94eab1247fbdd7f87a298f7e00fa9faffec9b5d5 | [log] [tgz] |
---|---|---|
author | Jan Lehnardt <jan@apache.org> | Fri Oct 31 17:48:02 2014 +0100 |
committer | Jan Lehnardt <jan@apache.org> | Fri Oct 31 17:48:02 2014 +0100 |
tree | 6d4bd80385c56091440d2b6f5fa32a5eba4de4be | |
parent | 068bdf18f0c2c9d30e5fa9fb70fb9c12a0247a7c [diff] |
add license
This module implements /_cluster_setup and manages the setting up, duh, of a CouchDB cluster.
The Plan:
N. End User Action
$ couchdb
, or init.d, or any other way, exactly like it is done in 1.x.x.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.
If this is a single node install that already has an admin set up, there is no need to ask for admin credentials here. If the bind_address is != 127.0.0.1, we can skip this entirely and Fauxton can show the add_node UI right away.
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.
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:
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.
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”: “”, } // 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.
b. Same as in a.
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.
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
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 POST /_setup {“action”:“delete_node”...} -> Stay in State 2, but delete node from /nodes, reflect the change in GET /_setup POST /_setup {“action”:“delete_node”,“node”:“unknown”} -> Error Unknown Node
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. POST /_setup {“action”:“delete_node”...} -> Stay in State 3, but delete node from /nodes, reflect the change in GET /_setup POST /_setup {“action”:“delete_node”,“node”:“unknown”} -> Error Unknown Node
// TBD: we need to persist the setup state somewhere.