Hi Jan,

Suddenly, gists doesn't supports per-line comments. Replied inline
with questions.

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!



--
,,,^..^,,,

Reply via email to