Skip to content

Commit

Permalink
optimize host project data store (#3262)
Browse files Browse the repository at this point in the history
* fix data

Signed-off-by: allenshen <[email protected]>

* update workload create logic

Signed-off-by: allenshen <[email protected]>

* update wd workload check logic

Signed-off-by: allenshen <[email protected]>

* update host project logic

Signed-off-by: allenshen <[email protected]>

* update host project logic

Signed-off-by: allenshen <[email protected]>

* rmeove unused code

* rmeove unused code

* [wip] add ua logic for host project

* add ua logic for host optimization

* optimize logic

* optimize transfer code

* optimize transfer code

* optimize transfer code

* remove useless debug log

* add external image update logic

* fix svc duplicate error

* optimize code

* optimize code

---------

Signed-off-by: allenshen <[email protected]>
  • Loading branch information
AllenShen authored Feb 29, 2024
1 parent aa85ec7 commit 029c807
Show file tree
Hide file tree
Showing 20 changed files with 371 additions and 655 deletions.
2 changes: 0 additions & 2 deletions pkg/cli/initconfig/cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,6 @@ func createOrUpdateMongodbIndex(ctx context.Context) {
commonrepo.NewWebHookUserColl(),
commonrepo.NewWorkflowColl(),
commonrepo.NewWorkflowStatColl(),
commonrepo.NewWorkLoadsStatColl(),
commonrepo.NewServicesInExternalEnvColl(),
commonrepo.NewExternalLinkColl(),
commonrepo.NewChartColl(),
commonrepo.NewDockerfileTemplateColl(),
Expand Down
167 changes: 167 additions & 0 deletions pkg/cli/upgradeassistant/cmd/migrate/230.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/*
Copyright 2023 The KodeRover 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 migrate

import (
"github.com/koderover/zadig/v2/pkg/cli/upgradeassistant/internal/upgradepath"
"github.com/koderover/zadig/v2/pkg/microservice/aslan/core/common/repository/models"
commonrepo "github.com/koderover/zadig/v2/pkg/microservice/aslan/core/common/repository/mongodb"
"github.com/koderover/zadig/v2/pkg/microservice/aslan/core/common/repository/mongodb/template"
"github.com/koderover/zadig/v2/pkg/microservice/aslan/core/common/service/kube"
"github.com/koderover/zadig/v2/pkg/setting"
"github.com/koderover/zadig/v2/pkg/tool/log"
"github.com/pkg/errors"
"k8s.io/apimachinery/pkg/util/sets"
"time"
)

func init() {
upgradepath.RegisterHandler("2.2.0", "2.3.0", V220ToV230)
upgradepath.RegisterHandler("2.3.0", "2.2.0", V230ToV220)
}

func V220ToV230() error {
log.Infof("-------- start migrate host project data --------")
err := migrateHostProjectData()
time.Sleep(time.Second * 100)
if err != nil {
log.Errorf("migrateHostProjectData error: %s", err)
return err
}

return nil
}

func V230ToV220() error {
return nil
}

func migrateHostProjectData() error {

allProjects, err := template.NewProductColl().ListWithOption(&template.ProductListOpt{
DeployType: setting.K8SDeployType,
BasicFacility: setting.BasicFacilityK8S,
})

if err != nil {
return errors.WithMessage(err, "failed to list all projects")
}

for _, project := range allProjects {
if !project.IsHostProduct() {
continue
}
templateServices, err := commonrepo.NewServiceColl().ListMaxRevisionsByProduct(project.ProductName)
if err != nil {
return errors.WithMessagef(err, "failed to list services for product %s", project.ProductName)
}
tempSvcMap := make(map[string]*models.Service)
for _, svc := range templateServices {
tempSvcMap[svc.ServiceName] = svc
}

//getSvcRevision := func(svcName string) int64 {
// if svc, ok := tempSvcMap[svcName]; ok {
// return svc.Revision
// }
// return 1
//}

products, err := commonrepo.NewProductColl().List(&commonrepo.ProductListOptions{
Name: project.ProductName,
})
if err != nil {
return errors.WithMessagef(err, "failed to find product %s, err: %s", project.ProductName, err)
}

for _, product := range products {
// product data has been handled
if len(product.Services) > 0 {
continue
}

log.Infof("------- handling single data for product %s, env %s -------", product.ProductName, product.EnvName)

productServices, err := commonrepo.NewServiceColl().ListExternalWorkloadsBy(project.ProductName, product.EnvName)
if err != nil {
log.Errorf("ListWorkloadDetails ListExternalServicesBy err:%s", err)
return errors.Wrapf(err, "failed to list external services for product %s", project.ProductName)
}

servicesInExternalEnv, _ := commonrepo.NewServicesInExternalEnvColl().List(&commonrepo.ServicesInExternalEnvArgs{
ProductName: project.ProductName,
EnvName: product.EnvName,
})

svcNameList := sets.NewString()
for _, singleProductSvc := range productServices {
svcNameList.Insert(singleProductSvc.ServiceName)
}
for _, singleSvc := range servicesInExternalEnv {
svcNameList.Insert(singleSvc.ServiceName)
}

// fetch workload from namespace and extract resource / container info
// note the image data in container may not be correct
productSvcs := make([]*models.ProductService, 0)

for _, templateSvc := range tempSvcMap {
if !svcNameList.Has(templateSvc.ServiceName) {
continue
}

resources, err := kube.ManifestToResource(templateSvc.Yaml)
if err != nil {
log.Errorf("ManifestToResource err:%s", err)
continue
}

containers := make([]*models.Container, 0)
for _, c := range templateSvc.Containers {
containers = append(containers, &models.Container{
Name: c.Name,
Image: c.Image,
ImageName: c.ImageName,
})
}

productSvc := &models.ProductService{
ServiceName: templateSvc.ServiceName,
ProductName: product.ProductName,
Type: templateSvc.WorkloadType,
Revision: templateSvc.Revision,
Containers: containers,
Resources: resources,
DeployStrategy: setting.ServiceDeployStrategyDeploy,
}

productSvc.GetServiceRender()
productSvcs = append(productSvcs, productSvc)
}

product.Services = make([][]*models.ProductService, 0)
product.Services = append(product.Services, productSvcs)

err = commonrepo.NewProductColl().Update(product)
if err != nil {
log.Errorf("Failed to update product %s, the error is: %s", product.ProductName, err)
continue
}
}
}
return nil
}
54 changes: 23 additions & 31 deletions pkg/microservice/aslan/core/common/service/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,29 +438,18 @@ func fillServiceInfo(svcList []*ServiceResp, productInfo *models.Product) {
// ListWorkloadDetailsInEnv returns all workloads in the given env which meet the filter.
// this function is used for two scenarios: 1. calculate product status 2. list workflow details
func BuildWorkloadFilterFunc(productInfo *models.Product, projectInfo *templatemodels.Product, filter string, log *zap.SugaredLogger) ([]FilterFunc, error) {
productName, envName := productInfo.ProductName, productInfo.EnvName
//productName, envName := productInfo.ProductName, productInfo.EnvName
filterArray := []FilterFunc{
func(workloads []*Workload) []*Workload {
if !projectInfo.IsHostProduct() {
return workloads
}

productServices, err := commonrepo.NewServiceColl().ListExternalWorkloadsBy(productName, envName)
if err != nil {
log.Errorf("ListWorkloadDetails ListExternalServicesBy err:%s", err)
return workloads
}
productServiceNames := sets.NewString()
for _, productService := range productServices {
productServiceNames.Insert(productService.ServiceName)
}
// add services in external env data
servicesInExternalEnv, _ := commonrepo.NewServicesInExternalEnvColl().List(&commonrepo.ServicesInExternalEnvArgs{
ProductName: productName,
EnvName: envName,
})
for _, serviceInExternalEnv := range servicesInExternalEnv {
productServiceNames.Insert(serviceInExternalEnv.ServiceName)
for _, svc := range productInfo.GetServiceMap() {
if len(svc.Resources) > 0 {
productServiceNames.Insert(svc.Resources[0].Name)
}
}

var res []*Workload
Expand Down Expand Up @@ -644,21 +633,22 @@ func (f *workloadFilter) Match(workload *Workload) bool {
}

type Workload struct {
EnvName string `json:"env_name"`
Name string `json:"name"`
Type string `json:"type"`
ServiceName string `json:"-"`
DeployedFromZadig bool `json:"-"`
ProductName string `json:"product_name"`
Replicas int32 `json:"-"`
Spec corev1.PodTemplateSpec `json:"-"`
Selector *metav1.LabelSelector `json:"-"`
Images []string `json:"-"`
Ready bool `json:"ready"`
Annotation map[string]string `json:"-"`
Status string `json:"-"`
ReleaseName string `json:"-"` //ReleaseName refers to the releaseName of helm services
ChartName string `json:"-"` //ChartName refers to chartName of helm services
EnvName string `json:"env_name"`
Name string `json:"name"`
Type string `json:"type"`
ServiceName string `json:"-"`
DeployedFromZadig bool `json:"-"`
ProductName string `json:"product_name"`
Replicas int32 `json:"-"`
Spec corev1.PodTemplateSpec `json:"-"`
Selector *metav1.LabelSelector `json:"-"`
Images []string `json:"-"`
Containers []*resource.ContainerImage `json:"-"`
Ready bool `json:"ready"`
Annotation map[string]string `json:"-"`
Status string `json:"-"`
ReleaseName string `json:"-"` //ReleaseName refers to the releaseName of helm services
ChartName string `json:"-"` //ChartName refers to chartName of helm services
}

// fillServiceName set service name defined in zadig to workloads, this would be helpful for helm release view
Expand Down Expand Up @@ -710,6 +700,7 @@ func ListWorkloads(envName, productName string, perPage, page int, informer info
Type: setting.Deployment,
Replicas: *v.Spec.Replicas,
Images: wrapper.Deployment(v).ImageInfos(),
Containers: wrapper.Deployment(v).GetContainers(),
Ready: wrapper.Deployment(v).Ready(),
Annotation: v.Annotations,
})
Expand All @@ -726,6 +717,7 @@ func ListWorkloads(envName, productName string, perPage, page int, informer info
Type: setting.StatefulSet,
Replicas: *v.Spec.Replicas,
Images: wrapper.StatefulSet(v).ImageInfos(),
Containers: wrapper.StatefulSet(v).GetContainers(),
Ready: wrapper.StatefulSet(v).Ready(),
Annotation: v.Annotations,
})
Expand Down
11 changes: 0 additions & 11 deletions pkg/microservice/aslan/core/common/service/kube/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,17 +372,6 @@ func CheckResourceAppliedByOtherEnv(serviceYaml string, productInfo *commonmodel
}

for _, env := range envs {
if env.Source == setting.SourceFromExternal {
workloadStat, _ := commonrepo.NewWorkLoadsStatColl().Find(productInfo.ClusterID, productInfo.Namespace)
for _, workload := range workloadStat.Workloads {
if resSet.Has(workload.String()) {
insertEnvData(workload.String(), env)
break
}
}
continue
}

for _, svc := range env.GetServiceMap() {
if env.ProductName == productInfo.ProductName && env.EnvName == productInfo.EnvName && svc.ServiceName == serviceName {
continue
Expand Down
46 changes: 3 additions & 43 deletions pkg/microservice/aslan/core/common/service/product.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,16 @@ import (
"strings"

"github.com/hashicorp/go-multierror"
"go.uber.org/zap"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/sets"

"github.com/koderover/zadig/v2/pkg/microservice/aslan/config"
commonmodels "github.com/koderover/zadig/v2/pkg/microservice/aslan/core/common/repository/models"
commonrepo "github.com/koderover/zadig/v2/pkg/microservice/aslan/core/common/repository/mongodb"
"github.com/koderover/zadig/v2/pkg/setting"
kubeclient "github.com/koderover/zadig/v2/pkg/shared/kube/client"
"github.com/koderover/zadig/v2/pkg/tool/kube/updater"
"github.com/koderover/zadig/v2/pkg/util"
"go.uber.org/zap"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
)

const SplitSymbol = "&"
Expand Down Expand Up @@ -232,45 +230,7 @@ func GetProductEnvNamespace(envName, productName, namespace string) string {
func GetProductTargetMap(prod *commonmodels.Product) (map[string][]commonmodels.DeployEnv, map[string]string) {
resp := make(map[string][]commonmodels.DeployEnv)
imageNameM := make(map[string]string)
if prod.Source == setting.SourceFromExternal {
services, _ := commonrepo.NewServiceColl().ListExternalWorkloadsBy(prod.ProductName, prod.EnvName)

currentServiceNames := sets.NewString()
for _, service := range services {
currentServiceNames.Insert(service.ServiceName)
}

servicesInExternalEnv, _ := commonrepo.NewServicesInExternalEnvColl().List(&commonrepo.ServicesInExternalEnvArgs{
ProductName: prod.ProductName,
EnvName: prod.EnvName,
})

externalServiceNames := sets.NewString()
for _, serviceInExternalEnv := range servicesInExternalEnv {
if !currentServiceNames.Has(serviceInExternalEnv.ServiceName) {
externalServiceNames.Insert(serviceInExternalEnv.ServiceName)
}
}

if len(externalServiceNames) > 0 {
newServices, _ := commonrepo.NewServiceColl().ListExternalWorkloadsBy(prod.ProductName, "", externalServiceNames.List()...)
for _, service := range newServices {
services = append(services, service)
}
}

for _, service := range services {
for _, container := range service.Containers {
env := service.ServiceName + "/" + container.Name
deployEnv := commonmodels.DeployEnv{Type: setting.K8SDeployType, Env: env}
target := strings.Join([]string{service.ProductName, service.ServiceName, container.Name}, SplitSymbol)
resp[target] = append(resp[target], deployEnv)

imageNameM[target] = util.GetImageNameFromContainerInfo(container.ImageName, container.Name)
}
}
return resp, imageNameM
}
for _, services := range prod.Services {
for _, serviceObj := range services {
switch serviceObj.Type {
Expand Down
Loading

0 comments on commit 029c807

Please sign in to comment.