diff --git a/docs/cmd/kn_service_apply.md b/docs/cmd/kn_service_apply.md index 04448c46f..fa8167353 100644 --- a/docs/cmd/kn_service_apply.md +++ b/docs/cmd/kn_service_apply.md @@ -65,6 +65,7 @@ kn service apply s0 --filename my-svc.yml --request strings The resource requirement requests for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource request, append "-" to the resource name, e.g. '--request cpu-'. --revision-name string The revision name to set. Must start with the service name and a dash as a prefix. Empty revision name will result in the server generating a name for the revision. Accepts golang templates, allowing {{.Service}} for the service name, {{.Generation}} for the generation, and {{.Random [n]}} for n random consonants (e.g. {{.Service}}-{{.Random 5}}-{{.Generation}}) --scale string Set the Minimum and Maximum number of replicas. You can use this flag to set both to a single value, or set a range with min/max values, or set either min or max values without specifying the other. Example: --scale 5 (scale-min = 5, scale-max = 5) or --scale 1..5 (scale-min = 1, scale-max = 5) or --scale 1.. (scale-min = 1, scale-max = unchanged) or --scale ..5 (scale-min = unchanged, scale-max = 5) + --scale-activation int Minimum non-zero value that a service should scale to. --scale-init int Initial number of replicas with which a service starts. Can be 0 or a positive integer. --scale-max int Maximum number of replicas. --scale-metric string Set the name of the metric the PodAutoscaler should scale on. Example: --scale-metric rps (to scale on rps) or --scale-metric concurrency (to scale on concurrency). The default metric is concurrency. diff --git a/docs/cmd/kn_service_create.md b/docs/cmd/kn_service_create.md index 3133ec407..0221644dc 100644 --- a/docs/cmd/kn_service_create.md +++ b/docs/cmd/kn_service_create.md @@ -90,6 +90,7 @@ kn service create NAME --image IMAGE --request strings The resource requirement requests for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource request, append "-" to the resource name, e.g. '--request cpu-'. --revision-name string The revision name to set. Must start with the service name and a dash as a prefix. Empty revision name will result in the server generating a name for the revision. Accepts golang templates, allowing {{.Service}} for the service name, {{.Generation}} for the generation, and {{.Random [n]}} for n random consonants (e.g. {{.Service}}-{{.Random 5}}-{{.Generation}}) --scale string Set the Minimum and Maximum number of replicas. You can use this flag to set both to a single value, or set a range with min/max values, or set either min or max values without specifying the other. Example: --scale 5 (scale-min = 5, scale-max = 5) or --scale 1..5 (scale-min = 1, scale-max = 5) or --scale 1.. (scale-min = 1, scale-max = unchanged) or --scale ..5 (scale-min = unchanged, scale-max = 5) + --scale-activation int Minimum non-zero value that a service should scale to. --scale-init int Initial number of replicas with which a service starts. Can be 0 or a positive integer. --scale-max int Maximum number of replicas. --scale-metric string Set the name of the metric the PodAutoscaler should scale on. Example: --scale-metric rps (to scale on rps) or --scale-metric concurrency (to scale on concurrency). The default metric is concurrency. diff --git a/docs/cmd/kn_service_update.md b/docs/cmd/kn_service_update.md index 42295defe..892807317 100644 --- a/docs/cmd/kn_service_update.md +++ b/docs/cmd/kn_service_update.md @@ -77,6 +77,7 @@ kn service update NAME --request strings The resource requirement requests for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource request, append "-" to the resource name, e.g. '--request cpu-'. --revision-name string The revision name to set. Must start with the service name and a dash as a prefix. Empty revision name will result in the server generating a name for the revision. Accepts golang templates, allowing {{.Service}} for the service name, {{.Generation}} for the generation, and {{.Random [n]}} for n random consonants (e.g. {{.Service}}-{{.Random 5}}-{{.Generation}}) --scale string Set the Minimum and Maximum number of replicas. You can use this flag to set both to a single value, or set a range with min/max values, or set either min or max values without specifying the other. Example: --scale 5 (scale-min = 5, scale-max = 5) or --scale 1..5 (scale-min = 1, scale-max = 5) or --scale 1.. (scale-min = 1, scale-max = unchanged) or --scale ..5 (scale-min = unchanged, scale-max = 5) + --scale-activation int Minimum non-zero value that a service should scale to. --scale-init int Initial number of replicas with which a service starts. Can be 0 or a positive integer. --scale-max int Maximum number of replicas. --scale-metric string Set the name of the metric the PodAutoscaler should scale on. Example: --scale-metric rps (to scale on rps) or --scale-metric concurrency (to scale on concurrency). The default metric is concurrency. diff --git a/pkg/kn/commands/service/configuration_edit_flags.go b/pkg/kn/commands/service/configuration_edit_flags.go index b2dcbcba8..17c9798af 100644 --- a/pkg/kn/commands/service/configuration_edit_flags.go +++ b/pkg/kn/commands/service/configuration_edit_flags.go @@ -41,6 +41,7 @@ type ConfigurationEditFlags struct { Scale string MinScale int MaxScale int + ScaleActivation int ScaleTarget int ScaleMetric string ConcurrencyLimit int @@ -94,6 +95,9 @@ func (p *ConfigurationEditFlags) addSharedFlags(command *cobra.Command) { command.Flags().IntVar(&p.MaxScale, "scale-max", 0, "Maximum number of replicas.") p.markFlagMakesRevision("scale-max") + command.Flags().IntVar(&p.ScaleActivation, "scale-activation", 0, "Minimum non-zero value that a service should scale to.") + p.markFlagMakesRevision("scale-activation") + command.Flags().StringVar(&p.ScaleMetric, "scale-metric", "", "Set the name of the metric the PodAutoscaler should scale on. "+ "Example: --scale-metric rps (to scale on rps) or --scale-metric concurrency (to scale on concurrency). The default metric is concurrency.") p.markFlagMakesRevision("scale-metric") @@ -358,6 +362,10 @@ func (p *ConfigurationEditFlags) Apply( servinglib.UpdateScaleMetric(template, p.ScaleMetric) } + if cmd.Flags().Changed("scale-activation") { + servinglib.UpdateScaleActivation(template, p.ScaleActivation) + } + if cmd.Flags().Changed("concurrency-limit") { err = servinglib.UpdateConcurrencyLimit(template, int64(p.ConcurrencyLimit)) if err != nil { diff --git a/pkg/kn/commands/service/configuration_edit_flags_test.go b/pkg/kn/commands/service/configuration_edit_flags_test.go index e5596656d..853407e86 100644 --- a/pkg/kn/commands/service/configuration_edit_flags_test.go +++ b/pkg/kn/commands/service/configuration_edit_flags_test.go @@ -20,6 +20,7 @@ import ( "gotest.tools/v3/assert" "knative.dev/client/pkg/kn/commands" "knative.dev/client/pkg/util" + "knative.dev/serving/pkg/apis/autoscaling" ) func TestApplyPullPolicyFlag(t *testing.T) { @@ -60,3 +61,17 @@ func TestScaleMetric(t *testing.T) { err := editFlags.Apply(&svc, nil, cmd) assert.NilError(t, err) } + +func TestScaleActivation(t *testing.T) { + var editFlags ConfigurationEditFlags + knParams := &commands.KnParams{} + cmd, _, _ := commands.CreateTestKnCommand(NewServiceCreateCommand(knParams), knParams) + + editFlags.AddCreateFlags(cmd) + svc := createTestService("test-svc", []string{"test-svc-00001"}, goodConditions()) + cmd.SetArgs([]string{"--scale-activation", "2"}) + cmd.Execute() + err := editFlags.Apply(&svc, nil, cmd) + assert.NilError(t, err) + assert.Equal(t, svc.Spec.Template.Annotations[autoscaling.ActivationScaleKey], "2") +} diff --git a/pkg/serving/config_changes.go b/pkg/serving/config_changes.go index 56847797d..6e7b9a7b5 100644 --- a/pkg/serving/config_changes.go +++ b/pkg/serving/config_changes.go @@ -77,6 +77,11 @@ func UpdateScaleTarget(template *servingv1.RevisionTemplateSpec, target int) err return UpdateRevisionTemplateAnnotation(template, autoscaling.TargetAnnotationKey, strconv.Itoa(target)) } +//UpdateScaleActivation updates the scale activation annotation +func UpdateScaleActivation(template *servingv1.RevisionTemplateSpec, activation int) error { + return UpdateRevisionTemplateAnnotation(template, autoscaling.ActivationScaleKey, strconv.Itoa(activation)) +} + // UpdateScaleUtilization updates container target utilization percentage annotation func UpdateScaleUtilization(template *servingv1.RevisionTemplateSpec, target int) error { return UpdateRevisionTemplateAnnotation(template, autoscaling.TargetUtilizationPercentageKey, strconv.Itoa(target)) diff --git a/test/e2e/service_options_test.go b/test/e2e/service_options_test.go index ab11b01cc..ce1962c49 100644 --- a/test/e2e/service_options_test.go +++ b/test/e2e/service_options_test.go @@ -231,6 +231,10 @@ func TestServiceOptions(t *testing.T) { test.ServiceDelete(r, "svc17") _, err = kubectl.Run("delete", "-n", it.Namespace(), "configmap", "test-cm2") assert.NilError(t, err) + + t.Log("create and validate a service with scale activation") + serviceCreateWithOptions(r, "svc18", "--scale-activation", "2") + validateServiceActivation(r, "svc18", 2) } func serviceCreateWithOptions(r *test.KnRunResultCollector, serviceName string, options ...string) { @@ -384,3 +388,12 @@ func validateServiceEnvVariables(r *test.KnRunResultCollector, serviceName strin } } } + +func validateServiceActivation(r *test.KnRunResultCollector, serviceName string, activation int) { + out := r.KnTest().Kn().Run("service", "describe", serviceName, "-o", "json") + r.AssertNoError(out) + var svc servingv1.Service + json.Unmarshal([]byte(out.Stdout), &svc) + activationStr := strconv.Itoa(activation) + assert.Check(r.T(), svc.Spec.Template.Annotations[autoscaling.ActivationScaleKey] == activationStr) +}