> On 26 Oct 2014, at 20:31 , Alexander Shorin <[email protected]> wrote: > > Hi Jan, > > Suddenly, gists doesn't supports per-line comments. Replied inline > with questions.
Ah yes, please reply here :) Best Jan -- > > On Sun, Oct 26, 2014 at 10:04 PM, Jan Lehnardt <[email protected]> wrote: >> 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. >> > > Question: > - Is /_setup admin-only resource? > - If node already has admin-party fixed should it accepts new admin > credentials? > - Any reasons to replace 1-3 PUT requests to /_config with single POST > one in this case? > >> 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. > > Question: > - Since Fauxton already known all the nodes admin credentials and all > the nodes are bounded to 0.0.0.0 iface (from previous step), will > Fauxton automate nodes join into the cluster? This is about to skip > "Repeat on all nodes" step > - If some of my nodes have different admin credentials, is this the > blocker error case or should Fauxton ask me for these credentials? > - Any reasons for replacing regular request to /_nodes with custom > /_setup? Point about cookie counts. > >> 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. > > This is the only useful thing that /_setup does from my current point > of view - everything else was just masking standard requests to > existed API. > >> ## 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 >> > > If "enable_cluster" only creates/setups admin and bind address, could > this step be skipped? Because the same actions are possible to do via > regular config setup. > > >> ### 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 >> > > Questions: > - How much nodes required to be added? 1? 2? 3?... > - How to remove accidentally added node from cluster? > >> ### 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. >> > > Questions: > - Why adding a new node after finish_cluster is some specific case to > mark it with "i_know_what_i_am_doing" parameter? > - How to enlarge / reduce cluster after his setup or even disband it? > Or this isn't what /_setup should cares about? > - What happens with /_setup resource after finish_cluster? Any case > for it to be useful? > >> * * * >> >> So far. >> >> I think this is simpler than the first try. It retains the simplicity >> of getting started of 1.x.x. It is fully scriptable via HTTP. It has >> the same setup-security properties as 1.x.x. It requires an admin account >> for cluster setup, but only on the last possible occasion in the >> process. It still fully hides the Erlang cluster / secure cookie setup >> from the end-user. >> >> Does this sound sensible to you? Am I missing anything aside from the >> TBD bits, for which, if you have ideas, I’d love your input! :) >> >> Are there any deal-breaker flaws in this? What can be made simpler or >> more clear? >> >> Note that all the HTTP endpoints and field names are just placeholders, >> no need to bikeshed on these just yet :) >> >> I’m looking forward to your feedback! > > > > -- > ,,,^..^,,,
