-
Notifications
You must be signed in to change notification settings - Fork 14
/
config.go
158 lines (129 loc) · 3.92 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package memongo
import (
"fmt"
"log"
"net"
"os"
"path"
"runtime"
"strconv"
"time"
"github.com/tryvium-travels/memongo/memongolog"
"github.com/tryvium-travels/memongo/mongobin"
)
// Options is the configuration options for a launched MongoDB binary
type Options struct {
// ShouldUseReplica indicates whether a replica should be used. If this is not specified,
// no replica will be used and mongo server will be run as standalone.
ShouldUseReplica bool
// Port to run MongoDB on. If this is not specified, a random (OS-assigned)
// port will be used
Port int
// Path to the cache for downloaded mongod binaries. Defaults to the
// system cache location.
CachePath string
// If DownloadURL and MongodBin are not given, this version of MongoDB will
// be downloaded
MongoVersion string
// If given, mongod will be downloaded from this URL instead of the
// auto-detected URL based on the current platform and MongoVersion
DownloadURL string
// If given, this binary will be run instead of downloading a mongod binary
MongodBin string
// Logger for printing messages. Defaults to printing to stdout.
Logger *log.Logger
// A LogLevel to log at. Defaults to LogLevelInfo.
LogLevel memongolog.LogLevel
// How long to wait for mongod to start up and report a port number. Does
// not include download time, only startup time. Defaults to 10 seconds.
StartupTimeout time.Duration
// If set, pass the --auth flag to mongod. This will allow tests to setup
// authentication.
Auth bool
}
func (opts *Options) fillDefaults() error {
if opts.MongodBin == "" {
opts.MongodBin = os.Getenv("MEMONGO_MONGOD_BIN")
}
if opts.MongodBin == "" {
// The user didn't give us a local path to a binary. That means we need
// a download URL and a cache path.
// Determine the cache path
if opts.CachePath == "" {
opts.CachePath = os.Getenv("MEMONGO_CACHE_PATH")
}
if opts.CachePath == "" && os.Getenv("XDG_CACHE_HOME") != "" {
opts.CachePath = path.Join(os.Getenv("XDG_CACHE_HOME"), "memongo")
}
if opts.CachePath == "" {
if runtime.GOOS == "darwin" {
opts.CachePath = path.Join(os.Getenv("HOME"), "Library", "Caches", "memongo")
} else {
opts.CachePath = path.Join(os.Getenv("HOME"), ".cache", "memongo")
}
}
// Determine the download URL
if opts.DownloadURL == "" {
opts.DownloadURL = os.Getenv("MEMONGO_DOWNLOAD_URL")
}
if opts.DownloadURL == "" {
if opts.MongoVersion == "" {
return fmt.Errorf("one of MongoVersion, DownloadURL, or MongodBin must be given")
}
spec, err := mongobin.MakeDownloadSpec(opts.MongoVersion)
if err != nil {
return err
}
opts.DownloadURL = spec.GetDownloadURL()
}
}
// Determine the port number
if opts.Port == 0 {
mongoVersionEnv := os.Getenv("MEMONGO_MONGOD_PORT")
if mongoVersionEnv != "" {
port, err := strconv.Atoi(mongoVersionEnv)
if err != nil {
return fmt.Errorf("error parsing MEMONGO_MONGOD_PORT: %s", err)
}
opts.Port = port
}
}
if opts.Port == 0 {
port, err := getFreePort()
if err != nil {
return fmt.Errorf("error finding a free port: %s", err)
}
opts.Port = port
if opts.StartupTimeout == 0 {
opts.StartupTimeout = 10 * time.Second
}
}
return nil
}
func (opts *Options) getLogger() *memongolog.Logger {
return memongolog.New(opts.Logger, opts.LogLevel)
}
func (opts *Options) getOrDownloadBinPath() (string, error) {
if opts.MongodBin != "" {
return opts.MongodBin, nil
}
// Download or fetch from cache
binPath, err := mongobin.GetOrDownloadMongod(opts.DownloadURL, opts.CachePath, opts.getLogger())
if err != nil {
return "", err
}
return binPath, nil
}
func getFreePort() (int, error) {
// Based on: https://github.com/phayes/freeport/blob/master/freeport.go
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
if err != nil {
return 0, err
}
l, err := net.ListenTCP("tcp", addr)
if err != nil {
return 0, err
}
defer l.Close()
return l.Addr().(*net.TCPAddr).Port, nil
}