diff --git a/cmd/run.go b/cmd/run.go index 7f01380..9fef71b 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -13,8 +13,8 @@ import ( ) func NewRunCmd() *cobra.Command { - restartOpts := options.RestartOptionsInstance rootOpts := options.RootOptionsInstance + restartOpts := options.RestartOptionsInstance restarter := restarters.NewRunRestarter(options.Logger) cmd := cli.SetDefaultsOn(&cobra.Command{ diff --git a/pkg/options/restart.go b/pkg/options/restart.go index 6e67b2e..a8456ad 100644 --- a/pkg/options/restart.go +++ b/pkg/options/restart.go @@ -22,6 +22,7 @@ const ( DefaultRetryCount = 3 DefaultRestartDurationSeconds = 60 DefaultCMSQueryIntervalSeconds = 10 + DefaultMaxStaticNodeId = 50000 ) var AvailabilityModes = []string{"strong", "weak", "force"} @@ -62,6 +63,8 @@ type RestartOptions struct { KubeconfigPath string K8sNamespace string + + MaxStaticNodeId int } var ( @@ -81,6 +84,10 @@ func (o *RestartOptions) Validate() error { return fmt.Errorf("specified --kubeconfig, but not --k8s-namespace") } + if o.MaxStaticNodeId < 0 { + return fmt.Errorf("specified invalid max-static-node-id: %d. Must be positive", o.MaxStaticNodeId) + } + if o.RestartDuration < 0 { return fmt.Errorf("specified invalid restart duration seconds: %d. Must be positive", o.RestartDuration) } @@ -204,6 +211,10 @@ after that would be considered a regular cluster failure`) for this invocation must be the same as for the previous invocation, and this can not be verified at runtime since the ydbops utility is stateless. Use at your own risk.`) + fs.IntVar(&o.MaxStaticNodeId, "max-static-node-id", DefaultMaxStaticNodeId, + `This argument is used to help ydbops distinguish storage and dynamic nodes. +Nodes with this nodeId or less will be considered storage.`) + profile.PopulateFromProfileLater( fs.StringVar, &o.KubeconfigPath, "kubeconfig", "", diff --git a/pkg/rolling/restarters/interface.go b/pkg/rolling/restarters/interface.go index c8c28c8..0ddb8d2 100644 --- a/pkg/rolling/restarters/interface.go +++ b/pkg/rolling/restarters/interface.go @@ -26,4 +26,5 @@ type FilterNodeParams struct { SelectedTenants []string SelectedNodeIds []uint32 SelectedHosts []string + MaxStaticNodeId uint32 } diff --git a/pkg/rolling/restarters/primitives.go b/pkg/rolling/restarters/primitives.go index d73c215..49980a0 100644 --- a/pkg/rolling/restarters/primitives.go +++ b/pkg/rolling/restarters/primitives.go @@ -14,10 +14,10 @@ import ( "github.com/ydb-platform/ydbops/pkg/options" ) -func FilterStorageNodes(nodes []*Ydb_Maintenance.Node) []*Ydb_Maintenance.Node { +func FilterStorageNodes(nodes []*Ydb_Maintenance.Node, maxStaticNodeId uint32) []*Ydb_Maintenance.Node { return collections.FilterBy(nodes, func(node *Ydb_Maintenance.Node) bool { - return node.GetStorage() != nil + return node.GetStorage() != nil && node.NodeId < maxStaticNodeId }, ) } diff --git a/pkg/rolling/restarters/run.go b/pkg/rolling/restarters/run.go index 484dc92..60d399c 100644 --- a/pkg/rolling/restarters/run.go +++ b/pkg/rolling/restarters/run.go @@ -63,7 +63,7 @@ func (r *RunRestarter) Filter(spec FilterNodeParams, cluster ClusterNodesInfo) [ var runScopeNodes []*Ydb_Maintenance.Node if r.storageOnly { - storageNodes := FilterStorageNodes(cluster.AllNodes) + storageNodes := FilterStorageNodes(cluster.AllNodes, spec.MaxStaticNodeId) runScopeNodes = PopulateByCommonFields(storageNodes, spec) } else if r.dynnodeOnly { tenantNodes := FilterTenantNodes(cluster.AllNodes) diff --git a/pkg/rolling/restarters/storage_k8s.go b/pkg/rolling/restarters/storage_k8s.go index d0ac0c0..73d5bb1 100644 --- a/pkg/rolling/restarters/storage_k8s.go +++ b/pkg/rolling/restarters/storage_k8s.go @@ -69,7 +69,7 @@ func (r *StorageK8sRestarter) Filter( r.prepareK8sState(r.Opts.kubeconfigPath, storageLabelSelector, r.Opts.namespace) - allStorageNodes := FilterStorageNodes(cluster.AllNodes) + allStorageNodes := FilterStorageNodes(cluster.AllNodes, spec.MaxStaticNodeId) selectedNodes := populateWithK8sRules(allStorageNodes, spec, r.FQDNToPodName) diff --git a/pkg/rolling/restarters/storage_ssh.go b/pkg/rolling/restarters/storage_ssh.go index 6e01660..5a2ab77 100644 --- a/pkg/rolling/restarters/storage_ssh.go +++ b/pkg/rolling/restarters/storage_ssh.go @@ -38,7 +38,7 @@ func (r StorageSSHRestarter) Filter( spec FilterNodeParams, cluster ClusterNodesInfo, ) []*Ydb_Maintenance.Node { - storageNodes := FilterStorageNodes(cluster.AllNodes) + storageNodes := FilterStorageNodes(cluster.AllNodes, spec.MaxStaticNodeId) preSelectedNodes := PopulateByCommonFields(storageNodes, spec) diff --git a/pkg/rolling/rolling.go b/pkg/rolling/rolling.go index 75bbbd4..daf9ab0 100644 --- a/pkg/rolling/rolling.go +++ b/pkg/rolling/rolling.go @@ -108,6 +108,7 @@ func (r *Rolling) DoRestart() error { StartedTime: r.opts.StartedTime, Version: r.opts.VersionSpec, ExcludeHosts: r.opts.ExcludeHosts, + MaxStaticNodeId: uint32(r.opts.MaxStaticNodeId), }, restarters.ClusterNodesInfo{ TenantToNodeIds: r.state.tenantNameToNodeIds, diff --git a/tests/filtering_test.go b/tests/filtering_test.go index 1001f6d..f79ef71 100644 --- a/tests/filtering_test.go +++ b/tests/filtering_test.go @@ -40,6 +40,7 @@ var _ = Describe("Test storage Filter", func() { nodes := mock.CreateNodesFromShortConfig(nodeGroups, nodeInfoMap) filterSpec := restarters.FilterNodeParams{ + MaxStaticNodeId: options.DefaultMaxStaticNodeId, StartedTime: &options.StartedTime{ Direction: '<', Timestamp: fiveMinutesAgoTimestamp, @@ -89,8 +90,9 @@ var _ = Describe("Test storage Filter", func() { nodes := mock.CreateNodesFromShortConfig(nodeGroups, nodeInfoMap) - // empty params equivalent to no arguments - filterSpec := restarters.FilterNodeParams{} + filterSpec := restarters.FilterNodeParams{ + MaxStaticNodeId: options.DefaultMaxStaticNodeId, + } clusterInfo := restarters.ClusterNodesInfo{ AllNodes: nodes, diff --git a/tests/run_e2e_test.go b/tests/run_e2e_test.go index aaf11a5..0340ba3 100644 --- a/tests/run_e2e_test.go +++ b/tests/run_e2e_test.go @@ -112,7 +112,6 @@ func RunTestCase(tc TestCase) { ), ) maintenanceTaskId = uuidOnlyRegexp.FindString(output) - fmt.Printf("DETERMINED taskId %s\n", maintenanceTaskId) } r := regexp.MustCompile(expectedOutputRegexp)