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) {
if e := s.CheckBuildNumber(projectId); e != nil {
return 0, e
}
if e := s.CheckBuildByName(r.Name, r.Version, projectId); e != nil {
return 0, e
}
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
}