Skip to content

Commit 8ccaa0d

Browse files
committed
Merge origin into package-ref: resolve conflicts with PackageRef and replicas fields
2 parents 4465a69 + 2ce7841 commit 8ccaa0d

File tree

7 files changed

+134
-1
lines changed

7 files changed

+134
-1
lines changed

operator/api/v1alpha1/function_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ type FunctionSpec struct {
4949
// Module name
5050
// +kubebuilder:validation:Required
5151
Module string `json:"module"`
52+
// Number of replicas for the function deployment
53+
// +kubebuilder:validation:Optional
54+
// +kubebuilder:default=1
55+
Replicas *int32 `json:"replicas,omitempty"`
5256
// +kubebuilder:validation:Optional
5357
SubscriptionName string `json:"subscriptionName,omitempty"`
5458
// List of sources

operator/api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 6 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

operator/config/crd/bases/fs.functionstream.github.io_functions.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ spec:
6565
required:
6666
- name
6767
type: object
68+
replicas:
69+
default: 1
70+
description: Number of replicas for the function deployment
71+
format: int32
72+
type: integer
6873
requestSource:
6974
description: Request source
7075
properties:

operator/deploy/chart/templates/crd/fs.functionstream.github.io_functions.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ spec:
6262
package:
6363
description: Package name
6464
type: string
65+
replicas:
66+
default: 1
67+
description: Number of replicas for the function deployment
68+
format: int32
69+
type: integer
6570
requestSource:
6671
description: Request source
6772
properties:

operator/internal/controller/function_controller.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ func (r *FunctionReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
114114
// 5. Build Deployment
115115
deployName := fmt.Sprintf("function-%s", fn.Name)
116116
var replicas int32 = 1
117+
if fn.Spec.Replicas != nil {
118+
replicas = *fn.Spec.Replicas
119+
}
117120
labels := map[string]string{
118121
"function": fn.Name,
119122
}

operator/internal/controller/function_controller_test.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,112 @@ var _ = Describe("Function Controller", func() {
559559
Expect(deploy2.Spec.Template.Spec.Containers[0].Image).To(Equal("nginx:latest"))
560560
})
561561

562+
It("should use the specified replicas from FunctionSpec", func() {
563+
By("creating a Function with custom replicas")
564+
controllerReconciler := &FunctionReconciler{
565+
Client: k8sClient,
566+
Scheme: k8sClient.Scheme(),
567+
Config: Config{
568+
PulsarServiceURL: "pulsar://test-broker:6650",
569+
PulsarAuthPlugin: "org.apache.pulsar.client.impl.auth.AuthenticationToken",
570+
PulsarAuthParams: "token:my-token",
571+
},
572+
}
573+
574+
// Create a Package resource first
575+
pkg := &fsv1alpha1.Package{
576+
ObjectMeta: metav1.ObjectMeta{
577+
Name: "test-pkg-replicas",
578+
Namespace: "default",
579+
},
580+
Spec: fsv1alpha1.PackageSpec{
581+
DisplayName: "Test Package Replicas",
582+
Description: "desc",
583+
FunctionType: fsv1alpha1.FunctionType{
584+
Cloud: &fsv1alpha1.CloudType{Image: "busybox:latest"},
585+
},
586+
Modules: map[string]fsv1alpha1.Module{},
587+
},
588+
}
589+
Expect(k8sClient.Create(ctx, pkg)).To(Succeed())
590+
591+
// Create a Function with custom replicas
592+
customReplicas := int32(3)
593+
fn := &fsv1alpha1.Function{
594+
ObjectMeta: metav1.ObjectMeta{
595+
Name: "test-fn-replicas",
596+
Namespace: "default",
597+
},
598+
Spec: fsv1alpha1.FunctionSpec{
599+
Package: "test-pkg-replicas",
600+
Module: "mod",
601+
Replicas: &customReplicas,
602+
SubscriptionName: "sub",
603+
Sink: &fsv1alpha1.SinkSpec{Pulsar: &fsv1alpha1.PulsarSinkSpec{Topic: "out"}},
604+
RequestSource: &fsv1alpha1.SourceSpec{Pulsar: &fsv1alpha1.PulsarSourceSpec{Topic: "in"}},
605+
},
606+
}
607+
Expect(k8sClient.Create(ctx, fn)).To(Succeed())
608+
609+
// Reconcile the Function
610+
_, err := controllerReconciler.Reconcile(ctx, reconcile.Request{
611+
NamespacedName: types.NamespacedName{Name: fn.Name, Namespace: fn.Namespace},
612+
})
613+
Expect(err).NotTo(HaveOccurred())
614+
615+
// Check that the Deployment has the correct number of replicas
616+
deployName := "function-" + fn.Name
617+
deploy := &appsv1.Deployment{}
618+
Expect(k8sClient.Get(ctx, types.NamespacedName{Name: deployName, Namespace: fn.Namespace}, deploy)).To(Succeed())
619+
Expect(deploy.Spec.Replicas).NotTo(BeNil())
620+
Expect(*deploy.Spec.Replicas).To(Equal(int32(3)))
621+
622+
// Test updating replicas
623+
newReplicas := int32(5)
624+
patch := client.MergeFrom(fn.DeepCopy())
625+
fn.Spec.Replicas = &newReplicas
626+
Expect(k8sClient.Patch(ctx, fn, patch)).To(Succeed())
627+
628+
// Reconcile again
629+
_, err = controllerReconciler.Reconcile(ctx, reconcile.Request{
630+
NamespacedName: types.NamespacedName{Name: fn.Name, Namespace: fn.Namespace},
631+
})
632+
Expect(err).NotTo(HaveOccurred())
633+
634+
// Verify the deployment was updated with new replicas
635+
Expect(k8sClient.Get(ctx, types.NamespacedName{Name: deployName, Namespace: fn.Namespace}, deploy)).To(Succeed())
636+
Expect(*deploy.Spec.Replicas).To(Equal(int32(5)))
637+
638+
// Test default replicas when not specified
639+
fnDefault := &fsv1alpha1.Function{
640+
ObjectMeta: metav1.ObjectMeta{
641+
Name: "test-fn-default-replicas",
642+
Namespace: "default",
643+
},
644+
Spec: fsv1alpha1.FunctionSpec{
645+
Package: "test-pkg-replicas",
646+
Module: "mod",
647+
SubscriptionName: "sub-default",
648+
Sink: &fsv1alpha1.SinkSpec{Pulsar: &fsv1alpha1.PulsarSinkSpec{Topic: "out-default"}},
649+
RequestSource: &fsv1alpha1.SourceSpec{Pulsar: &fsv1alpha1.PulsarSourceSpec{Topic: "in-default"}},
650+
},
651+
}
652+
Expect(k8sClient.Create(ctx, fnDefault)).To(Succeed())
653+
654+
// Reconcile the Function with default replicas
655+
_, err = controllerReconciler.Reconcile(ctx, reconcile.Request{
656+
NamespacedName: types.NamespacedName{Name: fnDefault.Name, Namespace: fnDefault.Namespace},
657+
})
658+
Expect(err).NotTo(HaveOccurred())
659+
660+
// Check that the Deployment has default replicas (1)
661+
deployDefaultName := "function-" + fnDefault.Name
662+
deployDefault := &appsv1.Deployment{}
663+
Expect(k8sClient.Get(ctx, types.NamespacedName{Name: deployDefaultName, Namespace: fnDefault.Namespace}, deployDefault)).To(Succeed())
664+
Expect(deployDefault.Spec.Replicas).NotTo(BeNil())
665+
Expect(*deployDefault.Spec.Replicas).To(Equal(int32(1)))
666+
})
667+
562668
It("should handle Package updates in different namespaces", func() {
563669
By("creating Functions and Packages in different namespaces")
564670
controllerReconciler := &FunctionReconciler{

operator/scripts/deploy.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ spec:
8383
package:
8484
description: Package name
8585
type: string
86+
replicas:
87+
default: 1
88+
description: Number of replicas for the function deployment
89+
format: int32
90+
type: integer
8691
requestSource:
8792
description: Request source
8893
properties:

0 commit comments

Comments
 (0)