forked from vitessio/vitess
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
227 lines (183 loc) · 6.24 KB
/
main.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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
// vttestserver is a native Go implementation of `run_local_server.py`.
// It allows users to spawn a self-contained Vitess server for local testing/CI
package main
import (
"encoding/json"
"flag"
"fmt"
"os"
"strconv"
"strings"
"github.com/golang/protobuf/proto"
"vitess.io/vitess/go/vt/log"
vttestpb "vitess.io/vitess/go/vt/proto/vttest"
"vitess.io/vitess/go/vt/vttest"
)
type topoFlags struct {
cells string
keyspaces string
shards string
replicas int
rdonly int
}
func (t *topoFlags) buildTopology() (*vttestpb.VTTestTopology, error) {
topo := &vttestpb.VTTestTopology{}
topo.Cells = strings.Split(t.cells, ",")
keyspaces := strings.Split(t.keyspaces, ",")
shardCounts := strings.Split(t.shards, ",")
if len(keyspaces) != len(shardCounts) {
return nil, fmt.Errorf("--keyspaces must be same length as --shards")
}
for i := range keyspaces {
name := keyspaces[i]
numshards, err := strconv.ParseInt(shardCounts[i], 10, 32)
if err != nil {
return nil, err
}
ks := &vttestpb.Keyspace{
Name: name,
ReplicaCount: int32(t.replicas),
RdonlyCount: int32(t.rdonly),
}
for _, shardname := range vttest.GetShardNames(int(numshards)) {
ks.Shards = append(ks.Shards, &vttestpb.Shard{
Name: shardname,
})
}
topo.Keyspaces = append(topo.Keyspaces, ks)
}
return topo, nil
}
func parseFlags() (config vttest.Config, env vttest.Environment, err error) {
var seed vttest.SeedConfig
var topo topoFlags
var basePort int
var protoTopo string
var doSeed bool
var mycnf string
flag.IntVar(&basePort, "port", 0,
"Port to use for vtcombo. If this is 0, a random port will be chosen.")
flag.StringVar(&protoTopo, "proto_topo", "",
"Define the fake cluster topology as a compact text format encoded"+
" vttest proto. See vttest.proto for more information.")
flag.StringVar(&config.SchemaDir, "schema_dir", "",
"Directory for initial schema files. Within this dir,"+
" there should be a subdir for each keyspace. Within"+
" each keyspace dir, each file is executed as SQL"+
" after the database is created on each shard."+
" If the directory contains a vschema.json file, it"+
" will be used as the vschema for the V3 API.")
flag.StringVar(&config.DefaultSchemaDir, "default_schema_dir", "",
"Default directory for initial schema files. If no schema is found"+
" in schema_dir, default to this location.")
flag.StringVar(&config.DataDir, "data_dir", "",
"Directory where the data files will be placed, defaults to a random "+
"directory under /vt/vtdataroot")
flag.BoolVar(&config.OnlyMySQL, "mysql_only", false,
"If this flag is set only mysql is initialized."+
" The rest of the vitess components are not started."+
" Also, the output specifies the mysql unix socket"+
" instead of the vtgate port.")
flag.BoolVar(&doSeed, "initialize_with_random_data", false,
"If this flag is each table-shard will be initialized"+
" with random data. See also the 'rng_seed' and 'min_shard_size'"+
" and 'max_shard_size' flags.")
flag.IntVar(&seed.RngSeed, "rng_seed", 123,
"The random number generator seed to use when initializing"+
" with random data (see also --initialize_with_random_data)."+
" Multiple runs with the same seed will result with the same"+
" initial data.")
flag.IntVar(&seed.MinSize, "min_table_shard_size", 1000,
"The minimum number of initial rows in a table shard. Ignored if"+
"--initialize_with_random_data is false. The actual number is chosen"+
" randomly.")
flag.IntVar(&seed.MaxSize, "max_table_shard_size", 10000,
"The maximum number of initial rows in a table shard. Ignored if"+
"--initialize_with_random_data is false. The actual number is chosen"+
" randomly")
flag.Float64Var(&seed.NullProbability, "null_probability", 0.1,
"The probability to initialize a field with 'NULL' "+
" if --initialize_with_random_data is true. Only applies to fields"+
" that can contain NULL values.")
flag.StringVar(&config.WebDir, "web_dir", "",
"location of the vtctld web server files.")
flag.StringVar(&config.WebDir2, "web_dir2", "",
"location of the vtctld2 web server files.")
flag.StringVar(&config.MySQLBindHost, "mysql_bind_host", "localhost",
"which host to bind vtgate mysql listener to")
flag.StringVar(&mycnf, "extra_my_cnf", "",
"extra files to add to the config, separated by ':'")
flag.StringVar(&topo.cells, "cells", "test", "Comma separated list of cells")
flag.StringVar(&topo.keyspaces, "keyspaces", "test_keyspace",
"Comma separated list of keyspaces")
flag.StringVar(&topo.shards, "num_shards", "2",
"Comma separated shard count (one per keyspace)")
flag.IntVar(&topo.replicas, "replica_count", 2,
"Replica tablets per shard (includes master)")
flag.IntVar(&topo.rdonly, "rdonly_count", 1,
"Rdonly tablets per shard")
flag.StringVar(&config.Charset, "charset", "utf8", "MySQL charset")
flag.StringVar(&config.SnapshotFile, "snapshot_file", "",
"A MySQL DB snapshot file")
flag.StringVar(&config.TransactionMode, "transaction_mode", "MULTI", "Transaction mode MULTI (default), SINGLE or TWOPC ")
flag.Parse()
if basePort != 0 {
if config.DataDir == "" {
env, err = vttest.NewLocalTestEnv("", basePort)
if err != nil {
return
}
} else {
env, err = vttest.NewLocalTestEnvWithDirectory("", basePort, config.DataDir)
if err != nil {
return
}
}
}
if protoTopo == "" {
config.Topology, err = topo.buildTopology()
if err != nil {
return
}
} else {
var topology vttestpb.VTTestTopology
err = proto.UnmarshalText(protoTopo, &topology)
if err != nil {
return
}
if len(topology.Cells) == 0 {
topology.Cells = append(topology.Cells, "test")
}
config.Topology = &topology
}
if doSeed {
config.Seed = &seed
}
if mycnf != "" {
config.ExtraMyCnf = strings.Split(mycnf, ":")
}
return
}
func main() {
config, env, err := parseFlags()
if err != nil {
log.Fatal(err)
}
log.Infof("Starting local cluster...")
log.Infof("config: %#v", config)
cluster := vttest.LocalCluster{
Config: config,
Env: env,
}
err = cluster.Setup()
defer cluster.TearDown()
if err != nil {
log.Fatal(err)
}
kvconf := cluster.JSONConfig()
if err := json.NewEncoder(os.Stdout).Encode(kvconf); err != nil {
log.Fatal(err)
}
log.Info("Local cluster started.")
select {}
}