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:
yunion-ci-robot
2019-11-12 21:44:27 +08:00
committed by GitHub
15 changed files with 94 additions and 49 deletions
+1 -1
View File
@@ -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)
}
+9 -9
View File
@@ -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()
+38 -14
View File
@@ -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)
+11 -7
View File
@@ -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)
}
}
}
+7 -4
View File
@@ -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) {
+5 -1
View File
@@ -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")
}
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
}
+5 -1
View File
@@ -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())
}
+1 -1
View File
@@ -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 {
+5 -2
View File
@@ -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 {
+2 -1
View File
@@ -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
+1 -1
View File
@@ -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) {
+3 -3
View File
@@ -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)
}
+4 -2
View File
@@ -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 {