Skip to content

Commit 4394eab

Browse files
authored
feat: implement config setup for each component in bare-metal mode (#153)
* add merge operation for bare-metal config Signed-off-by: sh2 <shawnhxh@outlook.com> * add custom configuration file support for each component in bare-metal mode Signed-off-by: sh2 <shawnhxh@outlook.com> --------- Signed-off-by: sh2 <shawnhxh@outlook.com>
1 parent 1cd3b44 commit 4394eab

File tree

15 files changed

+235
-19
lines changed

15 files changed

+235
-19
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# More options for storage: https://docs.greptime.com/user-guide/operations/configuration#storage-options
2+
3+
[storage]
4+
type = "S3"
5+
bucket = "test_greptimedb"
6+
root = "/greptimedb"
7+
access_key_id = "<access key id>"
8+
secret_access_key = "<secret access key>"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
cluster:
2+
name: mycluster # name of the cluster
3+
artifact:
4+
version: latest
5+
frontend:
6+
replicas: 1
7+
datanode:
8+
replicas: 3
9+
rpcAddr: 0.0.0.0:14100
10+
mysqlAddr: 0.0.0.0:14200
11+
httpAddr: 0.0.0.0:14300
12+
config: 'examples/bare-metal/cluster-with-s3-storage.datanode.toml'
13+
meta:
14+
replicas: 1
15+
storeAddr: 127.0.0.1:2379
16+
serverAddr: 0.0.0.0:3002
17+
httpAddr: 0.0.0.0:14001
18+
19+
etcd:
20+
artifact:
21+
version: v3.5.7

go.mod

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ require (
1919
github.com/onsi/gomega v1.23.0
2020
github.com/spf13/cobra v1.6.1
2121
github.com/stretchr/testify v1.8.2
22+
golang.org/x/exp v0.0.0-20230905200255-921286631fa9
2223
gopkg.in/yaml.v3 v3.0.1
2324
helm.sh/helm/v3 v3.11.1
2425
k8s.io/api v0.26.0
@@ -137,7 +138,7 @@ require (
137138
golang.org/x/net v0.10.0 // indirect
138139
golang.org/x/oauth2 v0.8.0 // indirect
139140
golang.org/x/sync v0.1.0 // indirect
140-
golang.org/x/sys v0.11.0 // indirect
141+
golang.org/x/sys v0.12.0 // indirect
141142
golang.org/x/term v0.11.0 // indirect
142143
golang.org/x/text v0.12.0 // indirect
143144
golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect

go.sum

+4-2
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
674674
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
675675
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
676676
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
677+
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
678+
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
677679
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
678680
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
679681
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -852,8 +854,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
852854
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
853855
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
854856
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
855-
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
856-
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
857+
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
858+
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
857859
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
858860
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
859861
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=

pkg/cmd/gtctl/cluster/create/create.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ func NewCluster(args []string, options ClusterCliOptions, l logger.Logger) error
180180
}
181181

182182
if options.BareMetal {
183-
if err := waitChildProcess(ctx, clusterDeployer, false, deleteOpts); err != nil {
183+
if err = waitChildProcess(ctx, clusterDeployer, false, deleteOpts); err != nil {
184184
return err
185185
}
186186
}
@@ -205,17 +205,17 @@ func newDeployer(l logger.Logger, clusterName string, options *ClusterCliOptions
205205
}
206206

207207
if options.Config != "" {
208-
var config bmconfig.Config
209-
data, err := os.ReadFile(options.Config)
208+
var cfg bmconfig.Config
209+
raw, err := os.ReadFile(options.Config)
210210
if err != nil {
211211
return nil, err
212212
}
213213

214-
if err := yaml.Unmarshal(data, &config); err != nil {
214+
if err = yaml.Unmarshal(raw, &cfg); err != nil {
215215
return nil, err
216216
}
217217

218-
opts = append(opts, baremetal.WithConfig(&config))
218+
opts = append(opts, baremetal.WithMergeConfig(&cfg, raw))
219219
}
220220

221221
opts = append(opts, baremetal.WithAlawaysDownload(options.AlwaysDownload))
@@ -358,6 +358,7 @@ func waitChildProcess(ctx context.Context, deployer deployer.Interface, close bo
358358
fmt.Printf("\x1b[32m%s\x1b[0m", fmt.Sprintf("To view dashboard by accessing: %s\n", logger.Bold("http://localhost:4000/dashboard/")))
359359
} else {
360360
fmt.Printf("\x1b[32m%s\x1b[0m", fmt.Sprintf("The cluster(pid=%d, version=%s) run in bare-metal has been deleted now...\n", os.Getpid(), v))
361+
return nil
361362
}
362363

363364
// Wait for all the child processes to exit.

pkg/deployer/baremetal/component/datanode.go

+5
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ func (d *datanode) BuildArgs(ctx context.Context, params ...interface{}) []strin
134134
fmt.Sprintf("--data-home=%s", dataHomeDir),
135135
fmt.Sprintf("--wal-dir=%s", walDir),
136136
}
137+
138+
if len(d.config.Config) > 0 {
139+
args = append(args, fmt.Sprintf("-c %s", d.config.Config))
140+
}
141+
137142
return args
138143
}
139144

pkg/deployer/baremetal/component/frontend.go

+6
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,17 @@ func (f *frontend) BuildArgs(ctx context.Context, params ...interface{}) []strin
8787
if logLevel == "" {
8888
logLevel = config.DefaultLogLevel
8989
}
90+
9091
args := []string{
9192
fmt.Sprintf("--log-level=%s", logLevel),
9293
f.Name(), "start",
9394
fmt.Sprintf("--metasrv-addr=%s", f.metaSrvAddr),
9495
}
96+
97+
if len(f.config.Config) > 0 {
98+
args = append(args, fmt.Sprintf("-c %s", f.config.Config))
99+
}
100+
95101
return args
96102
}
97103

pkg/deployer/baremetal/component/metasrv.go

+9-4
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,16 @@ func (m *metaSrv) BuildArgs(ctx context.Context, params ...interface{}) []string
119119
args := []string{
120120
fmt.Sprintf("--log-level=%s", logLevel),
121121
m.Name(), "start",
122-
"--store-addr", m.config.StoreAddr,
123-
"--server-addr", m.config.ServerAddr,
124-
"--http-addr", generateMetaSrvAddr(m.config.HTTPAddr, nodeID),
125-
"--bind-addr", generateMetaSrvAddr(bindAddr, nodeID),
122+
fmt.Sprintf("--store-addr=%s", m.config.StoreAddr),
123+
fmt.Sprintf("--server-addr=%s", m.config.ServerAddr),
124+
fmt.Sprintf("--http-addr=%s", generateMetaSrvAddr(m.config.HTTPAddr, nodeID)),
125+
fmt.Sprintf("--bind-addr=%s", generateMetaSrvAddr(bindAddr, nodeID)),
126126
}
127+
128+
if len(m.config.Config) > 0 {
129+
args = append(args, fmt.Sprintf("-c %s", m.config.Config))
130+
}
131+
127132
return args
128133
}
129134

pkg/deployer/baremetal/config/datanode.go

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ type Datanode struct {
2424
DataDir string `yaml:"dataDir" validate:"omitempty,dirpath"`
2525
WalDir string `yaml:"walDir" validate:"omitempty,dirpath"`
2626
ProcedureDir string `yaml:"procedureDir" validate:"omitempty,dirpath"`
27+
Config string `yaml:"config" validate:"omitempty,filepath"`
2728

2829
LogLevel string `yaml:"logLevel"`
2930
}

pkg/deployer/baremetal/config/frontend.go

+2
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,7 @@ type Frontend struct {
2222
PostgresAddr string `yaml:"postgresAddr" validate:"omitempty,hostname_port"`
2323
MetaAddr string `yaml:"metaAddr" validate:"omitempty,hostname_port"`
2424

25+
Config string `yaml:"config" validate:"omitempty,filepath"`
26+
2527
LogLevel string `yaml:"logLevel"`
2628
}

pkg/deployer/baremetal/config/metasrv.go

+2
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,7 @@ type MetaSrv struct {
2222
BindAddr string `yaml:"bindAddr" validate:"omitempty,hostname_port"`
2323
HTTPAddr string `yaml:"httpAddr" validate:"required,hostname_port"`
2424

25+
Config string `yaml:"config" validate:"omitempty,filepath"`
26+
2527
LogLevel string `yaml:"logLevel"`
2628
}

pkg/deployer/baremetal/deployer.go

+35-5
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,14 @@ func NewDeployer(l logger.Logger, clusterName string, opts ...Option) (Interface
9696
d.initClusterDirsAndPath(clusterName)
9797

9898
if !d.createNoDirs {
99-
if err := d.createClusterDirs(); err != nil {
99+
if err = d.createClusterDirs(); err != nil {
100100
return nil, err
101101
}
102102

103103
d.bm = component.NewBareMetalCluster(d.config.Cluster, d.workingDirs, &d.wg, d.logger)
104104

105105
// Save a copy of cluster config in yaml format.
106-
if err := d.createClusterConfigFile(); err != nil {
106+
if err = d.createClusterConfigFile(); err != nil {
107107
return nil, err
108108
}
109109
}
@@ -188,10 +188,40 @@ func (d *Deployer) createClusterConfigFile() error {
188188
return nil
189189
}
190190

191-
func WithConfig(config *config.Config) Option {
192-
// TODO(zyy17): Should merge the default configuration.
191+
// WithMergeConfig merges config with current deployer config.
192+
// It will perform WithReplaceConfig if any error occurs during merging or receive nil raw config.
193+
func WithMergeConfig(cfg *config.Config, rawConfig []byte) Option {
194+
if len(rawConfig) == 0 {
195+
return WithReplaceConfig(cfg)
196+
}
197+
198+
return func(d *Deployer) {
199+
defaultConfig, err := yaml.Marshal(d.config)
200+
if err != nil {
201+
d.config = cfg
202+
return
203+
}
204+
205+
out, err := fileutils.MergeYAML(defaultConfig, rawConfig)
206+
if err != nil {
207+
d.config = cfg
208+
return
209+
}
210+
211+
var newConfig config.Config
212+
if err = yaml.Unmarshal(out, &newConfig); err != nil {
213+
d.config = cfg
214+
return
215+
}
216+
217+
d.config = &newConfig
218+
}
219+
}
220+
221+
// WithReplaceConfig replaces config with current deployer config.
222+
func WithReplaceConfig(cfg *config.Config) Option {
193223
return func(d *Deployer) {
194-
d.config = config
224+
d.config = cfg
195225
}
196226
}
197227

pkg/deployer/baremetal/deployer_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ func TestNewDeployer(t *testing.T) {
6161
assert.NotNil(t, d2)
6262
assert.True(t, d2.alwaysDownload)
6363

64-
// New Deployer with config option
64+
// New Deployer with replace config option
6565
newConfig := config.DefaultConfig()
6666
newConfig.Cluster.Frontend.Replicas = 3
67-
deployer, err = NewDeployer(L, clusterName, WithConfig(newConfig))
67+
deployer, err = NewDeployer(L, clusterName, WithReplaceConfig(newConfig))
6868
assert.NoError(t, err)
6969
d3, ok := deployer.(*Deployer)
7070
assert.True(t, ok)

pkg/utils/file/yaml.go

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright 2023 Greptime Team
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package file
16+
17+
import (
18+
"bytes"
19+
20+
"golang.org/x/exp/maps"
21+
"gopkg.in/yaml.v3"
22+
)
23+
24+
// MergeYAML merges two yaml files from src to dst, the src yaml will override dst yaml if the same key exists.
25+
func MergeYAML(dst, src []byte) ([]byte, error) {
26+
map1 := map[string]interface{}{}
27+
map2 := map[string]interface{}{}
28+
29+
if err := yaml.Unmarshal(src, &map1); err != nil {
30+
return nil, err
31+
}
32+
33+
if err := yaml.Unmarshal(dst, &map2); err != nil {
34+
return nil, err
35+
}
36+
37+
maps.Copy(map2, map1)
38+
39+
buf := bytes.NewBuffer([]byte{})
40+
encoder := yaml.NewEncoder(buf)
41+
encoder.SetIndent(2)
42+
43+
if err := encoder.Encode(map2); err != nil {
44+
return nil, err
45+
}
46+
47+
if err := encoder.Close(); err != nil {
48+
return nil, err
49+
}
50+
51+
return buf.Bytes(), nil
52+
}

pkg/utils/file/yaml_test.go

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// Copyright 2023 Greptime Team
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package file
16+
17+
import (
18+
"reflect"
19+
"testing"
20+
)
21+
22+
func TestMergeYAML(t *testing.T) {
23+
tests := []struct {
24+
name string
25+
yaml1 string
26+
yaml2 string
27+
want string
28+
}{
29+
{
30+
name: "test",
31+
yaml1: `
32+
a: a
33+
b:
34+
c:
35+
d: d
36+
e:
37+
f:
38+
- g
39+
k:
40+
l: l
41+
`,
42+
yaml2: `
43+
a: a1
44+
b:
45+
c:
46+
d: d1
47+
e:
48+
f:
49+
- h
50+
i:
51+
j: j
52+
`,
53+
want: `a: a1
54+
b:
55+
c:
56+
d: d1
57+
e:
58+
f:
59+
- h
60+
i:
61+
j: j
62+
k:
63+
l: l
64+
`,
65+
},
66+
}
67+
for _, tt := range tests {
68+
t.Run(tt.name, func(t *testing.T) {
69+
got, err := MergeYAML([]byte(tt.yaml1), []byte(tt.yaml2))
70+
if err != nil {
71+
t.Errorf("MergeYAML() err = %v", err)
72+
}
73+
74+
actual := string(got)
75+
if !reflect.DeepEqual(actual, tt.want) {
76+
t.Errorf("MergeYAML() got = %v, want %v", actual, tt.want)
77+
}
78+
})
79+
}
80+
}

0 commit comments

Comments
 (0)