diff --git a/buildermgr/envwatcher.go b/buildermgr/envwatcher.go index 30d17f40..d237380d 100644 --- a/buildermgr/envwatcher.go +++ b/buildermgr/envwatcher.go @@ -35,6 +35,7 @@ import ( "github.com/fission/fission" "github.com/fission/fission/crd" fetcherConfig "github.com/fission/fission/environments/fetcher/config" + "github.com/fission/fission/executor/util" ) type requestType int @@ -515,7 +516,7 @@ func (envw *environmentWatcher) createBuilderDeployment(env *crd.Environment, ns }, Spec: apiv1.PodSpec{ Containers: []apiv1.Container{ - fission.MergeContainerSpecs(&apiv1.Container{ + util.MergeContainerSpecs(&apiv1.Container{ Name: "builder", Image: env.Spec.Builder.Image, ImagePullPolicy: envw.builderImagePullPolicy, diff --git a/common.go b/common.go index 5ad55240..74927925 100644 --- a/common.go +++ b/common.go @@ -29,12 +29,10 @@ import ( "strings" "syscall" - "go.uber.org/zap" - "github.com/gorilla/handlers" - "github.com/imdario/mergo" "github.com/mholt/archiver" - "github.com/satori/go.uuid" + uuid "github.com/satori/go.uuid" + "go.uber.org/zap" apiv1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -97,25 +95,6 @@ func LoggingMiddleware(logger *zap.Logger) func(next http.Handler) http.Handler } } -// MergeContainerSpecs merges container specs using a predefined order. -// -// The order of the arguments indicates which spec has precedence (lower index takes precedence over higher indexes). -// Slices and maps are merged; other fields are set only if they are a zero value. -func MergeContainerSpecs(specs ...*apiv1.Container) apiv1.Container { - result := &apiv1.Container{} - for _, spec := range specs { - if spec == nil { - continue - } - - err := mergo.Merge(result, spec) - if err != nil { - panic(err) - } - } - return *result -} - // IsNetworkDialError returns true if its a network dial error func IsNetworkDialError(err error) bool { netErr, ok := err.(net.Error) diff --git a/executor/newdeploy/newdeploy.go b/executor/newdeploy/newdeploy.go index 55cc519e..9815fbf8 100644 --- a/executor/newdeploy/newdeploy.go +++ b/executor/newdeploy/newdeploy.go @@ -32,6 +32,7 @@ import ( "github.com/fission/fission" "github.com/fission/fission/crd" + "github.com/fission/fission/executor/util" multierror "github.com/hashicorp/go-multierror" ) @@ -200,7 +201,7 @@ func (deploy *NewDeploy) getDeploymentSpec(fn *crd.Function, env *crd.Environmen }, Spec: apiv1.PodSpec{ Containers: []apiv1.Container{ - fission.MergeContainerSpecs(&apiv1.Container{ + util.MergeContainerSpecs(&apiv1.Container{ Name: fn.Metadata.Name, Image: env.Spec.Runtime.Image, ImagePullPolicy: deploy.runtimeImagePullPolicy, @@ -225,12 +226,23 @@ func (deploy *NewDeploy) getDeploymentSpec(fn *crd.Function, env *crd.Environmen }, } - deploy.fetcherConfig.AddSpecializingFetcherToPodSpec( + // Order of merging is important here - first fetcher, then containers and lastly pod spec + err := deploy.fetcherConfig.AddSpecializingFetcherToPodSpec( &deployment.Spec.Template.Spec, fn.Metadata.Name, fn, env, ) + if err != nil { + return nil, err + } + + if env.Spec.Runtime.PodSpec != nil { + err := util.MergePodSpec(&deployment.Spec.Template.Spec, env.Spec.Runtime.PodSpec) + if err != nil { + return nil, err + } + } return deployment, nil } diff --git a/executor/poolmgr/gp.go b/executor/poolmgr/gp.go index 8195bd26..5ca168d4 100644 --- a/executor/poolmgr/gp.go +++ b/executor/poolmgr/gp.go @@ -41,6 +41,7 @@ import ( fetcherClient "github.com/fission/fission/environments/fetcher/client" fetcherConfig "github.com/fission/fission/environments/fetcher/config" "github.com/fission/fission/executor/fscache" + "github.com/fission/fission/executor/util" ) type ( @@ -371,7 +372,7 @@ func (gp *GenericPool) createPool() error { }, Spec: apiv1.PodSpec{ Containers: []apiv1.Container{ - fission.MergeContainerSpecs(&apiv1.Container{ + util.MergeContainerSpecs(&apiv1.Container{ Name: gp.env.Metadata.Name, Image: gp.env.Spec.Runtime.Image, ImagePullPolicy: gp.runtimeImagePullPolicy, @@ -405,11 +406,19 @@ func (gp *GenericPool) createPool() error { }, } + // Order of merging is important here - first fetcher, then containers and lastly pod spec err := gp.fetcherConfig.AddFetcherToPodSpec(&deployment.Spec.Template.Spec, gp.env.Metadata.Name) if err != nil { return err } + if gp.env.Spec.Runtime.PodSpec != nil { + err = util.MergePodSpec(&deployment.Spec.Template.Spec, gp.env.Spec.Runtime.PodSpec) + if err != nil { + return err + } + } + depl, err := gp.kubernetesClient.ExtensionsV1beta1().Deployments(gp.namespace).Create(deployment) if err != nil { gp.logger.Error("error creating deployment in kubernetes", zap.Error(err), zap.String("deployment", deployment.Name)) diff --git a/executor/util/merge.go b/executor/util/merge.go new file mode 100644 index 00000000..7b0aab28 --- /dev/null +++ b/executor/util/merge.go @@ -0,0 +1,219 @@ +/* +Copyright 2016 The Fission Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package util + +import ( + "errors" + + "github.com/hashicorp/go-multierror" + "github.com/imdario/mergo" + apiv1 "k8s.io/api/core/v1" +) + +// MergeContainerSpecs merges container specs using a predefined order. +// +// The order of the arguments indicates which spec has precedence (lower index takes precedence over higher indexes). +// Slices and maps are merged; other fields are set only if they are a zero value. +func MergeContainerSpecs(specs ...*apiv1.Container) apiv1.Container { + result := &apiv1.Container{} + for _, spec := range specs { + if spec == nil { + continue + } + + err := mergo.Merge(result, spec) + if err != nil { + panic(err) + } + } + return *result +} + +// mergeContainer is a specialized implementation of MergeContainerSpecs +func mergeContainer(deployContainer *apiv1.Container, containerSpec apiv1.Container) error { + + if &containerSpec == nil { + return nil + } + + if deployContainer.Name == containerSpec.Name { + volMap := make(map[string]*apiv1.VolumeMount) + for _, vol := range deployContainer.VolumeMounts { + volMap[vol.Name] = &vol + } + for _, specVol := range containerSpec.VolumeMounts { + _, ok := volMap[specVol.Name] + if ok { + return errors.New("Duplicate volume name found in the spec") + } else { + deployContainer.VolumeMounts = append(deployContainer.VolumeMounts, specVol) + } + } + deployContainer.Env = append(deployContainer.Env, containerSpec.Env...) + } + return nil +} + +func MergePodSpec(srcPodSpec *apiv1.PodSpec, targetPodSpec *apiv1.PodSpec) error { + if &targetPodSpec == nil { + return nil + } + + var multierr *multierror.Error + + // Get item from spec, if they exist in deployment - merge, else append + // Same pattern for all lists (Mergo can not handle lists) + // At some point this is better done with generics/reflection? + err := mergeContainerLists(srcPodSpec, targetPodSpec) + if err != nil { + return err + } + + err = mergeInitContainerList(srcPodSpec, targetPodSpec) + if err != nil { + return err + } + + // For volumes - if duplicate exist, throw error + err = mergeVolumeLists(srcPodSpec, targetPodSpec) + if err != nil { + return err + } + + if targetPodSpec.NodeName != "" { + srcPodSpec.NodeName = targetPodSpec.NodeName + } + + if targetPodSpec.Subdomain != "" { + srcPodSpec.Subdomain = targetPodSpec.Subdomain + } + + if targetPodSpec.SchedulerName != "" { + srcPodSpec.SchedulerName = targetPodSpec.SchedulerName + } + + if targetPodSpec.PriorityClassName != "" { + srcPodSpec.PriorityClassName = targetPodSpec.PriorityClassName + } + + if targetPodSpec.TerminationGracePeriodSeconds != nil { + srcPodSpec.TerminationGracePeriodSeconds = targetPodSpec.TerminationGracePeriodSeconds + } + + //TODO - Security context should be merged instead of overriding. + if targetPodSpec.SecurityContext != nil { + srcPodSpec.SecurityContext = targetPodSpec.SecurityContext + } + + //TODO - Affinity should be merged instead of overriding. + if targetPodSpec.Affinity != nil { + srcPodSpec.Affinity = targetPodSpec.Affinity + } + + if targetPodSpec.Hostname != "" { + srcPodSpec.Hostname = targetPodSpec.Hostname + } + + for _, obj := range targetPodSpec.ImagePullSecrets { + srcPodSpec.ImagePullSecrets = append(srcPodSpec.ImagePullSecrets, obj) + } + + for _, obj := range targetPodSpec.Tolerations { + srcPodSpec.Tolerations = append(srcPodSpec.Tolerations, obj) + } + + for _, obj := range targetPodSpec.HostAliases { + srcPodSpec.HostAliases = append(srcPodSpec.HostAliases, obj) + } + + err = mergo.Merge(&srcPodSpec.NodeSelector, targetPodSpec.NodeSelector) + if err != nil { + multierr = multierror.Append(multierr, err) + } + + return multierr.ErrorOrNil() +} + +func mergeContainerLists(srcPodSpec *apiv1.PodSpec, targetPodSpec *apiv1.PodSpec) error { + targetSpecContainers := targetPodSpec.Containers + targetContainers := make(map[string]apiv1.Container) + for _, c := range targetSpecContainers { + targetContainers[c.Name] = c + } + + var multierr *multierror.Error + for _, c := range srcPodSpec.Containers { + container, ok := targetContainers[c.Name] + if ok { + err := mergeContainer(&c, container) + multierr = multierror.Append(multierr, err) + delete(targetContainers, c.Name) + } + } + + for _, container := range targetContainers { + srcPodSpec.Containers = append(srcPodSpec.Containers, container) + } + + return multierr.ErrorOrNil() +} + +func mergeInitContainerList(srcPodSpec *apiv1.PodSpec, targetPodSpec *apiv1.PodSpec) error { + targetSpecContainers := targetPodSpec.InitContainers + targetContainers := make(map[string]apiv1.Container) + for _, c := range targetSpecContainers { + targetContainers[c.Name] = c + } + + var multierr *multierror.Error + for _, c := range srcPodSpec.InitContainers { + container, ok := targetContainers[c.Name] + if ok { + err := mergeContainer(&c, container) + multierr = multierror.Append(multierr, err) + delete(targetContainers, c.Name) + } + } + + for _, container := range targetContainers { + srcPodSpec.InitContainers = append(srcPodSpec.InitContainers, container) + } + return multierr.ErrorOrNil() +} + +func mergeVolumeLists(srcPodSpec *apiv1.PodSpec, targetPodSpec *apiv1.PodSpec) error { + volumeList := targetPodSpec.Volumes + specVolumes := make(map[string]apiv1.Volume) + for _, vol := range volumeList { + specVolumes[vol.Name] = vol + } + + var multierr *multierror.Error + for _, vol := range srcPodSpec.Volumes { + _, ok := specVolumes[vol.Name] + if ok { + multierr = multierror.Append(multierr, errors.New("Duplicate volume name found in the spec")) + } else { + delete(specVolumes, vol.Name) + } + } + + for _, volume := range specVolumes { + srcPodSpec.Volumes = append(srcPodSpec.Volumes, volume) + } + return multierr.ErrorOrNil() +} diff --git a/merge_test.go b/executor/util/merge_test.go similarity index 99% rename from merge_test.go rename to executor/util/merge_test.go index 40fdfd91..f218c086 100644 --- a/merge_test.go +++ b/executor/util/merge_test.go @@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -package fission +package util import ( "testing" diff --git a/fission/spec.go b/fission/spec.go index b038e2f5..51396323 100644 --- a/fission/spec.go +++ b/fission/spec.go @@ -32,7 +32,7 @@ import ( multierror "github.com/hashicorp/go-multierror" "github.com/mholt/archiver" "github.com/pkg/errors" - "github.com/satori/go.uuid" + uuid "github.com/satori/go.uuid" "github.com/urfave/cli" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -395,6 +395,9 @@ func (fr *FissionResources) validate() error { environments := make(map[string]struct{}) for _, e := range fr.environments { environments[fmt.Sprintf("%s:%s", e.Metadata.Name, e.Metadata.Namespace)] = struct{}{} + if (e.Spec.Runtime.Container != nil) && (e.Spec.Runtime.PodSpec != nil) { + log.Warn("You have provided both - container spec and pod spec and while merging the pod spec will take precedence.") + } } for _, f := range fr.functions { diff --git a/go.sum b/go.sum index 9c9c923d..8737ed9f 100644 --- a/go.sum +++ b/go.sum @@ -145,6 +145,7 @@ github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.8.0 h1:1921Yw9Gc3iSc4VQh3PIoOqgPCZS7G/4xQNVUp8Mda8= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -173,6 +174,7 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/ulikunitz/xz v0.0.0-20180703112113-636d36a76670 h1:HQWT4ta3wW5GZ790GaqLCS+w1dvuA3rMfEQxLi+UOYU= github.com/ulikunitz/xz v0.0.0-20180703112113-636d36a76670/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= diff --git a/pkg/apis/fission.io/v1/typefields.go b/pkg/apis/fission.io/v1/typefields.go index cfa699a7..49f9ce9d 100644 --- a/pkg/apis/fission.io/v1/typefields.go +++ b/pkg/apis/fission.io/v1/typefields.go @@ -223,6 +223,16 @@ type ( // - ImagePullPolicy // (optional) Container *apiv1.Container `json:"container,omitempty"` + + // Podspec allows modification of deployed runtime pod with Kubernetes PodSpec + // The merging logic is briefly described below and detailed MergePodSpec function + // - Volumes mounts and env variables for function and fetcher container are appended + // - All additional containers and init containers are appended + // - Volume definitions are appended + // - Lists such as tolerations, ImagePullSecrets, HostAliases are appended + // - Structs are merged and variables from pod spec take precedence + // (optional) + PodSpec *apiv1.PodSpec `json:"podspec,omitempty"` } Builder struct { diff --git a/preupgradechecks/pre-upgrade-checks b/preupgradechecks/pre-upgrade-checks new file mode 100755 index 00000000..b58ae371 Binary files /dev/null and b/preupgradechecks/pre-upgrade-checks differ diff --git a/test/test_utils.sh b/test/test_utils.sh index e4e00d82..f54c5b63 100755 --- a/test/test_utils.sh +++ b/test/test_utils.sh @@ -477,7 +477,8 @@ run_all_tests() { $ROOT/test/tests/test_pass.sh \ $ROOT/test/tests/test_router_cache_invalidation.sh \ $ROOT/test/tests/test_specs/test_spec.sh \ - $ROOT/test/tests/test_specs/test_spec_multifile.sh + $ROOT/test/tests/test_specs/test_spec_multifile.sh \ + $ROOT/test/tests/test_specs/test_spec_merge/test_spec_merge.sh FAILURES=$? # FIXME: run tests with newdeploy one by one. diff --git a/test/tests/test_specs/test_spec_merge/hello.js b/test/tests/test_specs/test_spec_merge/hello.js new file mode 100644 index 00000000..aa94dc47 --- /dev/null +++ b/test/tests/test_specs/test_spec_merge/hello.js @@ -0,0 +1,7 @@ + +module.exports = async function(context) { + return { + status: 200, + body: "hello, world!\n" + }; +} diff --git a/test/tests/test_specs/test_spec_merge/specs/README b/test/tests/test_specs/test_spec_merge/specs/README new file mode 100644 index 00000000..1db3f9a5 --- /dev/null +++ b/test/tests/test_specs/test_spec_merge/specs/README @@ -0,0 +1,42 @@ + +Fission Specs +============= + +This is a set of specifications for a Fission app. This includes functions, +environments, and triggers; we collectively call these things "resources". + +How to use these specs +---------------------- + +These specs are handled with the 'fission spec' command. See 'fission spec --help'. + +'fission spec apply' will "apply" all resources specified in this directory to your +cluster. That means it checks what resources exist on your cluster, what resources are +specified in the specs directory, and reconciles the difference by creating, updating or +deleting resources on the cluster. + +'fission spec apply' will also package up your source code (or compiled binaries) and +upload the archives to the cluster if needed. It uses 'ArchiveUploadSpec' resources in +this directory to figure out which files to archive. + +You can use 'fission spec apply --watch' to watch for file changes and continuously keep +the cluster updated. + +You can add YAMLs to this directory by writing them manually, but it's easier to generate +them. Use 'fission function create --spec' to generate a function spec, +'fission environment create --spec' to generate an environment spec, and so on. + +You can edit any of the files in this directory, except 'fission-deployment-config.yaml', +which contains a UID that you should never change. To apply your changes simply use +'fission spec apply'. + +fission-deployment-config.yaml +------------------------------ + +fission-deployment-config.yaml contains a UID. This UID is what fission uses to correlate +resources on the cluster to resources in this directory. + +All resources created by 'fission spec apply' are annotated with this UID. Resources on +the cluster that are _not_ annotated with this UID are never modified or deleted by +fission. + diff --git a/test/tests/test_specs/test_spec_merge/specs/env-nodend.yaml b/test/tests/test_specs/test_spec_merge/specs/env-nodend.yaml new file mode 100644 index 00000000..76c38d21 --- /dev/null +++ b/test/tests/test_specs/test_spec_merge/specs/env-nodend.yaml @@ -0,0 +1,72 @@ +apiVersion: fission.io/v1 +kind: Environment +metadata: + creationTimestamp: null + name: nodend + namespace: default +spec: + TerminationGracePeriod: 360 + builder: {} + keeparchive: false + poolsize: 0 + resources: {} + runtime: + functionendpointport: 0 + image: fission/node-env + loadendpointpath: "" + loadendpointport: 0 + container: + name: nodehellond + volumeMounts: + - name: cvol + mountPath: /etc/cvoldata + readOnly: true + podspec: + hostname: foo-bar + # A container which will be merged with for pool manager + Containers: + - name: nodehellond + image: fission/node-env + volumeMounts: + - name: funcvol + mountPath: /etc/funcdata + readOnly: true + # A additional container in the pods + - name: yanode + image: fission/node-env + command: ['sh', '-c', 'sleep 36000000000'] + # Init container before function + initContainers: + - name: init-node + image: fission/node-env + command: ['sh', '-c', 'cat /etc/infopod/labels'] + volumeMounts: + - name: infopod + mountPath: /etc/infopod + readOnly: false + tolerations: + - key: "reservation" + operator: "Equal" + value: "fission" + effect: "NoSchedule" + # Additional volumes + volumes: + - name: infopod + downwardAPI: + items: + - path: "labels" + fieldRef: + fieldPath: metadata.labels + - name: funcvol + downwardAPI: + items: + - path: "labels" + fieldRef: + fieldPath: metadata.labels + - name: cvol + downwardAPI: + items: + - path: "labels" + fieldRef: + fieldPath: metadata.labels + version: 1 diff --git a/test/tests/test_specs/test_spec_merge/specs/env-nodep.yaml b/test/tests/test_specs/test_spec_merge/specs/env-nodep.yaml new file mode 100644 index 00000000..ff546800 --- /dev/null +++ b/test/tests/test_specs/test_spec_merge/specs/env-nodep.yaml @@ -0,0 +1,72 @@ +apiVersion: fission.io/v1 +kind: Environment +metadata: + creationTimestamp: null + name: nodep + namespace: default +spec: + TerminationGracePeriod: 360 + builder: {} + keeparchive: false + poolsize: 3 + resources: {} + runtime: + functionendpointport: 0 + image: fission/node-env + loadendpointpath: "" + loadendpointport: 0 + container: + name: nodep + volumeMounts: + - name: cvol + mountPath: /etc/cvoldata + readOnly: true + podspec: + hostname: foo-bar + # A container which will be merged with for pool manager + Containers: + - name: nodep + image: fission/node-env + volumeMounts: + - name: funcvol + mountPath: /etc/funcdata + readOnly: true + # A additional container in the pods + - name: yanode + image: fission/node-env + command: ['sh', '-c', 'sleep 36000000000'] + # Init container before function + initContainers: + - name: init-node + image: fission/node-env + command: ['sh', '-c', 'cat /etc/infopod/labels'] + volumeMounts: + - name: infopod + mountPath: /etc/infopod + readOnly: false + tolerations: + - key: "reservation" + operator: "Equal" + value: "fission" + effect: "NoSchedule" + # Additional volumes + volumes: + - name: infopod + downwardAPI: + items: + - path: "labels" + fieldRef: + fieldPath: metadata.labels + - name: funcvol + downwardAPI: + items: + - path: "labels" + fieldRef: + fieldPath: metadata.labels + - name: cvol + downwardAPI: + items: + - path: "labels" + fieldRef: + fieldPath: metadata.labels + version: 1 diff --git a/test/tests/test_specs/test_spec_merge/specs/fission-deployment-config.yaml b/test/tests/test_specs/test_spec_merge/specs/fission-deployment-config.yaml new file mode 100644 index 00000000..e37ae869 --- /dev/null +++ b/test/tests/test_specs/test_spec_merge/specs/fission-deployment-config.yaml @@ -0,0 +1,7 @@ +# This file is generated by the 'fission spec init' command. +# See the README in this directory for background and usage information. +# Do not edit the UID below: that will break 'fission spec apply' +apiVersion: fission.io/v1 +kind: DeploymentConfig +name: spec-merge +uid: b1573a35-f3a2-45a8-a430-1f1a08d71177 diff --git a/test/tests/test_specs/test_spec_merge/specs/function-nodehellond.yaml b/test/tests/test_specs/test_spec_merge/specs/function-nodehellond.yaml new file mode 100644 index 00000000..3bf57b4e --- /dev/null +++ b/test/tests/test_specs/test_spec_merge/specs/function-nodehellond.yaml @@ -0,0 +1,24 @@ +apiVersion: fission.io/v1 +kind: Function +metadata: + creationTimestamp: null + name: nodehellond + namespace: default +spec: + InvokeStrategy: + ExecutionStrategy: + ExecutorType: newdeploy + MaxScale: 3 + MinScale: 1 + TargetCPUPercent: 80 + StrategyType: execution + configmaps: null + environment: + name: nodend + namespace: default + package: + packageref: + name: hello-js-vm2y + namespace: default + resources: {} + secrets: null diff --git a/test/tests/test_specs/test_spec_merge/specs/function-nodehellop.yaml b/test/tests/test_specs/test_spec_merge/specs/function-nodehellop.yaml new file mode 100644 index 00000000..524c482f --- /dev/null +++ b/test/tests/test_specs/test_spec_merge/specs/function-nodehellop.yaml @@ -0,0 +1,50 @@ +include: +- hello.js +kind: ArchiveUploadSpec +name: hello-js-leSC + +--- +apiVersion: fission.io/v1 +kind: Package +metadata: + creationTimestamp: null + name: hello-js-vm2y + namespace: default +spec: + deployment: + checksum: {} + type: url + url: archive://hello-js-leSC + environment: + name: nodep + namespace: default + source: + checksum: {} +status: + buildstatus: none + +--- +apiVersion: fission.io/v1 +kind: Function +metadata: + creationTimestamp: null + name: nodehellop + namespace: default +spec: + InvokeStrategy: + ExecutionStrategy: + ExecutorType: poolmgr + MaxScale: 0 + MinScale: 0 + TargetCPUPercent: 0 + StrategyType: execution + configmaps: null + environment: + name: nodep + namespace: default + package: + packageref: + name: hello-js-vm2y + namespace: default + resources: {} + secrets: null diff --git a/test/tests/test_specs/test_spec_merge/test_spec_merge.sh b/test/tests/test_specs/test_spec_merge/test_spec_merge.sh new file mode 100755 index 00000000..d822eeba --- /dev/null +++ b/test/tests/test_specs/test_spec_merge/test_spec_merge.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +set -euo pipefail + +env_p=nodep +fn_p=nodehellop +env_n=nodend +fn_nd=nodehellond + +cleanup() { + echo "Cleaning up..." + popd + fission spec destroy || true +} + +trap cleanup EXIT + +pushd $(dirname $0) + +fission spec apply + +fission fn test --name $fn_p + +fission fn test --name $fn_nd + +hnd=$(kubectl -n $FUNCTION_NAMESPACE get deployment -l=functionName=$fn_nd -ojsonpath='{.items[0].spec.template.spec.hostname}') + +if [[ "${hnd}" == "foo-bar" ]] + then + echo "Hostname matches for newdeployment function, podspec test 1/2 passsed" + fi + +hnp=$(kubectl -n $FUNCTION_NAMESPACE get deployment -l=environmentName=$env_p -ojsonpath='{.items[0].spec.template.spec.hostname}') + +if [[ "${hnp}" == "foo-bar" ]] + then + echo "Hostname matches for poolmgr function, podspec test 2/2 passsed" + fi \ No newline at end of file