Skip to content

Commit 668b4c3

Browse files
adnan-cdenyeart
authored andcommitted
[FAB-2662] Implement CouchDB docker config
https://jira.hyperledger.org/browse/FAB-2662 Changing the CouchDB dockers used in fabric to use recommended configuration (couchdb local.ini). Include config comments in local.ini stating how to enable user security. Also, making sure that all CouchDB unit-tests follow the same procedure for setting up address and login credentials. Including test comments stating how to run tests against CouchDB with user security enabled. Change-Id: I975d04d757d0371c8db03acf0ddcf92c01c35f8c Signed-off-by: Adnan Choudhury <[email protected]> Signed-off-by: denyeart <[email protected]>
1 parent eba4a20 commit 668b4c3

File tree

7 files changed

+138
-45
lines changed

7 files changed

+138
-45
lines changed

core/chaincode/exectransaction_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ func finitPeer(lis net.Listener, chainIDs ...string) {
130130
requestTimeout := viper.GetDuration("ledger.state.couchDBConfig.requestTimeout")
131131

132132
couchInstance, _ := couchdb.CreateCouchInstance(connectURL, username, password, maxRetries, maxRetriesOnStartup, requestTimeout)
133-
db, _ := couchdb.CreateCouchDatabase(*couchInstance, chainID)
133+
db := couchdb.CouchDatabase{CouchInstance: *couchInstance, DBName: chainID}
134134
//drop the test database
135135
db.DropDatabase()
136136

core/ledger/kvledger/txmgmt/statedb/statecouchdb/statecouchdb_test.go

+16-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package statecouchdb
1919
import (
2020
"os"
2121
"testing"
22+
"time"
2223

2324
"github.com/hyperledger/fabric/common/ledger/testutil"
2425
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/statedb"
@@ -31,15 +32,28 @@ import (
3132

3233
func TestMain(m *testing.M) {
3334

34-
//call a helper method to load the core.yaml, will be used to detect if CouchDB is enabled
35+
// Read the core.yaml file for default config.
3536
ledgertestutil.SetupCoreYAMLConfig("./../../../../../../peer")
37+
3638
viper.Set("peer.fileSystemPath", "/tmp/fabric/ledgertests/kvledger/txmgmt/statedb/statecouchdb")
39+
40+
// Switch to CouchDB
3741
viper.Set("ledger.state.stateDatabase", "CouchDB")
3842

3943
// both vagrant and CI have couchdb configured at host "couchdb"
4044
viper.Set("ledger.state.couchDBConfig.couchDBAddress", "couchdb:5984")
41-
45+
// Replace with correct username/password such as
46+
// admin/admin if user security is enabled on couchdb.
47+
viper.Set("ledger.state.couchDBConfig.username", "")
48+
viper.Set("ledger.state.couchDBConfig.password", "")
49+
viper.Set("ledger.state.couchDBConfig.maxRetries", 3)
50+
viper.Set("ledger.state.couchDBConfig.maxRetriesOnStartup", 10)
51+
viper.Set("ledger.state.couchDBConfig.requestTimeout", time.Second*20)
52+
53+
//run the actual test
4254
result := m.Run()
55+
56+
//revert to default goleveldb
4357
viper.Set("ledger.state.stateDatabase", "goleveldb")
4458
os.Exit(result)
4559
}

core/ledger/kvledger/txmgmt/statedb/statecouchdb/statecouchdb_test_export.go

+5-10
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,13 @@ package statecouchdb
1919
import (
2020
"strings"
2121
"testing"
22-
"time"
2322

2423
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/statedb"
24+
"github.com/hyperledger/fabric/core/ledger/ledgerconfig"
2525
"github.com/hyperledger/fabric/core/ledger/util/couchdb"
2626
)
2727

28-
//Basic setup to test couch
29-
var connectURL = "couchdb:5984"
30-
var badConnectURL = "couchdb:5990"
31-
var username = ""
32-
var password = ""
33-
var maxRetries = 3
34-
var maxRetriesOnStartup = 10
35-
var connectionTimeout = time.Second * 60
28+
const badConnectURL = "couchdb:5990"
3629

3730
// TestVDBEnv provides a couch db backed versioned db for testing
3831
type TestVDBEnv struct {
@@ -59,7 +52,9 @@ func (env *TestVDBEnv) Cleanup(dbName string) {
5952
}
6053
func cleanupDB(dbName string) {
6154
//create a new connection
62-
couchInstance, _ := couchdb.CreateCouchInstance(connectURL, username, password, maxRetries, maxRetriesOnStartup, connectionTimeout)
55+
couchDBDef := ledgerconfig.GetCouchDBDefinition()
56+
couchInstance, _ := couchdb.CreateCouchInstance(couchDBDef.URL, couchDBDef.Username, couchDBDef.Password,
57+
couchDBDef.MaxRetries, couchDBDef.MaxRetriesOnStartup, couchDBDef.RequestTimeout)
6358
db := couchdb.CouchDatabase{CouchInstance: *couchInstance, DBName: dbName}
6459
//drop the test database
6560
db.DropDatabase()

core/ledger/kvledger/txmgmt/txmgr/commontests/pkg_test.go

+8
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package commontests
1818

1919
import (
2020
"testing"
21+
"time"
2122

2223
"github.com/hyperledger/fabric/common/ledger/testutil"
2324
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/statedb"
@@ -106,6 +107,13 @@ func (env *couchDBLockBasedEnv) init(t *testing.T, testLedgerID string) {
106107
viper.Set("peer.fileSystemPath", testFilesystemPath)
107108
// both vagrant and CI have couchdb configured at host "couchdb"
108109
viper.Set("ledger.state.couchDBConfig.couchDBAddress", "couchdb:5984")
110+
// Replace with correct username/password such as
111+
// admin/admin if user security is enabled on couchdb.
112+
viper.Set("ledger.state.couchDBConfig.username", "")
113+
viper.Set("ledger.state.couchDBConfig.password", "")
114+
viper.Set("ledger.state.couchDBConfig.maxRetries", 3)
115+
viper.Set("ledger.state.couchDBConfig.maxRetriesOnStartup", 10)
116+
viper.Set("ledger.state.couchDBConfig.requestTimeout", time.Second*20)
109117
testDBEnv := statecouchdb.NewTestVDBEnv(t)
110118
testDB, err := testDBEnv.DBProvider.GetDBHandle(testLedgerID)
111119
testutil.AssertNoError(t, err, "")

core/ledger/util/couchdb/couchdb_test.go

+62-31
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,17 @@ import (
3131
"github.com/spf13/viper"
3232
)
3333

34-
//Basic setup to test couch
35-
var connectURL = "couchdb:5984"
36-
var badConnectURL = "couchdb:5990"
37-
var username = ""
38-
var password = ""
39-
var maxRetries = 3
40-
var maxRetriesOnStartup = 10
41-
var requestTimeout = time.Second * 20
42-
34+
const badConnectURL = "couchdb:5990"
4335
const updateDocumentConflictError = "conflict"
4436
const updateDocumentConflictReason = "Document update conflict."
4537

38+
var couchDBDef *ledgerconfig.CouchDBDef
39+
4640
func cleanup(database string) error {
4741
//create a new connection
48-
couchInstance, err := CreateCouchInstance(connectURL, username, password, maxRetries, maxRetriesOnStartup, requestTimeout)
42+
couchInstance, err := CreateCouchInstance(couchDBDef.URL, couchDBDef.Username, couchDBDef.Password,
43+
couchDBDef.MaxRetries, couchDBDef.MaxRetriesOnStartup, couchDBDef.RequestTimeout)
44+
4945
if err != nil {
5046
fmt.Println("Unexpected error", err)
5147
return err
@@ -68,28 +64,47 @@ type Asset struct {
6864
var assetJSON = []byte(`{"asset_name":"marble1","color":"blue","size":"35","owner":"jerry"}`)
6965

7066
func TestMain(m *testing.M) {
67+
// Read the core.yaml file for default config.
7168
ledgertestutil.SetupCoreYAMLConfig("./../../../../peer")
69+
70+
// Switch to CouchDB
7271
viper.Set("ledger.state.stateDatabase", "CouchDB")
72+
73+
// both vagrant and CI have couchdb configured at host "couchdb"
74+
viper.Set("ledger.state.couchDBConfig.couchDBAddress", "couchdb:5984")
75+
// Replace with correct username/password such as
76+
// admin/admin if user security is enabled on couchdb.
77+
viper.Set("ledger.state.couchDBConfig.username", "")
78+
viper.Set("ledger.state.couchDBConfig.password", "")
79+
viper.Set("ledger.state.couchDBConfig.maxRetries", 3)
80+
viper.Set("ledger.state.couchDBConfig.maxRetriesOnStartup", 10)
81+
viper.Set("ledger.state.couchDBConfig.requestTimeout", time.Second*20)
82+
83+
// Create CouchDB definition from config parameters
84+
couchDBDef = ledgerconfig.GetCouchDBDefinition()
85+
86+
//run the tests
7387
result := m.Run()
88+
89+
//revert to default goleveldb
7490
viper.Set("ledger.state.stateDatabase", "goleveldb")
7591
os.Exit(result)
7692
}
7793

7894
func TestDBConnectionDef(t *testing.T) {
7995

80-
//call a helper method to load the core.yaml
81-
ledgertestutil.SetupCoreYAMLConfig("./../../../../peer")
82-
8396
//create a new connection
84-
_, err := CreateConnectionDefinition(connectURL, "", "", maxRetries, maxRetriesOnStartup, requestTimeout)
97+
_, err := CreateConnectionDefinition(couchDBDef.URL, couchDBDef.Username, couchDBDef.Password,
98+
couchDBDef.MaxRetries, couchDBDef.MaxRetriesOnStartup, couchDBDef.RequestTimeout)
8599
testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to create database connection definition"))
86100

87101
}
88102

89103
func TestDBBadConnectionDef(t *testing.T) {
90104

91105
//create a new connection
92-
_, err := CreateConnectionDefinition("^^^localhost:5984", "", "", maxRetries, maxRetriesOnStartup, requestTimeout)
106+
_, err := CreateConnectionDefinition("^^^localhost:5984", couchDBDef.Username, couchDBDef.Password,
107+
couchDBDef.MaxRetries, couchDBDef.MaxRetriesOnStartup, couchDBDef.RequestTimeout)
93108
testutil.AssertError(t, err, fmt.Sprintf("Did not receive error when trying to create database connection definition with a bad hostname"))
94109

95110
}
@@ -105,7 +120,8 @@ func TestDBCreateSaveWithoutRevision(t *testing.T) {
105120

106121
if err == nil {
107122
//create a new instance and database object
108-
couchInstance, err := CreateCouchInstance(connectURL, username, password, maxRetries, maxRetriesOnStartup, requestTimeout)
123+
couchInstance, err := CreateCouchInstance(couchDBDef.URL, couchDBDef.Username, couchDBDef.Password,
124+
couchDBDef.MaxRetries, couchDBDef.MaxRetriesOnStartup, couchDBDef.RequestTimeout)
109125
testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to create couch instance"))
110126
db := CouchDatabase{CouchInstance: *couchInstance, DBName: database}
111127

@@ -131,7 +147,8 @@ func TestDBCreateEnsureFullCommit(t *testing.T) {
131147

132148
if err == nil {
133149
//create a new instance and database object
134-
couchInstance, err := CreateCouchInstance(connectURL, username, password, maxRetries, maxRetriesOnStartup, requestTimeout)
150+
couchInstance, err := CreateCouchInstance(couchDBDef.URL, couchDBDef.Username, couchDBDef.Password,
151+
couchDBDef.MaxRetries, couchDBDef.MaxRetriesOnStartup, couchDBDef.RequestTimeout)
135152
testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to create couch instance"))
136153
db := CouchDatabase{CouchInstance: *couchInstance, DBName: database}
137154

@@ -156,25 +173,29 @@ func TestDBBadDatabaseName(t *testing.T) {
156173
if ledgerconfig.IsCouchDBEnabled() {
157174

158175
//create a new instance and database object using a valid database name mixed case
159-
couchInstance, err := CreateCouchInstance(connectURL, username, password, maxRetries, maxRetriesOnStartup, requestTimeout)
176+
couchInstance, err := CreateCouchInstance(couchDBDef.URL, couchDBDef.Username, couchDBDef.Password,
177+
couchDBDef.MaxRetries, couchDBDef.MaxRetriesOnStartup, couchDBDef.RequestTimeout)
160178
testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to create couch instance"))
161179
_, dberr := CreateCouchDatabase(*couchInstance, "testDB")
162180
testutil.AssertNoError(t, dberr, fmt.Sprintf("Error when testing a valid database name"))
163181

164182
//create a new instance and database object using a valid database name letters and numbers
165-
couchInstance, err = CreateCouchInstance(connectURL, username, password, maxRetries, maxRetriesOnStartup, requestTimeout)
183+
couchInstance, err = CreateCouchInstance(couchDBDef.URL, couchDBDef.Username, couchDBDef.Password,
184+
couchDBDef.MaxRetries, couchDBDef.MaxRetriesOnStartup, couchDBDef.RequestTimeout)
166185
testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to create couch instance"))
167186
_, dberr = CreateCouchDatabase(*couchInstance, "test132")
168187
testutil.AssertNoError(t, dberr, fmt.Sprintf("Error when testing a valid database name"))
169188

170189
//create a new instance and database object using a valid database name - special characters
171-
couchInstance, err = CreateCouchInstance(connectURL, username, password, maxRetries, maxRetriesOnStartup, requestTimeout)
190+
couchInstance, err = CreateCouchInstance(couchDBDef.URL, couchDBDef.Username, couchDBDef.Password,
191+
couchDBDef.MaxRetries, couchDBDef.MaxRetriesOnStartup, couchDBDef.RequestTimeout)
172192
testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to create couch instance"))
173193
_, dberr = CreateCouchDatabase(*couchInstance, "test1234~!@#$%^&*()[]{}.")
174194
testutil.AssertNoError(t, dberr, fmt.Sprintf("Error when testing a valid database name"))
175195

176196
//create a new instance and database object using a invalid database name - too long /*
177-
couchInstance, err = CreateCouchInstance(connectURL, username, password, maxRetries, maxRetriesOnStartup, requestTimeout)
197+
couchInstance, err = CreateCouchInstance(couchDBDef.URL, couchDBDef.Username, couchDBDef.Password,
198+
couchDBDef.MaxRetries, couchDBDef.MaxRetriesOnStartup, couchDBDef.RequestTimeout)
178199
testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to create couch instance"))
179200
_, dberr = CreateCouchDatabase(*couchInstance, "A12345678901234567890123456789012345678901234"+
180201
"56789012345678901234567890123456789012345678901234567890123456789012345678901234567890"+
@@ -195,7 +216,8 @@ func TestDBBadConnection(t *testing.T) {
195216
if ledgerconfig.IsCouchDBEnabled() {
196217

197218
//create a new instance and database object
198-
_, err := CreateCouchInstance(badConnectURL, username, password, maxRetries, maxRetriesOnStartup, requestTimeout)
219+
_, err := CreateCouchInstance(badConnectURL, couchDBDef.Username, couchDBDef.Password,
220+
couchDBDef.MaxRetries, couchDBDef.MaxRetriesOnStartup, couchDBDef.RequestTimeout)
199221
testutil.AssertError(t, err, fmt.Sprintf("Error should have been thrown for a bad connection"))
200222
}
201223
}
@@ -211,7 +233,8 @@ func TestDBCreateDatabaseAndPersist(t *testing.T) {
211233

212234
if err == nil {
213235
//create a new instance and database object
214-
couchInstance, err := CreateCouchInstance(connectURL, username, password, maxRetries, maxRetriesOnStartup, requestTimeout)
236+
couchInstance, err := CreateCouchInstance(couchDBDef.URL, couchDBDef.Username, couchDBDef.Password,
237+
couchDBDef.MaxRetries, couchDBDef.MaxRetriesOnStartup, couchDBDef.RequestTimeout)
215238
testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to create couch instance"))
216239
db := CouchDatabase{CouchInstance: *couchInstance, DBName: database}
217240

@@ -305,7 +328,8 @@ func TestDBRequestTimeout(t *testing.T) {
305328

306329
//create a new instance and database object with a timeout that will fail
307330
//Also use a maxRetriesOnStartup=3 to reduce the number of retries
308-
_, err := CreateCouchInstance(connectURL, username, password, maxRetries, 3, impossibleTimeout)
331+
_, err := CreateCouchInstance(couchDBDef.URL, couchDBDef.Username, couchDBDef.Password,
332+
couchDBDef.MaxRetries, 3, impossibleTimeout)
309333
testutil.AssertError(t, err, fmt.Sprintf("Error should have been thown while trying to create a couchdb instance with a connection timeout"))
310334

311335
//see if the error message contains the timeout error
@@ -327,7 +351,8 @@ func TestDBBadJSON(t *testing.T) {
327351
if err == nil {
328352

329353
//create a new instance and database object
330-
couchInstance, err := CreateCouchInstance(connectURL, username, password, maxRetries, maxRetriesOnStartup, requestTimeout)
354+
couchInstance, err := CreateCouchInstance(couchDBDef.URL, couchDBDef.Username, couchDBDef.Password,
355+
couchDBDef.MaxRetries, couchDBDef.MaxRetriesOnStartup, couchDBDef.RequestTimeout)
331356
testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to create couch instance"))
332357
db := CouchDatabase{CouchInstance: *couchInstance, DBName: database}
333358

@@ -363,7 +388,8 @@ func TestPrefixScan(t *testing.T) {
363388

364389
if err == nil {
365390
//create a new instance and database object
366-
couchInstance, err := CreateCouchInstance(connectURL, username, password, maxRetries, maxRetriesOnStartup, requestTimeout)
391+
couchInstance, err := CreateCouchInstance(couchDBDef.URL, couchDBDef.Username, couchDBDef.Password,
392+
couchDBDef.MaxRetries, couchDBDef.MaxRetriesOnStartup, couchDBDef.RequestTimeout)
367393
testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to create couch instance"))
368394
db := CouchDatabase{CouchInstance: *couchInstance, DBName: database}
369395

@@ -435,7 +461,8 @@ func TestDBSaveAttachment(t *testing.T) {
435461
attachments = append(attachments, attachment)
436462

437463
//create a new instance and database object
438-
couchInstance, err := CreateCouchInstance(connectURL, username, password, maxRetries, maxRetriesOnStartup, requestTimeout)
464+
couchInstance, err := CreateCouchInstance(couchDBDef.URL, couchDBDef.Username, couchDBDef.Password,
465+
couchDBDef.MaxRetries, couchDBDef.MaxRetriesOnStartup, couchDBDef.RequestTimeout)
439466
testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to create couch instance"))
440467
db := CouchDatabase{CouchInstance: *couchInstance, DBName: database}
441468

@@ -468,7 +495,8 @@ func TestDBDeleteDocument(t *testing.T) {
468495

469496
if err == nil {
470497
//create a new instance and database object
471-
couchInstance, err := CreateCouchInstance(connectURL, username, password, maxRetries, maxRetriesOnStartup, requestTimeout)
498+
couchInstance, err := CreateCouchInstance(couchDBDef.URL, couchDBDef.Username, couchDBDef.Password,
499+
couchDBDef.MaxRetries, couchDBDef.MaxRetriesOnStartup, couchDBDef.RequestTimeout)
472500
testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to create couch instance"))
473501
db := CouchDatabase{CouchInstance: *couchInstance, DBName: database}
474502

@@ -506,7 +534,8 @@ func TestDBDeleteNonExistingDocument(t *testing.T) {
506534

507535
if err == nil {
508536
//create a new instance and database object
509-
couchInstance, err := CreateCouchInstance(connectURL, username, password, maxRetries, maxRetriesOnStartup, requestTimeout)
537+
couchInstance, err := CreateCouchInstance(couchDBDef.URL, couchDBDef.Username, couchDBDef.Password,
538+
couchDBDef.MaxRetries, couchDBDef.MaxRetriesOnStartup, couchDBDef.RequestTimeout)
510539
testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to create couch instance"))
511540
db := CouchDatabase{CouchInstance: *couchInstance, DBName: database}
512541

@@ -645,7 +674,8 @@ func TestRichQuery(t *testing.T) {
645674

646675
if err == nil {
647676
//create a new instance and database object --------------------------------------------------------
648-
couchInstance, err := CreateCouchInstance(connectURL, username, password, maxRetries, maxRetriesOnStartup, requestTimeout)
677+
couchInstance, err := CreateCouchInstance(couchDBDef.URL, couchDBDef.Username, couchDBDef.Password,
678+
couchDBDef.MaxRetries, couchDBDef.MaxRetriesOnStartup, couchDBDef.RequestTimeout)
649679
testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to create couch instance"))
650680
db := CouchDatabase{CouchInstance: *couchInstance, DBName: database}
651681

@@ -859,7 +889,8 @@ func TestBatchBatchOperations(t *testing.T) {
859889
defer cleanup(database)
860890

861891
//create a new instance and database object --------------------------------------------------------
862-
couchInstance, err := CreateCouchInstance(connectURL, username, password, maxRetries, maxRetriesOnStartup, requestTimeout)
892+
couchInstance, err := CreateCouchInstance(couchDBDef.URL, couchDBDef.Username, couchDBDef.Password,
893+
couchDBDef.MaxRetries, couchDBDef.MaxRetriesOnStartup, couchDBDef.RequestTimeout)
863894
testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to create couch instance"))
864895
db := CouchDatabase{CouchInstance: *couchInstance, DBName: database}
865896

core/ledger/util/couchdb/couchdbutil_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ func TestCreateCouchDBConnectionAndDB(t *testing.T) {
3232
cleanup(database)
3333
defer cleanup(database)
3434
//create a new connection
35-
couchInstance, err := CreateCouchInstance(connectURL, "", "", maxRetries, maxRetriesOnStartup, requestTimeout)
35+
couchInstance, err := CreateCouchInstance(couchDBDef.URL, couchDBDef.Username, couchDBDef.Password,
36+
couchDBDef.MaxRetries, couchDBDef.MaxRetriesOnStartup, couchDBDef.RequestTimeout)
3637
testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to CreateCouchInstance"))
3738

3839
_, err = CreateCouchDatabase(*couchInstance, database)

images/couchdb/local.ini

+44
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,47 @@
77
[chttpd]
88
bind_address = 0.0.0.0
99

10+
[couchdb]
11+
; Specify the location of the database in container.
12+
; Optionally, these directories can be mounted in the host via docker.
13+
database_dir = /opt/couchdb/data/
14+
view_index_dir = /opt/couchdb/data/
15+
uri_file = /opt/couchdb/data/couch.uri
16+
17+
; only allow the admin user to connect
18+
; Uncomment the following statement to enable admin user security.
19+
; default_security = admin_only
20+
21+
; allow delayed commits since peer manages savepoints and flushing to disk
22+
delayed_commits = true
23+
24+
[cluster]
25+
; peer maintains a single replica
26+
n = 1
27+
28+
; adjust q to set the level of parallelism locally
29+
; recommended to have no more than 10 million documents/shard (q)
30+
; for 100 million documents, q=10 -- at a minimum
31+
q = 8
32+
33+
[log]
34+
writer = file
35+
file = /opt/couchdb/logs/couchdb.log
36+
level = info
37+
38+
; Uncomment the following two statements to enable admin user security.
39+
; [httpd]
40+
; www-authenticate = Basic realm="administrator"
41+
42+
[couch_httpd_auth]
43+
; Uncomment the following statement to enable admin user security.
44+
; require_valid_user = true
45+
iterations = 1000 ; iterations for password hashing
46+
47+
; Uncomment the following two statements to enable admin user security.
48+
; [admins]
49+
; admin = admin
50+
51+
[attachments]
52+
compressible_types = text/*, application/javascript, application/json, application/xml, application/octet-stream
53+

0 commit comments

Comments
 (0)