diff --git a/examples/build_image.sh b/examples/build_image.sh index 6588ae7be..a94ef0acb 100755 --- a/examples/build_image.sh +++ b/examples/build_image.sh @@ -61,11 +61,11 @@ IMAGE_TAG=${IMAGE_TAG:-v0.5.0} EXAMPLE_REPO_PREFIX=${IMAGE_REPO}/sedna-example- dockerfiles_multiedgeinference=( -multi-edge-inference-feature-extraction.Dockerfile -# multi-edge-inference-gpu-feature-extraction.Dockerfile -# multi-edge-inference-gpu-videoanalytics.Dockerfile -multi-edge-inference-reid.Dockerfile -multi-edge-inference-videoanalytics.Dockerfile +multi-edge-inference-pedestrian-tracking-feature-extraction.Dockerfile +# multi-edge-inference-pedestrian-tracking-gpu-feature-extraction.Dockerfile +# multi-edge-inference-pedestrian-tracking-gpu-videoanalytics.Dockerfile +multi-edge-inference-pedestrian-tracking-reid.Dockerfile +multi-edge-inference-pedestrian-tracking-videoanalytics.Dockerfile ) dockerfiles_federated_learning=( diff --git a/examples/multi-edge-inference-feature-extraction.Dockerfile b/examples/multi-edge-inference-pedestrian-tracking-feature-extraction.Dockerfile similarity index 100% rename from examples/multi-edge-inference-feature-extraction.Dockerfile rename to examples/multi-edge-inference-pedestrian-tracking-feature-extraction.Dockerfile diff --git a/examples/multi-edge-inference-gpu-feature-extraction.Dockerfile b/examples/multi-edge-inference-pedestrian-tracking-gpu-feature-extraction.Dockerfile similarity index 100% rename from examples/multi-edge-inference-gpu-feature-extraction.Dockerfile rename to examples/multi-edge-inference-pedestrian-tracking-gpu-feature-extraction.Dockerfile diff --git a/examples/multi-edge-inference-gpu-videoanalytics.Dockerfile b/examples/multi-edge-inference-pedestrian-tracking-gpu-videoanalytics.Dockerfile similarity index 100% rename from examples/multi-edge-inference-gpu-videoanalytics.Dockerfile rename to examples/multi-edge-inference-pedestrian-tracking-gpu-videoanalytics.Dockerfile diff --git a/examples/multi-edge-inference-reid.Dockerfile b/examples/multi-edge-inference-pedestrian-tracking-reid.Dockerfile similarity index 100% rename from examples/multi-edge-inference-reid.Dockerfile rename to examples/multi-edge-inference-pedestrian-tracking-reid.Dockerfile diff --git a/examples/multi-edge-inference-videoanalytics.Dockerfile b/examples/multi-edge-inference-pedestrian-tracking-videoanalytics.Dockerfile similarity index 100% rename from examples/multi-edge-inference-videoanalytics.Dockerfile rename to examples/multi-edge-inference-pedestrian-tracking-videoanalytics.Dockerfile diff --git a/examples/multiedgeinference/pedestrian_tracking/README.md b/examples/multiedgeinference/pedestrian_tracking/README.md index 1c14f46e5..86cd26430 100644 --- a/examples/multiedgeinference/pedestrian_tracking/README.md +++ b/examples/multiedgeinference/pedestrian_tracking/README.md @@ -32,14 +32,14 @@ The image below shows the system architecture and its simplified workflow: - Available for CPU only. - Folder with specific implementation `examples/multiedgeinference/pedestrian_tracking/reid`. - Component specs in `lib/sedna/core/multi_edge_inference/components/reid.py`. -- Defined by the Dockerfile `multi-edge-inference-reid.Dockerfile`. +- Defined by the Dockerfile `multi-edge-inference-pedestrian-tracking-reid.Dockerfile`. **Feature Extraction Service**: it performs the extraction of the features necessary for the ReID step. - Available for CPU and GPU. - Folder with specific implementation details `examples/multiedgeinference/pedestrian_tracking/feature_extraction`. - Component specs in `lib/sedna/core/multi_edge_inference/components/feature_extraction.py`. -- Defined by the Dockerfile `multi-edge-inference-feature-extraction.Dockerfile` or `multi-edge-inference-gpu-feature-extraction.Dockerfile`. +- Defined by the Dockerfile `multi-edge-inference-pedestrian-tracking-feature-extraction.Dockerfile` or `multi-edge-inference-pedestrian-tracking-gpu-feature-extraction.Dockerfile`. - It loads the model defined by the CRD in the YAML file `yaml/models/model_m3l.yaml`. **VideoAnalytics Job**: it performs tracking of objects (pedestrians) in a video. @@ -48,7 +48,7 @@ The image below shows the system architecture and its simplified workflow: - Folder with specific implementation details `examples/multiedgeinference/pedestrian_tracking/detection`. - AI model code in `examples/multiedgeinference/detection/estimator/bytetracker.py`. - Component specs in `lib/sedna/core/multi_edge_inference/components/detection.py`. -- Defined by the Dockerfile `multi-edge-inference-videoanalytics.Dockerfile` or `multi-edge-inference-gpu-videoanalytics.Dockerfile`. +- Defined by the Dockerfile `multi-edge-inference-pedestrian-tracking-videoanalytics.Dockerfile` or `multi-edge-inference-pedestrian-tracking-gpu-videoanalytics.Dockerfile`. - It loads the model defined by the CRD in the YAML file `yaml/models/model_detection.yaml`. # Build Phase diff --git a/examples/multiedgeinference/pedestrian_tracking/yaml/feature-extraction-service.yaml b/examples/multiedgeinference/pedestrian_tracking/yaml/feature-extraction-service.yaml index 0925af279..37d08aa21 100644 --- a/examples/multiedgeinference/pedestrian_tracking/yaml/feature-extraction-service.yaml +++ b/examples/multiedgeinference/pedestrian_tracking/yaml/feature-extraction-service.yaml @@ -18,7 +18,7 @@ spec: nodeSelector: node-role.kubernetes.io/master: '' containers: - - image: registry-cbu.huawei.com/kubeedge/sedna-example-multi-edge-inference-feature-extraction:v0.5.0 + - image: kubeedge/sedna-example-multi-edge-inference-pedestrian-tracking-feature-extraction:v0.5.0 imagePullPolicy: Always name: feature-extraction env: diff --git a/examples/multiedgeinference/pedestrian_tracking/yaml/reid-job.yaml b/examples/multiedgeinference/pedestrian_tracking/yaml/reid-job.yaml index 2b9b1f0b3..f3a5f8dd9 100644 --- a/examples/multiedgeinference/pedestrian_tracking/yaml/reid-job.yaml +++ b/examples/multiedgeinference/pedestrian_tracking/yaml/reid-job.yaml @@ -1,4 +1,4 @@ -apiVersion: sedna.io/v1alpha1 + apiVersion: sedna.io/v1alpha1 kind: ReidJob metadata: name: reid @@ -10,7 +10,7 @@ spec: nodeSelector: node-role.kubernetes.io/master: '' containers: - - image: registry-cbu.huawei.com/kubeedge/sedna-example-multi-edge-inference-reid:v0.5.0 + - image: kubeedge/sedna-example-multi-edge-inference-pedestrian-tracking-reid:v0.5.0 name: reid imagePullPolicy: Always env: diff --git a/examples/multiedgeinference/pedestrian_tracking/yaml/video-analytics-job.yaml b/examples/multiedgeinference/pedestrian_tracking/yaml/video-analytics-job.yaml index e32e94610..eb524cb4f 100644 --- a/examples/multiedgeinference/pedestrian_tracking/yaml/video-analytics-job.yaml +++ b/examples/multiedgeinference/pedestrian_tracking/yaml/video-analytics-job.yaml @@ -12,7 +12,7 @@ spec: nodeSelector: node-role.kubernetes.io/master: '' containers: - - image: registry-cbu.huawei.com/kubeedge/sedna-example-multi-edge-inference-videoanalytics:sase + - image: kubeedge/sedna-example-multi-edge-inference-pedestrian-tracking-videoanalytics:v0.5.0 imagePullPolicy: Always name: detection env: diff --git a/pkg/globalmanager/runtime/storage_initializer_injector.go b/pkg/globalmanager/runtime/storage_initializer_injector.go index d19c43d20..c8af83c09 100644 --- a/pkg/globalmanager/runtime/storage_initializer_injector.go +++ b/pkg/globalmanager/runtime/storage_initializer_injector.go @@ -21,6 +21,7 @@ import ( "path/filepath" "strings" + appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" "k8s.io/klog/v2" @@ -171,58 +172,60 @@ func (m *MountURL) parseSecret() { } func injectHostPathMount(pod *v1.Pod, workerParam *WorkerParam) { - var volumes []v1.Volume - var volumeMounts []v1.VolumeMount - var initContainerVolumeMounts []v1.VolumeMount + volumes, volumeMounts, initContainerVolumeMounts := PrepareHostPath(workerParam) - uniqVolumeName := make(map[string]bool) - uniqMountPath := make(map[string]bool) + injectVolume(pod, volumes, volumeMounts) - hostPathType := v1.HostPathDirectory + if len(volumeMounts) > 0 { + hostPathEnvs := []v1.EnvVar{ + { + Name: hostPathPrefixEnvKey, + Value: hostPathPrefix, + }, + } + injectEnvs(pod, hostPathEnvs) + } + if len(initContainerVolumeMounts) > 0 { + initIdx := len(pod.Spec.InitContainers) - 1 + pod.Spec.InitContainers[initIdx].VolumeMounts = append( + pod.Spec.InitContainers[initIdx].VolumeMounts, + initContainerVolumeMounts..., + ) + } +} + +func injectWorkerSecrets(pod *v1.Pod, workerParam *WorkerParam) { + var secretEnvs []v1.EnvVar for _, mount := range workerParam.Mounts { for _, m := range mount.URLs { - if m.HostPath == "" { + if m.Disable || m.DownloadByInitializer { continue } - - volumeName := ConvertK8SValidName(m.HostPath) - - if len(volumeName) == 0 { - volumeName = defaultVolumeName - klog.Warningf("failed to get name from url(%s), fallback to default name(%s)", m.URL, volumeName) - } - - if _, ok := uniqVolumeName[volumeName]; !ok { - volumes = append(volumes, v1.Volume{ - Name: volumeName, - VolumeSource: v1.VolumeSource{ - HostPath: &v1.HostPathVolumeSource{ - Path: m.HostPath, - Type: &hostPathType, - }, - }, - }) - uniqVolumeName[volumeName] = true + if len(m.SecretEnvs) > 0 { + secretEnvs = MergeSecretEnvs(secretEnvs, m.SecretEnvs, false) } + } + } + injectEnvs(pod, secretEnvs) +} - if _, ok := uniqMountPath[m.MountPath]; !ok { - vm := v1.VolumeMount{ - MountPath: m.MountPath, - Name: volumeName, - } +func injectInitializerContainer(pod *v1.Pod, workerParam *WorkerParam) { + volumes, volumeMounts, initContainer := PrepareInitContainer(workerParam) - if m.Indirect { - initContainerVolumeMounts = append(initContainerVolumeMounts, vm) - } else { - volumeMounts = append(volumeMounts, vm) - } - uniqMountPath[m.MountPath] = true - } - } + if (len(volumes) > 0) && (len(volumeMounts) > 0) && &initContainer != nil { + pod.Spec.InitContainers = append(pod.Spec.InitContainers, *initContainer) + injectVolume(pod, volumes, volumeMounts) } +} - injectVolume(pod, volumes, volumeMounts) +/* + Deployment Storage Hooks +*/ + +func injectHostPathMountDeployment(deployment *appsv1.Deployment, workerParam *WorkerParam) { + volumes, volumeMounts, initContainerVolumeMounts := PrepareHostPath(workerParam) + injectVolumeDeployment(deployment, volumes, volumeMounts) if len(volumeMounts) > 0 { hostPathEnvs := []v1.EnvVar{ @@ -231,19 +234,147 @@ func injectHostPathMount(pod *v1.Pod, workerParam *WorkerParam) { Value: hostPathPrefix, }, } - injectEnvs(pod, hostPathEnvs) + injectEnvsDeployment(deployment, hostPathEnvs) } if len(initContainerVolumeMounts) > 0 { - initIdx := len(pod.Spec.InitContainers) - 1 - pod.Spec.InitContainers[initIdx].VolumeMounts = append( - pod.Spec.InitContainers[initIdx].VolumeMounts, + initIdx := len(deployment.Spec.Template.Spec.InitContainers) - 1 + deployment.Spec.Template.Spec.InitContainers[initIdx].VolumeMounts = append( + deployment.Spec.Template.Spec.InitContainers[initIdx].VolumeMounts, initContainerVolumeMounts..., ) } } -func injectWorkerSecrets(pod *v1.Pod, workerParam *WorkerParam) { +func injectWorkerSecretsDeployment(deployment *appsv1.Deployment, workerParam *WorkerParam) { + secretEnvs := PrepareSecret(workerParam) + injectEnvsDeployment(deployment, secretEnvs) +} + +func injectInitializerContainerDeployment(deployment *appsv1.Deployment, workerParam *WorkerParam) { + volumes, volumeMounts, initContainer := PrepareInitContainer(workerParam) + + if (len(volumes) > 0) && (len(volumeMounts) > 0) && &initContainer != nil { + deployment.Spec.Template.Spec.InitContainers = append(deployment.Spec.Template.Spec.InitContainers, *initContainer) + injectVolumeDeployment(deployment, volumes, volumeMounts) + } +} + +// InjectStorageInitializer injects these storage related volumes and envs into deployment in-place +func InjectStorageInitializerDeployment(deployment *appsv1.Deployment, workerParam *WorkerParam) { + PrepareStorage(workerParam) + + // need to call injectInitializerContainer before injectHostPathMount + // since injectHostPathMount could inject volumeMount to init container + injectInitializerContainerDeployment(deployment, workerParam) + injectHostPathMountDeployment(deployment, workerParam) + injectWorkerSecretsDeployment(deployment, workerParam) +} + +func injectVolumeDeployment(deployment *appsv1.Deployment, volumes []v1.Volume, volumeMounts []v1.VolumeMount) { + if len(volumes) > 0 { + deployment.Spec.Template.Spec.Volumes = append(deployment.Spec.Template.Spec.Volumes, volumes...) + } + + if len(volumeMounts) > 0 { + for idx := range deployment.Spec.Template.Spec.Containers { + // inject every containers + deployment.Spec.Template.Spec.Containers[idx].VolumeMounts = append( + deployment.Spec.Template.Spec.Containers[idx].VolumeMounts, volumeMounts..., + ) + } + } +} + +func injectEnvsDeployment(deployment *appsv1.Deployment, envs []v1.EnvVar) { + if len(envs) > 0 { + for idx := range deployment.Spec.Template.Spec.Containers { + // inject every containers + deployment.Spec.Template.Spec.Containers[idx].Env = append( + deployment.Spec.Template.Spec.Containers[idx].Env, envs..., + ) + } + } +} + +// InjectStorageInitializer injects these storage related volumes and envs into pod in-place +func InjectStorageInitializer(pod *v1.Pod, workerParam *WorkerParam) { + PrepareStorage(workerParam) + + // need to call injectInitializerContainer before injectHostPathMount + // since injectHostPathMount could inject volumeMount to init container + injectInitializerContainer(pod, workerParam) + injectHostPathMount(pod, workerParam) + injectWorkerSecrets(pod, workerParam) +} + +func injectVolume(pod *v1.Pod, volumes []v1.Volume, volumeMounts []v1.VolumeMount) { + if len(volumes) > 0 { + pod.Spec.Volumes = append(pod.Spec.Volumes, volumes...) + } + + if len(volumeMounts) > 0 { + for idx := range pod.Spec.Containers { + // inject every containers + pod.Spec.Containers[idx].VolumeMounts = append( + pod.Spec.Containers[idx].VolumeMounts, volumeMounts..., + ) + } + } +} + +func injectEnvs(pod *v1.Pod, envs []v1.EnvVar) { + if len(envs) > 0 { + for idx := range pod.Spec.Containers { + // inject every containers + pod.Spec.Containers[idx].Env = append( + pod.Spec.Containers[idx].Env, envs..., + ) + } + } +} + +func PrepareStorage(workerParam *WorkerParam) { + var mounts []WorkerMount + // parse the mounts and environment key + for _, mount := range workerParam.Mounts { + var envPaths []string + + if mount.URL != nil { + mount.URLs = append(mount.URLs, *mount.URL) + } + + var mountURLs []MountURL + for _, m := range mount.URLs { + m.Parse() + if m.Disable { + continue + } + mountURLs = append(mountURLs, m) + + if m.ContainerPath != "" { + envPaths = append(envPaths, m.ContainerPath) + } else { + // keep the original URL if no container path + envPaths = append(envPaths, m.URL) + } + } + + if len(mountURLs) > 0 { + mount.URLs = mountURLs + mounts = append(mounts, mount) + } + + if mount.EnvName != "" { + workerParam.Env[mount.EnvName] = strings.Join( + envPaths, urlsFieldSep, + ) + } + } + workerParam.Mounts = mounts +} + +func PrepareSecret(workerParam *WorkerParam) []v1.EnvVar { var secretEnvs []v1.EnvVar for _, mount := range workerParam.Mounts { for _, m := range mount.URLs { @@ -255,10 +386,59 @@ func injectWorkerSecrets(pod *v1.Pod, workerParam *WorkerParam) { } } } - injectEnvs(pod, secretEnvs) + return secretEnvs } -func injectInitializerContainer(pod *v1.Pod, workerParam *WorkerParam) { +func PrepareHostPath(workerParam *WorkerParam) ([]v1.Volume, []v1.VolumeMount, []v1.VolumeMount) { + var volumes []v1.Volume + var volumeMounts []v1.VolumeMount + var initContainerVolumeMounts []v1.VolumeMount + + uniqVolumeName := make(map[string]bool) + + hostPathType := v1.HostPathDirectory + + for _, mount := range workerParam.Mounts { + for _, m := range mount.URLs { + if m.HostPath == "" { + continue + } + + volumeName := ConvertK8SValidName(m.HostPath) + + if len(volumeName) == 0 { + volumeName = defaultVolumeName + klog.Warningf("failed to get name from url(%s), fallback to default name(%s)", m.URL, volumeName) + } + + if _, ok := uniqVolumeName[volumeName]; !ok { + volumes = append(volumes, v1.Volume{ + Name: volumeName, + VolumeSource: v1.VolumeSource{ + HostPath: &v1.HostPathVolumeSource{ + Path: m.HostPath, + Type: &hostPathType, + }, + }, + }) + uniqVolumeName[volumeName] = true + } + + vm := v1.VolumeMount{ + MountPath: m.MountPath, + Name: volumeName, + } + if m.Indirect { + initContainerVolumeMounts = append(initContainerVolumeMounts, vm) + } else { + volumeMounts = append(volumeMounts, vm) + } + } + } + return volumes, volumeMounts, initContainerVolumeMounts +} + +func PrepareInitContainer(workerParam *WorkerParam) ([]v1.Volume, []v1.VolumeMount, *v1.Container) { var volumes []v1.Volume var volumeMounts []v1.VolumeMount @@ -289,7 +469,7 @@ func injectInitializerContainer(pod *v1.Pod, workerParam *WorkerParam) { // no need to download if len(downloadPairs) == 0 { - return + return nil, nil, nil } envs := secretEnvs @@ -343,80 +523,5 @@ func injectInitializerContainer(pod *v1.Pod, workerParam *WorkerParam) { Env: envs, } - pod.Spec.InitContainers = append(pod.Spec.InitContainers, initContainer) - injectVolume(pod, volumes, volumeMounts) -} - -// InjectStorageInitializer injects these storage related volumes and envs into pod in-place -func InjectStorageInitializer(pod *v1.Pod, workerParam *WorkerParam) { - var mounts []WorkerMount - // parse the mounts and environment key - for _, mount := range workerParam.Mounts { - var envPaths []string - - if mount.URL != nil { - mount.URLs = append(mount.URLs, *mount.URL) - } - - var mountURLs []MountURL - for _, m := range mount.URLs { - m.Parse() - if m.Disable { - continue - } - mountURLs = append(mountURLs, m) - - if m.ContainerPath != "" { - envPaths = append(envPaths, m.ContainerPath) - } else { - // keep the original URL if no container path - envPaths = append(envPaths, m.URL) - } - } - - if len(mountURLs) > 0 { - mount.URLs = mountURLs - mounts = append(mounts, mount) - } - - if mount.EnvName != "" { - workerParam.Env[mount.EnvName] = strings.Join( - envPaths, urlsFieldSep, - ) - } - } - - workerParam.Mounts = mounts - - // need to call injectInitializerContainer before injectHostPathMount - // since injectHostPathMount could inject volumeMount to init container - injectInitializerContainer(pod, workerParam) - injectHostPathMount(pod, workerParam) - injectWorkerSecrets(pod, workerParam) -} - -func injectVolume(pod *v1.Pod, volumes []v1.Volume, volumeMounts []v1.VolumeMount) { - if len(volumes) > 0 { - pod.Spec.Volumes = append(pod.Spec.Volumes, volumes...) - } - - if len(volumeMounts) > 0 { - for idx := range pod.Spec.Containers { - // inject every containers - pod.Spec.Containers[idx].VolumeMounts = append( - pod.Spec.Containers[idx].VolumeMounts, volumeMounts..., - ) - } - } -} - -func injectEnvs(pod *v1.Pod, envs []v1.EnvVar) { - if len(envs) > 0 { - for idx := range pod.Spec.Containers { - // inject every containers - pod.Spec.Containers[idx].Env = append( - pod.Spec.Containers[idx].Env, envs..., - ) - } - } + return volumes, volumeMounts, &initContainer } diff --git a/pkg/globalmanager/runtime/worker.go b/pkg/globalmanager/runtime/worker.go index f7ae95775..f6e126bb5 100644 --- a/pkg/globalmanager/runtime/worker.go +++ b/pkg/globalmanager/runtime/worker.go @@ -83,6 +83,48 @@ func GenerateWorkerSelector(object CommonInterface, workerType string) (labels.S return metav1.LabelSelectorAsSelector(ls) } +// CreateKubernetesService creates a k8s service for an object given ip and port +func CreateKubernetesService(kubeClient kubernetes.Interface, object CommonInterface, workerType string, inputPort int32, inputIP string) (int32, error) { + ctx := context.Background() + name := object.GetName() + namespace := object.GetNamespace() + kind := object.GroupVersionKind().Kind + targePort := intstr.IntOrString{ + IntVal: inputPort, + } + serviceSpec := &v1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: object.GetNamespace(), + Name: strings.ToLower(name + "-" + workerType), + OwnerReferences: []metav1.OwnerReference{ + *metav1.NewControllerRef(object, object.GroupVersionKind()), + }, + Labels: generateLabels(object, workerType), + }, + Spec: v1.ServiceSpec{ + Selector: generateLabels(object, workerType), + ExternalIPs: []string{ + inputIP, + }, + Type: v1.ServiceTypeNodePort, + Ports: []v1.ServicePort{ + { + Port: inputPort, + TargetPort: targePort, + }, + }, + }, + } + service, err := kubeClient.CoreV1().Services(namespace).Create(ctx, serviceSpec, metav1.CreateOptions{}) + if err != nil { + klog.Warningf("failed to create service for %v %v/%v, err:%s", kind, namespace, name, err) + return 0, err + } + + klog.V(2).Infof("Service %s is created successfully for %v %v/%v", service.Name, kind, namespace, name) + return service.Spec.Ports[0].NodePort, nil +} + // injectWorkerParam modifies pod in-place func injectWorkerParam(pod *v1.Pod, workerParam *WorkerParam, object CommonInterface) { InjectStorageInitializer(pod, workerParam) @@ -188,7 +230,9 @@ func CreateDeploymentWithTemplate(client kubernetes.Interface, object CommonInte objectKind := object.GroupVersionKind() objectName := object.GetNamespace() + "/" + object.GetName() deployment := newDeployment(object, spec, workerParam) + injectDeploymentParam(deployment, workerParam, object, port) + createdDeployment, err := client.AppsV1().Deployments(object.GetNamespace()).Create(context.TODO(), deployment, metav1.CreateOptions{}) if err != nil { klog.Warningf("failed to create deployment for %s %s, err:%s", objectKind, objectName, err) @@ -221,7 +265,16 @@ func newDeployment(object CommonInterface, spec *appsv1.DeploymentSpec, workerPa } // injectDeploymentParam modifies deployment in-place -func injectDeploymentParam(deployment *appsv1.Deployment, workerParam *WorkerParam, object CommonInterface, port int32) { +func injectDeploymentParam(deployment *appsv1.Deployment, workerParam *WorkerParam, object CommonInterface, _port int32) { + var appLabelKey = "app.sedna.io" + var appLabelValue = object.GetName() + "-" + workerParam.WorkerType + "-" + "svc" + + // Injection of the storage variables must be done before loading + // the environment variables! + if workerParam.Mounts != nil { + InjectStorageInitializerDeployment(deployment, workerParam) + } + // inject our labels if deployment.Labels == nil { deployment.Labels = make(map[string]string) @@ -229,16 +282,27 @@ func injectDeploymentParam(deployment *appsv1.Deployment, workerParam *WorkerPar if deployment.Spec.Template.Labels == nil { deployment.Spec.Template.Labels = make(map[string]string) } + if deployment.Spec.Selector.MatchLabels == nil { + deployment.Spec.Selector.MatchLabels = make(map[string]string) + } for k, v := range generateLabels(object, workerParam.WorkerType) { deployment.Labels[k] = v deployment.Spec.Template.Labels[k] = v deployment.Spec.Selector.MatchLabels[k] = v } - deployment.Spec.Template.Spec.Containers[0].Ports = []v1.ContainerPort{ - { - ContainerPort: port, - }, + + // Edgemesh part, useful for service mapping (not necessary!) + deployment.Labels[appLabelKey] = appLabelValue + deployment.Spec.Template.Labels[appLabelKey] = appLabelValue + deployment.Spec.Selector.MatchLabels[appLabelKey] = appLabelValue + + // Env variables injection + envs := createEnvVars(workerParam.Env) + for idx := range deployment.Spec.Template.Spec.Containers { + deployment.Spec.Template.Spec.Containers[idx].Env = append( + deployment.Spec.Template.Spec.Containers[idx].Env, envs..., + ) } }