Make NewDeployment specialization timeout configurable (#1260)
* Add specializationtimeout flag to function create/update * Set specialization timeout of 120 seconds if not present * Add default newdeploy timeout for rest of the test cases * Comment out specialization timeout in validations for compatibility * Add warning if specializationtimeout is lower than default value
This commit is contained in:
committed by
Ta-Ching Chen
parent
88b5343775
commit
80910562b3
@@ -167,10 +167,11 @@ type (
|
||||
and resources allocated to the function pod.
|
||||
*/
|
||||
ExecutionStrategy struct {
|
||||
ExecutorType ExecutorType
|
||||
MinScale int
|
||||
MaxScale int
|
||||
TargetCPUPercent int
|
||||
ExecutorType ExecutorType
|
||||
MinScale int
|
||||
MaxScale int
|
||||
TargetCPUPercent int
|
||||
SpecializationTimeout int
|
||||
}
|
||||
|
||||
FunctionReferenceType string
|
||||
|
||||
@@ -346,6 +346,11 @@ func (es ExecutionStrategy) Validate() error {
|
||||
if es.TargetCPUPercent <= 0 || es.TargetCPUPercent > 100 {
|
||||
result = multierror.Append(result, MakeValidationErr(ErrorInvalidValue, "ExecutionStrategy.TargetCPUPercent", es.TargetCPUPercent, "TargetCPUPercent must be a value between 1 - 100"))
|
||||
}
|
||||
|
||||
// TODO Add validation warning
|
||||
//if es.SpecializationTimeout < 120 {
|
||||
// result = multierror.Append(result, MakeValidationErr(ErrorInvalidValue, "ExecutionStrategy.SpecializationTimeout", es.SpecializationTimeout, "SpecializationTimeout must be a value equal to or greater than 120"))
|
||||
//}
|
||||
}
|
||||
|
||||
return result.ErrorOrNil()
|
||||
|
||||
@@ -38,14 +38,16 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
DeploymentKind = "Deployment"
|
||||
DeploymentVersion = "extensions/v1beta1"
|
||||
DeploymentKind = "Deployment"
|
||||
DeploymentVersion = "extensions/v1beta1"
|
||||
DEFAULT_SPECIALIZATION_TIMEOUT = 120
|
||||
)
|
||||
|
||||
func (deploy *NewDeploy) createOrGetDeployment(fn *fv1.Function, env *fv1.Environment,
|
||||
deployName string, deployLabels map[string]string, deployNamespace string, firstcreate bool) (*v1beta1.Deployment, error) {
|
||||
|
||||
minScale := int32(fn.Spec.InvokeStrategy.ExecutionStrategy.MinScale)
|
||||
specializationTimeout := int(fn.Spec.InvokeStrategy.ExecutionStrategy.SpecializationTimeout)
|
||||
|
||||
// If it's not the first time creation and minscale is 0 means that all pods for function were recycled,
|
||||
// in such cases we need set minscale to 1 for router to serve requests.
|
||||
@@ -65,7 +67,7 @@ func (deploy *NewDeploy) createOrGetDeployment(fn *fv1.Function, env *fv1.Enviro
|
||||
}
|
||||
|
||||
if existingDepl.Status.AvailableReplicas < minScale {
|
||||
existingDepl, err = deploy.waitForDeploy(existingDepl, minScale)
|
||||
existingDepl, err = deploy.waitForDeploy(existingDepl, minScale, specializationTimeout)
|
||||
}
|
||||
}
|
||||
return existingDepl, err
|
||||
@@ -93,7 +95,7 @@ func (deploy *NewDeploy) createOrGetDeployment(fn *fv1.Function, env *fv1.Enviro
|
||||
}
|
||||
|
||||
if waitForDeploy {
|
||||
depl, err = deploy.waitForDeploy(depl, minScale)
|
||||
depl, err = deploy.waitForDeploy(depl, minScale, specializationTimeout)
|
||||
}
|
||||
|
||||
return depl, err
|
||||
@@ -414,8 +416,13 @@ func (deploy *NewDeploy) deleteSvc(ns string, name string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (deploy *NewDeploy) waitForDeploy(depl *v1beta1.Deployment, replicas int32) (*v1beta1.Deployment, error) {
|
||||
for i := 0; i < 120; i++ {
|
||||
func (deploy *NewDeploy) waitForDeploy(depl *v1beta1.Deployment, replicas int32, specializationTimeout int) (*v1beta1.Deployment, error) {
|
||||
// if no specializationTimeout is set, use default value
|
||||
if specializationTimeout < DEFAULT_SPECIALIZATION_TIMEOUT {
|
||||
specializationTimeout = DEFAULT_SPECIALIZATION_TIMEOUT
|
||||
}
|
||||
|
||||
for i := 0; i < specializationTimeout; i++ {
|
||||
latestDepl, err := deploy.kubernetesClient.ExtensionsV1beta1().Deployments(depl.ObjectMeta.Namespace).Get(depl.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -428,7 +435,10 @@ func (deploy *NewDeploy) waitForDeploy(depl *v1beta1.Deployment, replicas int32)
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
return nil, errors.New("failed to create deployment within timeout window")
|
||||
|
||||
// this error appears in the executor pod logs
|
||||
timeoutError := fmt.Errorf("failed to create deployment within the timeout window of %d seconds", specializationTimeout)
|
||||
return nil, timeoutError
|
||||
}
|
||||
|
||||
// cleanupNewdeploy cleans all kubernetes objects related to function
|
||||
|
||||
@@ -29,7 +29,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/fission/fission/pkg/types"
|
||||
"github.com/satori/go.uuid"
|
||||
uuid "github.com/satori/go.uuid"
|
||||
"github.com/urfave/cli"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
@@ -43,8 +43,9 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
DEFAULT_MIN_SCALE = 1
|
||||
DEFAULT_TARGET_CPU_PERCENTAGE = 80
|
||||
DEFAULT_MIN_SCALE = 1
|
||||
DEFAULT_TARGET_CPU_PERCENTAGE = 80
|
||||
DEFAULT_SPECIALIZATION_TIMEOUT = 120
|
||||
)
|
||||
|
||||
func printPodLogs(c *cli.Context) error {
|
||||
@@ -101,6 +102,10 @@ func getInvokeStrategy(c *cli.Context, existingInvokeStrategy *fv1.InvokeStrateg
|
||||
fnExecutor = newFnExecutor
|
||||
}
|
||||
|
||||
if c.IsSet("specializationtimeout") && fnExecutor != types.ExecutorTypeNewdeploy {
|
||||
return nil, errors.New("specializationtimeout flag is only applicable for newdeploy type of executor")
|
||||
}
|
||||
|
||||
if fnExecutor == types.ExecutorTypePoolmgr {
|
||||
if c.IsSet("targetcpu") || c.IsSet("minscale") || c.IsSet("maxscale") {
|
||||
log.Fatal("To set target CPU or min/max scale for function, please specify \"--executortype newdeploy\"")
|
||||
@@ -120,11 +125,13 @@ func getInvokeStrategy(c *cli.Context, existingInvokeStrategy *fv1.InvokeStrateg
|
||||
targetCPU := DEFAULT_TARGET_CPU_PERCENTAGE
|
||||
minScale := DEFAULT_MIN_SCALE
|
||||
maxScale := minScale
|
||||
specializationTimeout := DEFAULT_SPECIALIZATION_TIMEOUT
|
||||
|
||||
if existingInvokeStrategy != nil && existingInvokeStrategy.ExecutionStrategy.ExecutorType == types.ExecutorTypeNewdeploy {
|
||||
minScale = existingInvokeStrategy.ExecutionStrategy.MinScale
|
||||
maxScale = existingInvokeStrategy.ExecutionStrategy.MaxScale
|
||||
targetCPU = existingInvokeStrategy.ExecutionStrategy.TargetCPUPercent
|
||||
specializationTimeout = existingInvokeStrategy.ExecutionStrategy.SpecializationTimeout
|
||||
}
|
||||
|
||||
if c.IsSet("targetcpu") {
|
||||
@@ -142,6 +149,13 @@ func getInvokeStrategy(c *cli.Context, existingInvokeStrategy *fv1.InvokeStrateg
|
||||
}
|
||||
}
|
||||
|
||||
if c.IsSet("specializationtimeout") {
|
||||
specializationTimeout = c.Int("specializationtimeout")
|
||||
if specializationTimeout < DEFAULT_SPECIALIZATION_TIMEOUT {
|
||||
return nil, errors.New("specializationtimeout must be greater than or equal to 120 seconds")
|
||||
}
|
||||
}
|
||||
|
||||
if minScale > maxScale {
|
||||
return nil, fmt.Errorf("minscale provided: %v can not be greater than maxscale value %v", minScale, maxScale)
|
||||
}
|
||||
@@ -151,10 +165,11 @@ func getInvokeStrategy(c *cli.Context, existingInvokeStrategy *fv1.InvokeStrateg
|
||||
strategy = &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
ExecutionStrategy: fv1.ExecutionStrategy{
|
||||
ExecutorType: fnExecutor,
|
||||
MinScale: minScale,
|
||||
MaxScale: maxScale,
|
||||
TargetCPUPercent: targetCPU,
|
||||
ExecutorType: fnExecutor,
|
||||
MinScale: minScale,
|
||||
MaxScale: maxScale,
|
||||
TargetCPUPercent: targetCPU,
|
||||
SpecializationTimeout: specializationTimeout,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -489,6 +504,7 @@ func fnUpdate(c *cli.Context) error {
|
||||
|
||||
secretName := c.String("secret")
|
||||
cfgMapName := c.String("configmap")
|
||||
specializationTimeout := c.Int("specializationtimeout")
|
||||
|
||||
if len(srcArchiveFiles) > 0 && len(deployArchiveFiles) > 0 {
|
||||
log.Fatal("Need either of --src or --deploy and not both arguments.")
|
||||
@@ -556,6 +572,19 @@ func fnUpdate(c *cli.Context) error {
|
||||
log.Fatal(err)
|
||||
}
|
||||
function.Spec.InvokeStrategy = *strategy
|
||||
|
||||
if c.IsSet("specializationtimeout") {
|
||||
if c.String("executortype") != types.ExecutorTypeNewdeploy {
|
||||
log.Fatal("specializationtimeout flag is only applicable for newdeploy type of executor")
|
||||
}
|
||||
|
||||
if specializationTimeout < DEFAULT_SPECIALIZATION_TIMEOUT {
|
||||
log.Fatal("specializationtimeout must be greater than or equal to 120 seconds")
|
||||
} else {
|
||||
function.Spec.InvokeStrategy.ExecutionStrategy.SpecializationTimeout = specializationTimeout
|
||||
}
|
||||
}
|
||||
|
||||
function.Spec.Resources = getResourceReq(c, function.Spec.Resources)
|
||||
|
||||
pkg, err := client.PackageGet(&metav1.ObjectMeta{
|
||||
|
||||
@@ -49,10 +49,11 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
expectedResult: &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
ExecutionStrategy: fv1.ExecutionStrategy{
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: DEFAULT_MIN_SCALE,
|
||||
MaxScale: DEFAULT_MIN_SCALE,
|
||||
TargetCPUPercent: DEFAULT_TARGET_CPU_PERCENTAGE,
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: DEFAULT_MIN_SCALE,
|
||||
MaxScale: DEFAULT_MIN_SCALE,
|
||||
TargetCPUPercent: DEFAULT_TARGET_CPU_PERCENTAGE,
|
||||
SpecializationTimeout: DEFAULT_SPECIALIZATION_TIMEOUT,
|
||||
},
|
||||
},
|
||||
expectError: false,
|
||||
@@ -69,10 +70,11 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
expectedResult: &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
ExecutionStrategy: fv1.ExecutionStrategy{
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: DEFAULT_MIN_SCALE,
|
||||
MaxScale: DEFAULT_MIN_SCALE,
|
||||
TargetCPUPercent: DEFAULT_TARGET_CPU_PERCENTAGE,
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: DEFAULT_MIN_SCALE,
|
||||
MaxScale: DEFAULT_MIN_SCALE,
|
||||
TargetCPUPercent: DEFAULT_TARGET_CPU_PERCENTAGE,
|
||||
SpecializationTimeout: DEFAULT_SPECIALIZATION_TIMEOUT,
|
||||
},
|
||||
},
|
||||
expectError: false,
|
||||
@@ -83,10 +85,11 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
existingInvokeStrategy: &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
ExecutionStrategy: fv1.ExecutionStrategy{
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: DEFAULT_MIN_SCALE,
|
||||
MaxScale: DEFAULT_MIN_SCALE,
|
||||
TargetCPUPercent: DEFAULT_TARGET_CPU_PERCENTAGE,
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: DEFAULT_MIN_SCALE,
|
||||
MaxScale: DEFAULT_MIN_SCALE,
|
||||
TargetCPUPercent: DEFAULT_TARGET_CPU_PERCENTAGE,
|
||||
SpecializationTimeout: DEFAULT_SPECIALIZATION_TIMEOUT,
|
||||
},
|
||||
},
|
||||
expectedResult: &fv1.InvokeStrategy{
|
||||
@@ -108,10 +111,11 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
expectedResult: &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
ExecutionStrategy: fv1.ExecutionStrategy{
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: 2,
|
||||
MaxScale: 3,
|
||||
TargetCPUPercent: DEFAULT_TARGET_CPU_PERCENTAGE,
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: 2,
|
||||
MaxScale: 3,
|
||||
TargetCPUPercent: DEFAULT_TARGET_CPU_PERCENTAGE,
|
||||
SpecializationTimeout: DEFAULT_SPECIALIZATION_TIMEOUT,
|
||||
},
|
||||
},
|
||||
expectError: false,
|
||||
@@ -147,10 +151,11 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
expectedResult: &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
ExecutionStrategy: fv1.ExecutionStrategy{
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: DEFAULT_MIN_SCALE,
|
||||
MaxScale: 3,
|
||||
TargetCPUPercent: DEFAULT_TARGET_CPU_PERCENTAGE,
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: DEFAULT_MIN_SCALE,
|
||||
MaxScale: 3,
|
||||
TargetCPUPercent: DEFAULT_TARGET_CPU_PERCENTAGE,
|
||||
SpecializationTimeout: DEFAULT_SPECIALIZATION_TIMEOUT,
|
||||
},
|
||||
},
|
||||
expectError: false,
|
||||
@@ -174,19 +179,21 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
existingInvokeStrategy: &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
ExecutionStrategy: fv1.ExecutionStrategy{
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: 2,
|
||||
MaxScale: 5,
|
||||
TargetCPUPercent: DEFAULT_TARGET_CPU_PERCENTAGE,
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: 2,
|
||||
MaxScale: 5,
|
||||
TargetCPUPercent: DEFAULT_TARGET_CPU_PERCENTAGE,
|
||||
SpecializationTimeout: DEFAULT_SPECIALIZATION_TIMEOUT,
|
||||
},
|
||||
},
|
||||
expectedResult: &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
ExecutionStrategy: fv1.ExecutionStrategy{
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: 2,
|
||||
MaxScale: 9,
|
||||
TargetCPUPercent: DEFAULT_TARGET_CPU_PERCENTAGE,
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: 2,
|
||||
MaxScale: 9,
|
||||
TargetCPUPercent: DEFAULT_TARGET_CPU_PERCENTAGE,
|
||||
SpecializationTimeout: DEFAULT_SPECIALIZATION_TIMEOUT,
|
||||
},
|
||||
},
|
||||
expectError: false,
|
||||
@@ -199,19 +206,21 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
existingInvokeStrategy: &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
ExecutionStrategy: fv1.ExecutionStrategy{
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: 2,
|
||||
MaxScale: 5,
|
||||
TargetCPUPercent: DEFAULT_TARGET_CPU_PERCENTAGE,
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: 2,
|
||||
MaxScale: 5,
|
||||
TargetCPUPercent: DEFAULT_TARGET_CPU_PERCENTAGE,
|
||||
SpecializationTimeout: DEFAULT_SPECIALIZATION_TIMEOUT,
|
||||
},
|
||||
},
|
||||
expectedResult: &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
ExecutionStrategy: fv1.ExecutionStrategy{
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: 2,
|
||||
MaxScale: 5,
|
||||
TargetCPUPercent: DEFAULT_TARGET_CPU_PERCENTAGE,
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: 2,
|
||||
MaxScale: 5,
|
||||
TargetCPUPercent: DEFAULT_TARGET_CPU_PERCENTAGE,
|
||||
SpecializationTimeout: DEFAULT_SPECIALIZATION_TIMEOUT,
|
||||
},
|
||||
},
|
||||
expectError: false,
|
||||
@@ -226,10 +235,11 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
expectedResult: &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
ExecutionStrategy: fv1.ExecutionStrategy{
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: DEFAULT_MIN_SCALE,
|
||||
MaxScale: DEFAULT_MIN_SCALE,
|
||||
TargetCPUPercent: 50,
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: DEFAULT_MIN_SCALE,
|
||||
MaxScale: DEFAULT_MIN_SCALE,
|
||||
TargetCPUPercent: 50,
|
||||
SpecializationTimeout: DEFAULT_SPECIALIZATION_TIMEOUT,
|
||||
},
|
||||
},
|
||||
expectError: false,
|
||||
@@ -243,23 +253,72 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
existingInvokeStrategy: &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
ExecutionStrategy: fv1.ExecutionStrategy{
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: 2,
|
||||
MaxScale: 5,
|
||||
TargetCPUPercent: 88,
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: 2,
|
||||
MaxScale: 5,
|
||||
TargetCPUPercent: 88,
|
||||
SpecializationTimeout: DEFAULT_SPECIALIZATION_TIMEOUT,
|
||||
},
|
||||
},
|
||||
expectedResult: &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
ExecutionStrategy: fv1.ExecutionStrategy{
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: 2,
|
||||
MaxScale: 5,
|
||||
TargetCPUPercent: 20,
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: 2,
|
||||
MaxScale: 5,
|
||||
TargetCPUPercent: 20,
|
||||
SpecializationTimeout: DEFAULT_SPECIALIZATION_TIMEOUT,
|
||||
},
|
||||
},
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
// case: change specializationtimeout
|
||||
testArgs: map[string]string{
|
||||
"executortype": fv1.ExecutorTypeNewdeploy,
|
||||
"specializationtimeout": "200",
|
||||
},
|
||||
existingInvokeStrategy: &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
ExecutionStrategy: fv1.ExecutionStrategy{
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: 2,
|
||||
MaxScale: 5,
|
||||
TargetCPUPercent: DEFAULT_TARGET_CPU_PERCENTAGE,
|
||||
},
|
||||
},
|
||||
expectedResult: &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
ExecutionStrategy: fv1.ExecutionStrategy{
|
||||
ExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
MinScale: 2,
|
||||
MaxScale: 5,
|
||||
SpecializationTimeout: 200,
|
||||
TargetCPUPercent: DEFAULT_TARGET_CPU_PERCENTAGE,
|
||||
},
|
||||
},
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
// case: specializationtimeout should not work for poolmgr
|
||||
testArgs: map[string]string{
|
||||
"executortype": fv1.ExecutorTypePoolmgr,
|
||||
"specializationtimeout": "10",
|
||||
},
|
||||
existingInvokeStrategy: nil,
|
||||
expectedResult: nil,
|
||||
expectError: true,
|
||||
},
|
||||
{
|
||||
// case: specializationtimeout should not be less than 120
|
||||
testArgs: map[string]string{
|
||||
"executortype": fv1.ExecutorTypeNewdeploy,
|
||||
"specializationtimeout": "90",
|
||||
},
|
||||
existingInvokeStrategy: nil,
|
||||
expectedResult: nil,
|
||||
expectError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
|
||||
@@ -94,6 +94,7 @@ func NewCliApp() *cli.App {
|
||||
minScale := cli.IntFlag{Name: "minscale", Usage: "Minimum number of pods (Uses resource inputs to configure HPA)"}
|
||||
maxScale := cli.IntFlag{Name: "maxscale", Usage: "Maximum number of pods (Uses resource inputs to configure HPA)"}
|
||||
targetcpu := cli.IntFlag{Name: "targetcpu", Usage: "Target average CPU usage percentage across pods for scaling"}
|
||||
specializationTimeoutFlag := cli.IntFlag{Name: "specializationtimeout, st", Usage: "Timeout for newdeploy to wait for function pod creation"}
|
||||
|
||||
// functions
|
||||
fnNameFlag := cli.StringFlag{Name: "name", Usage: "function name"}
|
||||
@@ -119,10 +120,10 @@ func NewCliApp() *cli.App {
|
||||
fnTimeoutFlag := cli.DurationFlag{Name: "timeout, t", Value: 30 * time.Second, Usage: "The length of time to wait for the response. If set to zero or negative number, no timeout is set."}
|
||||
|
||||
fnSubcommands := []cli.Command{
|
||||
{Name: "create", Usage: "Create new function (and optionally, an HTTP route to it)", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag, fnEnvNameFlag, envNamespaceFlag, specSaveFlag, fnCodeFlag, fnSrcArchiveFlag, fnDeployArchiveFlag, fnEntryPointFlag, fnBuildCmdFlag, fnPkgNameFlag, htUrlFlag, htMethodFlag, minCpu, maxCpu, minMem, maxMem, minScale, maxScale, fnExecutorTypeFlag, targetcpu, fnCfgMapFlag, fnSecretFlag}, Action: fnCreate},
|
||||
{Name: "create", Usage: "Create new function (and optionally, an HTTP route to it)", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag, fnEnvNameFlag, envNamespaceFlag, specSaveFlag, fnCodeFlag, fnSrcArchiveFlag, fnDeployArchiveFlag, fnEntryPointFlag, fnBuildCmdFlag, fnPkgNameFlag, htUrlFlag, htMethodFlag, minCpu, maxCpu, minMem, maxMem, minScale, maxScale, fnExecutorTypeFlag, targetcpu, fnCfgMapFlag, fnSecretFlag, specializationTimeoutFlag}, Action: fnCreate},
|
||||
{Name: "get", Usage: "Get function source code", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag}, Action: fnGet},
|
||||
{Name: "getmeta", Usage: "Get function metadata", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag}, Action: fnGetMeta},
|
||||
{Name: "update", Usage: "Update function source code", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag, fnEnvNameFlag, envNamespaceFlag, fnCodeFlag, fnSrcArchiveFlag, fnDeployArchiveFlag, fnEntryPointFlag, fnPkgNameFlag, pkgNamespaceFlag, fnBuildCmdFlag, fnForceFlag, minCpu, maxCpu, minMem, maxMem, minScale, maxScale, fnExecutorTypeFlag, targetcpu}, Action: fnUpdate},
|
||||
{Name: "update", Usage: "Update function source code", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag, fnEnvNameFlag, envNamespaceFlag, fnCodeFlag, fnSrcArchiveFlag, fnDeployArchiveFlag, fnEntryPointFlag, fnPkgNameFlag, pkgNamespaceFlag, fnBuildCmdFlag, fnForceFlag, minCpu, maxCpu, minMem, maxMem, minScale, maxScale, fnExecutorTypeFlag, targetcpu, specializationTimeoutFlag}, Action: fnUpdate},
|
||||
{Name: "delete", Usage: "Delete function", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag}, Action: fnDelete},
|
||||
// TODO : for fnList, i feel like it's nice to allow --fns all, to list functions across all namespaces for cluster admins, although, this is against ns isolation.
|
||||
// so, in the future, if we end up using kubeconfig in fission cli and enforcing rolebindings to be created for users by admins etc, we can add this option at the time.
|
||||
|
||||
@@ -437,6 +437,10 @@ func (fr *FissionResources) validate(c *cli.Context) error {
|
||||
if _, ok := environments[fmt.Sprintf("%s:%s", f.Spec.Environment.Name, f.Spec.Environment.Namespace)]; !ok {
|
||||
log.Warn(fmt.Sprintf("Environment %s is referenced in function %s but not declared in specs", f.Spec.Environment.Name, f.Metadata.Name))
|
||||
}
|
||||
strategy := f.Spec.InvokeStrategy.ExecutionStrategy
|
||||
if strategy.ExecutorType == fv1.ExecutorTypeNewdeploy && strategy.SpecializationTimeout < DEFAULT_SPECIALIZATION_TIMEOUT {
|
||||
log.Warn(fmt.Sprintf("SpecializationTimeout in function spec.InvokeStrategy.ExecutionStrategy should be a value equal to or greater than %v", DEFAULT_SPECIALIZATION_TIMEOUT))
|
||||
}
|
||||
}
|
||||
|
||||
// (ErrorOrNil returns nil if there were no errors appended.)
|
||||
|
||||
Reference in New Issue
Block a user