diff --git a/vclusterops/create_db.go b/vclusterops/create_db.go index 2e8f442..20c2716 100644 --- a/vclusterops/create_db.go +++ b/vclusterops/create_db.go @@ -539,8 +539,8 @@ func (vcc *VClusterCommands) produceCreateDBBootstrapInstructions( nmaStartNodeOp := makeNMAStartNodeOp(vcc.Log, bootstrapHost, *options.StartUpConf) - httpsPollBootstrapNodeStateOp, err := makeHTTPSPollNodeStateOp(vcc.Log, bootstrapHost, true, /* useHTTPPassword */ - *options.UserName, options.Password) + httpsPollBootstrapNodeStateOp, err := makeHTTPSPollNodeStateOpWithTimeoutAndCommand(vcc.Log, bootstrapHost, true, /* useHTTPPassword */ + *options.UserName, options.Password, *options.TimeoutNodeStartupSeconds, CreateDBCmd) if err != nil { return instructions, err } @@ -621,7 +621,8 @@ func (vcc *VClusterCommands) produceAdditionalCreateDBInstructions(vdb *VCoordin username := *options.UserName if !*options.SkipStartupPolling { - httpsPollNodeStateOp, err := makeHTTPSPollNodeStateOp(vcc.Log, hosts, true, username, options.Password) + httpsPollNodeStateOp, err := makeHTTPSPollNodeStateOpWithTimeoutAndCommand(vcc.Log, hosts, true, username, options.Password, + *options.TimeoutNodeStartupSeconds, CreateDBCmd) if err != nil { return instructions, err } diff --git a/vclusterops/https_poll_node_state_op.go b/vclusterops/https_poll_node_state_op.go index 4f7ceec..1c0c23f 100644 --- a/vclusterops/https_poll_node_state_op.go +++ b/vclusterops/https_poll_node_state_op.go @@ -31,6 +31,7 @@ const httpRequestTimeoutSeconds = 30 const ( StartDBCmd CmdType = iota StartNodeCmd + CreateDBCmd ) type CmdType int @@ -41,6 +42,8 @@ func (cmd CmdType) String() string { return "start_db" case StartNodeCmd: return "restart_node" + case CreateDBCmd: + return "create_db" } return "unknown_operation" } @@ -100,7 +103,6 @@ func makeHTTPSPollNodeStateOp(logger vlog.Printer, hosts []string, } func (op *httpsPollNodeStateOp) getPollingTimeout() int { - // a negative value indicates no timeout and should never be used for this op return util.Max(op.timeout, 0) } @@ -175,9 +177,10 @@ func (op *httpsPollNodeStateOp) shouldStopPolling() (bool, error) { op.name) return true, fmt.Errorf("[%s] wrong password/certificate for https service on host %s, but the nodes' startup have been in progress."+ "Please use vsql to check the nodes' status and manually run sync_catalog vsql command 'select sync_catalog()'", op.name, host) + case CreateDBCmd: + return true, fmt.Errorf("[%s] wrong password/certificate for https service on host %s", + op.name, host) } - return true, fmt.Errorf("[%s] wrong password/certificate for https service on host %s", - op.name, host) } if result.isPassing() { // parse the /nodes/{node} endpoint response diff --git a/vclusterops/https_poll_node_state_op_test.go b/vclusterops/https_poll_node_state_op_test.go index 19c29ed..c793f40 100644 --- a/vclusterops/https_poll_node_state_op_test.go +++ b/vclusterops/https_poll_node_state_op_test.go @@ -22,7 +22,7 @@ import ( "github.com/vertica/vcluster/vclusterops/vlog" ) -func TestTimeoutCase(t *testing.T) { +func TestTimeoutErrorCase(t *testing.T) { var instructions []clusterOp // use a non-existing IP to test the timeout error // 192.0.2.1 is one that is reserved for test purpose (by RFC 5737) @@ -33,8 +33,21 @@ func TestTimeoutCase(t *testing.T) { assert.Nil(t, err) instructions = append(instructions, &httpsPollNodeStateOp) + // default timeout value for the op certs := httpsCerts{} clusterOpEngine := makeClusterOpEngine(instructions, &certs) err = clusterOpEngine.run(vlog.Printer{}) + // expect timeout error in http response assert.ErrorContains(t, err, "[HTTPSPollNodeStateOp] cannot connect to host 192.0.2.1, please check if the host is still alive") + + // negative timeout value for the op (treated as 0, means no polling) + instructions = make([]clusterOp, 0) + httpsPollNodeStateOp, err = makeHTTPSPollNodeStateOpWithTimeoutAndCommand(vlog.Printer{}, hosts, true, username, &password, + -100, CreateDBCmd) + assert.Nil(t, err) + instructions = append(instructions, &httpsPollNodeStateOp) + clusterOpEngine = makeClusterOpEngine(instructions, &certs) + err = clusterOpEngine.run(vlog.Printer{}) + // no polling is done, directly error out + assert.ErrorContains(t, err, "reached polling timeout of 0 seconds") } diff --git a/vclusterops/nma_show_restore_points_op.go b/vclusterops/nma_show_restore_points_op.go index 27784e3..c406b09 100644 --- a/vclusterops/nma_show_restore_points_op.go +++ b/vclusterops/nma_show_restore_points_op.go @@ -114,6 +114,8 @@ type RestorePoint struct { Index int // The timestamp when the restore point was created. Timestamp string + // The version of Vertica running when the restore point was created. + VerticaVersion string } func (op *nmaShowRestorePointsOp) processResult(execContext *opEngineExecContext) error { diff --git a/vclusterops/revive_db_test.go b/vclusterops/revive_db_test.go index 8e81a0c..1a6e47b 100644 --- a/vclusterops/revive_db_test.go +++ b/vclusterops/revive_db_test.go @@ -45,7 +45,7 @@ func TestFindSpecifiedRestorePoint(t *testing.T) { *options.RestorePoint.ID = expectedID _, err = options.findSpecifiedRestorePoint(allRestorePoints) expectedErr := fmt.Errorf("found 2 restore points instead of 1: " + - "[{Archive:archive1 ID:id3 Index:2 Timestamp:} {Archive:archive1 ID:id3 Index:3 Timestamp:}]") + "[{Archive:archive1 ID:id3 Index:2 Timestamp: VerticaVersion:} {Archive:archive1 ID:id3 Index:3 Timestamp: VerticaVersion:}]") assert.EqualError(t, err, expectedErr.Error()) // Test case: No matching restore points found