Skip to content

Commit ffbbc1f

Browse files
authored
refactor(tasks): simplify context cluster task (#6081)
1 parent 702e096 commit ffbbc1f

File tree

29 files changed

+246
-137
lines changed

29 files changed

+246
-137
lines changed

pkg/apiutil/core/v1alpha1/group.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,6 @@ import (
2020
"github.com/pingcap/tidb-operator/pkg/runtime/scope"
2121
)
2222

23-
func Cluster[
24-
S scope.Object[F, T],
25-
F client.Object,
26-
T runtime.Object,
27-
](f F) string {
28-
return scope.From[S](f).Cluster()
29-
}
30-
3123
func Version[
3224
S scope.Group[F, T],
3325
F client.Object,
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2024 PingCAP, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package coreutil
16+
17+
import (
18+
"github.com/pingcap/tidb-operator/pkg/client"
19+
"github.com/pingcap/tidb-operator/pkg/runtime"
20+
"github.com/pingcap/tidb-operator/pkg/runtime/scope"
21+
)
22+
23+
func Cluster[
24+
S scope.Object[F, T],
25+
F client.Object,
26+
T runtime.Object,
27+
](f F) string {
28+
return scope.From[S](f).Cluster()
29+
}

pkg/controllers/common/resource_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,19 @@ func TestResource(t *testing.T) {
3333
}{
3434
{
3535
desc: "normal",
36-
ns: Namespace("aaa"),
36+
ns: Namespace("xxx"),
3737
name: Name("bbb"),
3838
obj: 42,
39-
expectedNs: "aaa",
39+
expectedNs: "xxx",
4040
expectedName: "bbb",
4141
expectedObj: 42,
4242
},
4343
{
4444
desc: "use name func",
45-
ns: Lazy[string](func() string { return "aaa" }),
45+
ns: Lazy[string](func() string { return "xxx" }),
4646
name: Lazy[string](func() string { return "bbb" }),
4747
obj: 42,
48-
expectedNs: "aaa",
48+
expectedNs: "xxx",
4949
expectedName: "bbb",
5050
expectedObj: 42,
5151
},
@@ -85,21 +85,21 @@ func TestResourceSlice(t *testing.T) {
8585
}{
8686
{
8787
desc: "normal",
88-
ns: Namespace("aaa"),
88+
ns: Namespace("nnn"),
8989
labels: Labels(map[string]string{"xxx": "yyy"}),
9090
objs: []*int{ptr.To(42)},
91-
expectedNs: "aaa",
91+
expectedNs: "nnn",
9292
expectedLabels: map[string]string{
9393
"xxx": "yyy",
9494
},
9595
expectedObjs: []*int{ptr.To(42)},
9696
},
9797
{
9898
desc: "use func",
99-
ns: Lazy[string](func() string { return "aaa" }),
99+
ns: Lazy[string](func() string { return "nnn" }),
100100
labels: LabelsFunc(func() map[string]string { return map[string]string{"xxx": "yyy"} }),
101101
objs: []*int{ptr.To(42)},
102-
expectedNs: "aaa",
102+
expectedNs: "nnn",
103103
expectedLabels: map[string]string{
104104
"xxx": "yyy",
105105
},

pkg/controllers/common/task.go

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,11 @@ import (
2727
"k8s.io/apimachinery/pkg/types"
2828

2929
"github.com/pingcap/tidb-operator/api/v2/core/v1alpha1"
30+
coreutil "github.com/pingcap/tidb-operator/pkg/apiutil/core/v1alpha1"
3031
"github.com/pingcap/tidb-operator/pkg/client"
3132
"github.com/pingcap/tidb-operator/pkg/features"
33+
"github.com/pingcap/tidb-operator/pkg/runtime"
34+
"github.com/pingcap/tidb-operator/pkg/runtime/scope"
3235
"github.com/pingcap/tidb-operator/pkg/utils/task/v3"
3336
)
3437

@@ -114,11 +117,6 @@ func TaskContextTiFlash(state TiFlashStateInitializer, c client.Client) task.Tas
114117
return taskContextResource("TiFlash", w, c, false)
115118
}
116119

117-
func TaskContextCluster(state ClusterStateInitializer, c client.Client) task.Task {
118-
w := state.ClusterInitializer()
119-
return taskContextResource("Cluster", w, c, true)
120-
}
121-
122120
func TaskContextPod(state PodStateInitializer, c client.Client) task.Task {
123121
w := state.PodInitializer()
124122
return taskContextResource("Pod", w, c, false)
@@ -193,3 +191,35 @@ func TaskFeatureGates(state ClusterState) task.Task {
193191
return task.Complete().With("feature gates are initialized")
194192
})
195193
}
194+
195+
type ContextClusterNewer[
196+
F client.Object,
197+
] interface {
198+
Object() F
199+
SetCluster(c *v1alpha1.Cluster)
200+
}
201+
202+
func TaskContextCluster[
203+
S scope.Object[F, T],
204+
F client.Object,
205+
T runtime.Object,
206+
](state ContextClusterNewer[F], c client.Client) task.Task {
207+
return task.NameTaskFunc("ContextCluster", func(ctx context.Context) task.Result {
208+
cluster := v1alpha1.Cluster{}
209+
obj := state.Object()
210+
211+
key := types.NamespacedName{
212+
Namespace: obj.GetNamespace(),
213+
Name: coreutil.Cluster[S](obj),
214+
}
215+
if err := c.Get(ctx, key, &cluster); err != nil {
216+
if !errors.IsNotFound(err) {
217+
return task.Fail().With("can't get %s: %v", key, err)
218+
}
219+
220+
return task.Fail().With("cannot find %s: %v", key, err)
221+
}
222+
state.SetCluster(&cluster)
223+
return task.Complete().With("cluster is set")
224+
})
225+
}

pkg/controllers/common/task_test.go

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"github.com/pingcap/tidb-operator/api/v2/core/v1alpha1"
2828
"github.com/pingcap/tidb-operator/pkg/client"
2929
"github.com/pingcap/tidb-operator/pkg/features"
30+
"github.com/pingcap/tidb-operator/pkg/runtime/scope"
3031
"github.com/pingcap/tidb-operator/pkg/utils/fake"
3132
"github.com/pingcap/tidb-operator/pkg/utils/task/v3"
3233
)
@@ -95,10 +96,35 @@ func TestTaskContextPD(t *testing.T) {
9596
}
9697
}
9798

99+
type fakeObjectState[
100+
F client.Object,
101+
] struct {
102+
obj F
103+
cluster *v1alpha1.Cluster
104+
}
105+
106+
func (s *fakeObjectState[F]) Object() F {
107+
return s.obj
108+
}
109+
110+
func (s *fakeObjectState[F]) SetCluster(c *v1alpha1.Cluster) {
111+
s.cluster = c
112+
}
113+
114+
func newFakeObjectState[
115+
F client.Object,
116+
](f F) *fakeObjectState[F] {
117+
return &fakeObjectState[F]{
118+
obj: f,
119+
}
120+
}
121+
98122
func TestTaskContextCluster(t *testing.T) {
123+
const ns = "aaa"
124+
const name = "bbb"
99125
cases := []struct {
100126
desc string
101-
state *fakeState[v1alpha1.Cluster]
127+
state *fakeObjectState[*v1alpha1.PD]
102128
objs []client.Object
103129
unexpectedErr bool
104130

@@ -107,32 +133,35 @@ func TestTaskContextCluster(t *testing.T) {
107133
}{
108134
{
109135
desc: "success",
110-
state: &fakeState[v1alpha1.Cluster]{
111-
ns: "aaa",
112-
name: "aaa",
113-
},
136+
state: newFakeObjectState(fake.FakeObj(name, func(obj *v1alpha1.PD) *v1alpha1.PD {
137+
obj.Namespace = ns
138+
obj.Spec.Cluster.Name = name
139+
return obj
140+
})),
114141
objs: []client.Object{
115-
fake.FakeObj("aaa", fake.SetNamespace[v1alpha1.Cluster]("aaa")),
142+
fake.FakeObj(name, fake.SetNamespace[v1alpha1.Cluster](ns)),
116143
},
117144
expectedResult: task.SComplete,
118-
expectedObj: fake.FakeObj("aaa", fake.SetNamespace[v1alpha1.Cluster]("aaa")),
145+
expectedObj: fake.FakeObj(name, fake.SetNamespace[v1alpha1.Cluster](ns)),
119146
},
120147
{
121148
desc: "not found",
122-
state: &fakeState[v1alpha1.Cluster]{
123-
ns: "aaa",
124-
name: "aaa",
125-
},
149+
state: newFakeObjectState(fake.FakeObj(name, func(obj *v1alpha1.PD) *v1alpha1.PD {
150+
obj.Namespace = ns
151+
obj.Spec.Cluster.Name = name
152+
return obj
153+
})),
126154
expectedResult: task.SFail,
127155
},
128156
{
129157
desc: "has unexpected error",
130-
state: &fakeState[v1alpha1.Cluster]{
131-
ns: "aaa",
132-
name: "aaa",
133-
},
158+
state: newFakeObjectState(fake.FakeObj(name, func(obj *v1alpha1.PD) *v1alpha1.PD {
159+
obj.Namespace = ns
160+
obj.Spec.Cluster.Name = name
161+
return obj
162+
})),
134163
objs: []client.Object{
135-
fake.FakeObj("aaa", fake.SetNamespace[v1alpha1.Cluster]("aaa")),
164+
fake.FakeObj(name, fake.SetNamespace[v1alpha1.Cluster](ns)),
136165
},
137166
unexpectedErr: true,
138167
expectedResult: task.SFail,
@@ -149,12 +178,10 @@ func TestTaskContextCluster(t *testing.T) {
149178
if c.unexpectedErr {
150179
fc.WithError("*", "*", errors.NewInternalError(fmt.Errorf("fake internal err")))
151180
}
152-
s := &fakeClusterState{s: c.state}
153-
154-
res, done := task.RunTask(context.Background(), TaskContextCluster(s, fc))
181+
res, done := task.RunTask(context.Background(), TaskContextCluster[scope.PD](c.state, fc))
155182
assert.Equal(tt, c.expectedResult, res.Status(), c.desc)
156183
assert.False(tt, done, c.desc)
157-
assert.Equal(tt, c.expectedObj, c.state.obj, c.desc)
184+
assert.Equal(tt, c.expectedObj, c.state.cluster, c.desc)
158185
})
159186
}
160187
}

pkg/controllers/pd/builder.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"github.com/pingcap/tidb-operator/pkg/controllers/common"
1919
"github.com/pingcap/tidb-operator/pkg/controllers/pd/tasks"
2020
"github.com/pingcap/tidb-operator/pkg/runtime"
21+
"github.com/pingcap/tidb-operator/pkg/runtime/scope"
2122
"github.com/pingcap/tidb-operator/pkg/utils/task/v3"
2223
)
2324

@@ -29,7 +30,7 @@ func (r *Reconciler) NewRunner(state *tasks.ReconcileContext, reporter task.Task
2930
task.IfBreak(common.CondInstanceHasBeenDeleted(state)),
3031

3132
// get cluster
32-
common.TaskContextCluster(state, r.Client),
33+
common.TaskContextCluster[scope.PD](state, r.Client),
3334
common.TaskFeatureGates(state),
3435
// if it's paused just return
3536
task.IfBreak(common.CondClusterIsPaused(state)),

pkg/controllers/pd/tasks/state.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ type state struct {
3636

3737
type State interface {
3838
common.PDStateInitializer
39-
common.ClusterStateInitializer
4039
common.PodStateInitializer
4140
common.PDSliceStateInitializer
4241

@@ -46,6 +45,9 @@ type State interface {
4645
common.PDSliceState
4746

4847
common.InstanceState[*runtime.PD]
48+
49+
common.ContextClusterNewer[*v1alpha1.PD]
50+
4951
SetPod(*corev1.Pod)
5052
}
5153

@@ -56,6 +58,10 @@ func NewState(key types.NamespacedName) State {
5658
return s
5759
}
5860

61+
func (s *state) Object() *v1alpha1.PD {
62+
return s.pd
63+
}
64+
5965
func (s *state) PD() *v1alpha1.PD {
6066
return s.pd
6167
}
@@ -76,6 +82,10 @@ func (s *state) SetPod(pod *corev1.Pod) {
7682
s.pod = pod
7783
}
7884

85+
func (s *state) SetCluster(cluster *v1alpha1.Cluster) {
86+
s.cluster = cluster
87+
}
88+
7989
func (s *state) PDSlice() []*v1alpha1.PD {
8090
return s.pds
8191
}
@@ -87,15 +97,6 @@ func (s *state) PDInitializer() common.PDInitializer {
8797
Initializer()
8898
}
8999

90-
func (s *state) ClusterInitializer() common.ClusterInitializer {
91-
return common.NewResource(func(cluster *v1alpha1.Cluster) { s.cluster = cluster }).
92-
WithNamespace(common.Namespace(s.key.Namespace)).
93-
WithName(common.Lazy[string](func() string {
94-
return s.pd.Spec.Cluster.Name
95-
})).
96-
Initializer()
97-
}
98-
99100
func (s *state) PodInitializer() common.PodInitializer {
100101
return common.NewResource(s.SetPod).
101102
WithNamespace(common.Namespace(s.key.Namespace)).

pkg/controllers/pd/tasks/state_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/pingcap/tidb-operator/api/v2/core/v1alpha1"
2626
"github.com/pingcap/tidb-operator/pkg/client"
2727
"github.com/pingcap/tidb-operator/pkg/controllers/common"
28+
"github.com/pingcap/tidb-operator/pkg/runtime/scope"
2829
"github.com/pingcap/tidb-operator/pkg/utils/fake"
2930
"github.com/pingcap/tidb-operator/pkg/utils/task/v3"
3031
)
@@ -120,7 +121,7 @@ func TestState(t *testing.T) {
120121
ctx := context.Background()
121122
res, done := task.RunTask(ctx, task.Block(
122123
common.TaskContextPD(s, fc),
123-
common.TaskContextCluster(s, fc),
124+
common.TaskContextCluster[scope.PD](s, fc),
124125
common.TaskContextPDSlice(s, fc),
125126
common.TaskContextPod(s, fc),
126127
))

pkg/controllers/pdgroup/builder.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"github.com/pingcap/tidb-operator/pkg/controllers/common"
1919
"github.com/pingcap/tidb-operator/pkg/controllers/pdgroup/tasks"
2020
"github.com/pingcap/tidb-operator/pkg/runtime"
21+
"github.com/pingcap/tidb-operator/pkg/runtime/scope"
2122
"github.com/pingcap/tidb-operator/pkg/utils/task/v3"
2223
)
2324

@@ -29,7 +30,7 @@ func (r *Reconciler) NewRunner(state *tasks.ReconcileContext, reporter task.Task
2930
task.IfBreak(common.CondGroupHasBeenDeleted(state)),
3031

3132
// get cluster
32-
common.TaskContextCluster(state, r.Client),
33+
common.TaskContextCluster[scope.PDGroup](state, r.Client),
3334
common.TaskFeatureGates(state),
3435
// if it's paused just return
3536
task.IfBreak(common.CondClusterIsPaused(state)),

0 commit comments

Comments
 (0)