cdbaf46c创建于 2023年8月25日历史提交
package build

import (
	"fleetmanager/api/errors"
	"fleetmanager/api/model/build"
	"fleetmanager/api/params"
	"fleetmanager/api/service/constants"
	"fleetmanager/db/dao"
	"fleetmanager/setting"
	"fleetmanager/workflow"
	"fleetmanager/workflow/directer"
	"fleetmanager/worknode"
	"github.com/beego/beego/v2/server/web/context"
)

func (s *Service) CreateDocker(ctx *context.Context, r build.CreateRequest) (*build.Build, *errors.CodedError) {
	s.createReq = &r
	projectId := ctx.Input.Param(params.ProjectId)

	enterpriseProjectId := r.EnterpriseProject
	if enterpriseProjectId == "" {
		enterpriseProjectId = setting.EnterpriseProject
	}

	_, _, userPassword := getUserInfo(&r)

	fileSize, e := s.checkDockerCreate(projectId, &r)
	if e != nil {
		s.Logger.Error("check create build failed with error:%+v", e)
		return nil, e
	}

	b, err := dao.InsertBuild(r, projectId, fileSize)
	if err != nil {
		s.Logger.Error("insert build error for %+v", err)
		return nil, errors.NewErrorF(errors.ServerInternalError, "insert build error")
	}
	bd := buildBuildModel(b)
	s.Build = b

	if e := s.startCreateDockerBuildImageWorkflow(r.OperatingSystem, r.VpcId, r.SubnetId, enterpriseProjectId, userPassword,
		r.Organization); e != nil {
		if e := s.updateStateError(); e != nil {
			s.Logger.Error("update build state to error failed: %v", e)
		}
		err := s.updateBuild(e.ErrD)
		if err != nil {
			s.Logger.Error("update build state reason to error failed: %v", err)
		}
		return &bd, e
	}

	return &bd, nil
}

func (s *Service) checkDockerCreate(projectId string, r *build.CreateRequest) (int64, *errors.CodedError) {

	// check build Number
	if e := s.CheckBuildNumber(projectId); e != nil {
		return 0, e
	}

	// check build name
	if e := s.CheckBuildByName(r.Name, r.Version, projectId); e != nil {
		return 0, e
	}

	// check build bucket
	if e := s.CheckBucket(r.StorageLocation.BucketName, projectId, r.Region); e != nil {
		return 0, e
	}

	fileSize, e := s.CheckObjAndSize(r.StorageLocation.BucketName, r.StorageLocation.BucketKey,
		projectId, r.Region)
	if e != nil {
		return 0, e
	}
	if r.BuildType != constants.PODTYPE || r.Organization == "" || r.OperatingSystem == "" {
		s.Logger.Info("check param failed type: %s, organization: %s, operating system: %s", r.BuildType, r.Organization, r.OperatingSystem)
		return 0, s.ErrorMsg(errors.InvalidParameterValue, "invalid param for organization or operating system", nil)
	}
	return fileSize, nil
}

func (s *Service) startCreateDockerBuildImageWorkflow(imageRef string, vpcId string, subnetId string,
	enterpriseProjectId string, userPassword string, organization string) (e *errors.CodedError) {
	parameter := map[string]interface{}{
		directer.WfKeyRegion:                s.Build.ImageRegion,
		directer.WfKeyBuild:                 s.Build,
		directer.WfKeyBuildVpcId:            vpcId,
		directer.WfKeyBuildSubnetId:         subnetId,
		directer.WfKeyOriProjectId:          s.Build.ProjectId,
		directer.WfKeyImageRef:              imageRef,
		directer.WfKeyBandwidthName:         s.Build.Id,
		directer.WfKeyBuildBandwidth:        s.createReq.Bandwidth.Size,
		directer.WfKeyBandwidthChargingMode: s.createReq.Bandwidth.ChargingMode,
		directer.WfKeyBandwidthType:         setting.Config.Get(setting.EipType + "." + s.Build.ImageRegion).ToString(""),
		directer.WfKeyEnterpriseProjectId:   enterpriseProjectId,
		directer.WfKeyBuildUser:             s.Build.User,
		directer.WfKeyBuildGroup:            s.Build.Group,
		directer.WfKeyBuildPassword:         userPassword,
		directer.WfKeyBuildOrganization:     organization,
		directer.WfKeyBuildType:             s.Build.BuildType,
	}

	wf, err := workflow.CreateWorkflow(setting.WorkflowPath+"create_build_docker_image_workflow.json",
		parameter,
		s.Build.Id,
		s.Build.ProjectId,
		s.Logger,
		worknode.WorkNodeId)

	if err != nil {
		s.Logger.Error("create workflow in create docker build error: %v", err)
		return errors.NewError(errors.ServerInternalError)
	}

	wf.Run()
	return nil
}