diff --git a/commands/cmd_base.go b/commands/cmd_base.go index 94cbaa5..aadde2e 100644 --- a/commands/cmd_base.go +++ b/commands/cmd_base.go @@ -28,7 +28,7 @@ import ( ) const ( - outputFilePerm = 0600 + outputFilePerm = 0644 ) /* CmdBase diff --git a/commands/cmd_show_restore_points.go b/commands/cmd_show_restore_points.go index 7b00537..d65b861 100644 --- a/commands/cmd_show_restore_points.go +++ b/commands/cmd_show_restore_points.go @@ -16,6 +16,8 @@ package commands import ( + "encoding/json" + "github.com/spf13/cobra" "github.com/vertica/vcluster/vclusterops" "github.com/vertica/vcluster/vclusterops/vlog" @@ -163,6 +165,11 @@ func (c *CmdShowRestorePoints) Run(vcc vclusterops.ClusterCommands) error { vcc.LogError(err, "fail to show restore points", "DBName", options.DBName) return err } + bytes, err := json.MarshalIndent(restorePoints, "", " ") + if err != nil { + return err + } + c.writeCmdOutputToFile(globals.file, bytes, vcc.GetLog()) vcc.PrintInfo("Successfully show restore points %v in database %s", restorePoints, options.DBName) return nil diff --git a/commands/vcluster_config.go b/commands/vcluster_config.go index b4c15e7..09dac52 100644 --- a/commands/vcluster_config.go +++ b/commands/vcluster_config.go @@ -33,7 +33,7 @@ const ( // default file name that we'll use. defConfigFileName = "vertica_cluster.yaml" currentConfigFileVersion = "1.0" - configFilePerm = 0600 + configFilePerm = 0644 ) // Config is the struct of vertica_cluster.yaml diff --git a/vclusterops/https_check_db_running_op.go b/vclusterops/https_check_db_running_op.go index 551f652..2bde78f 100644 --- a/vclusterops/https_check_db_running_op.go +++ b/vclusterops/https_check_db_running_op.go @@ -34,6 +34,7 @@ const ( StartDB ReviveDB StopSC + ReIP checkDBRunningOpName = "HTTPSCheckDBRunningOp" checkDBRunningOpDesc = "Verify database is running" @@ -51,6 +52,8 @@ func (op opType) String() string { return "Revive DB" case StopSC: return "Stop Subcluster" + case ReIP: + return "Re-ip Hosts" } return "unknown operation" } @@ -218,6 +221,10 @@ func (op *httpsCheckRunningDBOp) isDBRunningOnHost(host string, op.name, host) case StopDB, StartDB, ReviveDB, StopSC: msg = fmt.Sprintf("[%s] Detected HTTPS service running on host %s", op.name, host) + case ReIP: + msg = fmt.Sprintf(`[%s] Detected HTTPS service running on host %s, + please consider using start_node to re-ip nodes for the running database`, + op.name, host) } // check whether the node is starting and hasn't pulled the latest catalog yet rfcError := &rfc7807.VProblem{} @@ -352,6 +359,10 @@ func (op *httpsCheckRunningDBOp) handleDBRunning(allErrs error, msg string, upHo const reviveDBMsg = "aborting database revival" op.logger.PrintInfo(reviveDBMsg) op.updateSpinnerMessage(reviveDBMsg) + case ReIP: + const reIPMsg = "aborting re-ip hosts" + op.logger.PrintInfo(reIPMsg) + op.updateSpinnerMessage(reIPMsg) } // when db is running, append an error to allErrs for stopping VClusterOpEngine @@ -401,7 +412,7 @@ func (op *httpsCheckRunningDBOp) checkProcessedResult(sandboxedHosts map[string] func (op *httpsCheckRunningDBOp) execute(execContext *opEngineExecContext) error { op.logger.Info("Execute() called", "opType", op.opType) switch op.opType { - case CreateDB, StartDB, ReviveDB: + case CreateDB, StartDB, ReviveDB, ReIP: return op.checkDBConnection(execContext) case StopDB, StopSC: return op.pollForDBDown(execContext) diff --git a/vclusterops/re_ip.go b/vclusterops/re_ip.go index de43187..49cf21a 100644 --- a/vclusterops/re_ip.go +++ b/vclusterops/re_ip.go @@ -187,6 +187,17 @@ func (vcc VClusterCommands) produceReIPInstructions(options *VReIPOptions, vdb * nmaHealthOp := makeNMAHealthOp(hosts) + // Re-IP should only be used for down DB, checking if db is running + checkDBRunningOp, err := makeHTTPSCheckRunningDBOp(hosts, + options.usePassword, options.UserName, options.Password, ReIP) + if err != nil { + return instructions, err + } + instructions = append(instructions, + &nmaHealthOp, + &checkDBRunningOp, + ) + // get network profiles of the new addresses var newAddresses []string for _, info := range options.ReIPList { @@ -194,10 +205,7 @@ func (vcc VClusterCommands) produceReIPInstructions(options *VReIPOptions, vdb * } nmaNetworkProfileOp := makeNMANetworkProfileOp(newAddresses) - instructions = append(instructions, - &nmaHealthOp, - &nmaNetworkProfileOp, - ) + instructions = append(instructions, &nmaNetworkProfileOp) vdbWithPrimaryNodes := new(VCoordinationDatabase) // When we cannot get db info from cluster_config.json, we will fetch it from NMA /nodes endpoint. diff --git a/vclusterops/unsandbox.go b/vclusterops/unsandbox.go index 018b44d..b1bc000 100644 --- a/vclusterops/unsandbox.go +++ b/vclusterops/unsandbox.go @@ -116,11 +116,15 @@ func (vcc *VClusterCommands) unsandboxPreCheck(vdb *VCoordinationDatabase, optio scFound := false var sandboxedHosts []string + upHosts := []string{} for _, vnode := range vdb.HostNodeMap { if !scFound && vnode.Subcluster == options.SCName { scFound = true } + if vnode.State != util.NodeDownState { + upHosts = append(upHosts, vnode.Address) + } if vnode.Subcluster == options.SCName { // if the subcluster is not sandboxed, return error immediately if vnode.Sandbox == "" { @@ -134,6 +138,8 @@ func (vcc *VClusterCommands) unsandboxPreCheck(vdb *VCoordinationDatabase, optio } } } + // change hosts in options to all up hosts so the user can only provide hosts in main cluster + options.Hosts = upHosts if !scFound { vcc.Log.PrintError(`subcluster '%s' does not exist`, options.SCName)