Skip to content

Commit

Permalink
Support old UpdateSelectors too
Browse files Browse the repository at this point in the history
  • Loading branch information
wilwell committed Feb 5, 2025
1 parent e9c82c1 commit 7cd5113
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 56 deletions.
31 changes: 22 additions & 9 deletions api/v1/ytsaurus_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ type YtsaurusSpec struct {
EnableFullUpdate bool `json:"enableFullUpdate"`
//+optional
//+optional
// Deprecated: UpdateSelector is an experimental field. Behaviour may change.
// Deprecated: UpdateSelector is going to be removed soon. Please use UpdateSelectors instead.
UpdateSelector UpdateSelector `json:"updateSelector"`

//+optional
Expand Down Expand Up @@ -761,6 +761,27 @@ type TabletCellBundleInfo struct {

type UpdateSelector string

const (
// UpdateSelectorUnspecified means that selector is disabled and would be ignored completely.
UpdateSelectorUnspecified UpdateSelector = ""
// UpdateSelectorNothing means that no component could be updated.
UpdateSelectorNothing UpdateSelector = "Nothing"
// UpdateSelectorMasterOnly means that only master could be updated.
UpdateSelectorMasterOnly UpdateSelector = "MasterOnly"
// UpdateSelectorTabletNodesOnly means that only data nodes could be updated
UpdateSelectorDataNodesOnly UpdateSelector = "DataNodesOnly"
// UpdateSelectorTabletNodesOnly means that only tablet nodes could be updated
UpdateSelectorTabletNodesOnly UpdateSelector = "TabletNodesOnly"
// UpdateSelectorExecNodesOnly means that only tablet nodes could be updated
UpdateSelectorExecNodesOnly UpdateSelector = "ExecNodesOnly"
// UpdateSelectorStatelessOnly means that only stateless components (everything but master, data nodes, and tablet nodes)
// could be updated.
UpdateSelectorStatelessOnly UpdateSelector = "StatelessOnly"
// UpdateSelectorEverything means that all components could be updated.
// With this setting and if master or tablet nodes need update all the components would be updated.
UpdateSelectorEverything UpdateSelector = "Everything"
)

type ComponentUpdateSelector struct {
//+optional
ComponentType consts.ComponentType `json:"componentType,omitempty"`
Expand All @@ -774,14 +795,6 @@ type ComponentUpdateSelector struct {

type UpdateFlow string

const (
UpdateFlowNone UpdateFlow = ""
UpdateFlowStateless UpdateFlow = "Stateless"
UpdateFlowMaster UpdateFlow = "Master"
UpdateFlowTabletNodes UpdateFlow = "TabletNodes"
UpdateFlowFull UpdateFlow = "Full"
)

type UpdateStatus struct {
//+kubebuilder:default:=None
State UpdateState `json:"state,omitempty"`
Expand Down
20 changes: 20 additions & 0 deletions api/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions config/crd/bases/cluster.ytsaurus.tech_ytsaurus.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39570,8 +39570,7 @@ spec:
uiImage:
type: string
updateSelector:
description: 'Deprecated: UpdateSelector is an experimental field.
Behaviour may change.'
description: 'Deprecated: UpdateSelector is going to be removed soon.'
type: string
updateSelectors:
description: Controls the components that should be updated during
Expand Down
82 changes: 47 additions & 35 deletions controllers/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,59 +15,43 @@ import (
apiProxy "github.com/ytsaurus/ytsaurus-k8s-operator/pkg/apiproxy"
)

func getFlowFromComponent(component consts.ComponentType) ytv1.UpdateFlow {
if component == consts.MasterType {
return ytv1.UpdateFlowMaster
}
if component == consts.TabletNodeType {
return ytv1.UpdateFlowTabletNodes
}
if component == consts.DataNodeType || component == consts.ExecNodeType {
return ytv1.UpdateFlowFull
}
return ytv1.UpdateFlowStateless
}

func canUpdateComponent(selectors []ytv1.ComponentUpdateSelector, component ytv1.Component) (bool, error) {
func canUpdateComponent(selectors []ytv1.ComponentUpdateSelector, component ytv1.Component) bool {
for _, selector := range selectors {
if selector.ComponentType != "" {
if selector.ComponentType == component.Type {
return true, nil
}
} else if selector.ComponentName != "" {
if selector.ComponentName != "" {
if selector.ComponentName == component.Name {
return true, nil
return true
}
} else if selector.ComponentType != "" {
if selector.ComponentType == component.Type {
return true
}
} else {
switch selector.ComponentGroup {
case consts.ComponentGroupEverything:
return true, nil
return true
case consts.ComponentGroupNothing:
return false, nil
return false
case consts.ComponentGroupStateful:
if component.Type == consts.DataNodeType || component.Type == consts.TabletNodeType {
return true, nil
return true
}
case consts.ComponentGroupStateless:
if component.Type != consts.DataNodeType && component.Type != consts.TabletNodeType && component.Type != consts.MasterType {
return true, nil
return true
}
default:
return false, fmt.Errorf("unexpected component group %s", selector.ComponentGroup)
return false
}
}
}
return false, nil
return false
}

// Considers spec and decides if operator should proceed with update or block.
// Block case is indicated with non-empty blockMsg.
// If update is not blocked, updateMeta containing a chosen flow and the component names to update returned.
func chooseUpdatingComponents(spec ytv1.YtsaurusSpec, needUpdate []components.Component, allComponents []components.Component) (components []ytv1.Component, blockMsg string) {
configuredSelectors := spec.UpdateSelectors
if len(configuredSelectors) == 0 && spec.EnableFullUpdate {
configuredSelectors = []ytv1.ComponentUpdateSelector{{ComponentGroup: consts.ComponentGroupEverything}}
}
configuredSelectors := getEffectiveSelectors(spec)
needFullUpdate := false

var canUpdate []ytv1.Component
Expand All @@ -78,16 +62,13 @@ func chooseUpdatingComponents(spec ytv1.YtsaurusSpec, needUpdate []components.Co
Name: comp.GetName(),
Type: comp.GetType(),
}
upd, err := canUpdateComponent(configuredSelectors, component)
if err != nil {
return nil, err.Error()
}
upd := canUpdateComponent(configuredSelectors, component)
if upd {
canUpdate = append(canUpdate, component)
} else {
cannotUpdate = append(cannotUpdate, component)
}
statelessCheck, err := canUpdateComponent([]ytv1.ComponentUpdateSelector{{ComponentGroup: consts.ComponentGroupStateless}}, component)
statelessCheck := canUpdateComponent([]ytv1.ComponentUpdateSelector{{ComponentGroup: consts.ComponentGroupStateless}}, component)
if !statelessCheck && component.Type != consts.DataNodeType {
needFullUpdate = true
}
Expand All @@ -110,6 +91,37 @@ func chooseUpdatingComponents(spec ytv1.YtsaurusSpec, needUpdate []components.Co
return canUpdate, ""
}

func getEffectiveSelectors(spec ytv1.YtsaurusSpec) []ytv1.ComponentUpdateSelector {
if len(spec.UpdateSelectors) != 0 {
return spec.UpdateSelectors
}

if spec.UpdateSelector != ytv1.UpdateSelectorUnspecified {
switch spec.UpdateSelector {
case ytv1.UpdateSelectorNothing:
return []ytv1.ComponentUpdateSelector{{ComponentGroup: consts.ComponentGroupNothing}}
case ytv1.UpdateSelectorMasterOnly:
return []ytv1.ComponentUpdateSelector{{ComponentType: consts.MasterType}}
case ytv1.UpdateSelectorDataNodesOnly:
return []ytv1.ComponentUpdateSelector{{ComponentType: consts.DataNodeType}}
case ytv1.UpdateSelectorTabletNodesOnly:
return []ytv1.ComponentUpdateSelector{{ComponentType: consts.TabletNodeType}}
case ytv1.UpdateSelectorExecNodesOnly:
return []ytv1.ComponentUpdateSelector{{ComponentType: consts.ExecNodeType}}
case ytv1.UpdateSelectorStatelessOnly:
return []ytv1.ComponentUpdateSelector{{ComponentGroup: consts.ComponentGroupStateless}}
case ytv1.UpdateSelectorEverything:
return []ytv1.ComponentUpdateSelector{{ComponentGroup: consts.ComponentGroupEverything}}
}
}

if spec.EnableFullUpdate {
return []ytv1.ComponentUpdateSelector{{ComponentGroup: consts.ComponentGroupEverything}}
}

return []ytv1.ComponentUpdateSelector{{ComponentGroup: consts.ComponentGroupStateless}}
}

func convertToComponent(components []components.Component) []ytv1.Component {
var result []ytv1.Component
for _, c := range components {
Expand Down
28 changes: 20 additions & 8 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,24 @@ _Appears in:_
| `type` _[ComponentType](#componenttype)_ | | | |


#### ComponentUpdateSelector







_Appears in:_
- [YtsaurusSpec](#ytsaurusspec)

| Field | Description | Default | Validation |
| --- | --- | --- | --- |
| `componentType` _[ComponentType](#componenttype)_ | | | |
| `componentGroup` _[ComponentGroup](#componentgroup)_ | | | |
| `componentName` _string_ | | | |


#### ControllerAgentsSpec


Expand Down Expand Up @@ -2134,13 +2152,6 @@ _Underlying type:_ _string_
_Appears in:_
- [UpdateStatus](#updatestatus)

| Field | Description |
| --- | --- |
| `` | |
| `Stateless` | |
| `Master` | |
| `TabletNodes` | |
| `Full` | |


#### UpdateSelector
Expand Down Expand Up @@ -2317,7 +2328,8 @@ _Appears in:_
| `oauthService` _[OauthServiceSpec](#oauthservicespec)_ | | | |
| `isManaged` _boolean_ | | true | |
| `enableFullUpdate` _boolean_ | | true | |
| `updateSelector` _[UpdateSelector](#updateselector)_ | UpdateSelector is an experimental field. Behaviour may change.<br />If UpdateSelector is not empty EnableFullUpdate is ignored. | | Enum: [ Nothing MasterOnly DataNodesOnly TabletNodesOnly ExecNodesOnly StatelessOnly Everything] <br /> |
| `updateSelector` _[UpdateSelector](#updateselector)_ | Deprecated: UpdateSelector is going to be removed soon. Please use UpdateSelectors instead. | | |
| `updateSelectors` _[ComponentUpdateSelector](#componentupdateselector) array_ | Controls the components that should be updated during the update process. | | |
| `nodeSelector` _object (keys:string, values:string)_ | | | |
| `tolerations` _[Toleration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#toleration-v1-core) array_ | | | |
| `dnsConfig` _[PodDNSConfig](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#poddnsconfig-v1-core)_ | DNSConfig allows customizing the DNS settings for the pods. | | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39581,8 +39581,7 @@ spec:
uiImage:
type: string
updateSelector:
description: 'Deprecated: UpdateSelector is an experimental field.
Behaviour may change.'
description: 'Deprecated: UpdateSelector is going to be removed soon.'
type: string
updateSelectors:
description: Controls the components that should be updated during
Expand Down

0 comments on commit 7cd5113

Please sign in to comment.