Skip to content

Commit 95258d1

Browse files
committed
Playground should be triggered to create Services and then Pods once the model is created
1 parent 9c77c38 commit 95258d1

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

pkg/controller/inference/playground_controller.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,34 @@ 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+
namespace := obj.GetNamespace()
126+
name := obj.GetName()
127+
128+
playgrounds := &inferenceapi.PlaygroundList{}
129+
err := r.List(ctx, playgrounds, client.InNamespace(namespace))
130+
if err != nil {
131+
logger.Error(err, "failed to list playgrounds")
132+
return nil
133+
}
134+
135+
var reqs []ctrl.Request
136+
for _, playground := range playgrounds.Items {
137+
if playground.Spec.ModelClaim != nil && playground.Spec.ModelClaim.ModelName == coreapi.ModelName(name) {
138+
reqs = append(reqs, ctrl.Request{
139+
NamespacedName: types.NamespacedName{
140+
Namespace: namespace,
141+
Name: playground.Name,
142+
},
143+
})
144+
}
145+
// TODO: handle MultiModelsClaims in the future.
146+
}
147+
return reqs
148+
}
149+
122150
return ctrl.NewControllerManagedBy(mgr).
123151
For(&inferenceapi.Playground{}).
124152
Watches(&inferenceapi.Service{}, &handler.EnqueueRequestForObject{},
@@ -129,6 +157,12 @@ func (r *PlaygroundReconciler) SetupWithManager(mgr ctrl.Manager) error {
129157
return !reflect.DeepEqual(oldBar.Status, newBar.Status)
130158
},
131159
})).
160+
Watches(&coreapi.OpenModel{}, handler.EnqueueRequestsFromMapFunc(mapFn),
161+
builder.WithPredicates(predicate.Funcs{
162+
UpdateFunc: func(e event.UpdateEvent) bool { return false },
163+
DeleteFunc: func(e event.DeleteEvent) bool { return false },
164+
GenericFunc: func(e event.GenericEvent) bool { return false },
165+
})).
132166
Complete(r)
133167
}
134168

test/integration/controller/inference/playground_test.go

Lines changed: 50 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,53 @@ 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+
validation.ValidatePlayground(ctx, k8sClient, playground)
185+
gomega.Consistently(func() error {
186+
updatePlayground := inferenceapi.Playground{}
187+
if err := k8sClient.Get(ctx, types.NamespacedName{Name: playground.Name, Namespace: playground.Namespace}, &updatePlayground); err != nil {
188+
return err
189+
}
190+
if len(updatePlayground.Status.Conditions) != 0 {
191+
return fmt.Errorf("playground status conditions should be empty, got %v", updatePlayground.Status.Conditions)
192+
}
193+
return nil
194+
}, 3*util.Interval, util.Interval).Should(gomega.Succeed())
195+
},
196+
},
197+
{
198+
// create the model after playground is created.
199+
playgroundUpdateFn: func(_ *inferenceapi.Playground) {
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.ValidatePlaygroundStatusEqualTo(ctx, k8sClient, playground, inferenceapi.PlaygroundAvailable, "PlaygroundReady", metav1.ConditionTrue)
204+
},
205+
},
206+
},
207+
}),
158208
)
159209
})

0 commit comments

Comments
 (0)