Skip to content

Commit 15d5f2a

Browse files
committed
[gateway] add bootstrap gateway service command
1 parent 6f2355d commit 15d5f2a

File tree

13 files changed

+540
-0
lines changed

13 files changed

+540
-0
lines changed

cli/cli/cli.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,18 @@ func (curveadm *CurveAdm) FilterDeployConfig(deployConfigs []*topology.DeployCon
341341
return dcs
342342
}
343343

344+
func (curveadm *CurveAdm) FilterDeployConfigByGateway(deployConfigs []*topology.DeployConfig,
345+
options topology.FilterOption) *topology.DeployConfig {
346+
for _, dc := range deployConfigs {
347+
host := dc.GetHost()
348+
if options.Host == host {
349+
return dc
350+
}
351+
}
352+
353+
return nil
354+
}
355+
344356
func (curveadm *CurveAdm) FilterDeployConfigByRole(dcs []*topology.DeployConfig,
345357
role string) []*topology.DeployConfig {
346358
options := topology.FilterOption{Id: "*", Role: role, Host: "*"}

cli/command/cmd.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ package command
2626

2727
import (
2828
"fmt"
29+
"github.com/dingodb/curveadm/cli/command/gateway"
2930

3031
"github.com/dingodb/curveadm/cli/cli"
3132
"github.com/dingodb/curveadm/cli/command/client"
@@ -66,6 +67,7 @@ func addSubCommands(cmd *cobra.Command, curveadm *cli.CurveAdm) {
6667
target.NewTargetCommand(curveadm), // curveadm target ...
6768
pfs.NewPFSCommand(curveadm), // curveadm pfs ...
6869
monitor.NewMonitorCommand(curveadm), // curveadm monitor ...
70+
gateway.NewGatewayCommand(curveadm), // curveadm gateway ...
6971

7072
NewAuditCommand(curveadm), // curveadm audit
7173
NewCleanCommand(curveadm), // curveadm clean

cli/command/gateway/cmd.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright (c) 2024 dingodb.com, Inc. All Rights Reserved
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/*
18+
* Project: DingoFS
19+
* Created Date: 2024-10-28
20+
* Author: Wei Dong (jackblack369)
21+
*/
22+
23+
package gateway
24+
25+
import (
26+
"github.com/dingodb/curveadm/cli/cli"
27+
cliutil "github.com/dingodb/curveadm/internal/utils"
28+
"github.com/spf13/cobra"
29+
)
30+
31+
func NewGatewayCommand(curveadm *cli.CurveAdm) *cobra.Command {
32+
cmd := &cobra.Command{
33+
Use: "gateway",
34+
Short: "Manage gateway",
35+
Args: cliutil.NoArgs,
36+
RunE: cliutil.ShowHelp(curveadm.Err()),
37+
}
38+
39+
cmd.AddCommand(
40+
NewStartGatewayCommand(curveadm),
41+
)
42+
return cmd
43+
}

cli/command/gateway/start.go

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/*
2+
* Copyright (c) 2024 dingodb.com, Inc. All Rights Reserved
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/*
18+
* Project: DingoFS
19+
* Created Date: 2024-10-28
20+
* Author: Wei Dong (jackblack369)
21+
*/
22+
23+
package gateway
24+
25+
import (
26+
"github.com/dingodb/curveadm/cli/cli"
27+
comm "github.com/dingodb/curveadm/internal/common"
28+
"github.com/dingodb/curveadm/internal/configure"
29+
"github.com/dingodb/curveadm/internal/errno"
30+
"github.com/dingodb/curveadm/internal/playbook"
31+
cliutil "github.com/dingodb/curveadm/internal/utils"
32+
"github.com/spf13/cobra"
33+
)
34+
35+
const (
36+
START_GATEWAY_EXAMPLE = `Examples:
37+
$ curveadm gateway start --host dingfs1 --listen-address=:9000 --console-address=:9001 --mountpoint=/home/dingofs/client`
38+
)
39+
40+
type startOptions struct {
41+
name string
42+
host string
43+
fileName string
44+
mountPoint string
45+
}
46+
47+
var (
48+
START_GATEWAY_PLAYBOOK_STEPS = []int{
49+
playbook.START_GATEWAY,
50+
}
51+
)
52+
53+
func NewStartGatewayCommand(curveadm *cli.CurveAdm) *cobra.Command {
54+
var options startOptions
55+
56+
cmd := &cobra.Command{
57+
// Use: "start --host={hostName} --listen-address={listenAddr} --console-address={consoleAddr} --mountpoint={path} ",
58+
Use: "start {name} {mountpoint} --host dingo7232 -c gateway.yaml ",
59+
Short: "start s3 gateway",
60+
Args: cliutil.ExactArgs(2),
61+
Example: START_GATEWAY_EXAMPLE,
62+
RunE: func(cmd *cobra.Command, args []string) error {
63+
options.name = args[0]
64+
options.mountPoint = args[1]
65+
return runStart(curveadm, options)
66+
},
67+
DisableFlagsInUseLine: true,
68+
}
69+
70+
flags := cmd.Flags()
71+
flags.StringVar(&options.host, "host", "localhost", "Specify target host")
72+
flags.StringVarP(&options.fileName, "conf", "c", "gateway.yaml", "Specify gateway configuration file")
73+
74+
return cmd
75+
}
76+
77+
func runStart(curveadm *cli.CurveAdm, options startOptions) error {
78+
79+
// 1) generate mount playbook
80+
pb, err := genStartPlaybook(curveadm, options)
81+
if err != nil {
82+
return err
83+
}
84+
85+
// 2) run playground
86+
err = pb.Run()
87+
if err != nil {
88+
return err
89+
}
90+
91+
// 3) print success prompt
92+
// curveadm.WriteOutln(color.GreenString("start gateway success !\n gateway listen address: %s%s \n gateway console address: %s%s \n"),
93+
// options.host, options.listenAddress, options.host, options.consoleAddress)
94+
95+
return nil
96+
}
97+
98+
func genStartPlaybook(curveadm *cli.CurveAdm, options startOptions) (*playbook.Playbook, error) {
99+
steps := START_GATEWAY_PLAYBOOK_STEPS
100+
pb := playbook.NewPlaybook(curveadm)
101+
102+
// parse client configure
103+
gc, err := configure.ParseGatewayConfig(options.fileName)
104+
if err != nil {
105+
return nil, err
106+
}
107+
listenPort := gc.GetListenPort()
108+
if listenPort == "" {
109+
listenPort = "19000"
110+
}
111+
gatewayListenAddr := ":" + listenPort
112+
113+
consolePort := gc.GetConsolePort()
114+
if consolePort == "" {
115+
consolePort = "19001"
116+
}
117+
gatewayConsoleAddr := ":" + consolePort
118+
119+
mdsAddr := gc.GetDingofsMDSAddr()
120+
if mdsAddr == "" {
121+
return nil, errno.ERR_GATEWAY_MDSADDR_EMPTY
122+
}
123+
124+
for _, step := range steps {
125+
126+
pb.AddStep(&playbook.PlaybookStep{
127+
Type: step,
128+
Configs: gc,
129+
Options: map[string]interface{}{
130+
comm.GATEWAY_NAME: options.name,
131+
comm.GATEWAY_HOST: options.host,
132+
comm.GATEWAY_LISTEN_ADDR: gatewayListenAddr,
133+
comm.GATEWAY_CONSOLE_ADDR: gatewayConsoleAddr,
134+
comm.GATEWAY_MOUNTPOINT: options.mountPoint,
135+
comm.MDSADDR: mdsAddr,
136+
},
137+
})
138+
}
139+
return pb, nil
140+
}

internal/common/common.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,14 @@ const (
116116
KEY_SERVICE_HOSTS = "SERVICE_HOSTS"
117117
KEY_MONITOR_STATUS = "MONITOR_STATUS"
118118
CLEANED_MONITOR_CONF = "-"
119+
120+
// gateway
121+
GATEWAY_NAME = "GATEWAY_NAME"
122+
GATEWAY_HOST = "GATEWAY_HOST"
123+
GATEWAY_LISTEN_ADDR = "GATEWAY_LISTEN_ADDR"
124+
GATEWAY_CONSOLE_ADDR = "GATEWAY_CONSOLE_ADDR"
125+
GATEWAY_MOUNTPOINT = "GATEWAY_MOUNTPOINT"
126+
MDSADDR = "mdsaddr"
119127
)
120128

121129
// others

internal/configure/gateway.go

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package configure
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
"github.com/dingodb/curveadm/internal/errno"
8+
"github.com/dingodb/curveadm/internal/utils"
9+
"github.com/spf13/viper"
10+
)
11+
12+
const (
13+
KEY_GATEWAY_S3_ROOT_USER = "s3.root_user"
14+
KEY_GATEWAY_S3_ROOT_PASSWORD = "s3.root_password"
15+
KEY_GATEWAY_LISTEN_PORT = "gateway.listen_port"
16+
KEY_GATEWAY_CONSOLE_PORT = "gateway.console_port"
17+
KEY_DINGOFS_MDS_ADDRS = "dingofs.mdsaddr"
18+
KEY_GATEWAY_CONTAINER_IMAGE = "container_image"
19+
KEY_GATEWAY_LOG_DIR = "log_dir"
20+
KEY_GATEWAY_DATA_DIR = "data_dir"
21+
KEY_GATEWAY_CORE_DIR = "core_dir"
22+
DEFAULT_DINGOFS_GATEWAY_CONTAINER_IMAGE = "dingodatabase/dingofs:latest"
23+
)
24+
25+
type (
26+
GatewayConfig struct {
27+
configMap map[string]interface{}
28+
data string // configure file content
29+
}
30+
)
31+
32+
func NewGatewayConfig(config map[string]interface{}) (*GatewayConfig, error) {
33+
gc := &GatewayConfig{
34+
configMap: config,
35+
}
36+
37+
return gc, nil
38+
}
39+
40+
func ParseGatewayConfig(filename string) (*GatewayConfig, error) {
41+
// 1. read file content
42+
data, err := utils.ReadFile(filename)
43+
if err != nil {
44+
return nil, errno.ERR_PARSE_GATEWAY_CONFIGURE_FAILED.E(err)
45+
}
46+
47+
// 2. new parser
48+
parser := viper.NewWithOptions(viper.KeyDelimiter("::"))
49+
parser.SetConfigFile(filename)
50+
parser.SetConfigType("yaml")
51+
err = parser.ReadInConfig()
52+
if err != nil {
53+
return nil, errno.ERR_PARSE_GATEWAY_CONFIGURE_FAILED.E(err)
54+
}
55+
56+
// 3. parse
57+
m := map[string]interface{}{}
58+
err = parser.Unmarshal(&m)
59+
if err != nil {
60+
return nil, errno.ERR_PARSE_GATEWAY_CONFIGURE_FAILED.E(err)
61+
}
62+
63+
// 4. new config
64+
cfg, err := NewGatewayConfig(m)
65+
if err != nil {
66+
return nil, err
67+
}
68+
69+
cfg.data = data
70+
return cfg, nil
71+
}
72+
73+
func (gc *GatewayConfig) getString(key string) string {
74+
v := gc.configMap[strings.ToLower(key)]
75+
if v == nil {
76+
return ""
77+
}
78+
return fmt.Sprintf("%v", v)
79+
}
80+
81+
func (gc *GatewayConfig) getBool(key string) bool {
82+
v := gc.configMap[strings.ToLower(key)]
83+
if v == nil {
84+
return false
85+
}
86+
return v.(bool)
87+
}
88+
89+
func (gc *GatewayConfig) GetS3RootUser() string { return gc.getString(KEY_GATEWAY_S3_ROOT_USER) }
90+
func (gc *GatewayConfig) GetS3RootPassword() string {
91+
return gc.getString(KEY_GATEWAY_S3_ROOT_PASSWORD)
92+
}
93+
94+
func (gc *GatewayConfig) GetListenPort() string {
95+
return gc.getString(KEY_GATEWAY_LISTEN_PORT)
96+
}
97+
98+
func (gc *GatewayConfig) GetConsolePort() string {
99+
return gc.getString(KEY_GATEWAY_CONSOLE_PORT)
100+
}
101+
102+
func (gc *GatewayConfig) GetDataDir() string { return gc.getString(KEY_GATEWAY_DATA_DIR) }
103+
func (gc *GatewayConfig) GetLogDir() string { return gc.getString(KEY_GATEWAY_LOG_DIR) }
104+
func (gc *GatewayConfig) GetCoreDir() string { return gc.getString(KEY_GATEWAY_CORE_DIR) }
105+
func (gc *GatewayConfig) GetData() string { return gc.data }
106+
func (gc *GatewayConfig) GetContainerImage() string {
107+
containerImage := gc.getString(KEY_GATEWAY_CONTAINER_IMAGE)
108+
if len(containerImage) == 0 {
109+
containerImage = DEFAULT_DINGOFS_GATEWAY_CONTAINER_IMAGE
110+
}
111+
return containerImage
112+
}
113+
114+
func (gc *GatewayConfig) GetDingofsMDSAddr() string {
115+
return gc.getString(KEY_DINGOFS_MDS_ADDRS)
116+
}

internal/configure/gateway_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package configure
2+
3+
import "testing"
4+
5+
func TestParseGatewayFile(t *testing.T) {
6+
fileName := "/home/dongw/dingofs/gateway.yaml"
7+
gc, err := ParseGatewayConfig(fileName)
8+
if err != nil {
9+
t.Errorf("parse gateway config file failed: %v", err)
10+
}
11+
t.Logf("gateway config: %v", gc)
12+
}

internal/errno/errno.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,10 @@ var (
371371
ERR_REQUIRE_CURVEFS_KIND_CLIENT_CONFIGURE_FILE = EC(351003, "require curvefs kind client configure file")
372372
ERR_INVALID_CLUSTER_LISTEN_MDS_ADDRESS = EC(351004, "invalid cluster MDS listen address")
373373

374+
// 360: configure (gateway.yaml: parse failed)
375+
ERR_PARSE_GATEWAY_CONFIGURE_FAILED = EC(360000, "parse client configure failed")
376+
ERR_GATEWAY_MDSADDR_EMPTY = EC(360001, "dingofs mdsaddr is empty")
377+
374378
// 400: common (hosts)
375379
ERR_HOST_NOT_FOUND = EC(400000, "host not found")
376380

@@ -546,6 +550,10 @@ var (
546550
ERR_GET_CONTAINER_LOGS_FAILED = EC(630013, "get container logs failed")
547551
ERR_UPDATE_CONTAINER_FAILED = EC(630014, "update container failed")
548552

553+
// 640: gateway (curve gateway)
554+
ERR_NO_HOST_FOR_GATEWAY = EC(640000, "no host found")
555+
ERR_START_GATEWAY_FAILED = EC(640001, "start s3 gateway failed")
556+
549557
// 690: execuetr task (others)
550558
ERR_START_CRONTAB_IN_CONTAINER_FAILED = EC(690000, "start crontab in container failed")
551559

0 commit comments

Comments
 (0)