Skip to content

Commit 94563b7

Browse files
authored
Default single-node connstrs to direct connection; improve docs (#143)
mongosh [defaults single-node connections to a direct connection](https://github.com/mongodb-js/mongosh/blob/fea739edfa86edc2a60756d9a9d478f87d94ddda/packages/arg-parser/src/uri-generator.ts#L308). This changeset applies that logic to migration-verifier so that, if a connection string includes only a single node, the verifier will always connect to it. This is useful, e.g., when using a single, containerized mongod for the metadata DB and the mongod’s replication is set up to reference its hostname. In that case a direct connection is necessary when using Podman or other container engines that don’t “inject” the container name into the host’s name resolution (as, e.g., Docker Desktop on macOS does). At the same time, this changeset avoids the above problem by explicitly making the documentation’s container one-liner bind to `localhost`.
1 parent a2b6b9f commit 94563b7

File tree

3 files changed

+69
-8
lines changed

3 files changed

+69
-8
lines changed

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ curl -sSL https://raw.githubusercontent.com/mongodb-labs/migration-verifier/refs
1313

1414
Then start a local replica set to store verification metadata:
1515
```
16-
docker run -it -p27017:27017 -v ./verifier_db:/data/db --entrypoint bash mongodb/mongodb-community-server -c 'mongod --bind_ip_all --replSet rs & mpid=$! && until mongosh --eval "rs.initiate()"; do sleep 1; done && wait $mpid'
16+
podman run -it --rm -p27017:27017 -v ./verifier_db:/data/db --entrypoint bash docker.io/mongodb/mongodb-community-server -c 'mongod --bind_ip_all --replSet rs & mpid=$! && until mongosh --eval "rs.initiate({_id: \"rs\", members: [{_id: 0, host: \"localhost:27017\"}]})"; do sleep 1; done && wait $mpid'
1717
```
18-
(This will create a local `verifier_db` directory so that you can resume verification if needed.)
18+
(This will create a local `verifier_db` directory so that you can resume verification if needed. Omit `-v` with its argument to avoid that.)
1919

2020
Finally, run verification:
2121
```
@@ -40,7 +40,7 @@ The verifier can alternatively store its metadata on the destination cluster. Th
4040

4141
# More Details
4242

43-
To see all options:
43+
To see all options:
4444

4545

4646
```
@@ -52,7 +52,7 @@ To check all namespaces:
5252

5353

5454
```
55-
./migration_verifier --srcURI mongodb://127.0.0.1:27002 --dstURI mongodb://127.0.0.1:27003 --metaURI mongodb://127.0.0.1:27001 --verifyAll
55+
./migration_verifier --srcURI mongodb://127.0.0.1:27002 --dstURI mongodb://127.0.0.1:27003 --verifyAll
5656
```
5757

5858

@@ -133,9 +133,9 @@ The verifier will now check to completion to make sure that there are no inconsi
133133
| Flag | Description |
134134
|-----------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
135135
| `--configFile <value>` | path to an optional YAML config file |
136-
| `--srcURI <URI>` | source Host URI for migration verification (default: "mongodb://localhost:27017") |
137-
| `--dstURI <URI>` | destination Host URI for migration verification (default: "mongodb://localhost:27018") |
138-
| `--metaURI <URI>` | host URI for storing migration verification metadata (default: "mongodb://localhost:27019") |
136+
| `--srcURI <URI>` | source Host URI for migration verification (required) |
137+
| `--dstURI <URI>` | destination Host URI for migration verification (required) |
138+
| `--metaURI <URI>` | host URI for storing migration verification metadata (default: "mongodb://localhost") |
139139
| `--serverPort <port>` | port for the control web server (default: 27020) |
140140
| `--logPath <path>` | logging file path (default: "stdout") |
141141
| `--numWorkers <number>` | number of worker threads to use for verification (default: 10) |

main/migration_verifier.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"time"
1212

1313
"github.com/10gen/migration-verifier/internal/verifier"
14+
"github.com/10gen/migration-verifier/mmongo"
1415
"github.com/10gen/migration-verifier/mslices"
1516
"github.com/pkg/errors"
1617
"github.com/rs/zerolog"
@@ -275,18 +276,31 @@ func handleArgs(ctx context.Context, cCtx *cli.Context) (*verifier.Verifier, err
275276
Int("processID", os.Getpid()).
276277
Msg("migration-verifier started.")
277278

278-
err := v.SetSrcURI(ctx, cCtx.String(srcURI))
279+
srcConnStr := cCtx.String(srcURI)
280+
_, srcConnStr, err := mmongo.MaybeAddDirectConnection(srcConnStr)
281+
if err != nil {
282+
return nil, errors.Wrap(err, "parsing source connection string")
283+
}
284+
err = v.SetSrcURI(ctx, srcConnStr)
279285
if err != nil {
280286
return nil, err
281287
}
282288

283289
dstConnStr := cCtx.String(dstURI)
290+
_, dstConnStr, err = mmongo.MaybeAddDirectConnection(dstConnStr)
291+
if err != nil {
292+
return nil, errors.Wrap(err, "parsing destination connection string")
293+
}
284294
err = v.SetDstURI(ctx, dstConnStr)
285295
if err != nil {
286296
return nil, err
287297
}
288298

289299
metaConnStr := cCtx.String(metaURI)
300+
_, metaConnStr, err = mmongo.MaybeAddDirectConnection(metaConnStr)
301+
if err != nil {
302+
return nil, errors.Wrap(err, "parsing metadata connection string")
303+
}
290304
err = v.SetMetaURI(ctx, metaConnStr)
291305
if err != nil {
292306
return nil, err

mmongo/connstring.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package mmongo
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
"go.mongodb.org/mongo-driver/x/mongo/driver/connstring"
8+
)
9+
10+
// MaybeAddDirectConnection adds the `directConnection` parameter
11+
// to the connection string if:
12+
// - There is only 1 host.
13+
// - The connection string lacks parameters that contraindicate a
14+
// direct connection.
15+
//
16+
// This logic mimics mongosh’s behavior. See:
17+
// https://github.com/mongodb-js/mongosh/blob/fea739edfa86edc2a60756d9a9d478f87d94ddda/packages/arg-parser/src/uri-generator.ts#L308
18+
func MaybeAddDirectConnection(in string) (bool, string, error) {
19+
cs, err := connstring.ParseAndValidate(in)
20+
21+
if err != nil {
22+
return false, "", fmt.Errorf("parsing connection string %#q: %w", in, err)
23+
}
24+
25+
var added bool
26+
27+
switch len(cs.Hosts) {
28+
case 0:
29+
return false, "", fmt.Errorf("connection string has no hosts?? (%#q)", in)
30+
case 1:
31+
if cs.ReplicaSet == "" && !cs.DirectConnectionSet && !cs.LoadBalancedSet {
32+
if !strings.Contains(in, "?") {
33+
if cs.Database == "" {
34+
in += "/"
35+
}
36+
37+
in += "?"
38+
}
39+
40+
in += "directConnection=true"
41+
42+
added = true
43+
}
44+
}
45+
46+
return added, in, nil
47+
}

0 commit comments

Comments
 (0)