Skip to content

Commit 6a75b36

Browse files
committed
Add field for ActorTemplate API
1 parent 48ee6e0 commit 6a75b36

5 files changed

Lines changed: 70 additions & 4 deletions

File tree

‎charts/substrate-crds/templates/ate.dev_actortemplates.yaml‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,13 @@ spec:
256256
- message: All images must be pinned (changing the image invalidates
257257
snapshots)
258258
rule: self.contains('@')
259+
requiredWorkerPoolName:
260+
description: |-
261+
RequiredWorkerPoolName restricts actors from this template to one WorkerPool.
262+
When set, the scheduler only considers workers owned by that WorkerPool.
263+
If no worker in that pool is free, ResumeActor fails instead of falling
264+
back to another eligible pool.
265+
type: string
259266
sandboxClass:
260267
default: gvisor
261268
description: |-

‎cmd/ateapi/internal/controlapi/create_actor.go‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,19 @@ func (s *Service) CreateActor(ctx context.Context, req *ateapipb.CreateActorRequ
3737
templateNamespace := in.GetActorTemplateNamespace()
3838
templateName := in.GetActorTemplateName()
3939

40-
setSpanActorRefAttributes(ctx, in.GetMetadata().GetAtespace(), in.GetMetadata().GetName())
41-
42-
_, err := s.actorTemplateLister.ActorTemplates(templateNamespace).Get(templateName)
40+
actorTemplate, err := s.actorTemplateLister.ActorTemplates(templateNamespace).Get(templateName)
4341
if err != nil {
4442
if k8serrors.IsNotFound(err) {
4543
return nil, status.Errorf(codes.FailedPrecondition, "ActorTemplate %s/%s not found", templateNamespace, templateName)
4644
}
4745
return nil, fmt.Errorf("while getting ActorTemplate: %w", err)
4846
}
4947

48+
requiredWorkerPoolName := in.GetRequiredWorkerPoolName()
49+
if requiredWorkerPoolName == "" {
50+
requiredWorkerPoolName = actorTemplate.Spec.RequiredWorkerPoolName
51+
}
52+
5053
atespace := in.GetMetadata().GetAtespace()
5154
name := in.GetMetadata().GetName()
5255

@@ -68,7 +71,7 @@ func (s *Service) CreateActor(ctx context.Context, req *ateapipb.CreateActorRequ
6871
ActorTemplateNamespace: templateNamespace,
6972
ActorTemplateName: templateName,
7073
WorkerSelector: in.GetWorkerSelector(),
71-
RequiredWorkerPoolName: in.GetRequiredWorkerPoolName(),
74+
RequiredWorkerPoolName: requiredWorkerPoolName,
7275
}
7376
stored, err := s.persistence.CreateActor(ctx, actor)
7477
if err != nil {

‎cmd/ateapi/internal/controlapi/functional_test.go‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,6 +1333,47 @@ func TestResumeActor_NoWorkers(t *testing.T) {
13331333
assertGrpcError(t, err, codes.FailedPrecondition, "no free workers available")
13341334
}
13351335

1336+
func TestCreateActor_DefaultsRequiredWorkerPoolFromTemplate(t *testing.T) {
1337+
ns := namespaceForTest("ns-template-required-pool")
1338+
tc := setupTest(t, ns)
1339+
defer tc.cleanup()
1340+
1341+
ensureDefaultGvisorSandboxConfig(t, tc)
1342+
createWorkerPool(t, tc, ns, "pool-a", map[string]string{"group": ns})
1343+
1344+
actorTemplate := &atev1alpha1.ActorTemplate{
1345+
ObjectMeta: metav1.ObjectMeta{
1346+
Name: "tmpl-required-pool",
1347+
Namespace: ns,
1348+
},
1349+
Spec: atev1alpha1.ActorTemplateSpec{
1350+
PauseImage: "pause@sha256:abc",
1351+
SnapshotsConfig: atev1alpha1.SnapshotsConfig{
1352+
Location: "gs://fake-fake-fake",
1353+
},
1354+
Containers: []atev1alpha1.Container{
1355+
{Name: "main", Image: "main@sha256:abc", Command: []string{"/main"}},
1356+
},
1357+
RequiredWorkerPoolName: "pool-a",
1358+
},
1359+
}
1360+
if _, err := tc.substrateClient.ApiV1alpha1().ActorTemplates(ns).Create(context.Background(), actorTemplate, metav1.CreateOptions{}); err != nil {
1361+
t.Fatalf("failed to create actor template: %v", err)
1362+
}
1363+
1364+
resp, err := tc.client.CreateActor(context.Background(), &ateapipb.CreateActorRequest{Actor: &ateapipb.Actor{
1365+
Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "id1"},
1366+
ActorTemplateNamespace: ns,
1367+
ActorTemplateName: "tmpl-required-pool",
1368+
}})
1369+
if err != nil {
1370+
t.Fatalf("CreateActor failed: %v", err)
1371+
}
1372+
if got := resp.GetRequiredWorkerPoolName(); got != "pool-a" {
1373+
t.Fatalf("expected required_worker_pool_name to default from template, got %q", got)
1374+
}
1375+
}
1376+
13361377
func TestResumeActor_RequiredWorkerPoolDoesNotFallback(t *testing.T) {
13371378
ns := namespaceForTest("ns-required-pool-no-fallback")
13381379
tc := setupTest(t, ns)

‎manifests/ate-install/generated/ate.dev_actortemplates.yaml‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,13 @@ spec:
257257
- message: All images must be pinned (changing the image invalidates
258258
snapshots)
259259
rule: self.contains('@')
260+
requiredWorkerPoolName:
261+
description: |-
262+
RequiredWorkerPoolName restricts actors from this template to one WorkerPool.
263+
When set, the scheduler only considers workers owned by that WorkerPool.
264+
If no worker in that pool is free, ResumeActor fails instead of falling
265+
back to another eligible pool.
266+
type: string
260267
sandboxClass:
261268
default: gvisor
262269
description: |-

‎pkg/api/v1alpha1/actortemplate_types.go‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,14 @@ type ActorTemplateSpec struct {
323323
// +kubebuilder:default=gvisor
324324
SandboxClass SandboxClass `json:"sandboxClass,omitempty"`
325325

326+
// RequiredWorkerPoolName restricts actors from this template to one WorkerPool.
327+
// When set, the scheduler only considers workers owned by that WorkerPool.
328+
// If no worker in that pool is free, ResumeActor fails instead of falling
329+
// back to another eligible pool.
330+
//
331+
// +optional
332+
RequiredWorkerPoolName string `json:"requiredWorkerPoolName,omitempty"`
333+
326334
// WorkerSelector restricts which worker pools actors from this template may
327335
// use. The scheduler only considers pools whose labels match this selector.
328336
// If nil, all pools are eligible (subject to the actor's own worker_selector).

0 commit comments

Comments
 (0)