diff --git a/cmd/sealer/cmd/cluster/apply.go b/cmd/sealer/cmd/cluster/apply.go index 3e96c2698d5..e30cb99df96 100644 --- a/cmd/sealer/cmd/cluster/apply.go +++ b/cmd/sealer/cmd/cluster/apply.go @@ -27,7 +27,6 @@ import ( imagev1 "github.com/sealerio/sealer/pkg/define/image/v1" "github.com/sealerio/sealer/pkg/define/options" "github.com/sealerio/sealer/pkg/imageengine" - "github.com/sealerio/sealer/pkg/infradriver" "github.com/sealerio/sealer/utils/strings" "github.com/pkg/errors" @@ -102,7 +101,8 @@ func NewApplyCmd() *cobra.Command { } if imageSpec.ImageExtension.Type == imagev1.AppInstaller { - app := utils.ConstructApplication(cf.GetApplication(), desiredCluster.Spec.CMD, desiredCluster.Spec.APPNames) + app := utils.ConstructApplication(cf.GetApplication(), desiredCluster.Spec.CMD, + desiredCluster.Spec.APPNames, desiredCluster.Spec.Env) return runApplicationImage(&RunApplicationImageRequest{ ImageName: imageName, @@ -138,7 +138,8 @@ func NewApplyCmd() *cobra.Command { } // install application - app := utils.ConstructApplication(cf.GetApplication(), desiredCluster.Spec.CMD, desiredCluster.Spec.APPNames) + //TODO use flag env to construct application directly. at present ,sealer use cluster.env to construct application + app := utils.ConstructApplication(cf.GetApplication(), desiredCluster.Spec.CMD, desiredCluster.Spec.APPNames, desiredCluster.Spec.Env) return runApplicationImage(&RunApplicationImageRequest{ ImageName: imageName, Application: app, @@ -191,8 +192,11 @@ func applyClusterWithNew(cf clusterfile.Interface, applyMode string, return fmt.Errorf("failed to merge cluster with apply args: %v", err) } + // merge image extension + mergedWithExt := utils.MergeClusterWithImageExtension(cluster, imageSpec.ImageExtension) + // set merged cluster - cf.SetCluster(*cluster) + cf.SetCluster(*mergedWithExt) return runClusterImage(imageEngine, cf, imageSpec, applyMode, applyFlags.IgnoreCache) } @@ -218,12 +222,12 @@ func applyClusterWithExisted(cf clusterfile.Interface, client *k8s.Client, return false, fmt.Errorf("make sure all masters' ip exist in your clusterfile: %s", applyFlags.ClusterFile) } - infraDriver, err := infradriver.NewInfraDriver(&desiredCluster) - if err != nil { - return false, err - } + // merge image extension + mergedWithExt := utils.MergeClusterWithImageExtension(&desiredCluster, imageSpec.ImageExtension) + + cf.SetCluster(*mergedWithExt) - if err := scaleUpCluster(imageSpec.Name, mj, nj, infraDriver, imageEngine, cf, applyFlags.IgnoreCache); err != nil { + if err := scaleUpCluster(mj, nj, imageSpec, cf, imageEngine, applyFlags.IgnoreCache); err != nil { return false, err } return true, nil diff --git a/cmd/sealer/cmd/cluster/join.go b/cmd/sealer/cmd/cluster/join.go index 6b21da03efa..04c768095f0 100644 --- a/cmd/sealer/cmd/cluster/join.go +++ b/cmd/sealer/cmd/cluster/join.go @@ -18,16 +18,14 @@ import ( "fmt" "path/filepath" - "github.com/sirupsen/logrus" - "github.com/spf13/cobra" - "github.com/sealerio/sealer/cmd/sealer/cmd/types" "github.com/sealerio/sealer/cmd/sealer/cmd/utils" "github.com/sealerio/sealer/common" "github.com/sealerio/sealer/pkg/clusterfile" - imagecommon "github.com/sealerio/sealer/pkg/define/options" + "github.com/sealerio/sealer/pkg/define/options" "github.com/sealerio/sealer/pkg/imageengine" - "github.com/sealerio/sealer/pkg/infradriver" + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" ) var joinFlags *types.ScaleUpFlags @@ -85,19 +83,35 @@ func NewJoinCmd() *cobra.Command { if err != nil { return err } - cf.SetCluster(cluster) - infraDriver, err := infradriver.NewInfraDriver(&cluster) + // get image extension + imageName := cluster.Spec.Image + imageEngine, err := imageengine.NewImageEngine(options.EngineGlobalConfigurations{}) if err != nil { return err } - imageEngine, err := imageengine.NewImageEngine(imagecommon.EngineGlobalConfigurations{}) + id, err := imageEngine.Pull(&options.PullOptions{ + Quiet: false, + PullPolicy: "missing", + Image: imageName, + Platform: "local", + }) if err != nil { return err } - return scaleUpCluster(cluster.Spec.Image, mj, nj, infraDriver, imageEngine, cf, joinFlags.IgnoreCache) + imageSpec, err := imageEngine.Inspect(&options.InspectOptions{ImageNameOrID: id}) + if err != nil { + return fmt.Errorf("failed to get sealer image extension: %s", err) + } + + // merge image extension + mergedWithExt := utils.MergeClusterWithImageExtension(&cluster, imageSpec.ImageExtension) + + cf.SetCluster(*mergedWithExt) + + return scaleUpCluster(mj, nj, imageSpec, cf, imageEngine, joinFlags.IgnoreCache) }, } diff --git a/cmd/sealer/cmd/cluster/rollback.go b/cmd/sealer/cmd/cluster/rollback.go index b821168ee17..e05ed4e58c3 100644 --- a/cmd/sealer/cmd/cluster/rollback.go +++ b/cmd/sealer/cmd/cluster/rollback.go @@ -114,7 +114,10 @@ func rollbackCluster(cf clusterfile.Interface, imageEngine imageengine.Interface } cluster := cf.GetCluster() - infraDriver, err := infradriver.NewInfraDriver(&cluster) + // merge image extension + mergedWithExt := utils.MergeClusterWithImageExtension(&cluster, imageSpec.ImageExtension) + + infraDriver, err := infradriver.NewInfraDriver(mergedWithExt) if err != nil { return err } @@ -190,7 +193,7 @@ func rollbackCluster(cf clusterfile.Interface, imageEngine imageengine.Interface appNames := infraDriver.GetClusterLaunchApps() // merge to application between v2.ClusterSpec, v2.Application and image extension - v2App, err := application.NewV2Application(utils.ConstructApplication(cf.GetApplication(), cmds, appNames), imageSpec.ImageExtension) + v2App, err := application.NewV2Application(utils.ConstructApplication(cf.GetApplication(), cmds, appNames, cluster.Spec.Env), imageSpec.ImageExtension) if err != nil { return fmt.Errorf("failed to parse application from Clusterfile:%v ", err) } diff --git a/cmd/sealer/cmd/cluster/run.go b/cmd/sealer/cmd/cluster/run.go index 251967eab06..53b56cf2600 100644 --- a/cmd/sealer/cmd/cluster/run.go +++ b/cmd/sealer/cmd/cluster/run.go @@ -112,7 +112,7 @@ func NewRunCmd() *cobra.Command { } if imageSpec.ImageExtension.Type == imagev1.AppInstaller { - app := utils.ConstructApplication(nil, runFlags.Cmds, runFlags.AppNames) + app := utils.ConstructApplication(nil, runFlags.Cmds, runFlags.AppNames, runFlags.CustomEnv) return runApplicationImage(&RunApplicationImageRequest{ ImageName: args[0], @@ -221,7 +221,7 @@ func runWithClusterfile(clusterFile string, runFlags *types.RunFlags) error { } if imageSpec.ImageExtension.Type == imagev1.AppInstaller { - app := utils.ConstructApplication(cf.GetApplication(), cluster.Spec.CMD, cluster.Spec.APPNames) + app := utils.ConstructApplication(cf.GetApplication(), cluster.Spec.CMD, cluster.Spec.APPNames, runFlags.CustomEnv) return runApplicationImage(&RunApplicationImageRequest{ ImageName: imageName, @@ -241,7 +241,11 @@ func runWithClusterfile(clusterFile string, runFlags *types.RunFlags) error { func runClusterImage(imageEngine imageengine.Interface, cf clusterfile.Interface, imageSpec *imagev1.ImageSpec, mode string, ignoreCache bool) error { cluster := cf.GetCluster() - infraDriver, err := infradriver.NewInfraDriver(&cluster) + + // merge image extension + mergedWithExt := utils.MergeClusterWithImageExtension(&cluster, imageSpec.ImageExtension) + + infraDriver, err := infradriver.NewInfraDriver(mergedWithExt) if err != nil { return err } @@ -327,7 +331,7 @@ func runClusterImage(imageEngine imageengine.Interface, cf clusterfile.Interface // TODO valid construct application // merge to application between v2.ClusterSpec, v2.Application and image extension - v2App, err := application.NewV2Application(utils.ConstructApplication(cf.GetApplication(), cmds, appNames), imageSpec.ImageExtension) + v2App, err := application.NewV2Application(utils.ConstructApplication(cf.GetApplication(), cmds, appNames, cluster.Spec.Env), imageSpec.ImageExtension) if err != nil { return fmt.Errorf("failed to parse application from Clusterfile:%v ", err) } diff --git a/cmd/sealer/cmd/cluster/scale-up.go b/cmd/sealer/cmd/cluster/scale-up.go index ebc7bcb4257..6161294687c 100644 --- a/cmd/sealer/cmd/cluster/scale-up.go +++ b/cmd/sealer/cmd/cluster/scale-up.go @@ -19,18 +19,18 @@ import ( "net" "path/filepath" - "github.com/sirupsen/logrus" - "github.com/spf13/cobra" - "github.com/sealerio/sealer/cmd/sealer/cmd/types" "github.com/sealerio/sealer/cmd/sealer/cmd/utils" "github.com/sealerio/sealer/common" clusterruntime "github.com/sealerio/sealer/pkg/cluster-runtime" "github.com/sealerio/sealer/pkg/clusterfile" - imagecommon "github.com/sealerio/sealer/pkg/define/options" + imagev1 "github.com/sealerio/sealer/pkg/define/image/v1" + "github.com/sealerio/sealer/pkg/define/options" "github.com/sealerio/sealer/pkg/imagedistributor" "github.com/sealerio/sealer/pkg/imageengine" "github.com/sealerio/sealer/pkg/infradriver" + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" ) var scaleUpFlags *types.ScaleUpFlags @@ -87,19 +87,33 @@ func NewScaleUpCmd() *cobra.Command { if err != nil { return err } - cf.SetCluster(cluster) - infraDriver, err := infradriver.NewInfraDriver(&cluster) + imageEngine, err := imageengine.NewImageEngine(options.EngineGlobalConfigurations{}) if err != nil { return err } - imageEngine, err := imageengine.NewImageEngine(imagecommon.EngineGlobalConfigurations{}) + id, err := imageEngine.Pull(&options.PullOptions{ + Quiet: false, + PullPolicy: "missing", + Image: cluster.Spec.Image, + Platform: "local", + }) if err != nil { return err } - return scaleUpCluster(cluster.Spec.Image, mj, nj, infraDriver, imageEngine, cf, scaleUpFlags.IgnoreCache) + imageSpec, err := imageEngine.Inspect(&options.InspectOptions{ImageNameOrID: id}) + if err != nil { + return fmt.Errorf("failed to get sealer image extension: %s", err) + } + + // merge image extension + mergedWithExt := utils.MergeClusterWithImageExtension(&cluster, imageSpec.ImageExtension) + + cf.SetCluster(*mergedWithExt) + + return scaleUpCluster(mj, nj, imageSpec, cf, imageEngine, scaleUpFlags.IgnoreCache) }, } @@ -116,15 +130,23 @@ func NewScaleUpCmd() *cobra.Command { return scaleUpFlagsCmd } -func scaleUpCluster(clusterImageName string, scaleUpMasterIPList, scaleUpNodeIPList []net.IP, - infraDriver infradriver.InfraDriver, imageEngine imageengine.Interface, - cf clusterfile.Interface, ignoreCache bool) error { +func scaleUpCluster(scaleUpMasterIPList, scaleUpNodeIPList []net.IP, imageSpec *imagev1.ImageSpec, + cf clusterfile.Interface, imageEngine imageengine.Interface, ignoreCache bool) error { logrus.Infof("start to scale up cluster") var ( newHosts = append(scaleUpMasterIPList, scaleUpNodeIPList...) ) + cluster := cf.GetCluster() + + infraDriver, err := infradriver.NewInfraDriver(&cluster) + if err != nil { + return err + } + + clusterImageName := infraDriver.GetClusterImageName() + clusterHostsPlatform, err := infraDriver.GetHostsPlatform(newHosts) if err != nil { return err @@ -172,11 +194,6 @@ func scaleUpCluster(clusterImageName string, scaleUpMasterIPList, scaleUpNodeIPL runtimeConfig.KubeadmConfig = *cf.GetKubeadmConfig() } - imageSpec, err := imageEngine.Inspect(&imagecommon.InspectOptions{ImageNameOrID: clusterImageName}) - if err != nil { - return fmt.Errorf("failed to get sealer image extension: %s", err) - } - installer, err := clusterruntime.NewInstaller(infraDriver, *runtimeConfig, clusterruntime.GetClusterInstallInfo(imageSpec.ImageExtension.Labels, runtimeConfig.ContainerRuntimeConfig)) if err != nil { diff --git a/cmd/sealer/cmd/cluster/upgrade.go b/cmd/sealer/cmd/cluster/upgrade.go index f4ade43d48a..92d02dee195 100644 --- a/cmd/sealer/cmd/cluster/upgrade.go +++ b/cmd/sealer/cmd/cluster/upgrade.go @@ -122,7 +122,7 @@ func upgradeCluster(cf clusterfile.Interface, imageEngine imageengine.Interface, } cluster := cf.GetCluster() - infraDriver, err := infradriver.NewInfraDriver(&cluster) + infraDriver, err := infradriver.NewInfraDriver(utils.MergeClusterWithImageExtension(&cluster, imageSpec.ImageExtension)) if err != nil { return err } @@ -197,7 +197,7 @@ func upgradeCluster(cf clusterfile.Interface, imageEngine imageengine.Interface, appNames := infraDriver.GetClusterLaunchApps() // merge to application between v2.ClusterSpec, v2.Application and image extension - v2App, err := application.NewV2Application(utils.ConstructApplication(cf.GetApplication(), cmds, appNames), imageSpec.ImageExtension) + v2App, err := application.NewV2Application(utils.ConstructApplication(cf.GetApplication(), cmds, appNames, cluster.Spec.Env), imageSpec.ImageExtension) if err != nil { return fmt.Errorf("failed to parse application from Clusterfile:%v ", err) } diff --git a/cmd/sealer/cmd/utils/application.go b/cmd/sealer/cmd/utils/application.go index 5b3329e3770..bbdb522cbee 100644 --- a/cmd/sealer/cmd/utils/application.go +++ b/cmd/sealer/cmd/utils/application.go @@ -20,7 +20,7 @@ import ( ) //ConstructApplication merge flags to v2.Application -func ConstructApplication(app *v2.Application, cmds, appNames []string) *v2.Application { +func ConstructApplication(app *v2.Application, cmds, appNames, globalEnvs []string) *v2.Application { var newApp *v2.Application if app != nil { @@ -42,5 +42,15 @@ func ConstructApplication(app *v2.Application, cmds, appNames []string) *v2.Appl newApp.Spec.LaunchApps = appNames } + // add appEnvs from flag to application object. + if len(globalEnvs) > 0 { + var appConfigList []v2.ApplicationConfig + for _, appConfig := range newApp.Spec.Configs { + appConfig.Env = append(globalEnvs, appConfig.Env...) + appConfigList = append(appConfigList, appConfig) + } + newApp.Spec.Configs = appConfigList + } + return newApp } diff --git a/cmd/sealer/cmd/utils/application_test.go b/cmd/sealer/cmd/utils/application_test.go index faaf29b5085..cee8112d4b8 100644 --- a/cmd/sealer/cmd/utils/application_test.go +++ b/cmd/sealer/cmd/utils/application_test.go @@ -34,6 +34,9 @@ func getNewApp() *v2.Application { "app1", "app2", }, + Configs: []v2.ApplicationConfig{ + {Env: []string{"Key=Value"}}, + }, }, } newApp.Name = "my-application" @@ -60,6 +63,9 @@ func Test_ConstructApplication(t *testing.T) { "app1", "app2", }, + Configs: []v2.ApplicationConfig{ + {Env: []string{"Key=Value"}}, + }, }, } @@ -80,6 +86,9 @@ func Test_ConstructApplication(t *testing.T) { "overwrite app1", "overwrite app2", }, + Configs: []v2.ApplicationConfig{ + {Env: []string{"Key=Value"}}, + }, }, } @@ -100,6 +109,32 @@ func Test_ConstructApplication(t *testing.T) { "overwrite app1", "overwrite app2", }, + Configs: []v2.ApplicationConfig{ + {Env: []string{"Key=Value"}}, + }, + }, + } + + expectedAddAppEnvs := &v2.Application{ + TypeMeta: metav1.TypeMeta{ + APIVersion: constants.ApplicationKind, + Kind: v2.GroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-application", + }, + Spec: v2.ApplicationSpec{ + Cmds: []string{ + "cmd 1", + "cmd 2", + }, + LaunchApps: []string{ + "app1", + "app2", + }, + Configs: []v2.ApplicationConfig{ + {Env: []string{"Key1=Value1", "Key=Value"}}, + }, }, } @@ -107,6 +142,7 @@ func Test_ConstructApplication(t *testing.T) { name string cmds []string appNames []string + appEnvs []string rawApp *v2.Application expectedApp *v2.Application }{ @@ -122,7 +158,6 @@ func Test_ConstructApplication(t *testing.T) { rawApp: getNewApp(), expectedApp: expectedOverwriteAppNames, }, - { name: "test overwrite app names and cmds", cmds: []string{"overwrite cmd 1", "overwrite cmd 2"}, @@ -130,11 +165,17 @@ func Test_ConstructApplication(t *testing.T) { rawApp: getNewApp(), expectedApp: expectedOverwriteCmdsAndAppNames, }, + { + name: "test add app envs", + appEnvs: []string{"Key1=Value1"}, + rawApp: getNewApp(), + expectedApp: expectedAddAppEnvs, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - expectedApp := ConstructApplication(tt.rawApp, tt.cmds, tt.appNames) + expectedApp := ConstructApplication(tt.rawApp, tt.cmds, tt.appNames, tt.appEnvs) assert.Equal(t, expectedApp, tt.expectedApp) }) } diff --git a/cmd/sealer/cmd/utils/cluster.go b/cmd/sealer/cmd/utils/cluster.go index 5927b264ef2..fc0a4010afd 100644 --- a/cmd/sealer/cmd/utils/cluster.go +++ b/cmd/sealer/cmd/utils/cluster.go @@ -20,19 +20,31 @@ import ( "reflect" "strconv" - "github.com/sirupsen/logrus" - corev1 "k8s.io/api/core/v1" - "github.com/sealerio/sealer/cmd/sealer/cmd/types" "github.com/sealerio/sealer/common" "github.com/sealerio/sealer/pkg/client/k8s" + imagev1 "github.com/sealerio/sealer/pkg/define/image/v1" "github.com/sealerio/sealer/types/api/constants" v1 "github.com/sealerio/sealer/types/api/v1" v2 "github.com/sealerio/sealer/types/api/v2" + "github.com/sealerio/sealer/utils/maps" netutils "github.com/sealerio/sealer/utils/net" strUtils "github.com/sealerio/sealer/utils/strings" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" ) +// MergeClusterWithImageExtension :set default value get from image extension,such as image global env +func MergeClusterWithImageExtension(cluster *v2.Cluster, imageExt imagev1.ImageExtension) *v2.Cluster { + if len(imageExt.Env) > 0 { + envs := maps.ConvertToSlice(imageExt.Env) + envs = append(envs, cluster.Spec.Env...) + cluster.Spec.Env = envs + } + + return cluster +} + func MergeClusterWithFlags(cluster v2.Cluster, mergeFlags *types.MergeFlags) (*v2.Cluster, error) { if len(mergeFlags.CustomEnv) > 0 { cluster.Spec.Env = append(cluster.Spec.Env, mergeFlags.CustomEnv...) diff --git a/cmd/sealer/cmd/utils/cluster_test.go b/cmd/sealer/cmd/utils/cluster_test.go index 5d9c9e4edbb..b6ad301e7db 100644 --- a/cmd/sealer/cmd/utils/cluster_test.go +++ b/cmd/sealer/cmd/utils/cluster_test.go @@ -18,12 +18,12 @@ import ( "net" "testing" - "github.com/stretchr/testify/assert" - "github.com/sealerio/sealer/cmd/sealer/cmd/types" "github.com/sealerio/sealer/pkg/clusterfile" + imagev1 "github.com/sealerio/sealer/pkg/define/image/v1" v1 "github.com/sealerio/sealer/types/api/v1" v2 "github.com/sealerio/sealer/types/api/v2" + "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -292,3 +292,95 @@ func Test_ConstructClusterForScaleUp(t *testing.T) { assert.Equal(t, t1.rawCluster.Spec.Hosts, t1.expectedCluster.Spec.Hosts) }) } + +func Test_MergeClusterWithImageExtension(t *testing.T) { + rawCluster := &v2.Cluster{ + Spec: v2.ClusterSpec{ + Image: "kubernetes:v1.19.8", + Env: []string{"key=value", "key1=value1", "key2=value2"}, + SSH: v1.SSH{ + User: "root", + Passwd: "test123", + Port: "22", + }, + Hosts: []v2.Host{ + { + IPS: []net.IP{net.ParseIP("192.168.0.2")}, + Roles: []string{"master"}, + Env: []string{"etcd-dir=/data/etcd"}, + SSH: v1.SSH{ + User: "root", + Passwd: "test456", + Port: "22", + }, + }, + { + IPS: []net.IP{net.ParseIP("192.168.0.3")}, + Roles: []string{"node", "db"}, + }, + }, + }, + } + rawCluster.APIVersion = "sealer.io/v2" + rawCluster.Kind = "Cluster" + rawCluster.Name = "mycluster" + + extension := imagev1.ImageExtension{ + Env: map[string]string{"KeyDefault": "ValueDefault"}, + } + + expectedCluster := &v2.Cluster{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "sealer.io/v2", + Kind: "Cluster", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "mycluster", + }, + Spec: v2.ClusterSpec{ + Image: "kubernetes:v1.19.8", + Env: []string{"KeyDefault=ValueDefault", "key=value", "key1=value1", "key2=value2"}, + SSH: v1.SSH{ + User: "root", + Passwd: "test123", + Port: "22", + }, + Hosts: []v2.Host{ + { + IPS: []net.IP{net.ParseIP("192.168.0.2")}, + Roles: []string{"master"}, + Env: []string{"etcd-dir=/data/etcd"}, + SSH: v1.SSH{ + User: "root", + Passwd: "test456", + Port: "22", + }, + }, + { + IPS: []net.IP{net.ParseIP("192.168.0.3")}, + Roles: []string{"node", "db"}, + }, + }, + }, + } + + tests := []struct { + name string + rawCluster *v2.Cluster + imageExt imagev1.ImageExtension + }{ + { + name: " test merge image extension with v2.cluster", + rawCluster: rawCluster, + imageExt: extension, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mergedWithExt := MergeClusterWithImageExtension(tt.rawCluster, tt.imageExt) + + assert.Equal(t, mergedWithExt, expectedCluster) + }) + } +} diff --git a/pkg/application/v2app.go b/pkg/application/v2app.go index 39d1f65b90e..30d35f206bf 100644 --- a/pkg/application/v2app.go +++ b/pkg/application/v2app.go @@ -28,6 +28,7 @@ import ( "github.com/sealerio/sealer/pkg/infradriver" "github.com/sealerio/sealer/pkg/rootfs" v2 "github.com/sealerio/sealer/types/api/v2" + mapUtils "github.com/sealerio/sealer/utils/maps" strUtils "github.com/sealerio/sealer/utils/strings" "github.com/sirupsen/logrus" ) @@ -202,6 +203,8 @@ func NewV2Application(app *v2.Application, extension imagev1.ImageExtension) (In appConfigFromImageMap[appConfig.Name] = appConfig } + appEnvFromExtension := make(map[string]map[string]string) + for _, name := range v2App.launchApps { appRoot := makeItDir(filepath.Join(rootfs.GlobalManager.App().Root(), name)) v2App.appRootMap[name] = appRoot @@ -215,6 +218,7 @@ func NewV2Application(app *v2.Application, extension imagev1.ImageExtension) (In } else { v2App.appLaunchCmdsMap[name] = []string{v1app.LaunchCmd(appRoot, nil)} } + appEnvFromExtension[name] = mapUtils.Merge(v1app.AppEnv, extension.Env) } } @@ -239,7 +243,7 @@ func NewV2Application(app *v2.Application, extension imagev1.ImageExtension) (In } // add app env - v2App.appEnvMap[name] = strUtils.ConvertStringSliceToMap(config.Env) + v2App.appEnvMap[name] = mapUtils.Merge(strUtils.ConvertStringSliceToMap(config.Env), appEnvFromExtension[name]) // initialize app FileProcessors var fileProcessors []FileProcessor