diff --git a/pkg/generator/appconfiguration/generator/app_configurations_generator.go b/pkg/generator/appconfiguration/generator/app_configurations_generator.go index a7796b95..a1ff0560 100644 --- a/pkg/generator/appconfiguration/generator/app_configurations_generator.go +++ b/pkg/generator/appconfiguration/generator/app_configurations_generator.go @@ -16,7 +16,7 @@ type AppsGenerator struct { } func (acg *AppsGenerator) GenerateSpec( - o *generator.Options, + _ *generator.Options, project *projectstack.Project, stack *projectstack.Stack, ) (*models.Spec, error) { @@ -24,11 +24,14 @@ func (acg *AppsGenerator) GenerateSpec( Resources: []models.Resource{}, } - gfs := []appconfiguration.NewGeneratorFunc{} - appconfiguration.ForeachOrdered(acg.Apps, func(appName string, app appmodel.AppConfiguration) error { - gfs = append(gfs, NewAppConfigurationGeneratorFunc(project.Name, appName, &app)) + var gfs []appconfiguration.NewGeneratorFunc + err := appconfiguration.ForeachOrdered(acg.Apps, func(appName string, app appmodel.AppConfiguration) error { + gfs = append(gfs, NewAppConfigurationGeneratorFunc(project, stack, appName, &app)) return nil }) + if err != nil { + return nil, err + } if err := appconfiguration.CallGenerators(spec, gfs...); err != nil { return nil, err } @@ -37,16 +40,19 @@ func (acg *AppsGenerator) GenerateSpec( } type appConfigurationGenerator struct { - projectName string - appName string - app *appmodel.AppConfiguration + project *projectstack.Project + stack *projectstack.Stack + appName string + app *appmodel.AppConfiguration } func NewAppConfigurationGenerator( - projectName, appName string, + project *projectstack.Project, + stack *projectstack.Stack, app *appmodel.AppConfiguration, + appName string, ) (appconfiguration.Generator, error) { - if len(projectName) == 0 { + if len(project.Name) == 0 { return nil, fmt.Errorf("project name must not be empty") } @@ -59,18 +65,21 @@ func NewAppConfigurationGenerator( } return &appConfigurationGenerator{ - projectName: projectName, - appName: appName, - app: app, + project: project, + stack: stack, + appName: appName, + app: app, }, nil } func NewAppConfigurationGeneratorFunc( - projectName, appName string, + project *projectstack.Project, + stack *projectstack.Stack, + appName string, app *appmodel.AppConfiguration, ) appconfiguration.NewGeneratorFunc { return func() (appconfiguration.Generator, error) { - return NewAppConfigurationGenerator(projectName, appName, app) + return NewAppConfigurationGenerator(project, stack, app, appName) } } @@ -80,8 +89,8 @@ func (g *appConfigurationGenerator) Generate(spec *models.Spec) error { } gfs := []appconfiguration.NewGeneratorFunc{ - NewNamespaceGeneratorFunc(g.projectName), - workload.NewWorkloadGeneratorFunc(g.projectName, g.appName, g.app.Workload), + NewNamespaceGeneratorFunc(g.project.Name), + workload.NewWorkloadGeneratorFunc(g.project, nil, g.app.Workload, g.appName), } if err := appconfiguration.CallGenerators(spec, gfs...); err != nil { diff --git a/pkg/generator/appconfiguration/generator/workload/job_generator.go b/pkg/generator/appconfiguration/generator/workload/job_generator.go index ba89b53c..f92447e0 100644 --- a/pkg/generator/appconfiguration/generator/workload/job_generator.go +++ b/pkg/generator/appconfiguration/generator/workload/job_generator.go @@ -8,25 +8,38 @@ import ( "kusionstack.io/kusion/pkg/generator/appconfiguration" "kusionstack.io/kusion/pkg/models" "kusionstack.io/kusion/pkg/models/appconfiguration/workload" + "kusionstack.io/kusion/pkg/projectstack" ) type jobGenerator struct { - projectName string - appName string - job *workload.Job + project *projectstack.Project + stack *projectstack.Stack + appName string + job *workload.Job } -func NewJobGenerator(projectName, appName string, job *workload.Job) (appconfiguration.Generator, error) { +func NewJobGenerator( + project *projectstack.Project, + stack *projectstack.Stack, + appName string, + job *workload.Job, +) (appconfiguration.Generator, error) { return &jobGenerator{ - projectName: projectName, - appName: appName, - job: job, + project: project, + stack: stack, + appName: appName, + job: job, }, nil } -func NewJobGeneratorFunc(projectName, appName string, job *workload.Job) appconfiguration.NewGeneratorFunc { +func NewJobGeneratorFunc( + project *projectstack.Project, + stack *projectstack.Stack, + appName string, + job *workload.Job, +) appconfiguration.NewGeneratorFunc { return func() (appconfiguration.Generator, error) { - return NewJobGenerator(projectName, appName, job) + return NewJobGenerator(project, stack, appName, job) } } @@ -41,10 +54,10 @@ func (g *jobGenerator) Generate(spec *models.Spec) error { } meta := metav1.ObjectMeta{ - Namespace: g.projectName, - Name: appconfiguration.UniqueAppName(g.projectName, g.appName), + Namespace: g.project.Name, + Name: appconfiguration.UniqueAppName(g.project.Name, g.stack.Name, g.appName), Labels: appconfiguration.MergeMaps( - appconfiguration.UniqueAppLabels(g.projectName, g.appName), + appconfiguration.UniqueAppLabels(g.project.Name, g.appName), g.job.Labels, ), Annotations: appconfiguration.MergeMaps( @@ -60,7 +73,7 @@ func (g *jobGenerator) Generate(spec *models.Spec) error { Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: appconfiguration.MergeMaps( - appconfiguration.UniqueAppLabels(g.projectName, g.appName), + appconfiguration.UniqueAppLabels(g.project.Name, g.appName), g.job.Labels, ), Annotations: appconfiguration.MergeMaps( diff --git a/pkg/generator/appconfiguration/generator/workload/service_generator.go b/pkg/generator/appconfiguration/generator/workload/service_generator.go index 2f7ce8db..306d8243 100644 --- a/pkg/generator/appconfiguration/generator/workload/service_generator.go +++ b/pkg/generator/appconfiguration/generator/workload/service_generator.go @@ -10,24 +10,27 @@ import ( "kusionstack.io/kusion/pkg/generator/appconfiguration" "kusionstack.io/kusion/pkg/models" "kusionstack.io/kusion/pkg/models/appconfiguration/workload" + "kusionstack.io/kusion/pkg/projectstack" ) // workloadServiceGenerator is a struct for generating service // workload resources. type workloadServiceGenerator struct { - projectName string - appName string - service *workload.Service + project *projectstack.Project + stack *projectstack.Stack + appName string + service *workload.Service } // NewWorkloadServiceGenerator returns a new workloadServiceGenerator // instance. func NewWorkloadServiceGenerator( - projectName string, + project *projectstack.Project, + stack *projectstack.Stack, appName string, service *workload.Service, ) (appconfiguration.Generator, error) { - if len(projectName) == 0 { + if len(project.Name) == 0 { return nil, fmt.Errorf("project name must not be empty") } @@ -40,28 +43,30 @@ func NewWorkloadServiceGenerator( } return &workloadServiceGenerator{ - projectName: projectName, - appName: appName, - service: service, + project: project, + stack: stack, + appName: appName, + service: service, }, nil } // NewWorkloadServiceGeneratorFunc returns a new NewGeneratorFunc that // returns a workloadServiceGenerator instance. func NewWorkloadServiceGeneratorFunc( - projectName string, + project *projectstack.Project, + stack *projectstack.Stack, appName string, service *workload.Service, ) appconfiguration.NewGeneratorFunc { return func() (appconfiguration.Generator, error) { - return NewWorkloadServiceGenerator(projectName, appName, service) + return NewWorkloadServiceGenerator(project, stack, appName, service) } } // Generate generates a service workload resource to the given spec. func (g *workloadServiceGenerator) Generate(spec *models.Spec) error { - lrs := g.service - if lrs == nil { + service := g.service + if service == nil { return nil } @@ -72,7 +77,7 @@ func (g *workloadServiceGenerator) Generate(spec *models.Spec) error { // Create a slice of containers based on the app's // containers. - containers, err := toOrderedContainers(lrs.Containers) + containers, err := toOrderedContainers(service.Containers) if err != nil { return err } @@ -86,24 +91,24 @@ func (g *workloadServiceGenerator) Generate(spec *models.Spec) error { }, ObjectMeta: metav1.ObjectMeta{ Labels: appconfiguration.MergeMaps( - appconfiguration.UniqueAppLabels(g.projectName, g.appName), + appconfiguration.UniqueAppLabels(g.project.Name, g.appName), g.service.Labels, ), Annotations: appconfiguration.MergeMaps( g.service.Annotations, ), - Name: appconfiguration.UniqueAppName(g.projectName, g.appName), - Namespace: g.projectName, + Name: appconfiguration.UniqueAppName(g.project.Name, g.stack.Name, g.appName), + Namespace: g.project.Name, }, Spec: appsv1.DeploymentSpec{ - Replicas: appconfiguration.IntPtr(int32(lrs.Replicas)), + Replicas: appconfiguration.GenericPtr(int32(service.Replicas)), Selector: &metav1.LabelSelector{ - MatchLabels: appconfiguration.UniqueAppLabels(g.projectName, g.appName), + MatchLabels: appconfiguration.UniqueAppLabels(g.project.Name, g.appName), }, Template: v1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: appconfiguration.MergeMaps( - appconfiguration.UniqueAppLabels(g.projectName, g.appName), + appconfiguration.UniqueAppLabels(g.project.Name, g.appName), g.service.Labels, ), Annotations: appconfiguration.MergeMaps( diff --git a/pkg/generator/appconfiguration/generator/workload/workload_generator.go b/pkg/generator/appconfiguration/generator/workload/workload_generator.go index 58224be0..ae5a65c2 100644 --- a/pkg/generator/appconfiguration/generator/workload/workload_generator.go +++ b/pkg/generator/appconfiguration/generator/workload/workload_generator.go @@ -9,29 +9,42 @@ import ( "kusionstack.io/kusion/pkg/models" "kusionstack.io/kusion/pkg/models/appconfiguration/workload" "kusionstack.io/kusion/pkg/models/appconfiguration/workload/container" + "kusionstack.io/kusion/pkg/projectstack" ) type workloadGenerator struct { - projectName string - appName string - workload *workload.Workload + project *projectstack.Project + stack *projectstack.Stack + appName string + workload *workload.Workload } -func NewWorkloadGenerator(projectName, appName string, workload *workload.Workload) (appconfiguration.Generator, error) { - if len(projectName) == 0 { +func NewWorkloadGenerator( + project *projectstack.Project, + stack *projectstack.Stack, + workload *workload.Workload, + appName string, +) (appconfiguration.Generator, error) { + if len(project.Name) == 0 { return nil, fmt.Errorf("project name must not be empty") } return &workloadGenerator{ - projectName: projectName, - appName: appName, - workload: workload, + project: project, + stack: stack, + appName: appName, + workload: workload, }, nil } -func NewWorkloadGeneratorFunc(projectName, appName string, workload *workload.Workload) appconfiguration.NewGeneratorFunc { +func NewWorkloadGeneratorFunc( + project *projectstack.Project, + stack *projectstack.Stack, + workload *workload.Workload, + appName string, +) appconfiguration.NewGeneratorFunc { return func() (appconfiguration.Generator, error) { - return NewWorkloadGenerator(projectName, appName, workload) + return NewWorkloadGenerator(project, stack, workload, appName) } } @@ -41,13 +54,13 @@ func (g *workloadGenerator) Generate(spec *models.Spec) error { } if g.workload != nil { - gfs := []appconfiguration.NewGeneratorFunc{} + var gfs []appconfiguration.NewGeneratorFunc switch g.workload.Type { case workload.WorkloadTypeService: - gfs = append(gfs, NewWorkloadServiceGeneratorFunc(g.projectName, g.appName, g.workload.Service)) + gfs = append(gfs, NewWorkloadServiceGeneratorFunc(g.project, g.stack, g.appName, g.workload.Service)) case workload.WorkloadTypeJob: - gfs = append(gfs, NewJobGeneratorFunc(g.projectName, g.appName, g.workload.Job)) + gfs = append(gfs, NewJobGeneratorFunc(g.project, g.stack, g.appName, g.workload.Job)) } if err := appconfiguration.CallGenerators(spec, gfs...); err != nil { @@ -61,11 +74,10 @@ func (g *workloadGenerator) Generate(spec *models.Spec) error { func toOrderedContainers(appContainers map[string]container.Container) ([]corev1.Container, error) { // Create a slice of containers based on the app's // containers. - containers := []corev1.Container{} + var containers []corev1.Container if err := appconfiguration.ForeachOrdered(appContainers, func(containerName string, c container.Container) error { - // Create a slice of env vars based on the container's - // envvars. - envs := []corev1.EnvVar{} + // Create a slice of env vars based on the container's env vars. + var envs []corev1.EnvVar for k, v := range c.Env { envs = append(envs, corev1.EnvVar{ Name: k, diff --git a/pkg/generator/appconfiguration/util.go b/pkg/generator/appconfiguration/util.go index e3d269e2..054e49ff 100644 --- a/pkg/generator/appconfiguration/util.go +++ b/pkg/generator/appconfiguration/util.go @@ -41,10 +41,7 @@ func CallGenerators(spec *models.Spec, newGenerators ...NewGeneratorFunc) error // ForeachOrdered executes the given function on each // item in the map in order of their keys. -func ForeachOrdered[T any]( - m map[string]T, - f func(key string, value T) error, -) error { +func ForeachOrdered[T any](m map[string]T, f func(key string, value T) error) error { keys := make([]string, 0, len(m)) for k := range m { keys = append(keys, k) @@ -62,8 +59,8 @@ func ForeachOrdered[T any]( return nil } -// IntPtr returns a pointer to the provided value. -func IntPtr[T any](i T) *T { +// GenericPtr returns a pointer to the provided value. +func GenericPtr[T any](i T) *T { return &i } @@ -99,8 +96,7 @@ func KubernetesResourceID(typeMeta metav1.TypeMeta, objectMeta metav1.ObjectMeta return id } -// AppendToSpec adds a Kubernetes resource to a spec's resources -// slice. +// AppendToSpec adds a Kubernetes resource to a spec's resources slice. func AppendToSpec(resourceID string, resource any, spec *models.Spec) error { unstructured, err := runtime.DefaultUnstructuredConverter.ToUnstructured(resource) if err != nil { @@ -117,14 +113,12 @@ func AppendToSpec(resourceID string, resource any, spec *models.Spec) error { return nil } -// UniqueAppName returns a unique name for a workload based on -// its project and app name. -func UniqueAppName(projectName, appName string) string { - return projectName + appName +// UniqueAppName returns a unique name for a workload based on its project and app name. +func UniqueAppName(projectName, stackName, appName string) string { + return projectName + "-" + stackName + "-" + appName } -// UniqueAppLabels returns a map of labels that identify a -// app based on its project and name. +// UniqueAppLabels returns a map of labels that identify an app based on its project and name. func UniqueAppLabels(projectName, appName string) map[string]string { return map[string]string{ "app.kubernetes.io/part-of": projectName,