diff --git a/go.mod b/go.mod index 892305c405..57f994e93b 100644 --- a/go.mod +++ b/go.mod @@ -108,7 +108,7 @@ require ( k8s.io/cri-api v0.28.15 k8s.io/klog/v2 v2.90.1 moul.io/http2curl/v2 v2.3.0 - yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260409123844-2f5e06efeade + yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260411042903-0d42d35416dc yunion.io/x/executor v0.0.0-20260312022053-f538abd2b005 yunion.io/x/jsonutils v1.0.1-0.20250507052344-1abcf4f443b1 yunion.io/x/log v1.0.1-0.20240305175729-7cf2d6cd5a91 diff --git a/go.sum b/go.sum index 8e4238d3ff..4a4f278991 100644 --- a/go.sum +++ b/go.sum @@ -1785,8 +1785,8 @@ sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= -yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260409123844-2f5e06efeade h1:8DBeLhYpDrOW7oP5s/mGlc458zAN0mZq8ZMbH5b+JTA= -yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260409123844-2f5e06efeade/go.mod h1:TbMuTWxcTdyL2Usn+WQdIw0jdlBYO66SzPRY8LZ3Wj0= +yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260411042903-0d42d35416dc h1:r5S/o/GA4FczSmHM/DqKi3IzN+Mxl6C34vFFsMUFRcc= +yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260411042903-0d42d35416dc/go.mod h1:TbMuTWxcTdyL2Usn+WQdIw0jdlBYO66SzPRY8LZ3Wj0= yunion.io/x/executor v0.0.0-20260312022053-f538abd2b005 h1:3sWwcjGXGjG9mLBWa7AyLq+QSi0udTAx21pfVQRFMBE= yunion.io/x/executor v0.0.0-20260312022053-f538abd2b005/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws= yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634= diff --git a/pkg/esxi/options/options.go b/pkg/esxi/options/options.go index a10156a83a..86a34de828 100644 --- a/pkg/esxi/options/options.go +++ b/pkg/esxi/options/options.go @@ -36,6 +36,7 @@ type EsxiOptions struct { Zone string `help:"Zone where the agent locates"` DeployServerSocketPath string `help:"Deploy server listen socket path" default:"/var/run/onecloud/deploy.sock"` HostDelayTaskWorkerCount int `default:"8" help:"Host delay worker thread count, default is 8"` + EnableFolderNameUUID bool `default:"false" help:"Enable folder name uuid"` esxi.EsxiOptions } diff --git a/pkg/hostman/storageman/storage_agent.go b/pkg/hostman/storageman/storage_agent.go index 884ba4d19f..3d75fd229a 100644 --- a/pkg/hostman/storageman/storage_agent.go +++ b/pkg/hostman/storageman/storage_agent.go @@ -34,6 +34,7 @@ import ( api "yunion.io/x/onecloud/pkg/apis/compute" "yunion.io/x/onecloud/pkg/cloudcommon/agent/iagent" + esxi_options "yunion.io/x/onecloud/pkg/esxi/options" "yunion.io/x/onecloud/pkg/hostman/guestman/desc" deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis" "yunion.io/x/onecloud/pkg/hostman/hostdeployer/deployclient" @@ -148,7 +149,7 @@ func (as *SAgentStorage) agentRebuildRoot(ctx context.Context, data jsonutils.JS return vm.DoRebuildRoot(ctx, newPath, diskId, uefi) } -func (as *SAgentStorage) agentCreateGuest(ctx context.Context, data *jsonutils.JSONDict) (bool, error) { +func (as *SAgentStorage) agentCreateGuest(ctx context.Context, data jsonutils.JSONObject) (bool, error) { hd := SHostDatastore{} err := data.Unmarshal(&hd) if err != nil { @@ -168,6 +169,9 @@ func (as *SAgentStorage) agentCreateGuest(ctx context.Context, data *jsonutils.J if err != nil { return false, errors.Wrapf(err, "%s: fail to unmarshal to esxi.SCreateVMParam", hostutils.ParamsError) } + if !esxi_options.Options.EnableFolderNameUUID { + createParam.Uuid = "" + } needDeploy, vm, err := host.CreateVM2(ctx, ds, createParam) if err != nil { return false, errors.Wrap(err, "SHost.CreateVM2") @@ -180,10 +184,11 @@ func (as *SAgentStorage) agentCreateGuest(ctx context.Context, data *jsonutils.J log.Warningf("set tags for vm %s error: %v", createParam.Name, err) } } - name, _ := descDict.GetString("name") - err = as.tryRenameVm(ctx, vm, name) - if err != nil { - return false, errors.Wrapf(err, "RenameVm name '%s'", name) + if esxi_options.Options.EnableFolderNameUUID && len(createParam.Uuid) > 0 { + err = as.tryRenameVm(ctx, vm, createParam.Name) + if err != nil { + return false, errors.Wrapf(err, "RenameVm name '%s'", createParam.Name) + } } return needDeploy, nil } @@ -229,22 +234,55 @@ func (self esxiVm) GetName() string { return self.Name } +type SHostDatastore struct { + HostIp string + Datastore vcenter.SVCenterAccessInfo +} + +type SDeployInfo struct { + Action string + + SHostDatastore + + Desc desc.SGuestDesc + PublicKey string + DeletePublicKey string + AdminPublicKey string + ProjectPublicKey string + GuestExtId string + GuestId string + ResetPassword bool + Password string + EnableCloudInit bool + LoginAccount string + DeployTelegraf bool + TelegrafConf string + + Deploys []struct { + Path string + Content string + Action string + } +} + func (as *SAgentStorage) AgentDeployGuest(ctx context.Context, data interface{}) (jsonutils.JSONObject, error) { init := false dataDict := data.(*jsonutils.JSONDict) log.Debugf("dataDict: %s", dataDict) - action, _ := dataDict.GetString("action") - var ( - needDeploy = true - err error - ) - if action == "create" { + deployInfo := SDeployInfo{} + err := dataDict.Unmarshal(&deployInfo) + if err != nil { + return nil, errors.Wrap(err, "Unmarshal DeployInfo") + } + var needDeploy = true + switch deployInfo.Action { + case "create": needDeploy, err = as.agentCreateGuest(ctx, dataDict) if err != nil { return nil, errors.Wrap(err, "agentCreateGuest") } init = true - } else if action == "rebuild" { + case "rebuild": err := as.agentRebuildRoot(ctx, dataDict) if err != nil { return nil, errors.Wrap(err, "agentRebuildRoot") @@ -252,26 +290,25 @@ func (as *SAgentStorage) AgentDeployGuest(ctx context.Context, data interface{}) init = true } - var ( - hostIp, _ = dataDict.GetString("host_ip") - dsInfo, _ = dataDict.Get("datastore") - ) - dc, info, err := esxi.NewESXiClientFromJson(ctx, dsInfo) + dc, info, err := esxi.NewESXiClientFromJson(ctx, jsonutils.Marshal(deployInfo.Datastore)) if err != nil { return nil, errors.Wrap(err, "esxi.NewESXiClientFromJson") } - host, err := dc.FindHostByIp(hostIp) + host, err := dc.FindHostByIp(deployInfo.HostIp) if err != nil { return nil, errors.Wrap(err, "SDatacenter.FindHostByIp") } - vmId, _ := dataDict.GetString("guest_ext_id") + vmId := deployInfo.GuestExtId + if !esxi_options.Options.EnableFolderNameUUID && deployInfo.Action == "create" { + vmId = deployInfo.Desc.Name + } realHost := host ivm, err := host.GetIVMById(vmId) if err == cloudprovider.ErrNotFound { // reschedule by DRS, migrate to other host siblingHosts, err := host.GetSiblingHosts() if err != nil { - return nil, errors.Wrap(err, "SHost.GetSiblingHosts") + return nil, errors.Wrap(err, "GetSiblingHosts") } for _, sh := range siblingHosts { ivm, err = host.GetIVMById(vmId) @@ -314,48 +351,40 @@ func (as *SAgentStorage) AgentDeployGuest(ctx context.Context, data interface{}) return nil, errors.Wrapf(err, "%s: unmarshal to guestDesc", hostutils.ParamsError.Error()) } - var desc = new(desc.SGuestDesc) - err := dataDict.Unmarshal(desc, "desc") - if err != nil { - return nil, errors.Wrap(err, "Unmarshal Guest Desc") - } - // desc, _ := dataDict.Get("desc") guestDesc.Hypervisor = api.HYPERVISOR_ESXI - key := deployapi.SSHKeys{} - err = dataDict.Unmarshal(&key) - if err != nil { - return nil, errors.Wrapf(err, "%s: unmarshal to deployapi.SSHKeys", hostutils.ParamsError.Error()) + key := deployapi.SSHKeys{ + PublicKey: deployInfo.PublicKey, + DeletePublicKey: deployInfo.DeletePublicKey, + AdminPublicKey: deployInfo.AdminPublicKey, + ProjectPublicKey: deployInfo.ProjectPublicKey, } deployArray := make([]*deployapi.DeployContent, 0) - if dataDict.Contains("deploys") { - err = dataDict.Unmarshal(&deployArray, "deploys") - if err != nil { - return nil, errors.Wrapf(err, "%s: unmarshal to array of deployapi.DeployContent", hostutils.ParamsError.Error()) - } + for _, deploy := range deployInfo.Deploys { + deployArray = append(deployArray, &deployapi.DeployContent{ + Path: deploy.Path, + Content: deploy.Content, + Action: deploy.Action, + }) } isRandomPassword := false - passwd, _ := dataDict.GetString("password") - resetPassword := jsonutils.QueryBoolean(dataDict, "reset_password", false) + passwd := deployInfo.Password + resetPassword := deployInfo.ResetPassword if resetPassword && len(passwd) == 0 { passwd = seclib.RandomPassword(12) isRandomPassword = true } - enableCloudInit := jsonutils.QueryBoolean(dataDict, "enable_cloud_init", false) - loginAccount, _ := dataDict.GetString("login_account") - deployTelegraf := jsonutils.QueryBoolean(dataDict, "deploy_telegraf", false) - telegrafConfig, _ := dataDict.GetString("telegraf_conf") - if deployTelegraf && telegrafConfig == "" { + if deployInfo.DeployTelegraf && deployInfo.TelegrafConf == "" { return nil, errors.Errorf("missing telegraf_conf") } - deployInfo := deployapi.NewDeployInfo(&key, deployArray, passwd, isRandomPassword, init, false, + deployInformation := deployapi.NewDeployInfo(&key, deployArray, passwd, isRandomPassword, init, false, options.HostOptions.LinuxDefaultRootUser, options.HostOptions.WindowsDefaultAdminUser, - enableCloudInit, loginAccount, deployTelegraf, telegrafConfig, - desc.UserData, + deployInfo.EnableCloudInit, deployInfo.LoginAccount, deployInfo.DeployTelegraf, deployInfo.TelegrafConf, + deployInfo.Desc.UserData, ) log.Debugf("deployInfo: %s", jsonutils.Marshal(deployInfo)) deploy, err = deployclient.GetDeployClient().DeployGuestFs(ctx, &deployapi.DeployParams{ @@ -363,7 +392,7 @@ func (as *SAgentStorage) AgentDeployGuest(ctx context.Context, data interface{}) Path: rootPath, }, GuestDesc: &guestDesc, - DeployInfo: deployInfo, + DeployInfo: deployInformation, VddkInfo: &vddkInfo, }) customize := false @@ -382,7 +411,7 @@ func (as *SAgentStorage) AgentDeployGuest(ctx context.Context, data interface{}) } if customize { as.waitVmToolsVersion(ctx, vm) - err = vm.DoCustomize(ctx, jsonutils.Marshal(desc)) + err = vm.DoCustomize(ctx, jsonutils.Marshal(deployInfo.Desc)) if err != nil { log.Errorf("unable to DoCustomize for vm %s: %v", vm.GetId(), err) } @@ -438,11 +467,6 @@ func (as *SAgentStorage) waitVmToolsVersion(ctx context.Context, vm *esxi.SVirtu return } -type SHostDatastore struct { - HostIp string - Datastore vcenter.SVCenterAccessInfo -} - func (as *SAgentStorage) getHostAndDatastore(ctx context.Context, data SHostDatastore) (*esxi.SHost, *esxi.SDatastore, error) { client, err := esxi.NewESXiClientFromAccessInfo(ctx, &data.Datastore) if err != nil { diff --git a/vendor/modules.txt b/vendor/modules.txt index f03334d8f8..fb78351bf7 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -2603,7 +2603,7 @@ sigs.k8s.io/structured-merge-diff/v4/value # sigs.k8s.io/yaml v1.3.0 ## explicit; go 1.12 sigs.k8s.io/yaml -# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260409123844-2f5e06efeade +# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260411042903-0d42d35416dc ## explicit; go 1.24 yunion.io/x/cloudmux/pkg/apis yunion.io/x/cloudmux/pkg/apis/billing diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/esxi/datacenter.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/esxi/datacenter.go index 6379d26425..9755406f2f 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/esxi/datacenter.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/esxi/datacenter.go @@ -466,10 +466,25 @@ func (dc *SDatacenter) FetchVMById(id string) (*SVirtualMachine, error) { if err != nil { return nil, err } - if len(vms) == 0 { - return nil, errors.ErrNotFound + for i := range vms { + return vms[i], nil } - return vms[0], nil + return dc.FetchVMByName(id) +} + +func (dc *SDatacenter) FetchVMByName(name string) (*SVirtualMachine, error) { + filter := property.Match{} + filter["name"] = name + vms, err := dc.fetchVMsWithFilter(filter) + if err != nil { + return nil, err + } + for i := range vms { + if vms[i].GetName() == name { + return vms[i], nil + } + } + return nil, errors.Wrapf(errors.ErrNotFound, "FetchVMByName %s", name) } func (dc *SDatacenter) fetchDatastores(datastoreRefs []types.ManagedObjectReference) ([]cloudprovider.ICloudStorage, error) { diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/esxi/host.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/esxi/host.go index 2571835454..1149718ebd 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/esxi/host.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/esxi/host.go @@ -335,7 +335,7 @@ func (host *SHost) GetIVMById(id string) (cloudprovider.ICloudVM, error) { return nil, err } for i := 0; i < len(vms); i += 1 { - if vms[i].GetGlobalId() == id { + if vms[i].GetGlobalId() == id || vms[i].GetName() == id { return vms[i], nil } } @@ -1089,9 +1089,8 @@ func (host *SHost) DoCreateVM(ctx context.Context, ds *SDatastore, params SCreat needDeploy = true deviceChange := make([]types.BaseVirtualDeviceConfigSpec, 0, 5) - // uuid first name := params.Name - if len(params.Uuid) != 0 { + if len(params.Uuid) > 0 { name = params.Uuid } datastorePath := fmt.Sprintf("[%s] ", ds.GetRelName()) @@ -1228,7 +1227,11 @@ func (host *SHost) DoCreateVM(ctx context.Context, ds *SDatastore, params SCreat } vmRef := info.Result.(types.ManagedObjectReference) objectVM := object.NewVirtualMachine(host.manager.client.Client, vmRef) - vm, err = host.addDisks(ctx, ds, params.Disks, params.Uuid, objectVM) + uuid := params.Uuid + if len(uuid) == 0 { + uuid = params.Name + } + vm, err = host.addDisks(ctx, ds, params.Disks, uuid, objectVM) return }