go-kivik / kivik

Common interface to CouchDB or CouchDB-like databases for Go and GopherJS
Other
311 stars 44 forks source link

couchdb: GetReplication (and other Replication methods) fail on clean CouchDB node #655

Open iivvoo opened 3 years ago

iivvoo commented 3 years ago

With kivik/v4 and couchdb/v4

github.com/go-kivik/couchdb/v4 v4.0.0-20201202133216-34bafb9698c8

github.com/go-kivik/kivik/v4 v4.0.0-20201202093909-da42f0daa1b2

It seems the _replicator database has to be created explicitly (fauxton does this as well). Without it, GetReplications() will fail

package main

import (
    "context"
    "fmt"

    _ "github.com/go-kivik/couchdb/v4"
    "github.com/go-kivik/kivik/v4"
)

func main() {
    client, err := kivik.New("couch", "http://admin:a-secret@localhost:5984")
    if err != nil {
        panic(err)
    }

    existing, err := client.GetReplications(context.TODO())
    if err != nil {
        fmt.Printf("Failed to get replications: %v\n", err)

        if err := client.CreateDB(context.TODO(), "_replicator"); err != nil {
            panic(err)
        }
        existing, err = client.GetReplications(context.TODO())
        if err != nil {
            fmt.Println("Still doesn't work, giving up")
        }
    }
    fmt.Printf("Found %d replications\n", len(existing))
}

will print

# make sure it does not hold previous state, `docker rm` previous instances
» docker run -d -p 5984:5984 -e COUCHDB_USER=admin -e COUCHDB_PASSWORD=a-secret --name my-couchdb couchdb:3
» go run cmd/repl/main.go
Failed to get replications: Not Found: Database does not exist.
Found 0 replications

I'm not sure if this is something Kivik should deal with, but at least it might be worth mentioning

iivvoo commented 3 years ago

I learned that there is a basic setup required on new nodes,

https://docs.couchdb.org/en/stable/setup/single-node.html

Again, not sure if kivik should provide this in any way but especially if you don't use fauxton the steps are essential (e.g. in a dockerized Ci/CD setup)

flimzy commented 3 years ago

Thanks for raising this issue. There are a couple possible approaches here:

  1. I could add some of these "housekeeping" types of abilites to Kivik, i.e. the _cluster_setup endpoint. So far I have not done this, because it seems rare that this would need to be managed programatically. I expect it's typically done once during setup via curl or similar. If you think this type of thing would be useful in Kivik, let me know.
  2. Perhaps a more useful error message could be generated. Although "Database does not exist" might already be enough (WDYT?)

As a side project, I've also been working on a command-line couchdb control tool (working name kouchctl) to facilitate bootstrapping and maintenence of CouchDB instances, as part of this repo: https://github.com/go-kivik/xkivik

This will have a cluster-setup command to do this sort of thing. That might be a better approach than putting it in the kivik library directly. IDK.

I welcome your thoughts, based on your usage.

iivvoo commented 3 years ago

My current use case is to test an automatic replication setup which, in CI, happens against a clean, empty, uninitialzed couchdb where locally it runs against a local, reusable instance.

The actual error isn't that obvious:

        replication_test.go:126: 
                Error Trace:    replication_test.go:126
                                            test_helpers.go:67
                Error:          Received unexpected error:
                                Not Found: Database does not exist.:
                                    REQUEST: GET http://localhost:5984/_scheduler/docs (0 bytes)
                                    RESPONSE: 404 / Not Found (58 bytes)
                Test:           TestReplication/Test_Repeated_Replication#01

since the solution is to create _replicator and not _scheduler.

Mentioning it in the docs might help (not sure if this is common knowledge, it definitely caught me by surprise) Or alternatively catch and handle the 404 explicitly and return an "Couch not properly initialized" error?