Skip to content

Commit 19d12d6

Browse files
committed
register controller.
1 parent c3c32f6 commit 19d12d6

File tree

10 files changed

+105
-86
lines changed

10 files changed

+105
-86
lines changed

config/charts/inferencepool/templates/rbac.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ metadata:
4646
{{- include "gateway-api-inference-extension.labels" . | nindent 4 }}
4747
rules:
4848
- apiGroups: ["inference.networking.x-k8s.io"]
49-
resources: ["inferenceobjectives"]
49+
resources: ["inferenceobjectives", "inferencemodelrewrites"]
5050
verbs: ["get", "watch", "list"]
5151
- apiGroups: ["{{ (split "/" .Values.inferencePool.apiVersion)._0 }}"]
5252
resources: ["inferencepools"]

pkg/epp/controller/inferencemodelrewrite_reconciler.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ func (c *InferenceModelRewriteReconciler) Reconcile(ctx context.Context, req ctr
5454
notFound = true
5555
}
5656

57-
if notFound || !infModelRewrite.DeletionTimestamp.IsZero() || infModelRewrite.Spec.PoolRef.Name != v1alpha2.ObjectName(c.PoolGKNN.Name) {
57+
if notFound || !infModelRewrite.DeletionTimestamp.IsZero() || infModelRewrite.Spec.PoolRef == nil ||
58+
infModelRewrite.Spec.PoolRef.Name != v1alpha2.ObjectName(c.PoolGKNN.Name) ||
59+
(infModelRewrite.Spec.PoolRef.Group != v1alpha2.Group(c.PoolGKNN.Group) && infModelRewrite.Spec.PoolRef.Group != "inference.networking.x-k8s.io") {
5860
// InferenceModelRewrite object got deleted or changed the referenced pool.
5961
c.Datastore.RewriteDelete(req.NamespacedName)
6062
return ctrl.Result{}, nil

pkg/epp/controller/inferencemodelrewrite_reconciler_test.go

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import (
3636
"sigs.k8s.io/gateway-api-inference-extension/pkg/common"
3737
backendmetrics "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend/metrics"
3838
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/datastore"
39+
poolutil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/pool"
3940
utiltest "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/testing"
4041
)
4142

@@ -48,7 +49,10 @@ var (
4849
CreationTimestamp: metav1.Unix(1000, 0),
4950
},
5051
Spec: v1alpha2.InferenceModelRewriteSpec{
51-
PoolRef: &v1alpha2.PoolObjectReference{Name: v1alpha2.ObjectName(poolForRewrite.Name)},
52+
PoolRef: &v1alpha2.PoolObjectReference{
53+
Name: v1alpha2.ObjectName(poolForRewrite.Name),
54+
Group: v1alpha2.Group(poolForRewrite.GroupVersionKind().Group),
55+
},
5256
},
5357
}
5458
rewrite1Pool2 = &v1alpha2.InferenceModelRewrite{
@@ -58,7 +62,10 @@ var (
5862
CreationTimestamp: metav1.Unix(1001, 0),
5963
},
6064
Spec: v1alpha2.InferenceModelRewriteSpec{
61-
PoolRef: &v1alpha2.PoolObjectReference{Name: "test-pool2"},
65+
PoolRef: &v1alpha2.PoolObjectReference{
66+
Name: "test-pool2",
67+
Group: v1alpha2.Group(poolForRewrite.GroupVersionKind().Group),
68+
},
6269
},
6370
}
6471
rewrite1Updated = &v1alpha2.InferenceModelRewrite{
@@ -68,8 +75,11 @@ var (
6875
CreationTimestamp: metav1.Unix(1003, 0),
6976
},
7077
Spec: v1alpha2.InferenceModelRewriteSpec{
71-
PoolRef: &v1alpha2.PoolObjectReference{Name: v1alpha2.ObjectName(poolForRewrite.Name)},
72-
Rules: []v1alpha2.InferenceModelRewriteRule{{}},
78+
PoolRef: &v1alpha2.PoolObjectReference{
79+
Name: v1alpha2.ObjectName(poolForRewrite.Name),
80+
Group: v1alpha2.Group(poolForRewrite.GroupVersionKind().Group),
81+
},
82+
Rules: []v1alpha2.InferenceModelRewriteRule{{}},
7383
},
7484
}
7585
rewrite1Deleted = &v1alpha2.InferenceModelRewrite{
@@ -78,9 +88,13 @@ var (
7888
Namespace: rewrite1.Namespace,
7989
CreationTimestamp: metav1.Unix(1004, 0),
8090
DeletionTimestamp: &metav1.Time{Time: time.Now()},
91+
Finalizers: []string{"deleted"},
8192
},
8293
Spec: v1alpha2.InferenceModelRewriteSpec{
83-
PoolRef: &v1alpha2.PoolObjectReference{Name: v1alpha2.ObjectName(poolForRewrite.Name)},
94+
PoolRef: &v1alpha2.PoolObjectReference{
95+
Name: v1alpha2.ObjectName(poolForRewrite.Name),
96+
Group: v1alpha2.Group(poolForRewrite.GroupVersionKind().Group),
97+
},
8498
},
8599
}
86100
rewrite2 = &v1alpha2.InferenceModelRewrite{
@@ -90,7 +104,10 @@ var (
90104
CreationTimestamp: metav1.Unix(1001, 0),
91105
},
92106
Spec: v1alpha2.InferenceModelRewriteSpec{
93-
PoolRef: &v1alpha2.PoolObjectReference{Name: v1alpha2.ObjectName(poolForRewrite.Name)},
107+
PoolRef: &v1alpha2.PoolObjectReference{
108+
Name: v1alpha2.ObjectName(poolForRewrite.Name),
109+
Group: v1alpha2.Group(poolForRewrite.GroupVersionKind().Group),
110+
},
94111
},
95112
}
96113
)
@@ -155,7 +172,7 @@ func TestInferenceModelRewriteReconciler(t *testing.T) {
155172
_ = v1alpha2.Install(scheme)
156173
_ = v1.Install(scheme)
157174
initObjs := []client.Object{}
158-
if test.rewrite != nil && test.rewrite.DeletionTimestamp.IsZero() {
175+
if test.rewrite != nil {
159176
initObjs = append(initObjs, test.rewrite)
160177
}
161178
for _, r := range test.rewritesInAPIServer {
@@ -170,7 +187,8 @@ func TestInferenceModelRewriteReconciler(t *testing.T) {
170187
for _, r := range test.rewritesInStore {
171188
ds.RewriteSet(r)
172189
}
173-
_ = ds.PoolSet(context.Background(), fakeClient, poolForRewrite)
190+
endpointPool := poolutil.InferencePoolToEndpointPool(poolForRewrite)
191+
_ = ds.PoolSet(context.Background(), fakeClient, endpointPool)
174192
reconciler := &InferenceModelRewriteReconciler{
175193
Reader: fakeClient,
176194
Datastore: ds,

pkg/epp/datastore/datastore.go

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import (
3131

3232
"sigs.k8s.io/controller-runtime/pkg/client"
3333
"sigs.k8s.io/controller-runtime/pkg/log"
34-
v1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
3534
"sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha2"
3635
backendmetrics "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend/metrics"
3736
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/datalayer"
@@ -82,7 +81,7 @@ func NewDatastore(parentCtx context.Context, epFactory datalayer.EndpointFactory
8281
pool: nil,
8382
mu: sync.RWMutex{},
8483
objectives: make(map[string]*v1alpha2.InferenceObjective),
85-
rewrites: NewModelRewriteStore(),
84+
rewrites: newModelRewriteStore(),
8685
pods: &sync.Map{},
8786
modelServerMetricsPort: modelServerMetricsPort,
8887
epf: epFactory,
@@ -101,11 +100,11 @@ type datastore struct {
101100
parentCtx context.Context
102101
// mu is used to synchronize access to pool, objectives, and rewrites.
103102
mu sync.RWMutex
104-
pool *v1.InferencePool
103+
pool *datalayer.EndpointPool
105104
// key: InferenceObjective name, value: *InferenceObjective
106105
objectives map[string]*v1alpha2.InferenceObjective
107106
// rewrites store for InferenceModelRewrite objects.
108-
rewrites *ModelRewriteStore
107+
rewrites *modelRewriteStore
109108
// key: types.NamespacedName, value: backendmetrics.PodMetrics
110109
pods *sync.Map
111110
// modelServerMetricsPort metrics port from EPP command line argument
@@ -119,7 +118,7 @@ func (ds *datastore) Clear() {
119118
defer ds.mu.Unlock()
120119
ds.pool = nil
121120
ds.objectives = make(map[string]*v1alpha2.InferenceObjective)
122-
ds.rewrites = NewModelRewriteStore()
121+
ds.rewrites = newModelRewriteStore()
123122
// stop all pods go routines before clearing the pods map.
124123
ds.pods.Range(func(_, v any) bool {
125124
ds.epf.ReleaseEndpoint(v.(backendmetrics.PodMetrics))
@@ -156,7 +155,7 @@ func (ds *datastore) PoolSet(ctx context.Context, reader client.Reader, endpoint
156155
return nil
157156
}
158157

159-
func (ds *datastore) PoolGet() (*v1.InferencePool, error) {
158+
func (ds *datastore) PoolGet() (*datalayer.EndpointPool, error) {
160159
ds.mu.RLock()
161160
defer ds.mu.RUnlock()
162161
if !ds.PoolHasSynced() {
@@ -214,25 +213,25 @@ func (ds *datastore) ObjectiveGetAll() []*v1alpha2.InferenceObjective {
214213
func (ds *datastore) RewriteSet(infModelRewrite *v1alpha2.InferenceModelRewrite) {
215214
ds.mu.Lock()
216215
defer ds.mu.Unlock()
217-
ds.rewrites.Set(infModelRewrite)
216+
ds.rewrites.set(infModelRewrite)
218217
}
219218

220219
func (ds *datastore) RewriteDelete(namespacedName types.NamespacedName) {
221220
ds.mu.Lock()
222221
defer ds.mu.Unlock()
223-
ds.rewrites.Delete(namespacedName)
222+
ds.rewrites.delete(namespacedName)
224223
}
225224

226225
func (ds *datastore) RewriteGet(modelName string) *v1alpha2.InferenceModelRewriteRule {
227226
ds.mu.RLock()
228227
defer ds.mu.RUnlock()
229-
return ds.rewrites.GetRule(modelName)
228+
return ds.rewrites.getRule(modelName)
230229
}
231230

232231
func (ds *datastore) RewriteGetAll() []*v1alpha2.InferenceModelRewrite {
233232
ds.mu.RLock()
234233
defer ds.mu.RUnlock()
235-
return ds.rewrites.GetAll()
234+
return ds.rewrites.getAll()
236235
}
237236

238237
// /// Pods/endpoints APIs ///

pkg/epp/datastore/modelrewritestore.go

Lines changed: 34 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -24,39 +24,39 @@ import (
2424
"sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha2"
2525
)
2626

27-
// ModelRewriteStore encapsulates the logic for storing and retrieving
27+
// modelRewriteStore encapsulates the logic for storing and retrieving
2828
// InferenceModelRewrite rules, handling precedence correctly. This struct is not
2929
// thread-safe; concurrency must be managed by its consumer.
30-
type ModelRewriteStore struct {
30+
type modelRewriteStore struct {
3131
genericRules []*rewriteRuleWithMetadata
3232
rulesByExactModelMatch map[string][]*rewriteRuleWithMetadata
33-
allReWrites map[types.NamespacedName]*v1alpha2.InferenceModelRewrite
33+
allReWrites map[string]*v1alpha2.InferenceModelRewrite
3434
}
3535

36-
func NewModelRewriteStore() *ModelRewriteStore {
37-
return &ModelRewriteStore{
36+
func newModelRewriteStore() *modelRewriteStore {
37+
return &modelRewriteStore{
3838
genericRules: []*rewriteRuleWithMetadata{},
39-
rulesByExactModelMatch: map[string][]*rewriteRuleWithMetadata{},
40-
allReWrites: map[types.NamespacedName]*v1alpha2.InferenceModelRewrite{},
39+
rulesByExactModelMatch: map[string][]*rewriteRuleWithMetadata{}, // Key is the exact model name.
40+
allReWrites: map[string]*v1alpha2.InferenceModelRewrite{}, // Key is the rewrites name.
4141
}
4242
}
4343

44-
// Set adds or updates an InferenceModelRewrite in the store. It deconstructs the
44+
// set adds or updates an InferenceModelRewrite in the store. It deconstructs the
4545
// object into individual rules and stores them in the appropriate data structures,
4646
// ensuring they remain sorted by precedence.
47-
func (ms *ModelRewriteStore) Set(infModelRewrite *v1alpha2.InferenceModelRewrite) {
48-
nn := getNN(infModelRewrite)
49-
47+
func (ms *modelRewriteStore) set(infModelRewrite *v1alpha2.InferenceModelRewrite) {
48+
name := infModelRewrite.Name
5049
// If the rewrite object already exists, remove its old rules before adding new ones.
51-
if _, ok := ms.allReWrites[nn]; ok {
52-
ms.deleteInternal(nn)
50+
if _, ok := ms.allReWrites[name]; ok {
51+
ms.deleteInternal(infModelRewrite.Name)
5352
}
54-
ms.allReWrites[nn] = infModelRewrite
53+
ms.allReWrites[name] = infModelRewrite
5554

5655
for i := range infModelRewrite.Spec.Rules {
57-
ruleWithMetadata := newRuleWithMetadata(infModelRewrite, i)
58-
if ruleWithMetadata == nil {
59-
continue
56+
ruleWithMetadata := &rewriteRuleWithMetadata{
57+
rule: infModelRewrite.Spec.Rules[i],
58+
createTimestamp: infModelRewrite.CreationTimestamp.Time,
59+
parentRewriteName: name,
6060
}
6161

6262
if ruleWithMetadata.isGeneric() {
@@ -80,22 +80,22 @@ func (ms *ModelRewriteStore) Set(infModelRewrite *v1alpha2.InferenceModelRewrite
8080
}
8181
}
8282

83-
// Delete removes an InferenceModelRewrite and all its associated rules from the store.
84-
func (ms *ModelRewriteStore) Delete(nn types.NamespacedName) {
85-
ms.deleteInternal(nn)
83+
// delete removes an InferenceModelRewrite and all its associated rules from the store.
84+
func (ms *modelRewriteStore) delete(nn types.NamespacedName) {
85+
ms.deleteInternal(nn.Name)
8686
}
8787

8888
// deleteInternal is the non-locking implementation for deleting a rewrite.
89-
func (ms *ModelRewriteStore) deleteInternal(nn types.NamespacedName) {
90-
if _, ok := ms.allReWrites[nn]; !ok {
89+
func (ms *modelRewriteStore) deleteInternal(n string) {
90+
if _, ok := ms.allReWrites[n]; !ok {
9191
return
9292
}
93-
delete(ms.allReWrites, nn)
93+
delete(ms.allReWrites, n)
9494

9595
// Filter out the generic rules associated with the deleted rewrite.
9696
newGenericRules := make([]*rewriteRuleWithMetadata, 0, len(ms.genericRules))
9797
for _, ruleWithMd := range ms.genericRules {
98-
if ruleWithMd.parentNN() != nn {
98+
if ruleWithMd.parentName() != n {
9999
newGenericRules = append(newGenericRules, ruleWithMd)
100100
}
101101
}
@@ -105,7 +105,7 @@ func (ms *ModelRewriteStore) deleteInternal(nn types.NamespacedName) {
105105
for modelName, rulesWithMd := range ms.rulesByExactModelMatch {
106106
newRules := make([]*rewriteRuleWithMetadata, 0, len(rulesWithMd))
107107
for _, r := range rulesWithMd {
108-
if r.parentNN() != nn {
108+
if r.parentName() != n {
109109
newRules = append(newRules, r)
110110
}
111111
}
@@ -118,9 +118,9 @@ func (ms *ModelRewriteStore) deleteInternal(nn types.NamespacedName) {
118118
}
119119
}
120120

121-
// GetRule returns the single, highest-precedence rule for a given model name.
121+
// getRule returns the single, highest-precedence rule for a given model name.
122122
// It prioritizes exact matches over generic ones, and among those, the oldest rule wins.
123-
func (ms *ModelRewriteStore) GetRule(modelName string) *v1alpha2.InferenceModelRewriteRule {
123+
func (ms *modelRewriteStore) getRule(modelName string) *v1alpha2.InferenceModelRewriteRule {
124124
// Exact matches have the highest precedence.
125125
if rulesWithMd, ok := ms.rulesByExactModelMatch[modelName]; ok && len(rulesWithMd) > 0 {
126126
return &rulesWithMd[0].rule // The list is pre-sorted, so the first element is the oldest.
@@ -133,39 +133,21 @@ func (ms *ModelRewriteStore) GetRule(modelName string) *v1alpha2.InferenceModelR
133133
return nil
134134
}
135135

136-
// GetAll returns a slice of all InferenceModelRewrite objects currently in the store.
137-
func (ms *ModelRewriteStore) GetAll() []*v1alpha2.InferenceModelRewrite {
136+
// getAll returns a slice of all InferenceModelRewrite objects currently in the store.
137+
func (ms *modelRewriteStore) getAll() []*v1alpha2.InferenceModelRewrite {
138138
rewrites := make([]*v1alpha2.InferenceModelRewrite, 0, len(ms.allReWrites))
139139
for _, rewrite := range ms.allReWrites {
140140
rewrites = append(rewrites, rewrite)
141141
}
142142
return rewrites
143143
}
144144

145-
func getNN(infModelRewrite *v1alpha2.InferenceModelRewrite) types.NamespacedName {
146-
return types.NamespacedName{
147-
Namespace: infModelRewrite.Namespace,
148-
Name: infModelRewrite.Name,
149-
}
150-
}
151-
152145
// rewriteRuleWithMetadata decorates a rule with metadata from its parent object
153146
// to be used in precedence sorting.
154147
type rewriteRuleWithMetadata struct {
155-
rule v1alpha2.InferenceModelRewriteRule
156-
createTimestamp time.Time
157-
parentRewriteNN types.NamespacedName
158-
}
159-
160-
func newRuleWithMetadata(infModelRewrite *v1alpha2.InferenceModelRewrite, ruleIdx int) *rewriteRuleWithMetadata {
161-
if ruleIdx >= len(infModelRewrite.Spec.Rules) {
162-
return nil
163-
}
164-
return &rewriteRuleWithMetadata{
165-
rule: infModelRewrite.Spec.Rules[ruleIdx],
166-
createTimestamp: infModelRewrite.CreationTimestamp.Time,
167-
parentRewriteNN: getNN(infModelRewrite),
168-
}
148+
rule v1alpha2.InferenceModelRewriteRule
149+
createTimestamp time.Time
150+
parentRewriteName string
169151
}
170152

171153
func (rr rewriteRuleWithMetadata) isGeneric() bool {
@@ -182,6 +164,6 @@ func (rr rewriteRuleWithMetadata) exactModels() map[string]bool {
182164
return modelSet
183165
}
184166

185-
func (rr rewriteRuleWithMetadata) parentNN() types.NamespacedName {
186-
return rr.parentRewriteNN
167+
func (rr rewriteRuleWithMetadata) parentName() string {
168+
return rr.parentRewriteName
187169
}

0 commit comments

Comments
 (0)