Skip to content

Commit ba653c6

Browse files
committed
Playground should be triggered to create Services and then Pods once the model is created
1 parent a9ce1ff commit ba653c6

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

pkg/controller/inference/playground_controller.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,32 @@ func (r *PlaygroundReconciler) Reconcile(ctx context.Context, req ctrl.Request)
119119

120120
// SetupWithManager sets up the controller with the Manager.
121121
func (r *PlaygroundReconciler) SetupWithManager(mgr ctrl.Manager) error {
122+
mapFn := func(ctx context.Context, obj client.Object) []ctrl.Request {
123+
logger := log.FromContext(ctx)
124+
125+
modelName := obj.GetName()
126+
127+
playgrounds := &inferenceapi.PlaygroundList{}
128+
err := r.List(ctx, playgrounds, client.MatchingLabels{coreapi.ModelNameLabelKey: modelName})
129+
if err != nil {
130+
logger.Error(err, "failed to list playgrounds")
131+
return nil
132+
}
133+
134+
var reqs []ctrl.Request
135+
for _, playground := range playgrounds.Items {
136+
reqs = append(reqs, ctrl.Request{
137+
NamespacedName: types.NamespacedName{
138+
Name: playground.Name,
139+
},
140+
})
141+
}
142+
143+
// TODO: handle MultiModelsClaims in the future.
144+
145+
return reqs
146+
}
147+
122148
return ctrl.NewControllerManagedBy(mgr).
123149
For(&inferenceapi.Playground{}).
124150
Watches(&inferenceapi.Service{}, &handler.EnqueueRequestForObject{},
@@ -129,6 +155,12 @@ func (r *PlaygroundReconciler) SetupWithManager(mgr ctrl.Manager) error {
129155
return !reflect.DeepEqual(oldBar.Status, newBar.Status)
130156
},
131157
})).
158+
Watches(&coreapi.OpenModel{}, handler.EnqueueRequestsFromMapFunc(mapFn),
159+
builder.WithPredicates(predicate.Funcs{
160+
UpdateFunc: func(e event.UpdateEvent) bool { return false },
161+
DeleteFunc: func(e event.DeleteEvent) bool { return false },
162+
GenericFunc: func(e event.GenericEvent) bool { return false },
163+
})).
132164
Complete(r)
133165
}
134166

test/integration/controller/inference/playground_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ package inference
1818

1919
import (
2020
"context"
21+
"fmt"
2122

2223
"github.com/onsi/ginkgo/v2"
2324
"github.com/onsi/gomega"
2425
corev1 "k8s.io/api/core/v1"
26+
apierrors "k8s.io/apimachinery/pkg/api/errors"
2527
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2628
"k8s.io/apimachinery/pkg/types"
2729
"k8s.io/utils/ptr"
@@ -155,5 +157,54 @@ var _ = ginkgo.Describe("playground controller test", func() {
155157
},
156158
},
157159
}),
160+
ginkgo.Entry("create the model after playground is created", &testValidatingCase{
161+
makePlayground: func() *inferenceapi.Playground {
162+
return util.MockASamplePlayground(ns.Name)
163+
},
164+
updates: []*update{
165+
{
166+
playgroundUpdateFn: func(playground *inferenceapi.Playground) {
167+
// Delete the pre-provision model before creating playground.
168+
gomega.Expect(k8sClient.Delete(ctx, model)).To(gomega.Succeed())
169+
// To make sure model not exists.
170+
gomega.Eventually(func() error {
171+
oldModel := &coreapi.OpenModel{}
172+
if err := k8sClient.Get(ctx, types.NamespacedName{Name: model.Name, Namespace: model.Namespace}, oldModel); err != nil {
173+
if apierrors.IsNotFound(err) {
174+
return nil
175+
}
176+
return err
177+
}
178+
return fmt.Errorf("model %s/%s still exists", model.Namespace, model.Name)
179+
}, util.IntegrationTimeout, util.Interval).Should(gomega.Succeed())
180+
181+
gomega.Expect(k8sClient.Create(ctx, playground)).To(gomega.Succeed())
182+
},
183+
checkPlayground: func(ctx context.Context, k8sClient client.Client, playground *inferenceapi.Playground) {
184+
gomega.Consistently(func() error {
185+
updatePlayground := inferenceapi.Playground{}
186+
if err := k8sClient.Get(ctx, types.NamespacedName{Name: playground.Name, Namespace: playground.Namespace}, &updatePlayground); err != nil {
187+
return err
188+
}
189+
if len(updatePlayground.Status.Conditions) != 0 {
190+
return fmt.Errorf("playground status conditions should be empty, got %v", updatePlayground.Status.Conditions)
191+
}
192+
return nil
193+
}, 3*util.Interval, util.Interval).Should(gomega.Succeed())
194+
},
195+
},
196+
{
197+
// create the model after playground is created.
198+
playgroundUpdateFn: func(_ *inferenceapi.Playground) {
199+
model = util.MockASampleModel()
200+
gomega.Expect(k8sClient.Create(ctx, model)).To(gomega.Succeed())
201+
},
202+
checkPlayground: func(ctx context.Context, k8sClient client.Client, playground *inferenceapi.Playground) {
203+
validation.ValidatePlayground(ctx, k8sClient, playground)
204+
validation.ValidatePlaygroundStatusEqualTo(ctx, k8sClient, playground, inferenceapi.PlaygroundProgressing, "Pending", metav1.ConditionTrue)
205+
},
206+
},
207+
},
208+
}),
158209
)
159210
})

0 commit comments

Comments
 (0)