mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
Merge pull request #3603 from swordqiu/hotfix/qj-baremetal-misc-bugfix-20191112
fix: create baremetal server with iso, baremetal register support redfishApi
This commit is contained in:
@@ -218,7 +218,7 @@ func handleServerStatus(ctx *Context, bm *baremetal.SBaremetalInstance, _ bareme
|
||||
|
||||
func handleBaremetalRegister(ctx *Context, input *baremetal.BmRegisterInput) {
|
||||
ctx.DelayProcess(func(data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
baremetal.GetBaremetalManager().RegisterBaremetal(input)
|
||||
baremetal.GetBaremetalManager().RegisterBaremetal(ctx, input)
|
||||
return nil, nil
|
||||
}, nil)
|
||||
}
|
||||
|
||||
@@ -287,7 +287,7 @@ func (i *BmRegisterInput) isTimeout() bool {
|
||||
}
|
||||
|
||||
// delay task
|
||||
func (m *SBaremetalManager) RegisterBaremetal(input *BmRegisterInput) {
|
||||
func (m *SBaremetalManager) RegisterBaremetal(ctx context.Context, input *BmRegisterInput) {
|
||||
adminWire, err := m.checkNetworkFromIp(input.RemoteIp)
|
||||
if input.isTimeout() {
|
||||
return
|
||||
@@ -303,7 +303,7 @@ func (m *SBaremetalManager) RegisterBaremetal(input *BmRegisterInput) {
|
||||
return
|
||||
}
|
||||
|
||||
ipmiMac, err := m.checkIpmiInfo(input.Username, input.Password, input.IpAddr)
|
||||
ipmiLanChannel, ipmiMac, err := m.checkIpmiInfo(input.Username, input.Password, input.IpAddr)
|
||||
if input.isTimeout() {
|
||||
return
|
||||
} else if err != nil {
|
||||
@@ -330,7 +330,7 @@ func (m *SBaremetalManager) RegisterBaremetal(input *BmRegisterInput) {
|
||||
registerTask := tasks.NewBaremetalRegisterTask(
|
||||
m, sshCli, input.Hostname, input.RemoteIp,
|
||||
input.Username, input.Password, input.IpAddr,
|
||||
ipmiMac, adminWire, ipmiWire,
|
||||
ipmiMac, ipmiLanChannel, adminWire, ipmiWire,
|
||||
)
|
||||
err = registerTask.CreateBaremetal()
|
||||
if input.isTimeout() {
|
||||
@@ -341,7 +341,7 @@ func (m *SBaremetalManager) RegisterBaremetal(input *BmRegisterInput) {
|
||||
}
|
||||
|
||||
input.responseOk()
|
||||
registerTask.DoPrepare(sshCli)
|
||||
registerTask.DoPrepare(ctx, sshCli)
|
||||
}
|
||||
|
||||
func (m *SBaremetalManager) checkNetworkFromIp(ip string) (string, error) {
|
||||
@@ -407,11 +407,11 @@ func (m *SBaremetalManager) checkSshInfo(input *BmRegisterInput) (*ssh.Client, e
|
||||
return sshCLi, nil
|
||||
}
|
||||
|
||||
func (m *SBaremetalManager) checkIpmiInfo(username, password, ipAddr string) (net.HardwareAddr, error) {
|
||||
func (m *SBaremetalManager) checkIpmiInfo(username, password, ipAddr string) (int, net.HardwareAddr, error) {
|
||||
lanPlusTool := ipmitool.NewLanPlusIPMI(ipAddr, username, password)
|
||||
sysInfo, err := ipmitool.GetSysInfo(lanPlusTool)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return -1, nil, err
|
||||
}
|
||||
|
||||
for _, lanChannel := range ipmitool.GetLanChannels(sysInfo) {
|
||||
@@ -423,9 +423,9 @@ func (m *SBaremetalManager) checkIpmiInfo(username, password, ipAddr string) (ne
|
||||
if len(config.Mac) == 0 {
|
||||
continue
|
||||
}
|
||||
return config.Mac, nil
|
||||
return lanChannel, config.Mac, nil
|
||||
}
|
||||
return nil, fmt.Errorf("Ipmi can't fetch lan config")
|
||||
return -1, nil, fmt.Errorf("Ipmi can't fetch lan config")
|
||||
}
|
||||
|
||||
func (m *SBaremetalManager) Stop() {
|
||||
@@ -1861,7 +1861,7 @@ func (b *SBaremetalInstance) doCronJobs(ctx context.Context) {
|
||||
for _, job := range b.cronJobs {
|
||||
now := time.Now().UTC()
|
||||
if job.NeedsToRun(now) {
|
||||
log.Debugf("need to run %s", job.Name())
|
||||
// log.Debugf("need to run %s", job.Name())
|
||||
func() {
|
||||
job.StartRun()
|
||||
defer job.StopRun()
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
@@ -27,6 +28,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/baremetal/utils/ipmitool"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/types"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
"yunion.io/x/onecloud/pkg/util/redfish"
|
||||
"yunion.io/x/onecloud/pkg/util/ssh"
|
||||
"yunion.io/x/onecloud/pkg/util/sysutils"
|
||||
)
|
||||
@@ -44,26 +46,30 @@ type sBaremetalRegisterTask struct {
|
||||
IpmiPassword string
|
||||
IpmiIpAddr string
|
||||
IpmiMac net.HardwareAddr
|
||||
AdminWire string
|
||||
IpmiWire string
|
||||
|
||||
IpmiLanChannel int
|
||||
|
||||
AdminWire string
|
||||
IpmiWire string
|
||||
|
||||
accessNic *types.SNicDevInfo
|
||||
}
|
||||
|
||||
func NewBaremetalRegisterTask(bmManager IBmManager, sshCli *ssh.Client,
|
||||
hostname, remoteIp, ipmiUsername, ipmiPassword, ipmiIpAddr string,
|
||||
ipmiMac net.HardwareAddr, adminWire, ipmiWire string) *sBaremetalRegisterTask {
|
||||
ipmiMac net.HardwareAddr, ipmiLanChannel int, adminWire, ipmiWire string) *sBaremetalRegisterTask {
|
||||
return &sBaremetalRegisterTask{
|
||||
BmManager: bmManager,
|
||||
SshCli: sshCli,
|
||||
Hostname: hostname,
|
||||
RemoteIp: remoteIp,
|
||||
IpmiUsername: ipmiUsername,
|
||||
IpmiPassword: ipmiPassword,
|
||||
IpmiIpAddr: ipmiIpAddr,
|
||||
IpmiMac: ipmiMac,
|
||||
AdminWire: adminWire,
|
||||
IpmiWire: ipmiWire,
|
||||
BmManager: bmManager,
|
||||
SshCli: sshCli,
|
||||
Hostname: hostname,
|
||||
RemoteIp: remoteIp,
|
||||
IpmiUsername: ipmiUsername,
|
||||
IpmiPassword: ipmiPassword,
|
||||
IpmiIpAddr: ipmiIpAddr,
|
||||
IpmiMac: ipmiMac,
|
||||
IpmiLanChannel: ipmiLanChannel,
|
||||
AdminWire: adminWire,
|
||||
IpmiWire: ipmiWire,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,15 +134,33 @@ func (s *sBaremetalRegisterTask) update() {
|
||||
|
||||
}
|
||||
|
||||
func (s *sBaremetalRegisterTask) DoPrepare(cli *ssh.Client) error {
|
||||
func (s *sBaremetalRegisterTask) doRedfishProbe(ctx context.Context) (redfishSupport bool, cdromBoot bool) {
|
||||
redfishCli := redfish.NewRedfishDriver(ctx, "https://"+s.IpmiIpAddr, s.IpmiUsername, s.IpmiPassword, false)
|
||||
if redfishCli != nil {
|
||||
_, cdInfo, _ := redfishCli.GetVirtualCdromInfo(ctx)
|
||||
redfishSupport = true
|
||||
cdromBoot = cdInfo.SupportAction
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sBaremetalRegisterTask) DoPrepare(ctx context.Context, cli *ssh.Client) error {
|
||||
infos, err := s.prepareBaremetalInfo(cli)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
redfishSupport, cdromSupport := s.doRedfishProbe(ctx)
|
||||
|
||||
infos.ipmiInfo.IpAddr = s.IpmiIpAddr
|
||||
infos.ipmiInfo.Username = s.IpmiUsername
|
||||
infos.ipmiInfo.Password = s.IpmiPassword
|
||||
infos.ipmiInfo.LanChannel = s.IpmiLanChannel
|
||||
infos.ipmiInfo.Verified = true
|
||||
infos.ipmiInfo.Present = true
|
||||
infos.ipmiInfo.RedfishApi = redfishSupport
|
||||
infos.ipmiInfo.CdromBoot = cdromSupport
|
||||
|
||||
s.updateIpmiInfo(cli)
|
||||
|
||||
return s.updateBmInfo(cli, infos)
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"database/sql"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
@@ -65,19 +66,21 @@ func MergeServiceConfig(opts interface{}, serviceType string, serviceVersion str
|
||||
if len(serviceId) > 0 {
|
||||
serviceConf, err := getServiceConfig(s, serviceId)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getServiceConfig")
|
||||
log.Errorf("getServiceConfig for %s failed: %s", serviceType, err)
|
||||
} else {
|
||||
conf.Update(serviceConf)
|
||||
merged = true
|
||||
}
|
||||
conf.Update(serviceConf)
|
||||
merged = true
|
||||
}
|
||||
commonServiceId, _ := getServiceIdByType(s, consts.COMMON_SERVICE, "")
|
||||
if len(commonServiceId) > 0 {
|
||||
commonConf, err := getServiceConfig(s, commonServiceId)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getServiceConfig common service")
|
||||
log.Errorf("getServiceConfig for %s failed: %s", consts.COMMON_SERVICE, err)
|
||||
} else {
|
||||
conf.Update(commonConf)
|
||||
merged = true
|
||||
}
|
||||
conf.Update(commonConf)
|
||||
merged = true
|
||||
}
|
||||
if merged {
|
||||
err := conf.Unmarshal(opts)
|
||||
@@ -89,7 +92,8 @@ func MergeServiceConfig(opts interface{}, serviceType string, serviceVersion str
|
||||
nconf.Add(conf, "config", "default")
|
||||
_, err := modules.ServicesV3.PerformAction(s, serviceId, "config", nconf)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "modules.ServicesV3.PerformAction")
|
||||
// ignore the error
|
||||
log.Errorf("fail to save config: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,9 +261,13 @@ func (self *SBaremetalGuestDriver) RequestGuestCreateAllDisks(ctx context.Contex
|
||||
return storageCache.StartImageCacheTask(ctx, task.GetUserCred(), imageId, diskCat.Root.DiskFormat, false, task.GetTaskId())
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) RequestGuestHotAddIso(ctx context.Context, guest *models.SGuest, path string, task taskman.ITask) error {
|
||||
func (self *SBaremetalGuestDriver) NeedRequestGuestHotAddIso(ctx context.Context, guest *models.SGuest) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) RequestGuestHotAddIso(ctx context.Context, guest *models.SGuest, path string, boot bool, task taskman.ITask) error {
|
||||
host := guest.GetHost()
|
||||
return host.StartInsertIsoTask(ctx, task.GetUserCred(), filepath.Base(path), false, task.GetTaskId())
|
||||
return host.StartInsertIsoTask(ctx, task.GetUserCred(), filepath.Base(path), boot, task.GetTaskId())
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) RequestGuestHotRemoveIso(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
|
||||
@@ -272,8 +276,7 @@ func (self *SBaremetalGuestDriver) RequestGuestHotRemoveIso(ctx context.Context,
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) RequestGuestCreateInsertIso(ctx context.Context, imageId string, guest *models.SGuest, task taskman.ITask) error {
|
||||
host := guest.GetHost()
|
||||
return host.StartInsertIsoTask(ctx, task.GetUserCred(), imageId, true, task.GetTaskId())
|
||||
return guest.StartInsertIsoTask(ctx, imageId, true, guest.HostId, task.GetUserCred(), task.GetTaskId())
|
||||
}
|
||||
|
||||
func (self *SBaremetalGuestDriver) RequestStartOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, userCred mcclient.TokenCredential, task taskman.ITask) (jsonutils.JSONObject, error) {
|
||||
|
||||
@@ -199,7 +199,11 @@ func (self *SBaseGuestDriver) RequestChangeVmConfig(ctx context.Context, guest *
|
||||
return fmt.Errorf("Not Implement")
|
||||
}
|
||||
|
||||
func (self *SBaseGuestDriver) RequestGuestHotAddIso(ctx context.Context, guest *models.SGuest, path string, task taskman.ITask) error {
|
||||
func (self *SBaseGuestDriver) NeedRequestGuestHotAddIso(ctx context.Context, guest *models.SGuest) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SBaseGuestDriver) RequestGuestHotAddIso(ctx context.Context, guest *models.SGuest, path string, boot bool, task taskman.ITask) error {
|
||||
return fmt.Errorf("Not Implement")
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ func (self *SContainerDriver) RequestGuestCreateAllDisks(ctx context.Context, gu
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SContainerDriver) RequestGuestHotAddIso(ctx context.Context, guest *models.SGuest, path string, task taskman.ITask) error {
|
||||
func (self *SContainerDriver) RequestGuestHotAddIso(ctx context.Context, guest *models.SGuest, path string, boot bool, task taskman.ITask) error {
|
||||
// do nothing, call next stage
|
||||
task.ScheduleRun(nil)
|
||||
return nil
|
||||
|
||||
@@ -106,7 +106,7 @@ func (self *SESXiGuestDriver) CanKeepDetachDisk() bool {
|
||||
// return nil
|
||||
// }
|
||||
|
||||
func (self *SESXiGuestDriver) RequestGuestHotAddIso(ctx context.Context, guest *models.SGuest, path string, task taskman.ITask) error {
|
||||
func (self *SESXiGuestDriver) RequestGuestHotAddIso(ctx context.Context, guest *models.SGuest, path string, boot bool, task taskman.ITask) error {
|
||||
task.ScheduleRun(nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -408,7 +408,11 @@ func (self *SKVMGuestDriver) RequestGuestCreateAllDisks(ctx context.Context, gue
|
||||
return guest.StartGuestCreateDiskTask(ctx, task.GetUserCred(), input.Disks, task.GetTaskId())
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) RequestGuestHotAddIso(ctx context.Context, guest *models.SGuest, path string, task taskman.ITask) error {
|
||||
func (self *SKVMGuestDriver) NeedRequestGuestHotAddIso(ctx context.Context, guest *models.SGuest) bool {
|
||||
return guest.Status == api.VM_RUNNING
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) RequestGuestHotAddIso(ctx context.Context, guest *models.SGuest, path string, boot bool, task taskman.ITask) error {
|
||||
return guest.StartSyncTask(ctx, task.GetUserCred(), false, task.GetTaskId())
|
||||
}
|
||||
|
||||
|
||||
@@ -163,7 +163,7 @@ func (self *SVirtualizedGuestDriver) ChooseHostStorage(host *models.SHost, backe
|
||||
}
|
||||
|
||||
func (self *SVirtualizedGuestDriver) RequestGuestCreateInsertIso(ctx context.Context, imageId string, guest *models.SGuest, task taskman.ITask) error {
|
||||
return guest.StartInsertIsoTask(ctx, imageId, guest.HostId, task.GetUserCred(), task.GetTaskId())
|
||||
return guest.StartInsertIsoTask(ctx, imageId, true, guest.HostId, task.GetUserCred(), task.GetTaskId())
|
||||
}
|
||||
|
||||
func (self *SVirtualizedGuestDriver) StartGuestStopTask(guest *models.SGuest, ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict, parentTaskId string) error {
|
||||
|
||||
@@ -882,7 +882,7 @@ func (self *SGuest) PerformInsertiso(ctx context.Context, userCred mcclient.Toke
|
||||
}
|
||||
|
||||
if utils.IsInStringArray(self.Status, []string{api.VM_RUNNING, api.VM_READY}) {
|
||||
err = self.StartInsertIsoTask(ctx, image.Id, self.HostId, userCred, "")
|
||||
err = self.StartInsertIsoTask(ctx, image.Id, false, self.HostId, userCred, "")
|
||||
return nil, err
|
||||
} else {
|
||||
return nil, httperrors.NewServerStatusError("Insert ISO not allowed in status %s", self.Status)
|
||||
@@ -918,12 +918,15 @@ func (self *SGuest) StartEjectisoTask(ctx context.Context, userCred mcclient.Tok
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SGuest) StartInsertIsoTask(ctx context.Context, imageId string, hostId string, userCred mcclient.TokenCredential, parentTaskId string) error {
|
||||
func (self *SGuest) StartInsertIsoTask(ctx context.Context, imageId string, boot bool, hostId string, userCred mcclient.TokenCredential, parentTaskId string) error {
|
||||
self.insertIso(imageId)
|
||||
|
||||
data := jsonutils.NewDict()
|
||||
data.Add(jsonutils.NewString(imageId), "image_id")
|
||||
data.Add(jsonutils.NewString(hostId), "host_id")
|
||||
if boot {
|
||||
data.Add(jsonutils.JSONTrue, "boot")
|
||||
}
|
||||
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "GuestInsertIsoTask", self, userCred, data, parentTaskId, "", nil)
|
||||
if err != nil {
|
||||
|
||||
@@ -150,7 +150,8 @@ type IGuestDriver interface {
|
||||
DoGuestCreateDisksTask(ctx context.Context, guest *SGuest, task taskman.ITask) error
|
||||
RequestChangeVmConfig(ctx context.Context, guest *SGuest, task taskman.ITask, instanceType string, vcpuCount, vmemSize int64) error
|
||||
|
||||
RequestGuestHotAddIso(ctx context.Context, guest *SGuest, path string, task taskman.ITask) error
|
||||
NeedRequestGuestHotAddIso(ctx context.Context, guest *SGuest) bool
|
||||
RequestGuestHotAddIso(ctx context.Context, guest *SGuest, path string, boot bool, task taskman.ITask) error
|
||||
RequestGuestHotRemoveIso(ctx context.Context, guest *SGuest, task taskman.ITask) error
|
||||
RequestRebuildRootDisk(ctx context.Context, guest *SGuest, task taskman.ITask) error
|
||||
|
||||
|
||||
@@ -278,7 +278,7 @@ func (self *GuestCreateBackupTask) StartCreateBackupDisks(ctx context.Context, g
|
||||
|
||||
func (self *GuestCreateBackupTask) StartInsertIso(ctx context.Context, guest *models.SGuest, imageId string) {
|
||||
self.SetStage("OnInsertIso", nil)
|
||||
guest.StartInsertIsoTask(ctx, imageId, guest.BackupHostId, self.UserCred, self.GetTaskId())
|
||||
guest.StartInsertIsoTask(ctx, imageId, false, guest.BackupHostId, self.UserCred, self.GetTaskId())
|
||||
}
|
||||
|
||||
func (self *GuestCreateBackupTask) OnInsertIso(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
|
||||
|
||||
@@ -19,7 +19,6 @@ import (
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
@@ -77,9 +76,10 @@ func (self *GuestInsertIsoTask) OnIsoPrepareComplete(ctx context.Context, obj db
|
||||
guest := obj.(*models.SGuest)
|
||||
if guest.InsertIsoSucc(imageId, path, int(size), name) {
|
||||
db.OpsLog.LogEvent(guest, db.ACT_ISO_ATTACH, guest.GetDetailsIso(self.UserCred), self.UserCred)
|
||||
if guest.Status == api.VM_RUNNING {
|
||||
if guest.GetDriver().NeedRequestGuestHotAddIso(ctx, guest) {
|
||||
self.SetStage("OnConfigSyncComplete", nil)
|
||||
guest.GetDriver().RequestGuestHotAddIso(ctx, guest, path, self)
|
||||
boot := jsonutils.QueryBoolean(self.Params, "boot", false)
|
||||
guest.GetDriver().RequestGuestHotAddIso(ctx, guest, path, boot, self)
|
||||
} else {
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -51,8 +51,10 @@ func (m *SMetricData) Line() string {
|
||||
line := strings.Builder{}
|
||||
line.WriteString(m.Name)
|
||||
for i := range m.Tags {
|
||||
line.WriteByte(',')
|
||||
line.WriteString(m.Tags[i].String())
|
||||
if len(m.Tags[i].Key) > 0 && len(m.Tags[i].Value) > 0 {
|
||||
line.WriteByte(',')
|
||||
line.WriteString(m.Tags[i].String())
|
||||
}
|
||||
}
|
||||
line.WriteByte(' ')
|
||||
for i := range m.Metrics {
|
||||
|
||||
Reference in New Issue
Block a user