diff --git a/.github/workflows/CodeQL.yml b/.github/workflows/CodeQL.yml new file mode 100644 index 000000000..39b438f6f --- /dev/null +++ b/.github/workflows/CodeQL.yml @@ -0,0 +1,54 @@ +name: "CodeQL" + +on: + push: + branches: [ "master","develop" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "master","develop" ] + schedule: + - cron: '0 17 * * 5' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + # timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'go' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby', 'swift' ] + # Use only 'java' to analyze code written in Java, Kotlin or both + # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 42c520809..4218c0e6e 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -7,7 +7,23 @@ on: branches: [ $default-branch, "develop" ] jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Setup go + uses: actions/setup-go@v3 + with: + go-version: '1.19' + - name: Checkout repository + uses: actions/checkout@v3 + - name: Setup golangci-lint + uses: golangci/golangci-lint-action@v3.4.0 + with: + version: v1.52.2 + args: --verbose + test: + needs: lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -21,7 +37,7 @@ jobs: run: make test build: - needs: test + needs: lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -29,7 +45,5 @@ jobs: uses: actions/setup-go@v3 with: go-version: 1.19 - - name: Set dependencies - run: sudo apt update && sudo apt install musl-tools - name: Build - run: make build + run: go build -v ./... diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 000000000..9a8b315a9 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,38 @@ +run: + timeout: 5m +linters: + enable: + # Simple linter to check that your code does not contain non-ASCII identifiers. + - asciicheck + # Go linter that checks if package imports are in a list of acceptable packages. + - depguard + # Checks for pointers to enclosing loop variables. + - exportloopref + # Gofmt checks whether code was gofmt-ed + - gofmt + # Inspects source code for security problems. + - gosec + # Finds naked returns in functions greater than a specified function length. + - nakedret + # Reports ill-formed or insufficient nolint directives. + - nolintlint + # Checks for dangerous unicode character sequences. + - bidichk + disable: + # ignore errcheck + - errcheck +linters-settings: + gosec: + # Available rules: https://github.com/securego/gosec#available-rules + excludes: + - G101 # Look for hard coded credentials + - G204 # Audit use of command execution + - G401 # Detect the usage of DES, RC4, MD5 or SHA1 + - G403 # Ensure minimum RSA key length of 2048 bits + - G404 # Insecure random number source (rand) + - G501 # Import blocklist: crypto/md5 + - G502 # Import blocklist: crypto/des + - G503 # Import blocklist: crypto/rc4 + - G504 # Import blocklist: net/http/cgi + - G505 # Import blocklist: crypto/sha1 + - G601 # Implicit memory aliasing of items from a range statement diff --git a/Makefile b/Makefile index 4e92ad68c..471b0fcb9 100644 --- a/Makefile +++ b/Makefile @@ -56,14 +56,16 @@ SERVER_PACKAGES := $(PWD)/cmd/service/main.go # tar VERSION := "unknown" -build: +build: fmt vet $(GOENV) $(GO) build -o $(OUTPUT) $(BUILD_FLAGS) $(PACKAGES) $(GOENV) $(GO) build -o $(SERVER_OUTPUT) $(BUILD_FLAGS) $(SERVER_PACKAGES) -debug: + +debug: fmt vet $(GOENV) $(GO) build -o $(OUTPUT) $(DEBUG_FLAGS) $(PACKAGES) $(GOENV) $(GO) build -o $(SERVER_OUTPUT) $(DEBUG_FLAGS) $(SERVER_PACKAGES) + test: $(GO_TEST) $(TEST_FLAGS) ./... @@ -74,3 +76,8 @@ lint: go install github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCILINT_VERSION) $(GOBIN_GOLANGCILINT) run -v +fmt: + go fmt ./... + +vet: + go vet ./... diff --git a/cli/cli/cli.go b/cli/cli/cli.go index 26a516b79..8d3e538de 100644 --- a/cli/cli/cli.go +++ b/cli/cli/cli.go @@ -94,11 +94,11 @@ func NewCurveAdm() (*CurveAdm, error) { rootDir := fmt.Sprintf("%s/.curveadm", home) curveadm := &CurveAdm{ - rootDir: rootDir, - dataDir: path.Join(rootDir, "data"), - pluginDir: path.Join(rootDir, "plugins"), - logDir: path.Join(rootDir, "logs"), - tempDir: path.Join(rootDir, "temp"), + rootDir: rootDir, + dataDir: path.Join(rootDir, "data"), + pluginDir: path.Join(rootDir, "plugins"), + logDir: path.Join(rootDir, "logs"), + tempDir: path.Join(rootDir, "temp"), httpConfPath: path.Join(rootDir, "http/conf"), httpLogPath: path.Join(rootDir, "http/logs"), } @@ -248,7 +248,7 @@ func (curveadm *CurveAdm) detectVersion() { } func (curveadm *CurveAdm) Upgrade() (bool, error) { - if curveadm.config.GetAutoUpgrade() == false { + if !curveadm.config.GetAutoUpgrade() { return false, nil } @@ -294,6 +294,7 @@ func (curveadm *CurveAdm) LogPath() string { return curveadm.l func (curveadm *CurveAdm) Config() *configure.CurveAdmConfig { return curveadm.config } func (curveadm *CurveAdm) SudoAlias() string { return curveadm.config.GetSudoAlias() } func (curveadm *CurveAdm) SSHTimeout() int { return curveadm.config.GetSSHTimeout() } +func (curveadm *CurveAdm) Engine() string { return curveadm.config.GetEngine() } func (curveadm *CurveAdm) In() io.Reader { return curveadm.in } func (curveadm *CurveAdm) Out() io.Writer { return curveadm.out } func (curveadm *CurveAdm) Err() io.Writer { return curveadm.err } @@ -421,6 +422,7 @@ func (curveadm *CurveAdm) ExecOptions() module.ExecOptions { ExecInLocal: false, ExecSudoAlias: curveadm.config.GetSudoAlias(), ExecTimeoutSec: curveadm.config.GetTimeout(), + ExecWithEngine: curveadm.config.GetEngine(), } } @@ -549,8 +551,7 @@ func (curveadm *CurveAdm) PostAudit(id int64, ec error) { return } - auditLog := auditLogs[0] - status := auditLog.Status + var status int errorCode := 0 if ec == nil { status = comm.AUDIT_STATUS_SUCCESS diff --git a/cli/command/clean.go b/cli/command/clean.go index 3a5d138b4..27f703768 100644 --- a/cli/command/clean.go +++ b/cli/command/clean.go @@ -121,7 +121,7 @@ func genCleanPlaybook(curveadm *cli.CurveAdm, Configs: dcs, Options: map[string]interface{}{ comm.KEY_CLEAN_ITEMS: options.only, - comm.KEY_CLEAN_BY_RECYCLE: options.withoutRecycle == false, + comm.KEY_CLEAN_BY_RECYCLE: !options.withoutRecycle, }, }) } diff --git a/cli/command/client/map.go b/cli/command/client/map.go index 5255c7a14..9cb0b3c53 100644 --- a/cli/command/client/map.go +++ b/cli/command/client/map.go @@ -27,7 +27,6 @@ import ( "strings" "github.com/dustin/go-humanize" - "github.com/fatih/color" "github.com/opencurve/curveadm/cli/cli" comm "github.com/opencurve/curveadm/internal/common" diff --git a/cli/command/cluster/import.go b/cli/command/cluster/import.go index 2ef49de17..b9f916b88 100644 --- a/cli/command/cluster/import.go +++ b/cli/command/cluster/import.go @@ -138,10 +138,8 @@ func readDatabase(filename string) (storage.Cluster, []storage.Service, error) { switch id { case CLUSTER_DESCRIPTION: cluster.Description = value - break case CLUSTER_TOPOLOGY: cluster.Topology = value - break case SERVICE: items := strings.Split(value, " ") if len(items) != 2 { @@ -166,7 +164,8 @@ func importCluster(storage *storage.Storage, name, dbfile string) error { } // insert cluster - if storage.InsertCluster(name, cluster.Description, cluster.Topology); err != nil { + err = storage.InsertCluster(name, cluster.Description, cluster.Topology) + if err != nil { return err } diff --git a/cli/command/completion.go b/cli/command/completion.go index d2d601849..d3a50a2cf 100644 --- a/cli/command/completion.go +++ b/cli/command/completion.go @@ -77,7 +77,7 @@ PowerShell: `, "curveadm"), DisableFlagsInUseLine: true, ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, - Args: cobra.ExactValidArgs(1), + Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { switch args[0] { case "bash": diff --git a/cli/command/deploy.go b/cli/command/deploy.go index b2d3bc00c..e3a336f2f 100644 --- a/cli/command/deploy.go +++ b/cli/command/deploy.go @@ -43,6 +43,7 @@ const ( CREATE_CONTAINER = playbook.CREATE_CONTAINER SYNC_CONFIG = playbook.SYNC_CONFIG START_ETCD = playbook.START_ETCD + ENABLE_ETCD_AUTH = playbook.ENABLE_ETCD_AUTH START_MDS = playbook.START_MDS CREATE_PHYSICAL_POOL = playbook.CREATE_PHYSICAL_POOL START_CHUNKSERVER = playbook.START_CHUNKSERVER @@ -65,6 +66,7 @@ var ( CREATE_CONTAINER, SYNC_CONFIG, START_ETCD, + ENABLE_ETCD_AUTH, START_MDS, CREATE_PHYSICAL_POOL, START_CHUNKSERVER, @@ -79,6 +81,7 @@ var ( CREATE_CONTAINER, SYNC_CONFIG, START_ETCD, + ENABLE_ETCD_AUTH, START_MDS, CREATE_LOGICAL_POOL, START_METASERVER, @@ -86,6 +89,7 @@ var ( DEPLOY_FILTER_ROLE = map[int]string{ START_ETCD: ROLE_ETCD, + ENABLE_ETCD_AUTH: ROLE_ETCD, START_MDS: ROLE_MDS, START_CHUNKSERVER: ROLE_CHUNKSERVER, START_SNAPSHOTCLONE: ROLE_SNAPSHOTCLONE, @@ -99,6 +103,7 @@ var ( CREATE_PHYSICAL_POOL: 1, CREATE_LOGICAL_POOL: 1, BALANCE_LEADER: 1, + ENABLE_ETCD_AUTH: 1, } CAN_SKIP_ROLES = []string{ @@ -160,11 +165,12 @@ func skipServiceRole(deployConfigs []*topology.DeployConfig, options deployOptio return dcs } -func skipDeploySteps(deploySteps []int, options deployOptions) []int { +func skipDeploySteps(dcs []*topology.DeployConfig, deploySteps []int, options deployOptions) []int { steps := []int{} skipped := utils.Slice2Map(options.skip) for _, step := range deploySteps { - if step == START_SNAPSHOTCLONE && skipped[ROLE_SNAPSHOTCLONE] { + if (step == START_SNAPSHOTCLONE && skipped[ROLE_SNAPSHOTCLONE]) || + (step == ENABLE_ETCD_AUTH && len(dcs) > 0 && !dcs[0].GetEtcdAuthEnable()) { continue } steps = append(steps, step) @@ -211,7 +217,7 @@ func genDeployPlaybook(curveadm *cli.CurveAdm, if kind == topology.KIND_CURVEBS { steps = CURVEBS_DEPLOY_STEPS } - steps = skipDeploySteps(steps, options) + steps = skipDeploySteps(dcs, steps, options) poolset := options.poolset diskType := options.poolsetDiskType @@ -223,9 +229,9 @@ func genDeployPlaybook(curveadm *cli.CurveAdm, role := DEPLOY_FILTER_ROLE[step] config = curveadm.FilterDeployConfigByRole(config, role) } - n := len(config) + if DEPLOY_LIMIT_SERVICE[step] > 0 { - n = DEPLOY_LIMIT_SERVICE[step] + n := DEPLOY_LIMIT_SERVICE[step] config = config[:n] } diff --git a/cli/command/exec.go b/cli/command/exec.go index 7b62c037a..3c3c49f30 100644 --- a/cli/command/exec.go +++ b/cli/command/exec.go @@ -48,7 +48,6 @@ func NewExecCommand(curveadm *cli.CurveAdm) *cobra.Command { PreRunE: func(cmd *cobra.Command, args []string) error { options.id = args[0] options.cmd = strings.Join(args[1:], " ") - args = args[:1] return curveadm.CheckId(options.id) }, RunE: func(cmd *cobra.Command, args []string) error { diff --git a/cli/command/migrate.go b/cli/command/migrate.go index 2a1b1ddf5..188826245 100644 --- a/cli/command/migrate.go +++ b/cli/command/migrate.go @@ -152,7 +152,7 @@ func checkMigrateTopology(curveadm *cli.CurveAdm, data string) error { dcs2add[0].GetRole() != dcs2del[0].GetRole() { return errno.ERR_REQUIRE_SAME_ROLE_SERVICES_FOR_MIGRATING } - if len(dcs2del) != dcs2del[0].GetReplicas() { + if len(dcs2del) != dcs2del[0].GetInstances() { return errno.ERR_REQUIRE_WHOLE_HOST_SERVICES_FOR_MIGRATING } diff --git a/cli/command/status.go b/cli/command/status.go index 5bc2ea1cf..041f52768 100644 --- a/cli/command/status.go +++ b/cli/command/status.go @@ -48,11 +48,11 @@ var ( ) type statusOptions struct { - id string - role string - host string - verbose bool - showReplicas bool + id string + role string + host string + verbose bool + showInstances bool } func NewStatusCommand(curveadm *cli.CurveAdm) *cobra.Command { @@ -73,7 +73,7 @@ func NewStatusCommand(curveadm *cli.CurveAdm) *cobra.Command { flags.StringVar(&options.role, "role", "*", "Specify service role") flags.StringVar(&options.host, "host", "*", "Specify service host") flags.BoolVarP(&options.verbose, "verbose", "v", false, "Verbose output for status") - flags.BoolVarP(&options.showReplicas, "show-replicas", "s", false, "Display service replicas") + flags.BoolVarP(&options.showInstances, "show-instances", "s", false, "Display service instances") return cmd } @@ -113,7 +113,7 @@ func displayStatus(curveadm *cli.CurveAdm, dcs []*topology.DeployConfig, options } } - output := tui.FormatStatus(statuses, options.verbose, options.showReplicas) + output := tui.FormatStatus(statuses, options.verbose, options.showInstances) curveadm.WriteOutln("") curveadm.WriteOutln("cluster name : %s", curveadm.ClusterName()) curveadm.WriteOutln("cluster kind : %s", dcs[0].GetKind()) diff --git a/configs/bs/cluster/scale-out.yaml b/configs/bs/cluster/scale-out.yaml index 8469a5153..bd8d6ec65 100644 --- a/configs/bs/cluster/scale-out.yaml +++ b/configs/bs/cluster/scale-out.yaml @@ -1,10 +1,10 @@ chunkserver_services: deploy: - host: ${machine1} - replica: 20 # 请注意这里的replica不代表存储池的副本数,而是节点上同类进程的数量,比如这里指的是chunkserver进程的数量,也就是配置的磁盘数,相关问题可以参考:https://github.com/opencurve/curveadm/issues/146 + instances: 20 # 请注意这里的replica不代表存储池的副本数,而是节点上同类进程的数量,比如这里指的是chunkserver进程的数量,也就是配置的磁盘数,相关问题可以参考:https://github.com/opencurve/curveadm/issues/146 config: - host: ${machine2} - replica: 20 + instances: 20 - host: ${machine3} - replica: 20 + instances: 20 diff --git a/configs/bs/cluster/topology.yaml b/configs/bs/cluster/topology.yaml index f26db217c..abb8bf3c2 100644 --- a/configs/bs/cluster/topology.yaml +++ b/configs/bs/cluster/topology.yaml @@ -1,8 +1,8 @@ kind: curvebs global: container_image: opencurvedocker/curvebs:v1.2 - log_dir: ${home}/logs/${service_role}${service_replicas_sequence} - data_dir: ${home}/data/${service_role}${service_replicas_sequence} + log_dir: ${home}/logs/${service_role}${service_instances_sequence} + data_dir: ${home}/data/${service_role}${service_instances_sequence} s3.nos_address: <> s3.snapshot_bucket_name: <> s3.ak: <> @@ -36,16 +36,16 @@ mds_services: chunkserver_services: config: listen.ip: ${service_host} - listen.port: 82${format_replicas_sequence} # 8200,8201,8202 - data_dir: /data/chunkserver${service_replicas_sequence} # /data/chunkserver0, /data/chunksever1 + listen.port: 82${format_instances_sequence} # 8200,8201,8202 + data_dir: /data/chunkserver${service_instances_sequence} # /data/chunkserver0, /data/chunksever1 copysets: 100 deploy: - host: ${machine1} - replicas: 3 # 请注意这里的replica不代表存储池的副本数,而是节点上同类进程的数量,比如这里指的是chunkserver进程的数量,也就是配置的磁盘数,相关问题可以参考:https://github.com/opencurve/curveadm/issues/146 + instances: 3 - host: ${machine2} - replicas: 3 + instances: 3 - host: ${machine3} - replicas: 3 + instances: 3 snapshotclone_services: config: diff --git a/http/manager/manager.go b/http/manager/manager.go index b6099b00a..e919830f2 100644 --- a/http/manager/manager.go +++ b/http/manager/manager.go @@ -308,7 +308,7 @@ func GetClusterServicesAddr(r *pigeon.Request, ctx *Context) bool { pigeon.Field("error", err)) return core.ExitSuccessWithData(r, servicesAddr) } - } + } servicesAddr.ClusterId = adm.ClusterId() servicesAddr.Addrs = getServicesAddrFromConf(dcs, mcs) return core.ExitSuccessWithData(r, servicesAddr) diff --git a/internal/configure/client.go b/internal/configure/client.go index 607cb7638..1adb27232 100644 --- a/internal/configure/client.go +++ b/internal/configure/client.go @@ -83,7 +83,6 @@ type ( config map[string]interface{} serviceConfig map[string]string variables *variable.Variables - data string // configure file content } ) @@ -167,14 +166,6 @@ func (cc *ClientConfig) getString(key string) string { return v.(string) } -func (cc *ClientConfig) getBool(key string) bool { - v := cc.config[strings.ToLower(key)] - if v == nil { - return false - } - return v.(bool) -} - func (cc *ClientConfig) GetKind() string { return cc.getString(KEY_KIND) } func (cc *ClientConfig) GetDataDir() string { return cc.getString(KEY_DATA_DIR) } func (cc *ClientConfig) GetLogDir() string { return cc.getString(KEY_LOG_DIR) } diff --git a/internal/configure/curveadm/curveadm.go b/internal/configure/curveadm/curveadm.go index 4f1b850ba..460ba8e1a 100644 --- a/internal/configure/curveadm/curveadm.go +++ b/internal/configure/curveadm/curveadm.go @@ -44,6 +44,7 @@ import ( const ( KEY_LOG_LEVEL = "log_level" KEY_SUDO_ALIAS = "sudo_alias" + KEY_ENGINE = "engine" KEY_TIMEOUT = "timeout" KEY_AUTO_UPGRADE = "auto_upgrade" KEY_SSH_RETRIES = "retries" @@ -56,6 +57,7 @@ type ( CurveAdmConfig struct { LogLevel string SudoAlias string + Engine string Timeout int AutoUpgrade bool SSHRetries int @@ -74,6 +76,7 @@ var ( defaultCurveAdmConfig = &CurveAdmConfig{ LogLevel: "error", SudoAlias: "sudo", + Engine: "docker", Timeout: 180, AutoUpgrade: true, SSHRetries: 3, @@ -133,6 +136,10 @@ func parseDefaultsSection(cfg *CurveAdmConfig, defaults map[string]interface{}) case KEY_SUDO_ALIAS: cfg.SudoAlias = v.(string) + // container engine + case KEY_ENGINE: + cfg.Engine = v.(string) + // timeout case KEY_TIMEOUT: num, err := requirePositiveInt(KEY_TIMEOUT, v) @@ -229,6 +236,7 @@ func (cfg *CurveAdmConfig) GetTimeout() int { return cfg.Timeout } func (cfg *CurveAdmConfig) GetAutoUpgrade() bool { return cfg.AutoUpgrade } func (cfg *CurveAdmConfig) GetSSHRetries() int { return cfg.SSHRetries } func (cfg *CurveAdmConfig) GetSSHTimeout() int { return cfg.SSHTimeout } +func (cfg *CurveAdmConfig) GetEngine() string { return cfg.Engine } func (cfg *CurveAdmConfig) GetSudoAlias() string { if len(cfg.SudoAlias) == 0 { return WITHOUT_SUDO diff --git a/internal/configure/hosts/hosts.go b/internal/configure/hosts/hosts.go index c8fa86011..96f303368 100644 --- a/internal/configure/hosts/hosts.go +++ b/internal/configure/hosts/hosts.go @@ -158,7 +158,7 @@ func (hc *HostConfig) Build() error { F("hosts[%d].private_key_file = %s", hc.sequence, privateKeyFile) } - if hc.GetForwardAgent() == false { + if !hc.GetForwardAgent() { if !utils.PathExist(privateKeyFile) { return errno.ERR_PRIVATE_KEY_FILE_NOT_EXIST. F("%s: no such file", privateKeyFile) diff --git a/internal/configure/pool.go b/internal/configure/pool.go index a4f7b066f..b0e37c5c4 100644 --- a/internal/configure/pool.go +++ b/internal/configure/pool.go @@ -96,7 +96,7 @@ type ( * logicalpools: * - name: pool1 * physicalpool: pool1 - * replicasnum: 3 + * replicassum: 3 * copysetnum: 100 * zonenum: 3 * type: 0 @@ -119,7 +119,7 @@ type ( * ... * pools: * - name: pool1 - * replicasnum: 3 + * replicasum: 3 * copysetnum: 100 * zonenum: 3 */ @@ -137,7 +137,7 @@ func SortDeployConfigs(dcs []*topology.DeployConfig) { dc1, dc2 := dcs[i], dcs[j] if dc1.GetRole() == dc2.GetRole() { if dc1.GetHostSequence() == dc2.GetHostSequence() { - return dc1.GetReplicasSequence() < dc2.GetReplicasSequence() + return dc1.GetInstancesSequence() < dc2.GetInstancesSequence() } return dc1.GetHostSequence() < dc2.GetHostSequence() } @@ -146,7 +146,7 @@ func SortDeployConfigs(dcs []*topology.DeployConfig) { } func formatName(dc *topology.DeployConfig) string { - return fmt.Sprintf("%s_%s_%d", dc.GetHost(), dc.GetName(), dc.GetReplicasSequence()) + return fmt.Sprintf("%s_%s_%d", dc.GetHost(), dc.GetName(), dc.GetInstancesSequence()) } func createLogicalPool(dcs []*topology.DeployConfig, logicalPool string, poolset string) (LogicalPool, []Server) { @@ -166,14 +166,14 @@ func createLogicalPool(dcs []*topology.DeployConfig, logicalPool string, poolset zone = nextZone() } - // NOTE: if we deploy chunkservers with replica feature - // and the value of replica greater than 1, we should + // NOTE: if we deploy chunkservers with instance feature + // and the value of instance greater than 1, we should // set internal port and external port to 0 for let MDS // attribute them as services on the same machine. // see issue: https://github.com/opencurve/curve/issues/1441 internalPort := dc.GetListenPort() externalPort := dc.GetListenExternalPort() - if dc.GetReplicas() > 1 { + if dc.GetInstances() > 1 { internalPort = 0 externalPort = 0 } @@ -241,9 +241,7 @@ func ScaleOutClusterPool(old *CurveClusterTopo, dcs []*topology.DeployConfig, po npools := old.NPools topo := generateClusterPool(dcs, fmt.Sprintf("pool%d", npools+1), poolset, diskType) if dcs[0].GetKind() == KIND_CURVEBS { - for _, pool := range topo.LogicalPools { - old.LogicalPools = append(old.LogicalPools, pool) - } + old.LogicalPools = append(old.LogicalPools, topo.LogicalPools...) for _, newPst := range topo.Poolsets { isExist := false for _, oldPst := range old.Poolsets { @@ -256,13 +254,9 @@ func ScaleOutClusterPool(old *CurveClusterTopo, dcs []*topology.DeployConfig, po } } } else { - for _, pool := range topo.Pools { - old.Pools = append(old.Pools, pool) - } - } - for _, server := range topo.Servers { - old.Servers = append(old.Servers, server) + old.Pools = append(old.Pools, topo.Pools...) } + old.Servers = append(old.Servers, topo.Servers...) old.NPools = old.NPools + 1 } diff --git a/internal/configure/topology/dc.go b/internal/configure/topology/dc.go index a39112ff0..182a4a5eb 100644 --- a/internal/configure/topology/dc.go +++ b/internal/configure/topology/dc.go @@ -48,16 +48,16 @@ const ( type ( DeployConfig struct { - kind string // KIND_CURVEFS / KIND_CUVREBS - id string // role_host_[name/hostSequence]_replicasSequence - parentId string // role_host_[name/hostSequence]_0 - role string // etcd/mds/metaserevr/chunkserver - host string - hostname string - name string - replicas int - hostSequence int // start with 0 - replicasSequence int // start with 0 + kind string // KIND_CURVEFS / KIND_CUVREBS + id string // role_host_[name/hostSequence]_instancesSequence + parentId string // role_host_[name/hostSequence]_0 + role string // etcd/mds/metaserevr/chunkserver + host string + hostname string + name string + instances int + hostSequence int // start with 0 + instancesSequence int // start with 0 config map[string]interface{} serviceConfig map[string]string @@ -73,8 +73,8 @@ type ( ) // etcd_hostname_0_0 -func formatId(role, host, name string, replicasSequence int) string { - return fmt.Sprintf("%s_%s_%s_%d", role, host, name, replicasSequence) +func formatId(role, host, name string, instancesSequence int) string { + return fmt.Sprintf("%s_%s_%s_%d", role, host, name, instancesSequence) } func formatName(name string, hostSequence int) string { @@ -86,7 +86,7 @@ func formatName(name string, hostSequence int) string { func newVariables(m map[string]interface{}) (*variable.Variables, error) { vars := variable.NewVariables() - if m == nil || len(m) == 0 { + if len(m) == 0 { return vars, nil } @@ -104,8 +104,8 @@ func newVariables(m map[string]interface{}) (*variable.Variables, error) { return vars, nil } -func NewDeployConfig(ctx *Context, kind, role, host, name string, replicas int, - hostSequence, replicasSequence int, config map[string]interface{}) (*DeployConfig, error) { +func NewDeployConfig(ctx *Context, kind, role, host, name string, instances int, + hostSequence, instancesSequence int, config map[string]interface{}) (*DeployConfig, error) { // variable section v := config[CONFIG_VARIABLE.key] if !utils.IsStringAnyMap(v) && v != nil { @@ -137,19 +137,19 @@ func NewDeployConfig(ctx *Context, kind, role, host, name string, replicas int, name = formatName(name, hostSequence) return &DeployConfig{ - kind: kind, - id: formatId(role, host, name, replicasSequence), - parentId: formatId(role, host, name, 0), - role: role, - host: host, - name: name, - replicas: replicas, - hostSequence: hostSequence, - replicasSequence: replicasSequence, - config: config, - serviceConfig: map[string]string{}, - variables: vars, - ctx: ctx, + kind: kind, + id: formatId(role, host, name, instancesSequence), + parentId: formatId(role, host, name, 0), + role: role, + host: host, + name: name, + instances: instances, + hostSequence: hostSequence, + instancesSequence: instancesSequence, + config: config, + serviceConfig: map[string]string{}, + variables: vars, + ctx: ctx, }, nil } @@ -182,8 +182,8 @@ func (dc *DeployConfig) renderVariables() error { } dc.config[k] = realv build.DEBUG(build.DEBUG_TOPOLOGY, - build.Field{k, v}, - build.Field{k, realv}) + build.Field{Key: k, Value: v}, + build.Field{Key: k, Value: realv}) } return nil } @@ -192,7 +192,7 @@ func (dc *DeployConfig) convert() error { // init service config for k, v := range dc.config { item := itemset.get(k) - if item == nil || item.exclude == false { + if item == nil || !item.exclude { dc.serviceConfig[k] = v.(string) } } diff --git a/internal/configure/topology/dc_get.go b/internal/configure/topology/dc_get.go index 98a9b8f7c..aeefa430f 100644 --- a/internal/configure/topology/dc_get.go +++ b/internal/configure/topology/dc_get.go @@ -65,11 +65,11 @@ var ( DefaultCurveFSDeployConfig = &DeployConfig{kind: KIND_CURVEFS} ServiceConfigs = map[string][]string{ - ROLE_ETCD: []string{"etcd.conf"}, - ROLE_MDS: []string{"mds.conf"}, - ROLE_CHUNKSERVER: []string{"chunkserver.conf", "cs_client.conf", "s3.conf"}, - ROLE_SNAPSHOTCLONE: []string{"snapshotclone.conf", "snap_client.conf", "s3.conf", "nginx.conf"}, - ROLE_METASERVER: []string{"metaserver.conf"}, + ROLE_ETCD: {"etcd.conf"}, + ROLE_MDS: {"mds.conf"}, + ROLE_CHUNKSERVER: {"chunkserver.conf", "cs_client.conf", "s3.conf"}, + ROLE_SNAPSHOTCLONE: {"snapshotclone.conf", "snap_client.conf", "s3.conf", "nginx.conf"}, + ROLE_METASERVER: {"metaserver.conf"}, } ) @@ -117,9 +117,9 @@ func (dc *DeployConfig) GetRole() string { return dc.role } func (dc *DeployConfig) GetHost() string { return dc.host } func (dc *DeployConfig) GetHostname() string { return dc.hostname } func (dc *DeployConfig) GetName() string { return dc.name } -func (dc *DeployConfig) GetReplicas() int { return dc.replicas } +func (dc *DeployConfig) GetInstances() int { return dc.instances } func (dc *DeployConfig) GetHostSequence() int { return dc.hostSequence } -func (dc *DeployConfig) GetReplicasSequence() int { return dc.replicasSequence } +func (dc *DeployConfig) GetInstancesSequence() int { return dc.instancesSequence } func (dc *DeployConfig) GetServiceConfig() map[string]string { return dc.serviceConfig } func (dc *DeployConfig) GetVariables() *variable.Variables { return dc.variables } @@ -145,6 +145,9 @@ func (dc *DeployConfig) GetS3Address() string { return dc.getString(CONFI func (dc *DeployConfig) GetS3BucketName() string { return dc.getString(CONFIG_S3_BUCKET_NAME) } func (dc *DeployConfig) GetEnableRDMA() bool { return dc.getBool(CONFIG_ENABLE_RDMA) } func (dc *DeployConfig) GetEnableRenameAt2() bool { return dc.getBool(CONFIG_ENABLE_RENAMEAT2) } +func (dc *DeployConfig) GetEtcdAuthEnable() bool { return dc.getBool(CONFIG_ETCD_AUTH_ENABLE) } +func (dc *DeployConfig) GetEtcdAuthUsername() string { return dc.getString(CONFIG_ETCD_AUTH_USERNAME) } +func (dc *DeployConfig) GetEtcdAuthPassword() string { return dc.getString(CONFIG_ETCD_AUTH_PASSWORD) } func (dc *DeployConfig) GetEnableChunkfilePool() bool { return dc.getBool(CONFIG_ENABLE_CHUNKFILE_POOL) } diff --git a/internal/configure/topology/dc_item.go b/internal/configure/topology/dc_item.go index 1b6c39740..46b0b21b7 100644 --- a/internal/configure/topology/dc_item.go +++ b/internal/configure/topology/dc_item.go @@ -285,6 +285,27 @@ var ( true, nil, ) + + CONFIG_ETCD_AUTH_ENABLE = itemset.insert( + "etcd.auth.enable", + REQUIRE_BOOL, + false, + false, + ) + + CONFIG_ETCD_AUTH_USERNAME = itemset.insert( + "etcd.auth.username", + REQUIRE_STRING, + false, + nil, + ) + + CONFIG_ETCD_AUTH_PASSWORD = itemset.insert( + "etcd.auth.password", + REQUIRE_STRING, + false, + nil, + ) ) func (i *item) Key() string { diff --git a/internal/configure/topology/topology.go b/internal/configure/topology/topology.go index 45ee13d01..f3dc9da7a 100644 --- a/internal/configure/topology/topology.go +++ b/internal/configure/topology/topology.go @@ -34,11 +34,12 @@ import ( type ( Deploy struct { - Host string `mapstructure:"host"` - Name string `mapstructure:"name"` - Replica int `mapstructure:"replica"` // old version - Replicas int `mapstructure:"replicas"` - Config map[string]interface{} `mapstructure:"config"` + Host string `mapstructure:"host"` + Name string `mapstructure:"name"` + Replica int `mapstructure:"replica"` // old version + Replicas int `mapstructure:"replicas"` // old version + Instances int `mapstructure:"instances"` + Config map[string]interface{} `mapstructure:"config"` } Service struct { @@ -149,23 +150,28 @@ func ParseTopology(data string, ctx *Context) ([]*DeployConfig, error) { merge(servicesConfig, deployConfig, 1) // create deploy config - replicas := 1 + instances := 1 if deploy.Replicas < 0 { - return nil, errno.ERR_REPLICAS_REQUIRES_POSITIVE_INTEGER. + return nil, errno.ERR_INSTANCES_REQUIRES_POSITIVE_INTEGER. F("replicas: %d", deploy.Replicas) } else if deploy.Replica < 0 { - return nil, errno.ERR_REPLICAS_REQUIRES_POSITIVE_INTEGER. + return nil, errno.ERR_INSTANCES_REQUIRES_POSITIVE_INTEGER. F("replica: %d", deploy.Replica) + } else if deploy.Instances < 0 { + return nil, errno.ERR_INSTANCES_REQUIRES_POSITIVE_INTEGER. + F("Instance: %d", deploy.Instances) + } else if deploy.Instances > 0 { + instances = deploy.Instances } else if deploy.Replicas > 0 { - replicas = deploy.Replicas + instances = deploy.Replicas } else if deploy.Replica > 0 { - replicas = deploy.Replica + instances = deploy.Replica } - for replicasSequence := 0; replicasSequence < replicas; replicasSequence++ { + for instancesSequence := 0; instancesSequence < instances; instancesSequence++ { dc, err := NewDeployConfig(ctx, kind, - role, deploy.Host, deploy.Name, replicas, - hostSequence, replicasSequence, utils.DeepCopy(deployConfig)) + role, deploy.Host, deploy.Name, instances, + hostSequence, instancesSequence, utils.DeepCopy(deployConfig)) if err != nil { return nil, err // already is error code } diff --git a/internal/configure/topology/variables.go b/internal/configure/topology/variables.go index 1ed01f270..e1ec6dadf 100644 --- a/internal/configure/topology/variables.go +++ b/internal/configure/topology/variables.go @@ -43,11 +43,10 @@ const ( ) type Var struct { - name string - kind []string // kind limit for register variable - role []string // role limit for register variable - lookup bool // whether need to lookup host - resolved bool + name string + kind []string // kind limit for register variable + role []string // role limit for register variable + lookup bool // whether need to lookup host } /* @@ -59,8 +58,8 @@ type Var struct { * ${service_role} "mds" * ${service_host} "10.0.0.1" * ${service_host_sequence} "1" - * ${service_replicas_sequence} "1" - * ${format_replicas_sequence} "01" + * ${service_instances_sequence} "1" + * ${format_instances_sequence} "01" * ${service_addr} "10.0.0.1" * ${service_port} "6666" * ${service_client_port} "2379" (etcd) @@ -94,8 +93,10 @@ var ( {name: "service_host_sequence"}, {name: "service_replica_sequence"}, {name: "service_replicas_sequence"}, + {name: "service_instances_sequence"}, {name: "format_replica_sequence"}, {name: "format_replicas_sequence"}, + {name: "format_instances_sequence"}, {name: "service_addr", lookup: true}, {name: "service_port"}, {name: "service_client_port", role: []string{ROLE_ETCD}}, @@ -139,7 +140,7 @@ func skip(dc *DeployConfig, v Var) bool { func addVariables(dcs []*DeployConfig, idx int, vars []Var) error { dc := dcs[idx] for _, v := range vars { - if skip(dc, v) == true { + if skip(dc, v) { continue } @@ -174,10 +175,10 @@ func joinEtcdPeer(dcs []*DeployConfig) string { } hostSequence := dc.GetHostSequence() - replicaSquence := dc.GetReplicasSequence() + instanceSquence := dc.GetInstancesSequence() peerHost := dc.GetListenIp() peerPort := dc.GetListenPort() - peer := fmt.Sprintf("etcd%d%d=http://%s:%d", hostSequence, replicaSquence, peerHost, peerPort) + peer := fmt.Sprintf("etcd%d%d=http://%s:%d", hostSequence, instanceSquence, peerHost, peerPort) peers = append(peers, peer) } return strings.Join(peers, ",") @@ -245,13 +246,17 @@ func getValue(name string, dcs []*DeployConfig, idx int) string { case "service_host_sequence": return strconv.Itoa(dc.GetHostSequence()) case "service_replica_sequence": - return strconv.Itoa(dc.GetReplicasSequence()) + return strconv.Itoa(dc.GetInstancesSequence()) case "service_replicas_sequence": - return strconv.Itoa(dc.GetReplicasSequence()) + return strconv.Itoa(dc.GetInstancesSequence()) + case "service_instances_sequence": + return strconv.Itoa(dc.GetInstancesSequence()) case "format_replica_sequence": - return fmt.Sprintf("%02d", dc.GetReplicasSequence()) + return fmt.Sprintf("%02d", dc.GetInstancesSequence()) case "format_replicas_sequence": - return fmt.Sprintf("%02d", dc.GetReplicasSequence()) + return fmt.Sprintf("%02d", dc.GetInstancesSequence()) + case "format_instances_sequence": + return fmt.Sprintf("%02d", dc.GetInstancesSequence()) case "service_addr": return utils.Atoa(dc.get(CONFIG_LISTEN_IP)) case "service_port": diff --git a/internal/errno/errno.go b/internal/errno/errno.go index ccdbb2c3f..fd40bbc00 100644 --- a/internal/errno/errno.go +++ b/internal/errno/errno.go @@ -55,7 +55,7 @@ func Init(logpath string) { func List() error { count := map[int]int{} for _, e := range elist { - fmt.Printf(color.GreenString("%06d ", e.code)) + fmt.Print(color.GreenString("%06d ", e.code)) fmt.Println(color.YellowString("%s", e.description)) count[e.code]++ } @@ -107,6 +107,15 @@ func (e *ErrorCode) F(format string, a ...interface{}) *ErrorCode { return e } +func (e *ErrorCode) FD(format string, s ...interface{}) *ErrorCode { + newEC := &ErrorCode{ + code: e.code, + description: e.description, + } + newEC.description = fmt.Sprintf(newEC.description+" "+format, s...) + return newEC +} + func (e *ErrorCode) Error() string { if e.code == CODE_CANCEL_OPERATION { return "" @@ -348,11 +357,11 @@ var ( ERR_RENDERING_VARIABLE_FAILED = EC(330007, "rendering variable failed") ERR_CREATE_HASH_FOR_TOPOLOGY_FAILED = EC(330008, "create hash for topology failed") // 331: configure (topology.yaml: invalid configure value) - ERR_UNSUPPORT_CLUSTER_KIND = EC(331000, "unsupport cluster kind") - ERR_NO_SERVICES_IN_TOPOLOGY = EC(331001, "no services in topology") - ERR_REPLICAS_REQUIRES_POSITIVE_INTEGER = EC(331002, "replicas requires a positive integer") - ERR_INVALID_VARIABLE_SECTION = EC(331003, "invalid variable section") - ERR_DUPLICATE_SERVICE_ID = EC(331004, "service id is duplicate") + ERR_UNSUPPORT_CLUSTER_KIND = EC(331000, "unsupport cluster kind") + ERR_NO_SERVICES_IN_TOPOLOGY = EC(331001, "no services in topology") + ERR_INSTANCES_REQUIRES_POSITIVE_INTEGER = EC(331002, "instances requires a positive integer") + ERR_INVALID_VARIABLE_SECTION = EC(331003, "invalid variable section") + ERR_DUPLICATE_SERVICE_ID = EC(331004, "service id is duplicate") // 332: configure (topology.yaml: update topology) ERR_DELETE_SERVICE_WHILE_COMMIT_TOPOLOGY_IS_DENIED = EC(332000, "delete service while commit topology is denied") ERR_ADD_SERVICE_WHILE_COMMIT_TOPOLOGY_IS_DENIED = EC(332001, "add service while commit topology is denied") @@ -417,6 +426,7 @@ var ( ERR_INVALID_DEVICE_USAGE = EC(410020, "invalid device usage") ERR_ENCRYPT_FILE_FAILED = EC(410021, "encrypt file failed") ERR_CLIENT_ID_NOT_FOUND = EC(410022, "client id not found") + ERR_ENABLE_ETCD_AUTH_FAILED = EC(410023, "enable etcd auth failed") // 420: common (curvebs client) ERR_VOLUME_ALREADY_MAPPED = EC(420000, "volume already mapped") @@ -469,10 +479,10 @@ var ( ERR_SSH_CONNECT_FAILED = EC(510000, "SSH connect failed") // 520: checker (permission) - ERR_USER_NOT_FOUND = EC(520000, "user not found") - ERR_HOSTNAME_NOT_RESOLVED = EC(520001, "hostname not resolved") - ERR_CREATE_DIRECOTRY_PERMISSION_DENIED = EC(520002, "create direcotry permission denied") - ERR_EXECUTE_DOCKER_COMMAND_PERMISSION_DENIED = EC(520003, "execute docker command permission denied") + ERR_USER_NOT_FOUND = EC(520000, "user not found") + ERR_HOSTNAME_NOT_RESOLVED = EC(520001, "hostname not resolved") + ERR_CREATE_DIRECOTRY_PERMISSION_DENIED = EC(520002, "create direcotry permission denied") + ERR_EXECUTE_CONTAINER_ENGINE_COMMAND_PERMISSION_DENIED = EC(520003, "execute docker/podman command permission denied") // 530: checker (kernel) ERR_UNRECOGNIZED_KERNEL_VERSION = EC(530000, "unrecognized kernel version") @@ -499,9 +509,9 @@ var ( ERR_INVALID_CURVEFS_CLIENT_S3_BUCKET_NAME = EC(570003, "invalid curvefs client S3 bucket name") // 590: checker (others) - ERR_DOCKER_NOT_INSTALLED = EC(590000, "docker not installed") - ERR_DOCKER_DAEMON_IS_NOT_RUNNING = EC(590001, "docker daemon is not running") - ERR_NO_SPACE_LEFT_ON_DEVICE = EC(590002, "no space left on device") + ERR_CONTAINER_ENGINE_NOT_INSTALLED = EC(590000, "container engine docker/podman not installed") + ERR_DOCKER_DAEMON_IS_NOT_RUNNING = EC(590001, "docker daemon is not running") + ERR_NO_SPACE_LEFT_ON_DEVICE = EC(590002, "no space left on device") // 600: exeute task (common) ERR_EXECUTE_COMMAND_TIMED_OUT = EC(600000, "execute command timed out") @@ -546,22 +556,22 @@ var ( ERR_RUN_SCRIPT_FAILED = EC(620998, "run script failed (bash script.sh)") ERR_RUN_A_BASH_COMMAND_FAILED = EC(620999, "run a bash command failed (bash -c)") - // 630: execute task (docker command) - ERR_GET_DOCKER_INFO_FAILED = EC(630000, "get docker info failed (docker info)") - ERR_PULL_IMAGE_FAILED = EC(630001, "pull image failed (docker pull IMAGE)") - ERR_CREATE_CONTAINER_FAILED = EC(630002, "create container failed (docker create IMAGE)") - ERR_START_CONTAINER_FAILED = EC(630003, "start container failed (docker start CONTAINER)") - ERR_STOP_CONTAINER_FAILED = EC(630004, "stop container failed (docker stop CONTAINER)") - ERR_RESTART_CONTAINER_FAILED = EC(630005, "restart container failed (docker restart CONTAINER)") - ERR_WAIT_CONTAINER_STOP_FAILED = EC(630006, "wait container stop failed (docker wait CONTAINER)") - ERR_REMOVE_CONTAINER_FAILED = EC(630007, "remove container failed (docker rm CONTAINER)") - ERR_LIST_CONTAINERS_FAILED = EC(630008, "list containers failed (docker ps)") - ERR_RUN_COMMAND_IN_CONTAINER_FAILED = EC(630009, "run a command in container failed (docker exec CONTAINER COMMAND)") - ERR_COPY_FROM_CONTAINER_FAILED = EC(630010, "copy file from container failed (docker cp CONTAINER:SRC_PATH DEST_PATH)") - ERR_COPY_INTO_CONTAINER_FAILED = EC(630011, "copy file into container failed (docker cp SRC_PATH CONTAINER:DEST_PATH)") - ERR_INSPECT_CONTAINER_FAILED = EC(630012, "get container low-level information failed (docker inspect ID)") - ERR_GET_CONTAINER_LOGS_FAILED = EC(630013, "get container logs failed (docker logs ID)") - ERR_UPDATE_CONTAINER_FAILED = EC(630014, "update container failed (docker update ID)") + // 630: execute task (docker/podman command) + ERR_GET_CONTAINER_ENGINE_INFO_FAILED = EC(630000, "get container engine info failed") + ERR_PULL_IMAGE_FAILED = EC(630001, "pull image failed") + ERR_CREATE_CONTAINER_FAILED = EC(630002, "create container failed") + ERR_START_CONTAINER_FAILED = EC(630003, "start container failed") + ERR_STOP_CONTAINER_FAILED = EC(630004, "stop container failed") + ERR_RESTART_CONTAINER_FAILED = EC(630005, "restart container failed") + ERR_WAIT_CONTAINER_STOP_FAILED = EC(630006, "wait container stop failed") + ERR_REMOVE_CONTAINER_FAILED = EC(630007, "remove container failed") + ERR_LIST_CONTAINERS_FAILED = EC(630008, "list containers failed") + ERR_RUN_COMMAND_IN_CONTAINER_FAILED = EC(630009, "run a command in container failed") + ERR_COPY_FROM_CONTAINER_FAILED = EC(630010, "copy file from container failed") + ERR_COPY_INTO_CONTAINER_FAILED = EC(630011, "copy file into container failed") + ERR_INSPECT_CONTAINER_FAILED = EC(630012, "get container low-level information failed") + ERR_GET_CONTAINER_LOGS_FAILED = EC(630013, "get container logs failed") + ERR_UPDATE_CONTAINER_FAILED = EC(630014, "update container failed") // 690: execuetr task (others) ERR_START_CRONTAB_IN_CONTAINER_FAILED = EC(690000, "start crontab in container failed") diff --git a/internal/playbook/configs.go b/internal/playbook/configs.go index 4d03829cb..80c88b85b 100644 --- a/internal/playbook/configs.go +++ b/internal/playbook/configs.go @@ -133,72 +133,72 @@ func NewSmartConfig(configs interface{}) (*SmartConfig, error) { anys: []interface{}{}, } build.DEBUG(build.DEBUG_SMART_CONFIGS, - build.Field{"len", c.len}, - build.Field{"type", c.ctype}) + build.Field{Key: "len", Value: c.len}, + build.Field{Key: "type", Value: c.ctype}) - switch configs.(type) { + switch configs := configs.(type) { // multi-configs case []*hosts.HostConfig: c.ctype = TYPE_CONFIG_HOST - c.hcs = configs.([]*hosts.HostConfig) + c.hcs = configs c.len = len(c.hcs) case []*configure.FormatConfig: c.ctype = TYPE_CONFIG_FORMAT - c.fcs = configs.([]*configure.FormatConfig) + c.fcs = configs c.len = len(c.fcs) case []*topology.DeployConfig: c.ctype = TYPE_CONFIG_DEPLOY - c.dcs = configs.([]*topology.DeployConfig) + c.dcs = configs c.len = len(c.dcs) case []*configure.ClientConfig: c.ctype = TYPE_CONFIG_CLIENT - c.ccs = configs.([]*configure.ClientConfig) + c.ccs = configs c.len = len(c.ccs) case []*configure.PlaygroundConfig: c.ctype = TYPE_CONFIG_PLAYGROUND - c.pgcs = configs.([]*configure.PlaygroundConfig) + c.pgcs = configs c.len = len(c.pgcs) case []*configure.MonitorConfig: c.ctype = TYPE_CONFIG_MONITOR - c.mcs = configs.([]*configure.MonitorConfig) + c.mcs = configs c.len = len(c.mcs) case []*configure.WebsiteConfig: c.ctype = TYPE_CONFIG_WEBSITE - c.wcs = configs.([]*configure.WebsiteConfig) + c.wcs = configs c.len = len(c.wcs) case []interface{}: c.ctype = TYPE_CONFIG_ANY - c.anys = configs.([]interface{}) + c.anys = configs c.len = len(c.anys) // single-config case *hosts.HostConfig: c.ctype = TYPE_CONFIG_HOST - c.hcs = append(c.hcs, configs.(*hosts.HostConfig)) + c.hcs = append(c.hcs, configs) c.len = 1 case *configure.FormatConfig: c.ctype = TYPE_CONFIG_FORMAT - c.fcs = append(c.fcs, configs.(*configure.FormatConfig)) + c.fcs = append(c.fcs, configs) c.len = 1 case *topology.DeployConfig: c.ctype = TYPE_CONFIG_DEPLOY - c.dcs = append(c.dcs, configs.(*topology.DeployConfig)) + c.dcs = append(c.dcs, configs) c.len = 1 case *configure.ClientConfig: c.ctype = TYPE_CONFIG_CLIENT - c.ccs = append(c.ccs, configs.(*configure.ClientConfig)) + c.ccs = append(c.ccs, configs) c.len = 1 case *configure.PlaygroundConfig: c.ctype = TYPE_CONFIG_PLAYGROUND - c.pgcs = append(c.pgcs, configs.(*configure.PlaygroundConfig)) + c.pgcs = append(c.pgcs, configs) c.len = 1 case *configure.MonitorConfig: c.ctype = TYPE_CONFIG_MONITOR - c.mcs = append(c.mcs, configs.(*configure.MonitorConfig)) + c.mcs = append(c.mcs, configs) c.len = 1 case *configure.WebsiteConfig: c.ctype = TYPE_CONFIG_WEBSITE - c.wcs = append(c.wcs, configs.(*configure.WebsiteConfig)) + c.wcs = append(c.wcs, configs) c.len = 1 case nil: c.ctype = TYPE_CONFIG_NULL diff --git a/internal/playbook/factory.go b/internal/playbook/factory.go index 68ce8993d..7ab082c1c 100644 --- a/internal/playbook/factory.go +++ b/internal/playbook/factory.go @@ -61,6 +61,7 @@ const ( SYNC_CONFIG START_SERVICE START_ETCD + ENABLE_ETCD_AUTH START_MDS START_CHUNKSERVER START_SNAPSHOTCLONE @@ -85,6 +86,9 @@ const ( UNINSTALL_CLIENT // bs + FORMAT_CHUNKFILE_POOL + GET_FORMAT_STATUS + STOP_FORMAT BALANCE_LEADER START_NEBD_SERVICE CREATE_VOLUME @@ -125,8 +129,6 @@ const ( CHECK_CLIENT_S3 MOUNT_FILESYSTEM UMOUNT_FILESYSTEM - FORMAT_CHUNKFILE_POOL - GET_FORMAT_STATUS // polarfs DETECT_OS_RELEASE @@ -140,9 +142,6 @@ const ( REMOVE_PLAYGROUND GET_PLAYGROUND_STATUS - // STOP_FORMAT type stop formatting - STOP_FORMAT - // unknown UNKNOWN ) @@ -225,6 +224,8 @@ func (p *Playbook) createTasks(step *PlaybookStep) (*tasks.Tasks, error) { START_SNAPSHOTCLONE, START_METASERVER: t, err = comm.NewStartServiceTask(curveadm, config.GetDC(i)) + case ENABLE_ETCD_AUTH: + t, err = comm.NewEnableEtcdAuthTask(curveadm, config.GetDC(i)) case STOP_SERVICE: t, err = comm.NewStopServiceTask(curveadm, config.GetDC(i)) case RESTART_SERVICE: diff --git a/internal/playbook/tasks/tasks.go b/internal/playbook/tasks/tasks.go index 4322dc9d7..2e778df14 100644 --- a/internal/playbook/tasks/tasks.go +++ b/internal/playbook/tasks/tasks.go @@ -45,7 +45,7 @@ type ( Tasks struct { tasks []*task.Task monitor *monitor - wg sync.WaitGroup + wg *sync.WaitGroup progress *mpb.Progress mainBar *mpb.Bar subBar map[string]*mpb.Bar @@ -58,7 +58,7 @@ func NewTasks() *Tasks { return &Tasks{ tasks: []*task.Task{}, monitor: newMonitor(), - wg: wg, + wg: &wg, progress: mpb.New(mpb.WithWaitGroup(&wg)), mainBar: nil, subBar: map[string]*mpb.Bar{}, @@ -121,7 +121,7 @@ func (ts *Tasks) displayStatus() func(static decor.Statistics) string { } } -func (ts *Tasks) displayReplica(t *task.Task) func(static decor.Statistics) string { +func (ts *Tasks) displayInstance(t *task.Task) func(static decor.Statistics) string { total := ts.CountPtid(t.Ptid()) return func(static decor.Statistics) string { nsucc, nskip, _ := ts.monitor.sum(static.ID) @@ -149,7 +149,7 @@ func (ts *Tasks) addSubBar(t *task.Task) { mpb.PrependDecorators( decor.Name(" + "), decor.Name(t.Subname()+" "), - decor.Any(ts.displayReplica(t), decor.WCSyncWidthR), + decor.Any(ts.displayInstance(t), decor.WCSyncWidthR), decor.Name(" "), decor.OnComplete(decor.Spinner([]string{}), ""), decor.Any(ts.displayStatus()), @@ -212,7 +212,7 @@ func (ts *Tasks) Execute(option ExecOptions) error { // execute task by concurrency for _, t := range ts.tasks { - if ts.monitor.error() != nil && option.SkipError == false { + if ts.monitor.error() != nil && !option.SkipError { break } diff --git a/internal/task/scripts/enable_etcd_auth.go b/internal/task/scripts/enable_etcd_auth.go new file mode 100644 index 000000000..33e14102e --- /dev/null +++ b/internal/task/scripts/enable_etcd_auth.go @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 NetEase Inc. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + */ + +/* +* Project: Curveadm +* Created Date: 2023-08-02 +* Author: wanghai (SeanHai) + */ + +package scripts + +var ENABLE_ETCD_AUTH = ` +#!/usr/bin/env bash + +if [ $# -ne 3 ]; then + echo "Usage: $0 endpoints username password" + exit 1 +fi + +endpoints=$1 +username=$2 +password=$3 +root_user=root + +# create root user +etcdctl --endpoints=${endpoints} user add ${root_user}:${password} && \ +etcdctl --endpoints=${endpoints} user grant-role ${root_user} root || exit 1 + +# create user if not root +if [ "${username}" != "${root_user}" ]; then + etcdctl --endpoints=${endpoints} user add ${username}:${password} && \ + etcdctl --endpoints=${endpoints} user grant-role ${username} root || exit 1 +fi + +# enable auth +etcdctl --endpoints=${endpoints} auth enable --user=${root_user}:${password} || exit 1 +` diff --git a/internal/task/scripts/monitor.go b/internal/task/scripts/monitor.go index cf6f25302..824513a76 100644 --- a/internal/task/scripts/monitor.go +++ b/internal/task/scripts/monitor.go @@ -51,4 +51,4 @@ datasources: is_default: true version: 1 editable: true -` \ No newline at end of file +` diff --git a/internal/task/scripts/script.go b/internal/task/scripts/script.go index 1cd4c6e1c..83e4a499e 100644 --- a/internal/task/scripts/script.go +++ b/internal/task/scripts/script.go @@ -30,7 +30,7 @@ const ( var ( SCRIPT_WAIT string = WAIT - SCRIPT_COLLECT string = COLLECT + SCRIPT_COLLECT string = COLLECT // not used SCRIPT_REPORT string = REPORT SCRIPT_FORMAT string = FORMAT SCRIPT_MAP string = MAP diff --git a/internal/task/step/container.go b/internal/task/step/container.go index 55dc459ef..5dd0607d3 100644 --- a/internal/task/step/container.go +++ b/internal/task/step/container.go @@ -31,7 +31,7 @@ import ( ) type ( - DockerInfo struct { + EngineInfo struct { Success *bool Out *string module.ExecOptions @@ -164,16 +164,16 @@ type ( } ) -func (s *DockerInfo) Execute(ctx *context.Context) error { +func (s *EngineInfo) Execute(ctx *context.Context) error { cli := ctx.Module().DockerCli().DockerInfo() out, err := cli.Execute(s.ExecOptions) - return PostHandle(s.Success, s.Out, out, err, errno.ERR_GET_DOCKER_INFO_FAILED) + return PostHandle(s.Success, s.Out, out, err, errno.ERR_GET_CONTAINER_ENGINE_INFO_FAILED.FD("(%s info)", s.ExecWithEngine)) } func (s *PullImage) Execute(ctx *context.Context) error { cli := ctx.Module().DockerCli().PullImage(s.Image) out, err := cli.Execute(s.ExecOptions) - return PostHandle(nil, s.Out, out, err, errno.ERR_PULL_IMAGE_FAILED) + return PostHandle(nil, s.Out, out, err, errno.ERR_PULL_IMAGE_FAILED.FD("(%s pull IMAGE)", s.ExecWithEngine)) } func (s *CreateContainer) Execute(ctx *context.Context) error { @@ -239,13 +239,13 @@ func (s *CreateContainer) Execute(ctx *context.Context) error { } out, err := cli.Execute(s.ExecOptions) - return PostHandle(nil, s.Out, out, err, errno.ERR_CREATE_CONTAINER_FAILED) + return PostHandle(nil, s.Out, out, err, errno.ERR_CREATE_CONTAINER_FAILED.FD("(%s create IMAGE)", s.ExecWithEngine)) } func (s *StartContainer) Execute(ctx *context.Context) error { cli := ctx.Module().DockerCli().StartContainer(*s.ContainerId) out, err := cli.Execute(s.ExecOptions) - return PostHandle(s.Success, s.Out, out, err, errno.ERR_START_CONTAINER_FAILED) + return PostHandle(s.Success, s.Out, out, err, errno.ERR_START_CONTAINER_FAILED.FD("(%s start CONTAINER)", s.ExecWithEngine)) } func (s *StopContainer) Execute(ctx *context.Context) error { @@ -255,25 +255,25 @@ func (s *StopContainer) Execute(ctx *context.Context) error { } out, err := cli.Execute(s.ExecOptions) - return PostHandle(nil, s.Out, out, err, errno.ERR_STOP_CONTAINER_FAILED) + return PostHandle(nil, s.Out, out, err, errno.ERR_STOP_CONTAINER_FAILED.FD("(%s stop CONTAINER)", s.ExecWithEngine)) } func (s *RestartContainer) Execute(ctx *context.Context) error { cli := ctx.Module().DockerCli().RestartContainer(s.ContainerId) out, err := cli.Execute(s.ExecOptions) - return PostHandle(nil, s.Out, out, err, errno.ERR_RESTART_CONTAINER_FAILED) + return PostHandle(nil, s.Out, out, err, errno.ERR_RESTART_CONTAINER_FAILED.FD("(%s restart CONTAINER)", s.ExecWithEngine)) } func (s *WaitContainer) Execute(ctx *context.Context) error { cli := ctx.Module().DockerCli().WaitContainer(s.ContainerId) out, err := cli.Execute(s.ExecOptions) - return PostHandle(nil, s.Out, out, err, errno.ERR_WAIT_CONTAINER_STOP_FAILED) + return PostHandle(nil, s.Out, out, err, errno.ERR_WAIT_CONTAINER_STOP_FAILED.FD("(%s wait CONTAINER)", s.ExecWithEngine)) } func (s *RemoveContainer) Execute(ctx *context.Context) error { cli := ctx.Module().DockerCli().RemoveContainer(s.ContainerId) out, err := cli.Execute(s.ExecOptions) - return PostHandle(s.Success, s.Out, out, err, errno.ERR_REMOVE_CONTAINER_FAILED) + return PostHandle(s.Success, s.Out, out, err, errno.ERR_REMOVE_CONTAINER_FAILED.FD("(%s rm CONTAINER)", s.ExecWithEngine)) } func (s *ListContainers) Execute(ctx *context.Context) error { @@ -292,25 +292,25 @@ func (s *ListContainers) Execute(ctx *context.Context) error { } out, err := cli.Execute(s.ExecOptions) - return PostHandle(nil, s.Out, out, err, errno.ERR_LIST_CONTAINERS_FAILED) + return PostHandle(nil, s.Out, out, err, errno.ERR_LIST_CONTAINERS_FAILED.FD("(%s ps)", s.ExecWithEngine)) } func (s *ContainerExec) Execute(ctx *context.Context) error { cli := ctx.Module().DockerCli().ContainerExec(*s.ContainerId, s.Command) out, err := cli.Execute(s.ExecOptions) - return PostHandle(s.Success, s.Out, out, err, errno.ERR_RUN_COMMAND_IN_CONTAINER_FAILED) + return PostHandle(s.Success, s.Out, out, err, errno.ERR_RUN_COMMAND_IN_CONTAINER_FAILED.FD("(%s exec CONTAINER COMMAND)", s.ExecWithEngine)) } func (s *CopyFromContainer) Execute(ctx *context.Context) error { cli := ctx.Module().DockerCli().CopyFromContainer(s.ContainerId, s.ContainerSrcPath, s.HostDestPath) out, err := cli.Execute(s.ExecOptions) - return PostHandle(nil, s.Out, out, err, errno.ERR_COPY_FROM_CONTAINER_FAILED) + return PostHandle(nil, s.Out, out, err, errno.ERR_COPY_FROM_CONTAINER_FAILED.FD("(%s cp CONTAINER:SRC_PATH DEST_PATH)", s.ExecWithEngine)) } func (s *CopyIntoContainer) Execute(ctx *context.Context) error { cli := ctx.Module().DockerCli().CopyIntoContainer(s.HostSrcPath, s.ContainerId, s.ContainerDestPath) out, err := cli.Execute(s.ExecOptions) - return PostHandle(nil, s.Out, out, err, errno.ERR_COPY_INTO_CONTAINER_FAILED) + return PostHandle(nil, s.Out, out, err, errno.ERR_COPY_INTO_CONTAINER_FAILED.FD("(%s cp SRC_PATH CONTAINER:DEST_PATH)", s.ExecWithEngine)) } func (s *InspectContainer) Execute(ctx *context.Context) error { @@ -320,13 +320,13 @@ func (s *InspectContainer) Execute(ctx *context.Context) error { } out, err := cli.Execute(s.ExecOptions) - return PostHandle(s.Success, s.Out, out, err, errno.ERR_INSPECT_CONTAINER_FAILED) + return PostHandle(s.Success, s.Out, out, err, errno.ERR_INSPECT_CONTAINER_FAILED.FD("(%s inspect ID)", s.ExecWithEngine)) } func (s *ContainerLogs) Execute(ctx *context.Context) error { cli := ctx.Module().DockerCli().ContainerLogs(s.ContainerId) out, err := cli.Execute(s.ExecOptions) - return PostHandle(s.Success, s.Out, out, err, errno.ERR_GET_CONTAINER_LOGS_FAILED) + return PostHandle(s.Success, s.Out, out, err, errno.ERR_GET_CONTAINER_LOGS_FAILED.FD("(%s logs ID)", s.ExecWithEngine)) } func (s *UpdateContainer) Execute(ctx *context.Context) error { @@ -335,5 +335,5 @@ func (s *UpdateContainer) Execute(ctx *context.Context) error { cli.AddOption("--restart %s", s.Restart) } out, err := cli.Execute(s.ExecOptions) - return PostHandle(s.Success, s.Out, out, err, errno.ERR_UPDATE_CONTAINER_FAILED) + return PostHandle(s.Success, s.Out, out, err, errno.ERR_UPDATE_CONTAINER_FAILED.FD("(%s update ID)", s.ExecWithEngine)) } diff --git a/internal/task/step/file.go b/internal/task/step/file.go index 8e1381abe..cfd4fc575 100644 --- a/internal/task/step/file.go +++ b/internal/task/step/file.go @@ -124,7 +124,7 @@ func (s *ReadFile) Execute(ctx *context.Context) error { dockerCli := ctx.Module().DockerCli().CopyFromContainer(s.ContainerId, s.ContainerSrcPath, remotePath) _, err := dockerCli.Execute(s.ExecOptions) if err != nil { - return errno.ERR_COPY_FROM_CONTAINER_FAILED.E(err) + return errno.ERR_COPY_FROM_CONTAINER_FAILED.FD("(%s cp CONTAINER:SRC_PATH DEST_PATH)", s.ExecWithEngine).E(err) } } @@ -189,7 +189,7 @@ func (s *InstallFile) Execute(ctx *context.Context) error { cli := ctx.Module().DockerCli().CopyIntoContainer(remotePath, *s.ContainerId, s.ContainerDestPath) _, err = cli.Execute(s.ExecOptions) if err != nil { - return errno.ERR_COPY_INTO_CONTAINER_FAILED.E(err) + return errno.ERR_COPY_INTO_CONTAINER_FAILED.FD(" (%scp SRC_PATH CONTAINER:DEST_PATH)", s.ExecWithEngine).E(err) } } return nil diff --git a/internal/task/task/bs/add_target.go b/internal/task/task/bs/add_target.go index 2383fe24c..703267921 100644 --- a/internal/task/task/bs/add_target.go +++ b/internal/task/task/bs/add_target.go @@ -67,7 +67,6 @@ func NewAddTargetTask(curveadm *cli.CurveAdm, cc *configure.ClientConfig) (*task t.AddStep(&step.ListContainers{ ShowAll: true, Format: "'{{.ID}} {{.Status}}'", - Quiet: true, Filter: fmt.Sprintf("name=%s", DEFAULT_TGTD_CONTAINER_NAME), Out: &output, ExecOptions: curveadm.ExecOptions(), diff --git a/internal/task/task/bs/create_volume.go b/internal/task/task/bs/create_volume.go index e582b951f..829abb85e 100644 --- a/internal/task/task/bs/create_volume.go +++ b/internal/task/task/bs/create_volume.go @@ -87,7 +87,6 @@ func NewCreateVolumeTask(curveadm *cli.CurveAdm, cc *configure.ClientConfig) (*t t.AddStep(&step.ListContainers{ ShowAll: true, Format: "'{{.Status}}'", - Quiet: true, Filter: fmt.Sprintf("name=%s", containerName), Out: &out, ExecOptions: curveadm.ExecOptions(), diff --git a/internal/task/task/bs/delete_target.go b/internal/task/task/bs/delete_target.go index 7f5a6135e..7cb454fb0 100644 --- a/internal/task/task/bs/delete_target.go +++ b/internal/task/task/bs/delete_target.go @@ -67,7 +67,6 @@ func NewDeleteTargetTask(curveadm *cli.CurveAdm, cc *client.ClientConfig) (*task t.AddStep(&step.ListContainers{ ShowAll: true, Format: "'{{.ID}} {{.Status}}'", - Quiet: true, Filter: fmt.Sprintf("name=%s", DEFAULT_TGTD_CONTAINER_NAME), Out: &output, ExecOptions: curveadm.ExecOptions(), @@ -77,7 +76,7 @@ func NewDeleteTargetTask(curveadm *cli.CurveAdm, cc *client.ClientConfig) (*task }) t.AddStep(&step.ContainerExec{ ContainerId: &containerId, - Command: fmt.Sprintf("tgtadm --lld iscsi --mode target --op show"), + Command: "tgtadm --lld iscsi --mode target --op show", Out: &output, ExecOptions: curveadm.ExecOptions(), }) diff --git a/internal/task/task/bs/format.go b/internal/task/task/bs/format.go index e9a04aafc..3ec135383 100644 --- a/internal/task/task/bs/format.go +++ b/internal/task/task/bs/format.go @@ -252,7 +252,6 @@ func NewFormatChunkfilePoolTask(curveadm *cli.CurveAdm, fc *configure.FormatConf t.AddStep(&step.ListContainers{ ShowAll: true, Format: "'{{.ID}}'", - Quiet: true, Filter: fmt.Sprintf("name=%s", containerName), Out: &oldContainerId, ExecOptions: curveadm.ExecOptions(), diff --git a/internal/task/task/bs/format_stop.go b/internal/task/task/bs/format_stop.go index 424b1ec2a..aff2902a4 100644 --- a/internal/task/task/bs/format_stop.go +++ b/internal/task/task/bs/format_stop.go @@ -34,7 +34,7 @@ import ( func skipStopFormat(containerId *string) step.LambdaType { return func(ctx *context.Context) error { - if len(*containerId) < 0 { + if len(*containerId) == 0 { return task.ERR_SKIP_TASK } return nil @@ -105,7 +105,6 @@ func NewStopFormatTask(curveadm *cli.CurveAdm, fc *configure.FormatConfig) (*tas t.AddStep(&step.ListContainers{ ShowAll: true, Format: "'{{.ID}}'", - Quiet: true, Filter: fmt.Sprintf("name=%s", containerName), Out: &oldContainerId, ExecOptions: curveadm.ExecOptions(), diff --git a/internal/task/task/bs/list_targets.go b/internal/task/task/bs/list_targets.go index 32abc7dc3..f7543ca8c 100644 --- a/internal/task/task/bs/list_targets.go +++ b/internal/task/task/bs/list_targets.go @@ -120,7 +120,6 @@ func NewListTargetsTask(curveadm *cli.CurveAdm, v interface{}) (*task.Task, erro t.AddStep(&step.ListContainers{ ShowAll: true, Format: "'{{.ID}} {{.Status}}'", - Quiet: true, Filter: fmt.Sprintf("name=%s", DEFAULT_TGTD_CONTAINER_NAME), Out: &output, ExecOptions: curveadm.ExecOptions(), @@ -130,7 +129,7 @@ func NewListTargetsTask(curveadm *cli.CurveAdm, v interface{}) (*task.Task, erro }) t.AddStep(&step.ContainerExec{ ContainerId: &containerId, - Command: fmt.Sprintf("tgtadm --lld iscsi --mode target --op show"), + Command: "tgtadm --lld iscsi --mode target --op show", Out: &output, ExecOptions: curveadm.ExecOptions(), }) diff --git a/internal/task/task/bs/map.go b/internal/task/task/bs/map.go index c3c1803c6..adcb0c00c 100644 --- a/internal/task/task/bs/map.go +++ b/internal/task/task/bs/map.go @@ -94,7 +94,6 @@ func NewMapTask(curveadm *cli.CurveAdm, cc *configure.ClientConfig) (*task.Task, t.AddStep(&step.ListContainers{ ShowAll: true, Format: "'{{.Status}}'", - Quiet: true, Filter: fmt.Sprintf("name=%s", containerName), Out: &out, ExecOptions: curveadm.ExecOptions(), diff --git a/internal/task/task/bs/start_nebd.go b/internal/task/task/bs/start_nebd.go index d71b34d7e..d7fdcaccd 100644 --- a/internal/task/task/bs/start_nebd.go +++ b/internal/task/task/bs/start_nebd.go @@ -156,18 +156,17 @@ func NewStartNEBDServiceTask(curveadm *cli.CurveAdm, cc *configure.ClientConfig) hostname := containerName host2addr := fmt.Sprintf("%s:%s", hostname, hc.GetHostname()) - t.AddStep(&step.DockerInfo{ + t.AddStep(&step.EngineInfo{ Success: &success, Out: &out, ExecOptions: curveadm.ExecOptions(), }) t.AddStep(&step.Lambda{ - Lambda: checker.CheckDockerInfo(options.Host, &success, &out), + Lambda: checker.CheckEngineInfo(options.Host, curveadm.ExecOptions().ExecWithEngine, &success, &out), }) t.AddStep(&step.ListContainers{ ShowAll: true, Format: "'{{.ID}}'", - Quiet: true, Filter: fmt.Sprintf("name=%s", containerName), Out: &containerId, ExecOptions: curveadm.ExecOptions(), @@ -188,7 +187,7 @@ func NewStartNEBDServiceTask(curveadm *cli.CurveAdm, cc *configure.ClientConfig) AddHost: []string{host2addr}, Envs: []string{"LD_PRELOAD=/usr/local/lib/libjemalloc.so"}, Hostname: hostname, - Command: fmt.Sprintf("--role nebd"), + Command: "--role nebd", Name: containerName, Pid: "host", Privileged: true, diff --git a/internal/task/task/bs/start_tgtd.go b/internal/task/task/bs/start_tgtd.go index 7c5142b63..ef4358e35 100644 --- a/internal/task/task/bs/start_tgtd.go +++ b/internal/task/task/bs/start_tgtd.go @@ -77,7 +77,6 @@ func NewStartTargetDaemonTask(curveadm *cli.CurveAdm, cc *configure.ClientConfig t.AddStep(&step.ListContainers{ ShowAll: true, Format: "'{{.Status}}'", - Quiet: true, Filter: fmt.Sprintf("name=%s", DEFAULT_TGTD_CONTAINER_NAME), Out: &status, ExecOptions: curveadm.ExecOptions(), @@ -94,7 +93,7 @@ func NewStartTargetDaemonTask(curveadm *cli.CurveAdm, cc *configure.ClientConfig AddHost: []string{host2addr}, Envs: []string{"LD_PRELOAD=/usr/local/lib/libjemalloc.so"}, Hostname: hostname, - Command: fmt.Sprintf("--role nebd"), + Command: "--role nebd", Name: containerName, Pid: "host", Privileged: true, diff --git a/internal/task/task/bs/stop_tgtd.go b/internal/task/task/bs/stop_tgtd.go index 1531bd71a..0725c0355 100644 --- a/internal/task/task/bs/stop_tgtd.go +++ b/internal/task/task/bs/stop_tgtd.go @@ -57,7 +57,6 @@ func NewStopTargetDaemonTask(curveadm *cli.CurveAdm, v interface{}) (*task.Task, t.AddStep(&step.ListContainers{ ShowAll: true, Format: "'{{.ID}}'", - Quiet: true, Filter: fmt.Sprintf("name=%s", DEFAULT_TGTD_CONTAINER_NAME), Out: &containerId, ExecOptions: curveadm.ExecOptions(), diff --git a/internal/task/task/bs/unmap.go b/internal/task/task/bs/unmap.go index 603350e66..33a596373 100644 --- a/internal/task/task/bs/unmap.go +++ b/internal/task/task/bs/unmap.go @@ -148,7 +148,6 @@ func NewUnmapTask(curveadm *cli.CurveAdm, v interface{}) (*task.Task, error) { t.AddStep(&step.ListContainers{ ShowAll: true, Format: "'{{.ID}} {{.Status}}'", - Quiet: true, Filter: fmt.Sprintf("id=%s", containerId), Out: &output, ExecOptions: curveadm.ExecOptions(), diff --git a/internal/task/task/checker/common.go b/internal/task/task/checker/common.go index e9830da80..c97c379b3 100644 --- a/internal/task/task/checker/common.go +++ b/internal/task/task/checker/common.go @@ -55,11 +55,11 @@ const ( var ( CONNECT = map[string][]string{ - ROLE_ETCD: []string{ROLE_ETCD}, - ROLE_MDS: []string{ROLE_MDS, ROLE_ETCD}, - ROLE_CHUNKSERVER: []string{ROLE_CHUNKSERVER, ROLE_MDS}, - ROLE_SNAPSHOTCLONE: []string{ROLE_SNAPSHOTCLONE}, - ROLE_METASERVER: []string{ROLE_METASERVER, ROLE_MDS}, + ROLE_ETCD: {ROLE_ETCD}, + ROLE_MDS: {ROLE_MDS, ROLE_ETCD}, + ROLE_CHUNKSERVER: {ROLE_CHUNKSERVER, ROLE_MDS}, + ROLE_SNAPSHOTCLONE: {ROLE_SNAPSHOTCLONE}, + ROLE_METASERVER: {ROLE_METASERVER, ROLE_MDS}, } ) diff --git a/internal/task/task/checker/kernel.go b/internal/task/task/checker/kernel.go index 075c8404d..7a3c4b36e 100644 --- a/internal/task/task/checker/kernel.go +++ b/internal/task/task/checker/kernel.go @@ -42,7 +42,7 @@ import ( const ( CHUNKSERVER_LEAST_KERNEL_VERSION = "3.15.0" - REGEX_KERNEL_VAERSION = "^(\\d+\\.\\d+\\.\\d+)(-.+)?$" + REGEX_KERNEL_VAERSION = "^(\\d+\\.\\d+\\.\\d+)(?:[-_].+)?$" ) func calcKernelVersion(version string) int { @@ -84,7 +84,7 @@ func checkKernelVersion(out *string, dc *topology.DeployConfig) step.LambdaType func checkKernelModule(name string, success *bool, out *string) step.LambdaType { return func(ctx *context.Context) error { - if *success == true { + if *success { return nil } diff --git a/internal/task/task/checker/kernel_test.go b/internal/task/task/checker/kernel_test.go index 4f7d3b497..2669e1666 100644 --- a/internal/task/task/checker/kernel_test.go +++ b/internal/task/task/checker/kernel_test.go @@ -39,6 +39,7 @@ func TestCheckKernelVersion(t *testing.T) { }{ {"5.12.0", nil}, {"4.9.65-netease", nil}, + {"4.18.0_80.7.1.el8_0_bch_v1.0", nil}, {"4.19.0-16-amd64", nil}, {"3.15.0", nil}, {"3.15.0.0.", errno.ERR_UNRECOGNIZED_KERNEL_VERSION}, diff --git a/internal/task/task/checker/network.go b/internal/task/task/checker/network.go index 0edcf9142..1869eb1cb 100644 --- a/internal/task/task/checker/network.go +++ b/internal/task/task/checker/network.go @@ -43,6 +43,7 @@ const ( FORMAT_FILTER_SPORT = "( sport = :%d )" HTTP_SERVER_CONTAINER_NAME = "curveadm-precheck-nginx" + CHECK_PORT_CONTAINER_NAME = "curveadm-precheck-port" ) // TASK: check port in use @@ -65,12 +66,59 @@ func joinPorts(dc *topology.DeployConfig, addresses []Address) string { for _, address := range addresses { ports = append(ports, strconv.Itoa(address.Port)) } - if dc.GetReplicas() > 1 { // replicas service + if dc.GetInstances() > 1 { // instances service ports = append(ports, "...") } return strings.Join(ports, ",") } +func getCheckPortContainerName(curveadm *cli.CurveAdm, dc *topology.DeployConfig) string { + return fmt.Sprintf("%s-%s-%s", + CHECK_PORT_CONTAINER_NAME, + dc.GetRole(), + curveadm.GetServiceId(dc.GetId())) +} + +type step2CheckPortStatus struct { + containerId *string + success *bool + dc *topology.DeployConfig + curveadm *cli.CurveAdm + port int +} + +// execute the "ss" command within a temporary container +func (s *step2CheckPortStatus) Execute(ctx *context.Context) error { + filter := fmt.Sprintf(FORMAT_FILTER_SPORT, s.port) + cli := ctx.Module().Shell().SocketStatistics(filter) + cli.AddOption("--no-header") + cli.AddOption("--listening") + command, err := cli.String() + if err != nil { + return err + } + + var out string + steps := []task.Step{} + steps = append(steps, &step.ContainerExec{ + ContainerId: s.containerId, + Command: command, + Out: &out, + ExecOptions: s.curveadm.ExecOptions(), + }) + steps = append(steps, &step.Lambda{ + Lambda: checkPortInUse(s.success, &out, s.dc.GetHost(), s.port), + }) + + for _, step := range steps { + err := step.Execute(ctx) + if err != nil { + return err + } + } + return nil +} + func NewCheckPortInUseTask(curveadm *cli.CurveAdm, dc *topology.DeployConfig) (*task.Task, error) { hc, err := curveadm.GetHost(dc.GetHost()) if err != nil { @@ -82,19 +130,35 @@ func NewCheckPortInUseTask(curveadm *cli.CurveAdm, dc *topology.DeployConfig) (* dc.GetHost(), dc.GetRole(), joinPorts(dc, addresses)) t := task.NewTask("Check Port In Use ", subname, hc.GetSSHConfig()) - var out string + var containerId, out string var success bool + t.AddStep(&step.PullImage{ + Image: dc.GetContainerImage(), + ExecOptions: curveadm.ExecOptions(), + }) + t.AddStep(&step.CreateContainer{ + Image: dc.GetContainerImage(), + Command: "-c 'sleep infinity'", // keep the container running + Entrypoint: "/bin/bash", + Name: getCheckPortContainerName(curveadm, dc), + Remove: true, + Out: &containerId, + ExecOptions: curveadm.ExecOptions(), + }) + t.AddStep(&step.StartContainer{ + ContainerId: &containerId, + Success: &success, + Out: &out, + ExecOptions: curveadm.ExecOptions(), + }) + for _, address := range addresses { - t.AddStep(&step.SocketStatistics{ - Filter: fmt.Sprintf(FORMAT_FILTER_SPORT, address.Port), - Listening: true, - NoHeader: true, - Success: &success, - Out: &out, - ExecOptions: curveadm.ExecOptions(), - }) - t.AddStep(&step.Lambda{ - Lambda: checkPortInUse(&success, &out, dc.GetHost(), address.Port), + t.AddStep(&step2CheckPortStatus{ + containerId: &containerId, + success: &success, + dc: dc, + curveadm: curveadm, + port: address.Port, }) } @@ -164,7 +228,7 @@ func getNginxListens(dc *topology.DeployConfig) string { return strings.Join(listens, " ") } -func getContainerName(curveadm *cli.CurveAdm, dc *topology.DeployConfig) string { +func getHTTPServerContainerName(curveadm *cli.CurveAdm, dc *topology.DeployConfig) string { return fmt.Sprintf("%s-%s-%s", HTTP_SERVER_CONTAINER_NAME, dc.GetRole(), @@ -204,7 +268,7 @@ func NewStartHTTPServerTask(curveadm *cli.CurveAdm, dc *topology.DeployConfig) ( Image: dc.GetContainerImage(), Command: command, Entrypoint: "/bin/bash", - Name: getContainerName(curveadm, dc), + Name: getHTTPServerContainerName(curveadm, dc), Remove: true, Out: &containerId, ExecOptions: curveadm.ExecOptions(), @@ -283,7 +347,7 @@ func NewCheckNetworkFirewallTask(curveadm *cli.CurveAdm, dc *topology.DeployConf return t, nil } -// TASK: stop http server +// TASK: stop container type step2StopContainer struct { containerId *string dc *topology.DeployConfig @@ -332,7 +396,19 @@ func NewCleanEnvironmentTask(curveadm *cli.CurveAdm, dc *topology.DeployConfig) t.AddStep(&step.ListContainers{ ShowAll: true, Format: `"{{.ID}}"`, - Filter: fmt.Sprintf("name=%s", getContainerName(curveadm, dc)), + Filter: fmt.Sprintf("name=%s", getCheckPortContainerName(curveadm, dc)), + Out: &out, + ExecOptions: curveadm.ExecOptions(), + }) + t.AddStep(&step2StopContainer{ + containerId: &out, + dc: dc, + curveadm: curveadm, + }) + t.AddStep(&step.ListContainers{ + ShowAll: true, + Format: `"{{.ID}}"`, + Filter: fmt.Sprintf("name=%s", getHTTPServerContainerName(curveadm, dc)), Out: &out, ExecOptions: curveadm.ExecOptions(), }) diff --git a/internal/task/task/checker/permission.go b/internal/task/task/checker/permission.go index d074bb5f2..cf906c63f 100644 --- a/internal/task/task/checker/permission.go +++ b/internal/task/task/checker/permission.go @@ -87,7 +87,7 @@ func checkCreateDirectory(dc *topology.DeployConfig, path string, success *bool, } } -func CheckDockerInfo(host string, success *bool, out *string) step.LambdaType { +func CheckEngineInfo(host, engine string, success *bool, out *string) step.LambdaType { return func(ctx *context.Context) error { if *success { return nil @@ -95,13 +95,13 @@ func CheckDockerInfo(host string, success *bool, out *string) step.LambdaType { *out = strings.ToLower(*out) if strings.Contains(*out, SIGNATURE_COMMAND_NOT_FOUND) { - return errno.ERR_DOCKER_NOT_INSTALLED. + return errno.ERR_CONTAINER_ENGINE_NOT_INSTALLED. F("host=%s\n%s", host, *out) } else if strings.Contains(*out, SIGNATURE_PERMISSION_DENIED) { - return errno.ERR_EXECUTE_DOCKER_COMMAND_PERMISSION_DENIED. + return errno.ERR_EXECUTE_CONTAINER_ENGINE_COMMAND_PERMISSION_DENIED. F("host=%s\n%s", host, *out) } else if strings.Contains(*out, SIGNATURE_PERMISSION_WITH_PASSWORD) { - return errno.ERR_EXECUTE_DOCKER_COMMAND_PERMISSION_DENIED. + return errno.ERR_EXECUTE_CONTAINER_ENGINE_COMMAND_PERMISSION_DENIED. F("host=%s (need password)", host) } else if strings.Contains(*out, SIGNATURE_DOCKER_DEAMON_IS_NOT_RUNNING) { return errno.ERR_DOCKER_DAEMON_IS_NOT_RUNNING. @@ -164,14 +164,14 @@ func NewCheckPermissionTask(curveadm *cli.CurveAdm, dc *topology.DeployConfig) ( Lambda: checkCreateDirectory(dc, dir.Path, &success, &out), }) } - // (4) check docker command {exist, permission, running} - t.AddStep(&step.DockerInfo{ + // (4) check docker/podman engine command {exist, permission, running} + t.AddStep(&step.EngineInfo{ Success: &success, Out: &out, ExecOptions: curveadm.ExecOptions(), }) t.AddStep(&step.Lambda{ - Lambda: CheckDockerInfo(dc.GetHost(), &success, &out), + Lambda: CheckEngineInfo(dc.GetHost(), curveadm.ExecOptions().ExecWithEngine, &success, &out), }) return t, nil diff --git a/internal/task/task/checker/service.go b/internal/task/task/checker/service.go index a4c642765..4a9a3af35 100644 --- a/internal/task/task/checker/service.go +++ b/internal/task/task/checker/service.go @@ -64,7 +64,7 @@ type ( func (s *step2CheckChunkfilePool) Execute(ctx *context.Context) error { dc := s.dc dataDir := dc.GetDataDir() - if dc.GetEnableChunkfilePool() == false { + if !dc.GetEnableChunkfilePool() { return nil } else if len(dataDir) == 0 { return errno.ERR_CHUNKFILE_POOL_NOT_EXIST diff --git a/internal/task/task/checker/ssh.go b/internal/task/task/checker/ssh.go index 9d0e893bd..f5e3a4528 100644 --- a/internal/task/task/checker/ssh.go +++ b/internal/task/task/checker/ssh.go @@ -51,7 +51,7 @@ func doNothing() step.LambdaType { func checkHost(hc *hosts.HostConfig) step.LambdaType { return func(ctx *context.Context) error { privateKeyFile := hc.GetPrivateKeyFile() - if hc.GetForwardAgent() == false { + if !hc.GetForwardAgent() { if !utils.PathExist(privateKeyFile) { return errno.ERR_PRIVATE_KEY_FILE_NOT_EXIST. F("%s: no such file", privateKeyFile) diff --git a/internal/task/task/checker/topology.go b/internal/task/task/checker/topology.go index 9b6c5185e..4e4a23875 100644 --- a/internal/task/task/checker/topology.go +++ b/internal/task/task/checker/topology.go @@ -55,8 +55,7 @@ type ( // check whether directory path is absolute path step2CheckDirectoryPath struct { - sequence int - dc *topology.DeployConfig + dc *topology.DeployConfig } // check whether the data directory is duplicate diff --git a/internal/task/task/common/clean_service.go b/internal/task/task/common/clean_service.go index 870302f65..d20513929 100644 --- a/internal/task/task/common/clean_service.go +++ b/internal/task/task/common/clean_service.go @@ -205,7 +205,7 @@ func NewCleanServiceTask(curveadm *cli.CurveAdm, dc *topology.DeployConfig) (*ta Files: files, ExecOptions: curveadm.ExecOptions(), }) - if clean[comm.CLEAN_ITEM_CONTAINER] == true { + if clean[comm.CLEAN_ITEM_CONTAINER] { t.AddStep(&Step2CleanContainer{ ServiceId: serviceId, ContainerId: containerId, diff --git a/internal/task/task/common/collect_report.go b/internal/task/task/common/collect_report.go index 19bd9b447..67fb4a336 100644 --- a/internal/task/task/common/collect_report.go +++ b/internal/task/task/common/collect_report.go @@ -23,14 +23,10 @@ package common import ( - "fmt" - "strings" - "github.com/opencurve/curveadm/cli/cli" "github.com/opencurve/curveadm/internal/configure/topology" "github.com/opencurve/curveadm/internal/errno" "github.com/opencurve/curveadm/internal/task/context" - "github.com/opencurve/curveadm/internal/task/step" "github.com/opencurve/curveadm/internal/task/task" "github.com/opencurve/curveadm/internal/utils" ) @@ -43,24 +39,6 @@ type ( } ) -func appendOut(command string, success *bool, out *string, outs *[]string) step.LambdaType { - return func(ctx *context.Context) error { - if !*success { - *outs = append(*outs, fmt.Sprintf("<%s>: failed", command)) - } else { - *outs = append(*outs, *out) - } - return nil - } -} - -func convert2Content(outs *[]string, content *string) step.LambdaType { - return func(ctx *context.Context) error { - *content = strings.Join(*outs, "\n---\n") - return nil - } -} - func (s *step2EncryptFile) Execute(ctx *context.Context) error { err := utils.EncryptFile(s.source, s.dest, s.secret) if err != nil { diff --git a/internal/task/task/common/create_pool.go b/internal/task/task/common/create_pool.go index eca5b1810..dd6ffaa29 100644 --- a/internal/task/task/common/create_pool.go +++ b/internal/task/task/common/create_pool.go @@ -94,7 +94,7 @@ func prepare(curveadm *cli.CurveAdm, dc *topology.DeployConfig) (clusterPoolJson var clusterPool configure.CurveClusterTopo clusterPool, err = getClusterPool(curveadm, dc) if err != nil { - return + return clusterPoolJson, clusterMDSAddrs, err } // 2. scale out cluster or migrate servers @@ -112,14 +112,14 @@ func prepare(curveadm *cli.CurveAdm, dc *topology.DeployConfig) (clusterPoolJson var bytes []byte bytes, err = json.Marshal(clusterPool) if err != nil { - return + return clusterPoolJson, clusterMDSAddrs, err } clusterPoolJson = string(bytes) // cluster MDS address clusterMDSAddrs, err = dc.GetVariables().Get("cluster_mds_addr") clusterMDSAddrs = strings.Replace(clusterMDSAddrs, ",", " ", -1) - return + return clusterPoolJson, clusterMDSAddrs, err } func checkWaitMDSElectionSuccess(success *bool, out *string) step.LambdaType { @@ -210,7 +210,7 @@ func NewCreateTopologyTask(curveadm *cli.CurveAdm, dc *topology.DeployConfig) (* return nil, err } build.DEBUG(build.DEBUG_CREATE_POOL, - build.Field{"pool json", clusterPoolJson}) + build.Field{Key: "pool json", Value: clusterPoolJson}) t.AddStep(&step.ListContainers{ ShowAll: true, diff --git a/internal/task/task/common/etcd_auth_enable.go b/internal/task/task/common/etcd_auth_enable.go new file mode 100644 index 000000000..9d3b71109 --- /dev/null +++ b/internal/task/task/common/etcd_auth_enable.go @@ -0,0 +1,106 @@ +/* +* Copyright (c) 2023 NetEase Inc. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + */ + +/* +* Project: Curveadm +* Created Date: 2023-08-02 +* Author: wanghai (SeanHai) + */ + +package common + +import ( + "fmt" + + "github.com/opencurve/curveadm/cli/cli" + "github.com/opencurve/curveadm/internal/configure/topology" + "github.com/opencurve/curveadm/internal/errno" + "github.com/opencurve/curveadm/internal/task/context" + "github.com/opencurve/curveadm/internal/task/scripts" + "github.com/opencurve/curveadm/internal/task/step" + "github.com/opencurve/curveadm/internal/task/task" + tui "github.com/opencurve/curveadm/internal/tui/common" +) + +func checkEnableEtcdAuthStatus(success *bool, out *string) step.LambdaType { + return func(ctx *context.Context) error { + if !*success { + return errno.ERR_ENABLE_ETCD_AUTH_FAILED.S(*out) + } + return nil + } +} + +func NewEnableEtcdAuthTask(curveadm *cli.CurveAdm, dc *topology.DeployConfig) (*task.Task, error) { + serviceId := curveadm.GetServiceId(dc.GetId()) + containerId, err := curveadm.GetContainerId(serviceId) + if curveadm.IsSkip(dc) { + return nil, nil + } else if err != nil { + return nil, err + } + hc, err := curveadm.GetHost(dc.GetHost()) + if err != nil { + return nil, err + } + + var success bool + var out string + host, role := dc.GetHost(), dc.GetRole() + // new task + subname := fmt.Sprintf("host=%s role=%s containerId=%s", + dc.GetHost(), dc.GetRole(), tui.TrimContainerId(containerId)) + t := task.NewTask("Enable Etcd Auth", subname, hc.GetSSHConfig()) + + script := scripts.ENABLE_ETCD_AUTH + layout := dc.GetProjectLayout() + scriptPath := fmt.Sprintf("%s/enable_auth.sh", layout.ServiceBinDir) + + etcdEndPoints, err := dc.GetVariables().Get("cluster_etcd_addr") + if err != nil { + return nil, err + } + + t.AddStep(&step.ListContainers{ + ShowAll: true, + Format: `"{{.ID}}"`, + Filter: fmt.Sprintf("id=%s", containerId), + Out: &out, + ExecOptions: curveadm.ExecOptions(), + }) + t.AddStep(&step.Lambda{ + Lambda: CheckContainerExist(host, role, containerId, &out), + }) + t.AddStep(&step.InstallFile{ // install /curvebs(fs)/etcd/sbin/enable_auth.sh + ContainerId: &containerId, + ContainerDestPath: scriptPath, + Content: &script, + ExecOptions: curveadm.ExecOptions(), + }) + command := fmt.Sprintf("/bin/bash %s %s %s %s", scriptPath, etcdEndPoints, dc.GetEtcdAuthUsername(), + dc.GetEtcdAuthPassword()) + t.AddStep(&step.ContainerExec{ + ContainerId: &containerId, + Success: &success, + Out: &out, + Command: command, + ExecOptions: curveadm.ExecOptions(), + }) + t.AddStep(&step.Lambda{ + Lambda: checkEnableEtcdAuthStatus(&success, &out), + }) + return t, nil +} diff --git a/internal/task/task/common/restart_service.go b/internal/task/task/common/restart_service.go index 25915a7e3..9f81741c3 100644 --- a/internal/task/task/common/restart_service.go +++ b/internal/task/task/common/restart_service.go @@ -30,24 +30,12 @@ import ( "github.com/opencurve/curveadm/cli/cli" "github.com/opencurve/curveadm/internal/configure/topology" - "github.com/opencurve/curveadm/internal/errno" "github.com/opencurve/curveadm/internal/task/context" "github.com/opencurve/curveadm/internal/task/step" "github.com/opencurve/curveadm/internal/task/task" tui "github.com/opencurve/curveadm/internal/tui/common" ) -func checkContainerStatus(host, role, containerId string, status *string) step.LambdaType { - return func(ctx *context.Context) error { - if *status != "running" { - return errno.ERR_CONTAINER_IS_ABNORMAL. - F("host=%s role=%s containerId=%s", - host, role, tui.TrimContainerId(containerId)) - } - return nil - } -} - func WaitContainerStart(seconds int) step.LambdaType { return func(ctx *context.Context) error { time.Sleep(time.Duration(seconds)) diff --git a/internal/task/task/common/service_status.go b/internal/task/task/common/service_status.go index 66b7d21dd..660fd68c7 100644 --- a/internal/task/task/common/service_status.go +++ b/internal/task/task/common/service_status.go @@ -85,7 +85,7 @@ type ( ParentId string Role string Host string - Replica string + Instances string ContainerId string Ports string IsLeader bool @@ -117,7 +117,7 @@ func (s *step2InitStatus) Execute(ctx *context.Context) error { ParentId: dc.GetParentId(), Role: dc.GetRole(), Host: dc.GetHost(), - Replica: fmt.Sprintf("1/%d", dc.GetReplicas()), + Instances: fmt.Sprintf("1/%d", dc.GetInstances()), ContainerId: tui.TrimContainerId(s.containerId), Status: comm.SERVICE_STATUS_UNKNOWN, LogDir: dc.GetLogDir(), @@ -206,7 +206,7 @@ func (s *step2FormatServiceStatus) Execute(ctx *context.Context) error { ParentId: dc.GetParentId(), Role: dc.GetRole(), Host: dc.GetHost(), - Replica: fmt.Sprintf("1/%d", dc.GetReplicas()), + Instances: fmt.Sprintf("1/%d", dc.GetInstances()), ContainerId: tui.TrimContainerId(s.containerId), Ports: *s.ports, IsLeader: *s.isLeader, diff --git a/internal/task/task/common/sync_binary.go b/internal/task/task/common/sync_binary.go deleted file mode 100644 index a4276768c..000000000 --- a/internal/task/task/common/sync_binary.go +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2021 NetEase Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Project: CurveAdm - * Created Date: 2021-11-25 - * Author: Hailang Mo (wavemomo) - */ - -package common - -/* -import ( - "fmt" - "path" - "path/filepath" - - "github.com/opencurve/curveadm/internal/task" - "github.com/opencurve/curveadm/cli/cli" - "github.com/opencurve/curveadm/internal/configure" - "github.com/opencurve/curveadm/internal/task/context" -) - -const KEY_BINARY_PATH = "BINARY_PATH" - -type step2SyncBinary struct { - containerID string - remoteContainerBinary string - localBinary string -} - -func (s *step2SyncBinary) Execute(ctx *context.Context) error { - remoteHostBinaryPath := fmt.Sprintf("/tmp/%s", path.Base(s.localBinary)) - if err := ctx.Module().Scp(s.localBinary, remoteHostBinaryPath); err != nil { - return err - } - - _, err := ctx.Module().SshShell("sudo docker cp %s %s:%s", remoteHostBinaryPath, s.containerID, - s.remoteContainerBinary) - return err - -} - -func (s *step2SyncBinary) Rollback(ctx *context.Context) {} - -func NewSyncBinaryTask(curveadm *cli.CurveAdm, dc *configure.DeployConfig) (*task.Task, error) { - serviceId := configure.GetServiceId(curveadm.ClusterId(), dc.GetId()) - containerId, err := curveadm.Storage().GetContainerId(serviceId) - if err != nil { - return nil, err - } else if containerId == "" { - return nil, fmt.Errorf("service(id=%s) not found", serviceId) - } - - binaryPath := curveadm.MemStorage().Get(KEY_BINARY_PATH).(string) - absPath, err := filepath.Abs(binaryPath) - if err != nil { - return nil, err - } - subname := fmt.Sprintf("host=%s role=%s binary=%s", dc.GetHost(), dc.GetRole(), absPath) - t := task.NewTask("Sync Binary", subname, dc) - remotePath := fmt.Sprintf("/usr/local/curvefs/%s/sbin/%s", dc.GetRole(), path.Base(binaryPath)) - t.AddStep(&step2SyncBinary{ - containerID: containerId, - localBinary: binaryPath, - remoteContainerBinary: remotePath, - }) - return t, nil -} -*/ diff --git a/internal/task/task/common/sync_config.go b/internal/task/task/common/sync_config.go index 4cbbeb527..ba1243b39 100644 --- a/internal/task/task/common/sync_config.go +++ b/internal/task/task/common/sync_config.go @@ -102,7 +102,7 @@ func newToolV2Mutate(dc *topology.DeployConfig, delimiter string, forceRender bo func newCrontab(uuid string, dc *topology.DeployConfig, reportScriptPath string) string { var period, command string - if dc.GetReportUsage() == true { + if dc.GetReportUsage() { period = func(minute, hour, day, month, week string) string { return fmt.Sprintf("%s %s %s %s %s", minute, hour, day, month, week) }("0", "*", "*", "*", "*") // every hour diff --git a/internal/task/task/fs/mount.go b/internal/task/task/fs/mount.go index 31e6e6309..26091cb9a 100644 --- a/internal/task/task/fs/mount.go +++ b/internal/task/task/fs/mount.go @@ -331,18 +331,17 @@ func NewMountFSTask(curveadm *cli.CurveAdm, cc *configure.ClientConfig) (*task.T createfsScript := scripts.SCRIPT_CREATEFS createfsScriptPath := "/client.sh" - t.AddStep(&step.DockerInfo{ + t.AddStep(&step.EngineInfo{ Success: &success, Out: &out, ExecOptions: curveadm.ExecOptions(), }) t.AddStep(&step.Lambda{ - Lambda: checker.CheckDockerInfo(options.Host, &success, &out), + Lambda: checker.CheckEngineInfo(options.Host, curveadm.ExecOptions().ExecWithEngine, &success, &out), }) t.AddStep(&step.ListContainers{ ShowAll: true, Format: "'{{.Status}}'", - Quiet: true, Filter: fmt.Sprintf("name=%s", containerName), Out: &out, ExecOptions: curveadm.ExecOptions(), diff --git a/internal/task/task/fs/umount.go b/internal/task/task/fs/umount.go index 8d4b35d05..ea4e55f9a 100644 --- a/internal/task/task/fs/umount.go +++ b/internal/task/task/fs/umount.go @@ -136,7 +136,6 @@ func NewUmountFSTask(curveadm *cli.CurveAdm, v interface{}) (*task.Task, error) t.AddStep(&step.ListContainers{ ShowAll: true, Format: "'{{.Status}}'", - Quiet: true, Filter: fmt.Sprintf("id=%s", containerId), Out: &status, ExecOptions: curveadm.ExecOptions(), diff --git a/internal/task/task/monitor/clean_service.go b/internal/task/task/monitor/clean_service.go index cb9fcf373..2e7d02fa8 100644 --- a/internal/task/task/monitor/clean_service.go +++ b/internal/task/task/monitor/clean_service.go @@ -82,7 +82,7 @@ func NewCleanMonitorTask(curveadm *cli.CurveAdm, cfg *configure.MonitorConfig) ( Files: files, ExecOptions: curveadm.ExecOptions(), }) - if clean[comm.CLEAN_ITEM_CONTAINER] == true { + if clean[comm.CLEAN_ITEM_CONTAINER] { t.AddStep(&common.Step2CleanContainer{ ServiceId: serviceId, ContainerId: containerId, diff --git a/internal/task/task/playground/init.go b/internal/task/task/playground/init.go index d51c35dec..7443432df 100644 --- a/internal/task/task/playground/init.go +++ b/internal/task/task/playground/init.go @@ -48,13 +48,13 @@ const ( func newMutate(cfg interface{}, delimiter string) step.Mutate { var serviceCfg map[string]string var variables *variable.Variables - switch cfg.(type) { + switch cfg := cfg.(type) { case *topology.DeployConfig: - dc := cfg.(*topology.DeployConfig) + dc := cfg serviceCfg = dc.GetServiceConfig() variables = dc.GetVariables() case *configure.ClientConfig: - cc := cfg.(*configure.ClientConfig) + cc := cfg serviceCfg = cc.GetServiceConfig() variables = cc.GetVariables() } diff --git a/internal/task/task/playground/list.go b/internal/task/task/playground/list.go index efb382323..99dd534c1 100644 --- a/internal/task/task/playground/list.go +++ b/internal/task/task/playground/list.go @@ -90,7 +90,6 @@ func NewGetPlaygroundStatusTask(curveadm *cli.CurveAdm, v interface{}) (*task.Ta t.AddStep(&step.ListContainers{ ShowAll: true, Format: "'{{.Status}}'", - Quiet: true, Filter: fmt.Sprintf("name=%s", playground.Name), Out: &status, ExecOptions: execOptions(curveadm), diff --git a/internal/task/task/playground/remove.go b/internal/task/task/playground/remove.go index 53aad3484..df6bdf647 100644 --- a/internal/task/task/playground/remove.go +++ b/internal/task/task/playground/remove.go @@ -102,7 +102,6 @@ func NewRemovePlaygroundTask(curveadm *cli.CurveAdm, v interface{}) (*task.Task, t.AddStep(&step.ListContainers{ ShowAll: true, Format: "'{{.ID}}'", - Quiet: true, Filter: fmt.Sprintf("name=%s", playground.Name), Out: &containerId, ExecOptions: execOptions(curveadm), diff --git a/internal/task/task/task.go b/internal/task/task/task.go index 47a6fa6f2..3eb0d755b 100644 --- a/internal/task/task/task.go +++ b/internal/task/task/task.go @@ -51,7 +51,6 @@ type ( steps []Step postSteps []Step sshConfig *module.SSHConfig - context context.Context } ) diff --git a/internal/task/task/website/clean_service.go b/internal/task/task/website/clean_service.go index 3eb003083..682225488 100644 --- a/internal/task/task/website/clean_service.go +++ b/internal/task/task/website/clean_service.go @@ -51,7 +51,7 @@ func getCleanFiles(clean map[string]bool, cfg *configure.WebsiteConfig) []string func NewCleanWebsiteTask(curveadm *cli.CurveAdm, cfg *configure.WebsiteConfig) (*task.Task, error) { serviceId := curveadm.GetWebsiteServiceId(cfg.GetId()) - containerId, err := curveadm.GetContainerId(serviceId) + containerId, _ := curveadm.GetContainerId(serviceId) hc, err := curveadm.GetHost(cfg.GetHost()) if err != nil { @@ -71,7 +71,7 @@ func NewCleanWebsiteTask(curveadm *cli.CurveAdm, cfg *configure.WebsiteConfig) ( Files: files, ExecOptions: curveadm.ExecOptions(), }) - if clean[comm.CLEAN_ITEM_CONTAINER] == true { + if clean[comm.CLEAN_ITEM_CONTAINER] { t.AddStep(&common.Step2CleanContainer{ ServiceId: serviceId, ContainerId: containerId, diff --git a/internal/task/task/website/restart_service.go b/internal/task/task/website/restart_service.go index 0b32ffe6d..c714bd5e2 100644 --- a/internal/task/task/website/restart_service.go +++ b/internal/task/task/website/restart_service.go @@ -35,7 +35,7 @@ import ( func NewRestartServiceTask(curveadm *cli.CurveAdm, cfg *configure.WebsiteConfig) (*task.Task, error) { serviceId := curveadm.GetWebsiteServiceId(cfg.GetId()) - containerId, err := curveadm.GetContainerId(serviceId) + containerId, _ := curveadm.GetContainerId(serviceId) hc, err := curveadm.GetHost(cfg.GetHost()) if err != nil { diff --git a/internal/task/task/website/start_service.go b/internal/task/task/website/start_service.go index 39ce2a840..2c25ba316 100644 --- a/internal/task/task/website/start_service.go +++ b/internal/task/task/website/start_service.go @@ -35,7 +35,7 @@ import ( func NewStartServiceTask(curveadm *cli.CurveAdm, cfg *configure.WebsiteConfig) (*task.Task, error) { serviceId := curveadm.GetWebsiteServiceId(cfg.GetId()) - containerId, err := curveadm.GetContainerId(serviceId) + containerId, _ := curveadm.GetContainerId(serviceId) hc, err := curveadm.GetHost(cfg.GetHost()) if err != nil { diff --git a/internal/task/task/website/stop_service.go b/internal/task/task/website/stop_service.go index 4a100f62d..a6300b2dc 100644 --- a/internal/task/task/website/stop_service.go +++ b/internal/task/task/website/stop_service.go @@ -35,7 +35,7 @@ import ( func NewStopServiceTask(curveadm *cli.CurveAdm, cfg *configure.WebsiteConfig) (*task.Task, error) { serviceId := curveadm.GetWebsiteServiceId(cfg.GetId()) - containerId, err := curveadm.GetContainerId(serviceId) + containerId, _ := curveadm.GetContainerId(serviceId) hc, err := curveadm.GetHost(cfg.GetHost()) if err != nil { diff --git a/internal/task/task/website/sync_config.go b/internal/task/task/website/sync_config.go index 9ea98a11f..ea837f40b 100644 --- a/internal/task/task/website/sync_config.go +++ b/internal/task/task/website/sync_config.go @@ -59,7 +59,7 @@ func NewMutate(cfg *configure.WebsiteConfig, delimiter string) step.Mutate { func NewSyncConfigTask(curveadm *cli.CurveAdm, cfg *configure.WebsiteConfig) (*task.Task, error) { serviceId := curveadm.GetWebsiteServiceId(cfg.GetId()) - containerId, err := curveadm.GetContainerId(serviceId) + containerId, _ := curveadm.GetContainerId(serviceId) role, host := cfg.GetRole(), cfg.GetHost() hc, err := curveadm.GetHost(host) diff --git a/internal/task/tasks/tasks.go b/internal/task/tasks/tasks.go index 4322dc9d7..2e778df14 100644 --- a/internal/task/tasks/tasks.go +++ b/internal/task/tasks/tasks.go @@ -45,7 +45,7 @@ type ( Tasks struct { tasks []*task.Task monitor *monitor - wg sync.WaitGroup + wg *sync.WaitGroup progress *mpb.Progress mainBar *mpb.Bar subBar map[string]*mpb.Bar @@ -58,7 +58,7 @@ func NewTasks() *Tasks { return &Tasks{ tasks: []*task.Task{}, monitor: newMonitor(), - wg: wg, + wg: &wg, progress: mpb.New(mpb.WithWaitGroup(&wg)), mainBar: nil, subBar: map[string]*mpb.Bar{}, @@ -121,7 +121,7 @@ func (ts *Tasks) displayStatus() func(static decor.Statistics) string { } } -func (ts *Tasks) displayReplica(t *task.Task) func(static decor.Statistics) string { +func (ts *Tasks) displayInstance(t *task.Task) func(static decor.Statistics) string { total := ts.CountPtid(t.Ptid()) return func(static decor.Statistics) string { nsucc, nskip, _ := ts.monitor.sum(static.ID) @@ -149,7 +149,7 @@ func (ts *Tasks) addSubBar(t *task.Task) { mpb.PrependDecorators( decor.Name(" + "), decor.Name(t.Subname()+" "), - decor.Any(ts.displayReplica(t), decor.WCSyncWidthR), + decor.Any(ts.displayInstance(t), decor.WCSyncWidthR), decor.Name(" "), decor.OnComplete(decor.Spinner([]string{}), ""), decor.Any(ts.displayStatus()), @@ -212,7 +212,7 @@ func (ts *Tasks) Execute(option ExecOptions) error { // execute task by concurrency for _, t := range ts.tasks { - if ts.monitor.error() != nil && option.SkipError == false { + if ts.monitor.error() != nil && !option.SkipError { break } diff --git a/internal/tasks/tasks.go b/internal/tasks/tasks.go index 687317c31..4f7b20a3d 100644 --- a/internal/tasks/tasks.go +++ b/internal/tasks/tasks.go @@ -47,7 +47,7 @@ type ( Tasks struct { tasks []*task.Task monitor *monitor - wg sync.WaitGroup + wg *sync.WaitGroup progress *mpb.Progress mainBar *mpb.Bar subBar map[string]*mpb.Bar @@ -60,7 +60,7 @@ func NewTasks() *Tasks { return &Tasks{ tasks: []*task.Task{}, monitor: newMonitor(), - wg: wg, + wg: &wg, progress: mpb.New(mpb.WithWaitGroup(&wg)), mainBar: nil, subBar: map[string]*mpb.Bar{}, @@ -123,7 +123,7 @@ func (ts *Tasks) displayStatus() func(static decor.Statistics) string { } } -func (ts *Tasks) displayReplicas(t *task.Task) func(static decor.Statistics) string { +func (ts *Tasks) displayInstances(t *task.Task) func(static decor.Statistics) string { total := ts.CountPtid(t.Ptid()) return func(static decor.Statistics) string { nsucc, nskip, _ := ts.monitor.sum(static.ID) @@ -151,7 +151,7 @@ func (ts *Tasks) addSubBar(t *task.Task) { mpb.PrependDecorators( decor.Name(" + "), decor.Name(t.Subname()+" "), - decor.Any(ts.displayReplicas(t), decor.WCSyncWidthR), + decor.Any(ts.displayInstances(t), decor.WCSyncWidthR), decor.Name(" "), decor.OnComplete(decor.Spinner([]string{}), ""), decor.Any(ts.displayStatus()), diff --git a/internal/tools/ssh.go b/internal/tools/ssh.go index 25f1a19b7..ec516018c 100644 --- a/internal/tools/ssh.go +++ b/internal/tools/ssh.go @@ -40,9 +40,9 @@ const ( TEMPLATE_SCP = `scp -P {{.port}} {{or .options ""}} {{.source}} {{.user}}@{{.host}}:{{.target}}` TEMPLATE_SSH_COMMAND = `ssh {{.user}}@{{.host}} -p {{.port}} {{or .options ""}} {{or .become ""}} {{.command}}` TEMPLATE_SSH_ATTACH = `ssh -tt {{.user}}@{{.host}} -p {{.port}} {{or .options ""}} {{or .become ""}} {{.command}}` - TEMPLATE_COMMAND_EXEC_CONTAINER = `{{.sudo}} docker exec -it {{.container_id}} /bin/bash -c "cd {{.home_dir}}; /bin/bash"` - TEMPLATE_LOCAL_EXEC_CONTAINER = `docker exec -it {{.container_id}} /bin/bash` // FIXME: merge it - TEMPLATE_COMMAND_EXEC_CONTAINER_NOATTACH = `{{.sudo}} docker exec -t {{.container_id}} /bin/bash -c "{{.command}}"` + TEMPLATE_COMMAND_EXEC_CONTAINER = `{{.sudo}} {{.engine}} exec -it {{.container_id}} /bin/bash -c "cd {{.home_dir}}; /bin/bash"` + TEMPLATE_LOCAL_EXEC_CONTAINER = `{{.engine}} exec -it {{.container_id}} /bin/bash` // FIXME: merge it + TEMPLATE_COMMAND_EXEC_CONTAINER_NOATTACH = `{{.sudo}} {{.engine}} exec -t {{.container_id}} /bin/bash -c "{{.command}}"` ) func prepareOptions(curveadm *cli.CurveAdm, host string, become bool, extra map[string]interface{}) (map[string]interface{}, error) { @@ -138,6 +138,7 @@ func AttachRemoteHost(curveadm *cli.CurveAdm, host string, become bool) error { func AttachRemoteContainer(curveadm *cli.CurveAdm, host, containerId, home string) error { data := map[string]interface{}{ "sudo": curveadm.Config().GetSudoAlias(), + "engine": curveadm.Config().GetEngine(), "container_id": containerId, "home_dir": home, } @@ -159,6 +160,7 @@ func AttachRemoteContainer(curveadm *cli.CurveAdm, host, containerId, home strin func AttachLocalContainer(curveadm *cli.CurveAdm, containerId string) error { data := map[string]interface{}{ "container_id": containerId, + "engine": curveadm.Config().GetEngine(), } tmpl := template.Must(template.New("command").Parse(TEMPLATE_LOCAL_EXEC_CONTAINER)) buffer := bytes.NewBufferString("") @@ -172,6 +174,7 @@ func AttachLocalContainer(curveadm *cli.CurveAdm, containerId string) error { func ExecCmdInRemoteContainer(curveadm *cli.CurveAdm, host, containerId, cmd string) error { data := map[string]interface{}{ "sudo": curveadm.Config().GetSudoAlias(), + "engine": curveadm.Config().GetEngine(), "container_id": containerId, "command": cmd, } diff --git a/internal/tui/service/status.go b/internal/tui/service/status.go index 05fc5f06f..0b16c4c8f 100644 --- a/internal/tui/service/status.go +++ b/internal/tui/service/status.go @@ -58,7 +58,7 @@ const ( STATUS_CLEANED = comm.SERVICE_STATUS_CLEANED STATUS_LOSED = comm.SERVICE_STATUS_LOSED STATUS_UNKNWON = comm.SERVICE_STATUS_UNKNOWN - // for replica merged status + // for instance merged status STATUS_RUNNING = "RUNNING" STATUS_STOPPED = "STOPPED" STATUS_ABNORMAL = "ABNORMAL" @@ -95,7 +95,7 @@ func sortStatues(statuses []task.ServiceStatus) { c1, c2 := s1.Config, s2.Config if s1.Role == s2.Role { if c1.GetHostSequence() == c2.GetHostSequence() { - return c1.GetReplicasSequence() < c2.GetReplicasSequence() + return c1.GetInstancesSequence() < c2.GetInstancesSequence() } return c1.GetHostSequence() < c2.GetHostSequence() } @@ -107,7 +107,7 @@ func id(items []string) string { if len(items) == 1 { return items[0] } - return "" + return "" } func status(items []string) string { @@ -194,7 +194,7 @@ func mergeStatues(statuses []task.ServiceStatus) []task.ServiceStatus { Id: merge(statuses[i:j], ITEM_ID), Role: status.Role, Host: status.Host, - Replica: fmt.Sprintf("%d/%s", j-i, strings.Split(status.Replica, "/")[1]), + Instances: fmt.Sprintf("%d/%s", j-i, strings.Split(status.Instances, "/")[1]), ContainerId: merge(statuses[i:j], ITEM_CONTAINER_ID), Status: merge(statuses[i:j], ITEM_STATUS), Ports: merge(statuses[i:j], ITEM_PORTS), @@ -214,7 +214,7 @@ func FormatStatus(statuses []task.ServiceStatus, verbose, expand bool) string { "Id", "Role", "Host", - "Replicas", + "Instances", "Container Id", "Status", "Ports", @@ -235,7 +235,7 @@ func FormatStatus(statuses []task.ServiceStatus, verbose, expand bool) string { status.Id, status.Role, status.Host, - status.Replica, + status.Instances, status.ContainerId, tui.DecorateMessage{Message: status.Status, Decorate: statusDecorate}, utils.Choose(len(status.Ports) == 0, "-", status.Ports), @@ -260,7 +260,7 @@ func sortMonitorStatues(statuses []monitor.MonitorStatus) { sort.Slice(statuses, func(i, j int) bool { s1, s2 := statuses[i], statuses[j] if s1.Role == s2.Role { - return s1.Host < s1.Host + return s1.Host < s2.Host } return MONITOT_ROLE_SCORE[s1.Role] < ROLE_SCORE[s2.Role] }) diff --git a/internal/utils/cobra.go b/internal/utils/cobra.go index 6693480fa..d5b4afcec 100644 --- a/internal/utils/cobra.go +++ b/internal/utils/cobra.go @@ -25,7 +25,6 @@ package utils import ( - "errors" "fmt" "io" @@ -145,7 +144,7 @@ func SetFlagErrorFunc(cmd *cobra.Command) { return nil } - return errors.New(fmt.Sprintf("%s\nSee '%s --help'.", err, cmd.CommandPath())) + return fmt.Errorf("%s\nSee '%s --help'.", err, cmd.CommandPath()) }) } diff --git a/internal/utils/common.go b/internal/utils/common.go index be9aae86a..618bbe436 100644 --- a/internal/utils/common.go +++ b/internal/utils/common.go @@ -145,7 +145,7 @@ func Str2Bool(s string) (bool, bool) { // value, ok func IsTrueStr(s string) bool { v, yes := Str2Bool(s) - return yes && v == true + return yes && v } func TrimSuffixRepeat(s, suffix string) string { diff --git a/internal/utils/map.go b/internal/utils/map.go index 0be87594d..f7d2de490 100644 --- a/internal/utils/map.go +++ b/internal/utils/map.go @@ -40,12 +40,12 @@ func NewSafeMap() *SafeMap { func (m *SafeMap) Get(key string) interface{} { if m.transaction { - val, _ := m.Map[key] + val := m.Map[key] return val } m.RLock() defer m.RUnlock() - val, _ := m.Map[key] + val := m.Map[key] return val } diff --git a/pkg/log/glg/log.go b/pkg/log/glg/log.go index 5846d12b6..16b45ce76 100644 --- a/pkg/log/glg/log.go +++ b/pkg/log/glg/log.go @@ -49,7 +49,6 @@ func convertLevel(level string) glg.LEVEL { default: return glg.DEBG } - return glg.DEBG } func Init(level, filename string) error { @@ -68,18 +67,18 @@ func Init(level, filename string) error { } func Field(key string, val interface{}) string { - switch val.(type) { + switch val := val.(type) { case bool: - return fmt.Sprintf("%s: %s", key, strconv.FormatBool(val.(bool))) + return fmt.Sprintf("%s: %s", key, strconv.FormatBool(val)) case string: return fmt.Sprintf("%s: %s", key, val) case []byte: - return fmt.Sprintf("%s: %s", key, string(val.([]byte))) + return fmt.Sprintf("%s: %s", key, string(val)) case int: case int64: return fmt.Sprintf("%s: %d", key, val) case error: - return fmt.Sprintf("%s: %s", key, val.(error).Error()) + return fmt.Sprintf("%s: %s", key, val.Error()) } return fmt.Sprintf("%s: %v", key, val) } diff --git a/pkg/log/log.go b/pkg/log/log.go index eb67ca580..b91b9f894 100644 --- a/pkg/log/log.go +++ b/pkg/log/log.go @@ -59,19 +59,19 @@ func SwitchLevel(err error) func(msg string, fields ...zap.Field) { } func Field(key string, val interface{}) zap.Field { - switch val.(type) { + switch val := val.(type) { case bool: - return zap.Bool(key, val.(bool)) + return zap.Bool(key, val) case string: - return zap.String(key, val.(string)) + return zap.String(key, val) case []byte: - return zap.String(key, string(val.([]byte))) + return zap.String(key, string(val)) case int: - return zap.Int(key, val.(int)) + return zap.Int(key, val) case int64: - return zap.Int64(key, val.(int64)) + return zap.Int64(key, val) case error: - return zap.String(key, val.(error).Error()) + return zap.String(key, val.Error()) } return zap.Skip() } diff --git a/pkg/log/zaplog/log.go b/pkg/log/zaplog/log.go index 76e22b69d..8d553ca95 100644 --- a/pkg/log/zaplog/log.go +++ b/pkg/log/zaplog/log.go @@ -61,19 +61,19 @@ func SwitchLevel(err error) func(msg string, fields ...zap.Field) { } func Field(key string, val interface{}) zap.Field { - switch val.(type) { + switch val := val.(type) { case bool: - return zap.Bool(key, val.(bool)) + return zap.Bool(key, val) case string: - return zap.String(key, val.(string)) + return zap.String(key, val) case []byte: - return zap.String(key, string(val.([]byte))) + return zap.String(key, string(val)) case int: - return zap.Int(key, val.(int)) + return zap.Int(key, val) case int64: - return zap.Int64(key, val.(int64)) + return zap.Int64(key, val) case error: - return zap.String(key, val.(error).Error()) + return zap.String(key, val.Error()) } return zap.Skip() } diff --git a/pkg/module/docker_cli.go b/pkg/module/docker_cli.go index 79b927d86..1668a2311 100644 --- a/pkg/module/docker_cli.go +++ b/pkg/module/docker_cli.go @@ -31,21 +31,21 @@ import ( ) const ( - TEMPLATE_DOCKER_INFO = "docker info" - TEMPLATE_PULL_IMAGE = "docker pull {{.options}} {{.name}}" - TEMPLATE_CREATE_CONTAINER = "docker create {{.options}} {{.image}} {{.command}}" - TEMPLATE_START_CONTAINER = "docker start {{.options}} {{.containers}}" - TEMPLATE_STOP_CONTAINER = "docker stop {{.options}} {{.containers}}" - TEMPLATE_RESTART_CONTAINER = "docker restart {{.options}} {{.containers}}" - TEMPLATE_WAIT_CONTAINER = "docker wait {{.options}} {{.containers}}" - TEMPLATE_REMOVE_CONTAINER = "docker rm {{.options}} {{.containers}}" - TEMPLATE_LIST_CONTAINERS = "docker ps {{.options}}" - TEMPLATE_CONTAINER_EXEC = "docker exec {{.options}} {{.container}} {{.command}}" - TEMPLATE_COPY_FROM_CONTAINER = "docker cp {{.options}} {{.container}}:{{.srcPath}} {{.destPath}}" - TEMPLATE_COPY_INTO_CONTAINER = "docker cp {{.options}} {{.srcPath}} {{.container}}:{{.destPath}}" - TEMPLATE_INSPECT_CONTAINER = "docker inspect {{.options}} {{.container}}" - TEMPLATE_CONTAINER_LOGS = "docker logs {{.options}} {{.container}}" - TEMPLATE_UPDATE_CONTAINER = "docker update {{.options}} {{.container}}" + TEMPLATE_DOCKER_INFO = "{{.engine}} info" + TEMPLATE_PULL_IMAGE = "{{.engine}} pull {{.options}} {{.name}}" + TEMPLATE_CREATE_CONTAINER = "{{.engine}} create {{.options}} {{.image}} {{.command}}" + TEMPLATE_START_CONTAINER = "{{.engine}} start {{.options}} {{.containers}}" + TEMPLATE_STOP_CONTAINER = "{{.engine}} stop {{.options}} {{.containers}}" + TEMPLATE_RESTART_CONTAINER = "{{.engine}} restart {{.options}} {{.containers}}" + TEMPLATE_WAIT_CONTAINER = "{{.engine}} wait {{.options}} {{.containers}}" + TEMPLATE_REMOVE_CONTAINER = "{{.engine}} rm {{.options}} {{.containers}}" + TEMPLATE_LIST_CONTAINERS = "{{.engine}} ps {{.options}}" + TEMPLATE_CONTAINER_EXEC = "{{.engine}} exec {{.options}} {{.container}} {{.command}}" + TEMPLATE_COPY_FROM_CONTAINER = "{{.engine}} cp {{.options}} {{.container}}:{{.srcPath}} {{.destPath}}" + TEMPLATE_COPY_INTO_CONTAINER = "{{.engine}} cp {{.options}} {{.srcPath}} {{.container}}:{{.destPath}}" + TEMPLATE_INSPECT_CONTAINER = "{{.engine}} inspect {{.options}} {{.container}}" + TEMPLATE_CONTAINER_LOGS = "{{.engine}} logs {{.options}} {{.container}}" + TEMPLATE_UPDATE_CONTAINER = "{{.engine}} update {{.options}} {{.container}}" ) type DockerCli struct { @@ -71,6 +71,7 @@ func (s *DockerCli) AddOption(format string, args ...interface{}) *DockerCli { func (cli *DockerCli) Execute(options ExecOptions) (string, error) { cli.data["options"] = strings.Join(cli.options, " ") + cli.data["engine"] = options.ExecWithEngine return execCommand(cli.sshClient, cli.tmpl, cli.data, options) } diff --git a/pkg/module/module.go b/pkg/module/module.go index 9d82a7fe5..72618e822 100644 --- a/pkg/module/module.go +++ b/pkg/module/module.go @@ -47,6 +47,7 @@ type ( ExecInLocal bool ExecSudoAlias string ExecTimeoutSec int + ExecWithEngine string } TimeoutError struct { diff --git a/pkg/module/ssh.go b/pkg/module/ssh.go index 4e8abf889..8f2d47f79 100644 --- a/pkg/module/ssh.go +++ b/pkg/module/ssh.go @@ -72,7 +72,7 @@ func VerifyHost(host string, remote net.Addr, key ssh.PublicKey) error { return err } else if hostFound && err == nil { // handshake because public key already exists. return nil - } else if askIsHostTrusted(host, key) == false { // Ask user to check if he trust the host public key. + } else if !askIsHostTrusted(host, key) { // Ask user to check if he trust the host public key. // Make sure to return error on non trusted keys. return errors.New("you typed no, aborted!") } diff --git a/pkg/variable/variables.go b/pkg/variable/variables.go index a22fe1937..71defa40e 100644 --- a/pkg/variable/variables.go +++ b/pkg/variable/variables.go @@ -67,7 +67,7 @@ func (vars *Variables) Get(name string) (string, error) { v, ok := vars.m[name] if !ok { return "", fmt.Errorf("variable '%s' not found", name) - } else if v.Resolved == false { + } else if !v.Resolved { return "", fmt.Errorf("variable '%s' unresolved", name) } @@ -152,6 +152,9 @@ func (vars *Variables) Rendering(s string) (string, error) { func (vars *Variables) Debug() { for _, v := range vars.m { - log.Info("Variable", log.Field(v.Name, v.Value)) + err := log.Info("Variable", log.Field(v.Name, v.Value)) + if err != nil { + return + } } } diff --git a/playbook/memcached/hosts.yaml b/playbook/memcached/hosts.yaml index bc6be31cf..ee69994cc 100644 --- a/playbook/memcached/hosts.yaml +++ b/playbook/memcached/hosts.yaml @@ -10,6 +10,7 @@ hosts: - memcached envs: - SUDO_ALIAS=sudo + - ENGINE=docker - IMAGE=memcached:1.6.17 - LISTEN=10.0.1.1 - PORT=11211 @@ -28,6 +29,7 @@ hosts: - memcached envs: - SUDO_ALIAS=sudo + - ENGINE=docker - IMAGE=memcached:1.6.17 - LISTEN=10.0.1.2 - PORT=11211 @@ -46,6 +48,7 @@ hosts: - memcached envs: - SUDO_ALIAS=sudo + - ENGINE=docker - IMAGE=memcached:1.6.17 - LISTEN=10.0.1.3 - PORT=11211 diff --git a/playbook/memcached/scripts/clean.sh b/playbook/memcached/scripts/clean.sh index 84fbe15e9..84e0f2a6a 100644 --- a/playbook/memcached/scripts/clean.sh +++ b/playbook/memcached/scripts/clean.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash g_container_name="memcached-"${PORT} -g_docker_cmd="${SUDO_ALIAS} docker" +g_docker_cmd="${SUDO_ALIAS} ${ENGINE}" g_rm_cmd="${SUDO_ALIAS} rm -rf" function msg() { diff --git a/playbook/memcached/scripts/deploy.sh b/playbook/memcached/scripts/deploy.sh index deda5f5f3..f2c48b165 100644 --- a/playbook/memcached/scripts/deploy.sh +++ b/playbook/memcached/scripts/deploy.sh @@ -2,7 +2,7 @@ g_container_name="memcached-"${PORT} g_start_args="" -g_docker_cmd="${SUDO_ALIAS} docker" +g_docker_cmd="${SUDO_ALIAS} ${ENGINE}" g_lsof_cmd="${SUDO_ALIAS} lsof" g_rm_cmd="${SUDO_ALIAS} rm -rf" g_mkdir_cmd="${SUDO_ALIAS} mkdir -p" diff --git a/playbook/memcached/scripts/start.sh b/playbook/memcached/scripts/start.sh index cf8c4f69c..9c7c380fa 100644 --- a/playbook/memcached/scripts/start.sh +++ b/playbook/memcached/scripts/start.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash g_container_name="memcached-"${PORT} -g_docker_cmd="${SUDO_ALIAS} docker" +g_docker_cmd="${SUDO_ALIAS} ${ENGINE}" g_rm_cmd="${SUDO_ALIAS} rm -rf" g_mkdir_cmd="${SUDO_ALIAS} mkdir -p" g_touch_cmd="${SUDO_ALIAS} touch" diff --git a/playbook/memcached/scripts/status.sh b/playbook/memcached/scripts/status.sh index eca3918e0..ed875ec85 100644 --- a/playbook/memcached/scripts/status.sh +++ b/playbook/memcached/scripts/status.sh @@ -2,7 +2,7 @@ g_container_name="memcached-"${PORT} g_start_args="" -g_docker_cmd="${SUDO_ALIAS} docker" +g_docker_cmd="${SUDO_ALIAS} ${ENGINE}" g_volume_bind="" g_container_id="" g_status="running" diff --git a/playbook/memcached/scripts/stop.sh b/playbook/memcached/scripts/stop.sh index 117e4ac99..2dc84e53f 100644 --- a/playbook/memcached/scripts/stop.sh +++ b/playbook/memcached/scripts/stop.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash g_container_name="memcached-"${PORT} -g_docker_cmd="${SUDO_ALIAS} docker" +g_docker_cmd="${SUDO_ALIAS} ${ENGINE}" function msg() { printf '%b' "$1" >&2