feature: support baremetal profile (#20687)

Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
This commit is contained in:
Jian Qiu
2024-06-30 22:22:45 +08:00
committed by GitHub
parent c333a80cfa
commit 44183fb021
43 changed files with 995 additions and 328 deletions
@@ -0,0 +1,50 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/printutils"
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient"
baremetalmodules "yunion.io/x/onecloud/pkg/mcclient/modules/compute/baremetal"
baremetaloptions "yunion.io/x/onecloud/pkg/mcclient/options/compute/baremetal"
)
func init() {
cmd := shell.NewResourceCmd(&baremetalmodules.BaremetalProfiles)
cmd.List(new(baremetaloptions.BaremetalProfileListOptions))
cmd.Show(new(baremetaloptions.BaremetalProfileIdOptions))
cmd.Delete(new(baremetaloptions.BaremetalProfileIdOptions))
type BaremetalProfileMatchOpts struct {
OEMNAME string
MODEL string
}
R(&BaremetalProfileMatchOpts{}, "baremetal-profile-match", "find match baremetal profile by oemname and model", func(s *mcclient.ClientSession, args *BaremetalProfileMatchOpts) error {
specs, err := baremetalmodules.BaremetalProfiles.GetMatchProfiles(s, args.OEMNAME, args.MODEL)
if err != nil {
return errors.Wrap(err, "GetMatchProfiles")
}
listResults := printutils.ListResult{}
for _, spec := range specs {
listResults.Data = append(listResults.Data, jsonutils.Marshal(spec))
}
printList(&listResults, nil)
return nil
})
}
+15
View File
@@ -0,0 +1,15 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package baremetal // import "yunion.io/x/onecloud/pkg/apis/compute/baremetal"
+165
View File
@@ -0,0 +1,165 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package baremetal
import (
"strings"
"yunion.io/x/onecloud/pkg/apis"
"yunion.io/x/onecloud/pkg/cloudcommon/types"
)
const (
DefaultBaremetalProfileId = "default"
)
type BaremetalProfileListInput struct {
apis.StandaloneAnonResourceListInput
OemName []string `json:"oem_name"`
Model []string `json:"model"`
}
func (input *BaremetalProfileListInput) Normalize() {
for i := range input.OemName {
input.OemName[i] = strings.TrimSpace(input.OemName[i])
}
for i := range input.Model {
input.Model[i] = strings.TrimSpace(input.Model[i])
}
}
type BaremetalProfileCreateInput struct {
apis.StandaloneAnonResourceCreateInput
OemName string
Model string
LanChannel uint8
RootId int
RootName string
StrongPass bool
}
type BaremetalProfileUpdateInput struct {
apis.StandaloneAnonResourceBaseUpdateInput
LanChannel uint8
RootId *int
RootName string
StrongPass *bool
}
type BaremetalProfileDetails struct {
SBaremetalProfile
}
func (detail BaremetalProfileDetails) ToSpec() BaremetalProfileSpec {
channels := make([]uint8, 0)
if detail.LanChannel > 0 {
channels = append(channels, detail.LanChannel)
}
if detail.LanChannel2 > 0 {
channels = append(channels, detail.LanChannel2)
}
if detail.LanChannel3 > 0 {
channels = append(channels, detail.LanChannel3)
}
return BaremetalProfileSpec{
OemName: detail.OemName,
Model: detail.Model,
LanChannels: channels,
RootName: detail.RootName,
RootId: detail.RootId,
StrongPass: detail.StrongPass,
}
}
type BaremetalProfileSpec struct {
OemName string
Model string
LanChannels []uint8
RootName string
RootId int
StrongPass bool
}
type BaremetalProfileSpecs []BaremetalProfileSpec
func (a BaremetalProfileSpecs) Len() int { return len(a) }
func (a BaremetalProfileSpecs) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a BaremetalProfileSpecs) Less(i, j int) bool {
if a[i].OemName != a[j].OemName {
return a[i].OemName < a[j].OemName
}
if a[i].Model != a[j].Model {
return a[i].Model < a[j].Model
}
return false
}
var PredefinedProfiles = []BaremetalProfileSpec{
{
OemName: "",
LanChannels: []uint8{1, 2, 8},
RootName: "root",
RootId: 2,
},
{
OemName: types.OEM_NAME_INSPUR,
LanChannels: []uint8{8, 1},
RootName: "admin",
RootId: 2,
},
{
OemName: types.OEM_NAME_LENOVO,
LanChannels: []uint8{1, 8},
RootName: "root",
RootId: 2,
},
{
OemName: types.OEM_NAME_HP,
LanChannels: []uint8{1, 2},
RootName: "root",
RootId: 1,
},
{
OemName: types.OEM_NAME_HUAWEI,
LanChannels: []uint8{1},
RootName: "root",
RootId: 2,
StrongPass: true,
},
{
OemName: types.OEM_NAME_FOXCONN,
LanChannels: []uint8{1},
RootName: "root",
RootId: 2,
StrongPass: true,
},
{
OemName: types.OEM_NAME_QEMU,
LanChannels: []uint8{8, 1},
RootName: "root",
RootId: 2,
StrongPass: true,
},
{
OemName: types.OEM_NAME_H3C,
LanChannels: []uint8{1},
RootName: "root",
RootId: 2,
StrongPass: true,
},
}
@@ -0,0 +1,36 @@
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Code generated by model-api-gen. DO NOT EDIT.
package baremetal
import (
"yunion.io/x/onecloud/pkg/apis"
)
// SBaremetalProfile is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models/baremetal.SBaremetalProfile.
type SBaremetalProfile struct {
apis.SStandaloneAnonResourceBase
// 品牌名称(English)
OemName string `json:"oem_name"`
Model string `json:"model"`
LanChannel byte `json:"lan_channel"`
LanChannel2 byte `json:"lan_channel2"`
LanChannel3 byte `json:"lan_channel3"`
// BMC Root账号名称,默认为 root
RootName string `json:"root_name"`
// BMC Root账号ID,默认为 2
RootId int `json:"root_id"`
// 是否要求强密码
StrongPass bool `json:"strong_pass"`
}
+1 -1
View File
@@ -414,7 +414,7 @@ type HostIpmiAttributes struct {
// presence
IpmiPresent *bool `json:"ipmi_present"`
// lan channel
IpmiLanChannel *int `json:"ipmi_lan_channel"`
IpmiLanChannel *uint8 `json:"ipmi_lan_channel"`
// verified
IpmiVerified *bool `json:"ipmi_verified"`
// Redfish API support
+2
View File
@@ -269,6 +269,8 @@ type SCloudaccount struct {
// 跳过部分资源同步
SkipSyncResources *SkipSyncResources `json:"skip_sync_resources"`
EnableAutoSyncResource *bool `json:"enable_auto_sync_resource,omitempty"`
// 云平台默认区域id
RegionId string `json:"region_id"`
}
// SCloudimage is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SCloudimage.
+3 -1
View File
@@ -134,7 +134,9 @@ func (agent *SBaremetalAgent) StartService() error {
if err != nil {
return fmt.Errorf("Baremetal manager load config error: %v", err)
}
if err := manager.initBaremetals(files); err != nil {
ctx := context.Background()
if err := manager.initBaremetals(ctx, files); err != nil {
log.Warningf("init baremetals by files err: %v", err)
}
+1 -1
View File
@@ -107,7 +107,7 @@ func (job *SStatusProbeJob) Do(ctx context.Context, now time.Time) error {
pps := PowerStatusToBaremetalStatus(ps)
if pps != bStatus {
log.Debugf("Detected baremetal status change!")
job.baremetal.SyncAllStatus(ps)
job.baremetal.SyncAllStatus(ctx, ps)
return nil
}
}
+4 -2
View File
@@ -15,6 +15,7 @@
package handler
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
@@ -30,9 +31,10 @@ func init() {
delayTaskWorkerMan = appsrv.NewWorkerManager("DelayTaskWorkerManager", 8, 1024, false)
}
type ProcessFunc func(data jsonutils.JSONObject) (jsonutils.JSONObject, error)
type ProcessFunc func(ctx context.Context, data jsonutils.JSONObject) (jsonutils.JSONObject, error)
type delayTask struct {
ctx context.Context
process ProcessFunc
taskId string
session *mcclient.ClientSession
@@ -40,7 +42,7 @@ type delayTask struct {
}
func (t *delayTask) Run() {
ret, err := t.process(t.data)
ret, err := t.process(t.ctx, t.data)
if err != nil {
modules.ComputeTasks.TaskFailed(t.session, t.taskId, err)
return
+4 -4
View File
@@ -109,7 +109,7 @@ func handleBaremetalNotify(ctx *Context, bm *baremetal.SBaremetalInstance) {
task := bm.GetTask()
if task == nil {
task = tasks.NewBaremetalServerPrepareTask(bm)
bm.SyncStatus(baremetalstatus.PREPARE, "")
bm.SyncStatus(ctx, baremetalstatus.PREPARE, "")
}
log.Infof("Get notify from pxe rom os, start exec task: %s", task.GetName())
task.SSHExecute(remoteAddr, key, nil)
@@ -157,7 +157,7 @@ func handleBaremetalResetBMC(ctx *Context, bm *baremetal.SBaremetalInstance) {
}
func handleBaremetalIpmiProbe(ctx *Context, bm *baremetal.SBaremetalInstance) {
bm.StartBaremetalIpmiProbeTask(ctx.UserCred(), ctx.TaskId(), ctx.Data())
bm.StartBaremetalIpmiProbeTask(ctx, ctx.UserCred(), ctx.TaskId(), ctx.Data())
ctx.ResponseOk()
}
@@ -178,7 +178,7 @@ func handleBaremetalJnlpTask(ctx *Context, bm *baremetal.SBaremetalInstance) {
}
func handleServerCreate(ctx *Context, bm *baremetal.SBaremetalInstance) {
err := bm.StartServerCreateTask(ctx.UserCred(), ctx.TaskId(), ctx.Data())
err := bm.StartServerCreateTask(ctx, ctx.UserCred(), ctx.TaskId(), ctx.Data())
if err != nil {
ctx.ResponseError(httperrors.NewGeneralError(err))
return
@@ -238,7 +238,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) {
ctx.DelayProcess(func(_ context.Context, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
baremetal.GetBaremetalManager().RegisterBaremetal(ctx, ctx.userCred, input)
return nil, nil
}, nil)
+1 -1
View File
@@ -88,7 +88,7 @@ func bmObjMiddlewareWithFetch(h bmObjHandlerFunc, fetch bool) appsrv.FilterHandl
baremetal := newCtx.GetBaremetalManager().GetBaremetalById(bmId)
if baremetal == nil {
if fetch {
err := newCtx.GetBaremetalManager().InitBaremetal(bmId, false)
err := newCtx.GetBaremetalManager().InitBaremetal(newCtx, bmId, false)
if err != nil {
newCtx.ResponseError(err)
return
+109 -86
View File
@@ -17,6 +17,7 @@ package baremetal
import (
"context"
"fmt"
"io/fs"
"io/ioutil"
"net"
"net/http"
@@ -43,6 +44,7 @@ import (
"yunion.io/x/onecloud/pkg/apis"
api "yunion.io/x/onecloud/pkg/apis/compute"
baremetalapi "yunion.io/x/onecloud/pkg/apis/compute/baremetal"
apiidenty "yunion.io/x/onecloud/pkg/apis/identity"
o "yunion.io/x/onecloud/pkg/baremetal/options"
"yunion.io/x/onecloud/pkg/baremetal/profiles"
@@ -114,16 +116,16 @@ func (m *SBaremetalManager) GetZoneName() string {
return m.Agent.Zone.Name
}
func (m *SBaremetalManager) loadConfigs() ([]os.FileInfo, error) {
func (m *SBaremetalManager) loadConfigs() ([]fs.DirEntry, error) {
m.killAllIPMITool()
files, err := ioutil.ReadDir(m.configPath)
files, err := os.ReadDir(m.configPath)
if err != nil {
return nil, err
}
return files, nil
}
func (m *SBaremetalManager) initBaremetals(files []os.FileInfo) error {
func (m *SBaremetalManager) initBaremetals(ctx context.Context, files []fs.DirEntry) error {
bmIds := make([]string, 0)
for _, file := range files {
if file.IsDir() && regutils.MatchUUID(file.Name()) {
@@ -134,7 +136,7 @@ func (m *SBaremetalManager) initBaremetals(files []os.FileInfo) error {
errsChannel := make(chan error, len(bmIds))
initBaremetal := func(i int) {
bmId := bmIds[i]
err := m.InitBaremetal(bmId, true)
err := m.InitBaremetal(ctx, bmId, true)
if err != nil {
errsChannel <- err
return
@@ -151,7 +153,7 @@ func (m *SBaremetalManager) initBaremetals(files []os.FileInfo) error {
return errors.NewAggregate(errs)
}
func (m *SBaremetalManager) InitBaremetal(bmId string, update bool) error {
func (m *SBaremetalManager) InitBaremetal(ctx context.Context, bmId string, update bool) error {
session := m.GetClientSession()
var err error
var desc jsonutils.JSONObject
@@ -167,7 +169,7 @@ func (m *SBaremetalManager) InitBaremetal(bmId string, update bool) error {
if !isBaremetal {
return errors.Error("not a baremetal???")
}
bmInstance, err := m.AddBaremetal(desc)
bmInstance, err := m.AddBaremetal(ctx, desc)
if err != nil {
return err
}
@@ -213,15 +215,15 @@ func (m *SBaremetalManager) fetchBaremetal(session *mcclient.ClientSession, bmId
return obj, nil
}
func (m *SBaremetalManager) AddBaremetal(desc jsonutils.JSONObject) (pxe.IBaremetalInstance, error) {
func (m *SBaremetalManager) AddBaremetal(ctx context.Context, desc jsonutils.JSONObject) (pxe.IBaremetalInstance, error) {
id, err := desc.GetString("id")
if err != nil {
return nil, fmt.Errorf("Not found baremetal id in desc %s", desc)
}
if instance, ok := m.baremetals.Get(id); ok {
return instance, instance.SaveDesc(desc)
return instance, instance.SaveDesc(ctx, desc)
}
bm, err := newBaremetalInstance(m, desc)
bm, err := newBaremetalInstance(ctx, m, desc)
if err != nil {
return nil, err
}
@@ -337,7 +339,7 @@ func (m *SBaremetalManager) RegisterBaremetal(ctx context.Context, userCred mccl
return
}
ipmiLanChannel, ipmiMac, err := m.checkIpmiInfo(input.Username, input.Password, input.IpAddr)
ipmiLanChannel, ipmiMac, err := m.checkIpmiInfo(ctx, input.Username, input.Password, input.IpAddr)
if input.isTimeout() {
return
} else if err != nil {
@@ -360,9 +362,9 @@ func (m *SBaremetalManager) RegisterBaremetal(ctx context.Context, userCred mccl
)
var bmId string
if !registered {
bmId, err = registerTask.CreateBaremetal()
bmId, err = registerTask.CreateBaremetal(ctx)
} else {
bmId, err = registerTask.UpdateBaremetal()
bmId, err = registerTask.UpdateBaremetal(ctx)
}
if err != nil {
input.responseErr(ctx, httperrors.NewInternalServerError("%v", err))
@@ -452,14 +454,18 @@ func (m *SBaremetalManager) checkSshInfo(input *BmRegisterInput) (*ssh.Client, e
return sshCLi, nil
}
func (m *SBaremetalManager) checkIpmiInfo(username, password, ipAddr string) (int, net.HardwareAddr, error) {
func (m *SBaremetalManager) checkIpmiInfo(ctx context.Context, username, password, ipAddr string) (uint8, net.HardwareAddr, error) {
lanPlusTool := ipmitool.NewLanPlusIPMI(ipAddr, username, password)
sysInfo, err := ipmitool.GetSysInfo(lanPlusTool)
if err != nil {
return -1, nil, err
return 0, nil, errors.Wrap(err, "GetSysInfo")
}
profile, err := profiles.GetProfile(ctx, sysInfo)
if err != nil {
return 0, nil, errors.Wrap(err, "GetProfile")
}
for _, lanChannel := range ipmitool.GetLanChannels(sysInfo) {
for _, lanChannel := range profile.LanChannels {
config, err := ipmitool.GetLanConfig(lanPlusTool, lanChannel)
if err != nil {
log.Errorf("GetLanConfig failed %s", err)
@@ -470,7 +476,7 @@ func (m *SBaremetalManager) checkIpmiInfo(username, password, ipAddr string) (in
}
return lanChannel, config.Mac, nil
}
return -1, nil, fmt.Errorf("Ipmi can't fetch lan config")
return 0, nil, fmt.Errorf("Ipmi can't fetch lan config")
}
func (m *SBaremetalManager) Stop() {
@@ -521,10 +527,12 @@ type SBaremetalInstance struct {
server baremetaltypes.IBaremetalServer
serverLock *sync.Mutex
profile *baremetalapi.BaremetalProfileSpec
cronJobs []IBaremetalCronJob
}
func newBaremetalInstance(man *SBaremetalManager, desc jsonutils.JSONObject) (*SBaremetalInstance, error) {
func newBaremetalInstance(ctx context.Context, man *SBaremetalManager, desc jsonutils.JSONObject) (*SBaremetalInstance, error) {
bm := &SBaremetalInstance{
manager: man,
desc: desc.(*jsonutils.JSONDict),
@@ -541,7 +549,7 @@ func newBaremetalInstance(man *SBaremetalManager, desc jsonutils.JSONObject) (*S
if err != nil {
return nil, err
}
err = bm.SaveDesc(desc)
err = bm.SaveDesc(ctx, desc)
if err != nil {
return nil, err
}
@@ -614,17 +622,29 @@ func (b *SBaremetalInstance) GetStatus() string {
return status
}
func (b *SBaremetalInstance) AutoSaveDesc() error {
return b.SaveDesc(nil)
func (b *SBaremetalInstance) AutoSaveDesc(ctx context.Context) error {
return b.SaveDesc(ctx, nil)
}
func (b *SBaremetalInstance) SaveDesc(desc jsonutils.JSONObject) error {
func (b *SBaremetalInstance) SaveDesc(ctx context.Context, desc jsonutils.JSONObject) error {
b.descLock.Lock()
defer b.descLock.Unlock()
if desc != nil {
b.desc = desc.(*jsonutils.JSONDict)
if b.desc.Contains("sys_info") {
sysInfo := types.SSystemInfo{}
err := b.desc.Unmarshal(&sysInfo, "sys_info")
if err != nil {
return errors.Wrap(err, "Unmarshal sys_info")
}
b.profile, err = profiles.GetProfile(ctx, &sysInfo)
if err != nil {
return errors.Wrap(err, "GetProfile")
}
}
}
return ioutil.WriteFile(b.GetDescFilePath(), []byte(b.desc.String()), 0644)
return os.WriteFile(b.GetDescFilePath(), []byte(b.desc.String()), 0644)
}
func (b *SBaremetalInstance) loadServer() {
@@ -634,7 +654,7 @@ func (b *SBaremetalInstance) loadServer() {
return
}
descPath := b.GetServerDescFilePath()
desc, err := ioutil.ReadFile(descPath)
desc, err := os.ReadFile(descPath)
if err != nil {
log.Errorf("Failed to read server desc %s: %v", descPath, err)
return
@@ -668,7 +688,7 @@ func (b *SBaremetalInstance) SaveSSHConfig(remoteAddr string, key string) error
RemoteIP: remoteAddr,
}
conf := jsonutils.Marshal(sshConf)
err = ioutil.WriteFile(b.GetSSHConfigFilePath(), []byte(conf.String()), 0644)
err = os.WriteFile(b.GetSSHConfigFilePath(), []byte(conf.String()), 0644)
if err != nil {
return err
}
@@ -679,7 +699,7 @@ func (b *SBaremetalInstance) SaveSSHConfig(remoteAddr string, key string) error
func (b *SBaremetalInstance) GetSSHConfig() (*types.SSHConfig, error) {
path := b.GetSSHConfigFilePath()
content, err := ioutil.ReadFile(path)
content, err := os.ReadFile(path)
if err != nil {
if os.IsNotExist(err) {
return nil, nil
@@ -774,7 +794,7 @@ func (b *SBaremetalInstance) SyncSSHConfig(conf types.SSHConfig) error {
func (b *SBaremetalInstance) SyncStatusBackground() {
go func() {
b.AutoSyncAllStatus()
b.AutoSyncAllStatus(context.Background())
}()
}
@@ -785,12 +805,12 @@ func (b *SBaremetalInstance) InitializeServer(s *mcclient.ClientSession, name st
return err
}
func (b *SBaremetalInstance) ServerLoadDesc() error {
func (b *SBaremetalInstance) ServerLoadDesc(ctx context.Context) error {
res, err := modules.Hosts.Get(b.manager.GetClientSession(), b.GetId(), nil)
if err != nil {
return err
}
b.SaveDesc(res)
b.SaveDesc(ctx, res)
sid, err := res.GetString("server_id")
if err == nil {
sDesc := jsonutils.NewDict()
@@ -830,11 +850,11 @@ func PowerStatusToServerStatus(bm *SBaremetalInstance, status string) string {
return baremetalstatus.UNKNOWN
}
func (b *SBaremetalInstance) AutoSyncStatus() {
b.SyncStatus("", "")
func (b *SBaremetalInstance) AutoSyncStatus(ctx context.Context) {
b.SyncStatus(ctx, "", "")
}
func (b *SBaremetalInstance) SyncStatus(status string, reason string) {
func (b *SBaremetalInstance) SyncStatus(ctx context.Context, status string, reason string) {
if status == "" {
powerStatus, err := b.GetPowerStatus()
if err != nil {
@@ -843,7 +863,7 @@ func (b *SBaremetalInstance) SyncStatus(status string, reason string) {
status = PowerStatusToBaremetalStatus(powerStatus)
}
b.desc.Set("status", jsonutils.NewString(status))
b.AutoSaveDesc()
b.AutoSaveDesc(ctx)
params := jsonutils.NewDict()
params.Add(jsonutils.NewString(status), "status")
if reason != "" {
@@ -857,16 +877,16 @@ func (b *SBaremetalInstance) SyncStatus(status string, reason string) {
log.Infof("Update baremetal %s to status %s", b.GetId(), status)
}
func (b *SBaremetalInstance) AutoSyncAllStatus() {
b.SyncAllStatus("")
func (b *SBaremetalInstance) AutoSyncAllStatus(ctx context.Context) {
b.SyncAllStatus(ctx, "")
}
func (b *SBaremetalInstance) DelayedSyncStatus(_ jsonutils.JSONObject) (jsonutils.JSONObject, error) {
b.AutoSyncAllStatus()
func (b *SBaremetalInstance) DelayedSyncStatus(ctx context.Context, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
b.AutoSyncAllStatus(ctx)
return nil, nil
}
func (b *SBaremetalInstance) SyncAllStatus(status string) {
func (b *SBaremetalInstance) SyncAllStatus(ctx context.Context, status string) {
var err error
if status == "" {
status, err = b.GetPowerStatus()
@@ -874,7 +894,7 @@ func (b *SBaremetalInstance) SyncAllStatus(status string) {
log.Errorf("Get power status error: %v", err)
}
}
b.SyncStatus(PowerStatusToBaremetalStatus(status), "")
b.SyncStatus(ctx, PowerStatusToBaremetalStatus(status), "")
b.SyncServerStatus(PowerStatusToServerStatus(b, status))
}
@@ -1295,6 +1315,7 @@ func (b *SBaremetalInstance) SetTask(task tasks.ITask) {
}
func (b *SBaremetalInstance) InitAdminNetif(
ctx context.Context,
cliMac net.HardwareAddr,
wireId string,
nicType compute.TNicType,
@@ -1312,7 +1333,7 @@ func (b *SBaremetalInstance) InitAdminNetif(
baremetalstatus.UNKNOWN}) &&
b.GetTask() == nil && b.GetServer() == nil {
b.SetTask(tasks.NewBaremetalServerPrepareTask(b))
b.SyncStatus(baremetalstatus.PREPARE, "")
b.SyncStatus(ctx, baremetalstatus.PREPARE, "")
}
nic := b.GetNicByMac(cliMac)
@@ -1321,14 +1342,14 @@ func (b *SBaremetalInstance) InitAdminNetif(
if err != nil {
return err
}
return b.postAttachWire(cliMac, nicType, netType, importIpAddr)
return b.postAttachWire(ctx, cliMac, nicType, netType, importIpAddr)
} else if nic.IpAddr == "" {
return b.postAttachWire(cliMac, nicType, netType, importIpAddr)
return b.postAttachWire(ctx, cliMac, nicType, netType, importIpAddr)
}
return nil
}
func (b *SBaremetalInstance) RegisterNetif(cliMac net.HardwareAddr, wireId string) error {
func (b *SBaremetalInstance) RegisterNetif(ctx context.Context, cliMac net.HardwareAddr, wireId string) error {
var nicType compute.TNicType
nic := b.GetNicByMac(cliMac)
if nic != nil {
@@ -1339,7 +1360,7 @@ func (b *SBaremetalInstance) RegisterNetif(cliMac net.HardwareAddr, wireId strin
if err != nil {
return err
}
return b.SaveDesc(desc)
return b.SaveDesc(ctx, desc)
}
return nil
}
@@ -1357,7 +1378,7 @@ func (b *SBaremetalInstance) attachWire(mac net.HardwareAddr, wireId string, nic
return modules.Hosts.PerformAction(session, b.GetId(), "add-netif", params)
}
func (b *SBaremetalInstance) postAttachWire(mac net.HardwareAddr, nicType compute.TNicType, netType api.TNetworkType, ipAddr string) error {
func (b *SBaremetalInstance) postAttachWire(ctx context.Context, mac net.HardwareAddr, nicType compute.TNicType, netType api.TNetworkType, ipAddr string) error {
if ipAddr == "" {
switch nicType {
case api.NIC_TYPE_IPMI:
@@ -1376,7 +1397,7 @@ func (b *SBaremetalInstance) postAttachWire(mac net.HardwareAddr, nicType comput
if err != nil {
return err
}
return b.SaveDesc(desc)
return b.SaveDesc(ctx, desc)
}
func (b *SBaremetalInstance) enableWire(mac net.HardwareAddr, ipAddr string, nicType compute.TNicType, netType api.TNetworkType) (jsonutils.JSONObject, error) {
@@ -1410,13 +1431,8 @@ func (b *SBaremetalInstance) GetIPMIConfig() *types.SIPMIInfo {
log.Debugf("GetIPMIConfig password is nil")
return nil
}
if conf.Username == "" {
sysInfo := types.SSystemInfo{}
err := b.desc.Unmarshal(&sysInfo, "sys_info")
if err != nil {
log.Errorf("Unmarshal get sys_info error: %v", err)
}
conf.Username = profiles.GetRootName(&sysInfo)
if conf.Username == "" && b.profile != nil {
conf.Username = b.profile.RootName
}
if conf.IpAddr == "" {
nicIPAddr := b.GetIPMINicIPAddr()
@@ -1628,19 +1644,19 @@ func (b *SBaremetalInstance) sshRun(hostCmd string, serverCmd string) ([]string,
)
}
func (b *SBaremetalInstance) adjustUEFIWrapper(cli *ssh.Client, f func() error) error {
func (b *SBaremetalInstance) adjustUEFIWrapper(ctx context.Context, cli *ssh.Client, f func() error) error {
isUEFI, err := uefi.RemoteIsUEFIBoot(cli)
if err != nil {
return errors.Wrap(err, "Check is uefi boot")
}
if !isUEFI {
return b.CleanUEFIInfo()
return b.CleanUEFIInfo(ctx)
}
return f()
}
func (b *SBaremetalInstance) AdjustUEFICurrentBootOrder(hostCli *ssh.Client) error {
return b.adjustUEFIWrapper(hostCli, func() error {
func (b *SBaremetalInstance) AdjustUEFICurrentBootOrder(ctx context.Context, hostCli *ssh.Client) error {
return b.adjustUEFIWrapper(ctx, hostCli, func() error {
mgr, err := uefi.NewEFIBootMgrFromRemote(hostCli, false)
if err != nil {
return errors.Wrap(err, "NewEFIBootMgrFromRemote")
@@ -1648,14 +1664,14 @@ func (b *SBaremetalInstance) AdjustUEFICurrentBootOrder(hostCli *ssh.Client) err
if err := uefi.RemoteSetCurrentBootAtFirst(hostCli, mgr); err != nil {
return errors.Wrap(err, "Set current boot order at first")
}
return b.SendUEFIInfo(mgr)
return b.SendUEFIInfo(ctx, mgr)
})
}
func (b *SBaremetalInstance) updateUEFIInfo(uefiData jsonutils.JSONObject) error {
func (b *SBaremetalInstance) updateUEFIInfo(ctx context.Context, uefiData jsonutils.JSONObject) error {
desc := b.desc
desc.Add(uefiData, "uefi_info")
if err := b.SaveDesc(desc); err != nil {
if err := b.SaveDesc(ctx, desc); err != nil {
return errors.Wrap(err, "Save uefi_info")
}
updateData := jsonutils.NewDict()
@@ -1666,26 +1682,26 @@ func (b *SBaremetalInstance) updateUEFIInfo(uefiData jsonutils.JSONObject) error
return nil
}
func (b *SBaremetalInstance) CleanUEFIInfo() error {
if err := b.updateUEFIInfo(jsonutils.NewDict()); err != nil {
func (b *SBaremetalInstance) CleanUEFIInfo(ctx context.Context) error {
if err := b.updateUEFIInfo(ctx, jsonutils.NewDict()); err != nil {
return errors.Wrap(err, "CleanUEFIInfo")
}
return nil
}
func (b *SBaremetalInstance) SendUEFIInfo(mgr *uefi.BootMgr) error {
func (b *SBaremetalInstance) SendUEFIInfo(ctx context.Context, mgr *uefi.BootMgr) error {
info, err := mgr.ToEFIBootMgrInfo()
if err != nil {
return err
}
if err := b.updateUEFIInfo(jsonutils.Marshal(info)); err != nil {
if err := b.updateUEFIInfo(ctx, jsonutils.Marshal(info)); err != nil {
return errors.Wrap(err, "SendUEFIInfo")
}
return nil
}
func (b *SBaremetalInstance) adjustServerUEFIBootOrder(srvCli *ssh.Client) error {
return b.adjustUEFIWrapper(srvCli, func() error {
func (b *SBaremetalInstance) adjustServerUEFIBootOrder(ctx context.Context, srvCli *ssh.Client) error {
return b.adjustUEFIWrapper(ctx, srvCli, func() error {
info, err := b.GetUEFIInfo()
if err != nil {
return errors.Wrap(err, "GetUEFIInfo from local desc")
@@ -1701,22 +1717,22 @@ func (b *SBaremetalInstance) adjustServerUEFIBootOrder(srvCli *ssh.Client) error
})
}
func (b *SBaremetalInstance) AdjustUEFIBootOrder() error {
func (b *SBaremetalInstance) AdjustUEFIBootOrder(ctx context.Context) error {
_, err := b.sshRunWrapper(
func(hostCli *ssh.Client) ([]string, error) {
return nil, b.AdjustUEFICurrentBootOrder(hostCli)
return nil, b.AdjustUEFICurrentBootOrder(ctx, hostCli)
},
func(srvCli *ssh.Client) ([]string, error) {
return nil, b.adjustServerUEFIBootOrder(srvCli)
return nil, b.adjustServerUEFIBootOrder(ctx, srvCli)
},
)
return err
}
func (b *SBaremetalInstance) SSHReboot() error {
func (b *SBaremetalInstance) SSHReboot(ctx context.Context) error {
if !b.HasBMC() {
// try adjust uefi boot order before reboot
if err := b.AdjustUEFIBootOrder(); err != nil {
if err := b.AdjustUEFIBootOrder(ctx); err != nil {
return errors.Wrap(err, "Adjust uefi boot order")
}
}
@@ -1771,7 +1787,7 @@ func (b *SBaremetalInstance) GetRedfishCli(ctx context.Context) redfish.IRedfish
conf.Username, conf.Password, false)
}
func (b *SBaremetalInstance) GetIPMILanChannel() int {
func (b *SBaremetalInstance) GetIPMILanChannel() uint8 {
conf := b.GetIPMIConfig()
if conf == nil {
return 0
@@ -1941,7 +1957,7 @@ func (b *SBaremetalInstance) GetMemGb() string {
return strconv.FormatInt(memMb/1024, 10)
}
func (b *SBaremetalInstance) DelayedRemove(_ jsonutils.JSONObject) (jsonutils.JSONObject, error) {
func (b *SBaremetalInstance) DelayedRemove(_ context.Context, _ jsonutils.JSONObject) (jsonutils.JSONObject, error) {
b.remove()
return nil, nil
}
@@ -1982,10 +1998,10 @@ func (b *SBaremetalInstance) StartBaremetalResetBMCTask(userCred mcclient.TokenC
return nil
}
func (b *SBaremetalInstance) StartBaremetalIpmiProbeTask(userCred mcclient.TokenCredential, taskId string, data jsonutils.JSONObject) error {
func (b *SBaremetalInstance) StartBaremetalIpmiProbeTask(ctx context.Context, userCred mcclient.TokenCredential, taskId string, data jsonutils.JSONObject) error {
session := b.manager.GetClientSession()
data, _ = b.manager.fetchBaremetal(session, b.GetId())
if err := b.SaveDesc(data); err != nil {
if err := b.SaveDesc(ctx, data); err != nil {
return err
}
b.StartNewTask(tasks.NewBaremetalIpmiProbeTask, userCred, taskId, data)
@@ -1997,12 +2013,12 @@ func (b *SBaremetalInstance) StartBaremetalCdromTask(userCred mcclient.TokenCred
return nil
}
func (b *SBaremetalInstance) DelayedServerReset(_ jsonutils.JSONObject) (jsonutils.JSONObject, error) {
func (b *SBaremetalInstance) DelayedServerReset(ctx context.Context, _ jsonutils.JSONObject) (jsonutils.JSONObject, error) {
err := b.DoPXEBoot()
return nil, err
}
func (b *SBaremetalInstance) StartServerCreateTask(userCred mcclient.TokenCredential, taskId string, data jsonutils.JSONObject) error {
func (b *SBaremetalInstance) StartServerCreateTask(ctx context.Context, userCred mcclient.TokenCredential, taskId string, data jsonutils.JSONObject) error {
b.serverLock.Lock()
defer b.serverLock.Unlock()
if b.server != nil {
@@ -2018,7 +2034,7 @@ func (b *SBaremetalInstance) StartServerCreateTask(userCred mcclient.TokenCreden
}
b.server = server
b.desc.Set("server_id", jsonutils.NewString(b.server.GetId()))
if err := b.AutoSaveDesc(); err != nil {
if err := b.AutoSaveDesc(ctx); err != nil {
return err
}
b.StartNewTask(tasks.NewBaremetalServerCreateTask, userCred, taskId, data)
@@ -2063,15 +2079,22 @@ func (b *SBaremetalInstance) StartServerDestroyTask(userCred mcclient.TokenCrede
b.StartNewTask(tasks.NewBaremetalServerDestroyTask, userCred, taskId, data)
}
func (b *SBaremetalInstance) DelayedSyncIPMIInfo(data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
func (b *SBaremetalInstance) DelayedSyncIPMIInfo(ctx context.Context, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
ipmiCli := b.GetIPMITool()
lanChannel := b.GetIPMILanChannel()
sysInfo, err := ipmitool.GetSysInfo(ipmiCli)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "GetSysInfo")
}
profile, err := profiles.GetProfile(ctx, sysInfo)
if err != nil {
return nil, errors.Wrap(err, "GetProfile")
}
if lanChannel <= 0 {
lanChannel = ipmitool.GetDefaultLanChannel(sysInfo)
if len(profile.LanChannels) == 0 {
return nil, errors.Wrap(errors.ErrInvalidStatus, "baremetal profile not valid lan channel?")
}
lanChannel = profile.LanChannels[0]
}
retObj := make(map[string]string)
if ipAddr, _ := data.GetString("ip_addr"); ipAddr != "" {
@@ -2083,7 +2106,7 @@ func (b *SBaremetalInstance) DelayedSyncIPMIInfo(data jsonutils.JSONObject) (jso
retObj["ipmi_ip_addr"] = ipAddr
}
if passwd, _ := data.GetString("password"); passwd != "" {
err = ipmitool.SetLanPasswd(ipmiCli, ipmitool.GetRootId(sysInfo), passwd)
err = ipmitool.SetLanPasswd(ipmiCli, profile.RootId, passwd)
if err != nil {
return nil, err
}
@@ -2092,16 +2115,16 @@ func (b *SBaremetalInstance) DelayedSyncIPMIInfo(data jsonutils.JSONObject) (jso
return jsonutils.Marshal(retObj), nil
}
func (b *SBaremetalInstance) DelayedSyncDesc(data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
func (b *SBaremetalInstance) DelayedSyncDesc(ctx context.Context, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
if data == nil {
session := b.manager.GetClientSession()
data, _ = b.manager.fetchBaremetal(session, b.GetId())
}
err := b.SaveDesc(data)
err := b.SaveDesc(ctx, data)
return nil, err
}
func (b *SBaremetalInstance) DelayedServerStatus(data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
func (b *SBaremetalInstance) DelayedServerStatus(ctx context.Context, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
ps, err := b.GetPowerStatus()
if err != nil {
return nil, err
@@ -2112,7 +2135,7 @@ func (b *SBaremetalInstance) DelayedServerStatus(data jsonutils.JSONObject) (jso
return resp, err
}
func (b *SBaremetalInstance) SendNicInfo(nic *types.SNicDevInfo, idx int, nicType compute.TNicType, reset bool, ipAddr string, reserve bool) error {
func (b *SBaremetalInstance) SendNicInfo(ctx context.Context, nic *types.SNicDevInfo, idx int, nicType compute.TNicType, reset bool, ipAddr string, reserve bool) error {
params := jsonutils.NewDict()
params.Add(jsonutils.NewString(nic.Mac.String()), "mac")
params.Add(jsonutils.NewInt(int64(nic.Speed)), "rate")
@@ -2149,7 +2172,7 @@ func (b *SBaremetalInstance) SendNicInfo(nic *types.SNicDevInfo, idx int, nicTyp
if err != nil {
return err
}
return b.SaveDesc(resp)
return b.SaveDesc(ctx, resp)
}
func bindMount(src, dst string) error {
+43 -92
View File
@@ -15,117 +15,68 @@
package profiles
import (
"context"
"yunion.io/x/pkg/errors"
baremetalapi "yunion.io/x/onecloud/pkg/apis/compute/baremetal"
"yunion.io/x/onecloud/pkg/baremetal/options"
"yunion.io/x/onecloud/pkg/cloudcommon/types"
"yunion.io/x/onecloud/pkg/mcclient/auth"
baremetalmodules "yunion.io/x/onecloud/pkg/mcclient/modules/compute/baremetal"
)
type IPMIProfile struct {
LanChannel []int
RootName string
RootId int
StrongPass bool
}
func DefaultProfile() IPMIProfile {
return IPMIProfile{
LanChannel: []int{1, 2, 8},
RootName: "root",
RootId: 2,
func GetProfile(ctx context.Context, sysinfo *types.SSystemInfo) (*baremetalapi.BaremetalProfileSpec, error) {
adminSession := auth.GetAdminSession(ctx, options.Options.Region)
specs, err := baremetalmodules.BaremetalProfiles.GetMatchProfiles(adminSession, sysinfo.OemName, sysinfo.Model)
if err != nil {
return nil, errors.Wrapf(err, "GetMatchProfile %s %s", sysinfo.OemName, sysinfo.Model)
}
}
func InspurProfile() IPMIProfile {
return IPMIProfile{
LanChannel: []int{8, 1},
RootName: "admin",
RootId: 2,
if len(specs) > 0 {
return &specs[len(specs)-1], nil
}
return nil, errors.ErrNotFound
}
func LenovoProfile() IPMIProfile {
return IPMIProfile{
LanChannel: []int{1, 8},
RootName: "root",
RootId: 2,
func GetLanChannels(ctx context.Context, sysinfo *types.SSystemInfo) ([]uint8, error) {
profile, err := GetProfile(ctx, sysinfo)
if err != nil {
return nil, errors.Wrap(err, "GetProfile")
}
return profile.LanChannels, nil
}
func HpProfile() IPMIProfile {
return IPMIProfile{
LanChannel: []int{1, 2},
RootName: "root",
RootId: 1,
func GetDefaultLanChannel(ctx context.Context, sysinfo *types.SSystemInfo) (uint8, error) {
channels, err := GetLanChannels(ctx, sysinfo)
if err != nil {
return 0, errors.Wrap(err, "GetLanChannels")
}
}
func HuaweiProfile() IPMIProfile {
return IPMIProfile{
LanChannel: []int{1},
RootName: "root",
RootId: 2,
StrongPass: true,
if len(channels) > 0 {
return channels[0], nil
}
return 0, errors.ErrNotFound
}
func FoxconnProfile() IPMIProfile {
return IPMIProfile{
LanChannel: []int{1},
RootName: "root",
RootId: 2,
StrongPass: true,
func GetRootId(ctx context.Context, sysinfo *types.SSystemInfo) (int, error) {
profile, err := GetProfile(ctx, sysinfo)
if err != nil {
return 0, errors.Wrap(err, "GetProfile")
}
return profile.RootId, nil
}
func QemuProfile() IPMIProfile {
return IPMIProfile{
LanChannel: []int{8, 1},
RootName: "root",
RootId: 2,
StrongPass: true,
func GetRootName(ctx context.Context, sysinfo *types.SSystemInfo) (string, error) {
profile, err := GetProfile(ctx, sysinfo)
if err != nil {
return "", errors.Wrap(err, "GetProfile")
}
return profile.RootName, nil
}
func H3CProfile() IPMIProfile {
return IPMIProfile{
// LanChannel: []int{8, 1},
LanChannel: []int{1},
RootName: "root",
RootId: 2,
StrongPass: true,
func IsStrongPass(ctx context.Context, sysinfo *types.SSystemInfo) (bool, error) {
profile, err := GetProfile(ctx, sysinfo)
if err != nil {
return false, errors.Wrap(err, "GetProfile")
}
}
var (
PROFILES map[string]IPMIProfile = map[string]IPMIProfile{
types.OEM_NAME_INSPUR: InspurProfile(),
types.OEM_NAME_LENOVO: LenovoProfile(),
types.OEM_NAME_HP: HpProfile(),
types.OEM_NAME_HUAWEI: HuaweiProfile(),
types.OEM_NAME_FOXCONN: FoxconnProfile(),
types.OEM_NAME_QEMU: QemuProfile(),
types.OEM_NAME_H3C: H3CProfile(),
}
)
func GetProfile(sysinfo *types.SSystemInfo) IPMIProfile {
profile, ok := PROFILES[sysinfo.OemName]
if ok {
return profile
}
return DefaultProfile()
}
func GetLanChannel(sysinfo *types.SSystemInfo) []int {
return GetProfile(sysinfo).LanChannel
}
func GetRootId(sysinfo *types.SSystemInfo) int {
return GetProfile(sysinfo).RootId
}
func GetRootName(sysinfo *types.SSystemInfo) string {
return GetProfile(sysinfo).RootName
}
func IsStrongPass(sysinfo *types.SSystemInfo) bool {
return GetProfile(sysinfo).StrongPass
return profile.StrongPass, nil
}
+10 -9
View File
@@ -15,6 +15,7 @@
package pxe
import (
"context"
"encoding/hex"
"fmt"
"net"
@@ -69,7 +70,7 @@ type dhcpRequest struct {
netConfig *types.SNetworkConfig
}
func (h *DHCPHandler) ServeDHCP(pkt dhcp.Packet, _ *net.UDPAddr, _ *net.Interface) (dhcp.Packet, []string, error) {
func (h *DHCPHandler) ServeDHCP(ctx context.Context, pkt dhcp.Packet, _ *net.UDPAddr, _ *net.Interface) (dhcp.Packet, []string, error) {
req, err := h.newRequest(pkt, h.baremetalManager)
if err != nil {
log.Errorf("[DHCP] new request by packet error: %v", err)
@@ -81,7 +82,7 @@ func (h *DHCPHandler) ServeDHCP(pkt dhcp.Packet, _ *net.UDPAddr, _ *net.Interfac
return nil, nil, fmt.Errorf("Request not from a DHCP relay, ignore mac: %s", req.ClientMac)
}
log.Infof("[DHCP] from relay %s packet, mac: %s", req.RelayAddr, req.ClientMac)
conf, targets, err := req.fetchConfig(h.baremetalManager.GetClientSession())
conf, targets, err := req.fetchConfig(ctx, h.baremetalManager.GetClientSession())
if err != nil {
return nil, nil, errors.Wrapf(err, "fetchConfig for %s", req.ClientMac.String())
}
@@ -185,7 +186,7 @@ func formatUuidString(uuidBytes []byte) string {
}, "-")
}
func (req *dhcpRequest) fetchConfig(session *mcclient.ClientSession) (*dhcp.ResponseConfig, []string, error) {
func (req *dhcpRequest) fetchConfig(ctx context.Context, session *mcclient.ClientSession) (*dhcp.ResponseConfig, []string, error) {
// 1. find_network_conf
netConf, err := req.findNetworkConf(session, false)
if err != nil {
@@ -209,7 +210,7 @@ func (req *dhcpRequest) fetchConfig(session *mcclient.ClientSession) (*dhcp.Resp
if err != nil {
return nil, nil, errors.Wrapf(err, "createOrUpdateBaremetal for %s", req.ClientMac.String())
}
err = req.doInitBaremetalAdminNetif(bmDesc)
err = req.doInitBaremetalAdminNetif(ctx, bmDesc)
if err != nil {
return nil, nil, errors.Wrapf(err, "doInitBaremetalAdminNetif for %s", req.ClientMac.String())
}
@@ -241,13 +242,13 @@ func (req *dhcpRequest) fetchConfig(session *mcclient.ClientSession) (*dhcp.Resp
req.baremetalInstance = bmInstance
ipmiNic := req.baremetalInstance.GetIPMINic(req.ClientMac)
if ipmiNic != nil && ipmiNic.Mac == req.ClientMac.String() {
err = req.baremetalInstance.InitAdminNetif(
err = req.baremetalInstance.InitAdminNetif(ctx,
req.ClientMac, req.netConfig.WireId, api.NIC_TYPE_IPMI, api.NETWORK_TYPE_IPMI, false, "")
if err != nil {
return nil, nil, errors.Wrapf(err, "InitAdminNetif for %s", req.ClientMac.String())
}
} else {
err = req.baremetalInstance.RegisterNetif(req.ClientMac, req.netConfig.WireId)
err = req.baremetalInstance.RegisterNetif(ctx, req.ClientMac, req.netConfig.WireId)
if err != nil {
log.Errorf("RegisterNetif %s error: %v", req.ClientMac.String(), err)
return nil, nil, errors.Wrapf(err, "RegisterNetif for %s", req.ClientMac.String())
@@ -424,13 +425,13 @@ func (req *dhcpRequest) updateBaremetal(session *mcclient.ClientSession, id stri
return desc, nil
}
func (req *dhcpRequest) doInitBaremetalAdminNetif(desc jsonutils.JSONObject) error {
func (req *dhcpRequest) doInitBaremetalAdminNetif(ctx context.Context, desc jsonutils.JSONObject) error {
var err error
req.baremetalInstance, err = req.baremetalManager.AddBaremetal(desc)
req.baremetalInstance, err = req.baremetalManager.AddBaremetal(ctx, desc)
if err != nil {
return err
}
err = req.baremetalInstance.InitAdminNetif(
err = req.baremetalInstance.InitAdminNetif(ctx,
req.ClientMac, req.netConfig.WireId, api.NIC_TYPE_ADMIN, api.NETWORK_TYPE_PXE, false, "")
return err
}
+4 -3
View File
@@ -15,6 +15,7 @@
package pxe
import (
"context"
"fmt"
"net"
@@ -85,7 +86,7 @@ const (
type IBaremetalManager interface {
GetZoneId() string
GetBaremetalByMac(mac net.HardwareAddr) IBaremetalInstance
AddBaremetal(desc jsonutils.JSONObject) (IBaremetalInstance, error)
AddBaremetal(ctx context.Context, desc jsonutils.JSONObject) (IBaremetalInstance, error)
GetClientSession() *mcclient.ClientSession
}
@@ -94,8 +95,8 @@ type IBaremetalInstance interface {
GetIPMINic(cliMac net.HardwareAddr) *types.SNic
GetPXEDHCPConfig(arch uint16) (*dhcp.ResponseConfig, error)
GetDHCPConfig(cliMac net.HardwareAddr) (*dhcp.ResponseConfig, error)
InitAdminNetif(cliMac net.HardwareAddr, wireId string, nicType compute.TNicType, netType computeapi.TNetworkType, isDoImport bool, ipAddr string) error
RegisterNetif(cliMac net.HardwareAddr, wireId string) error
InitAdminNetif(ctx context.Context, cliMac net.HardwareAddr, wireId string, nicType compute.TNicType, netType computeapi.TNetworkType, isDoImport bool, ipAddr string) error
RegisterNetif(ctx context.Context, cliMac net.HardwareAddr, wireId string) error
GetTFTPResponse() string
}
+5 -5
View File
@@ -342,8 +342,8 @@ func (self *SBaremetalTaskBase) EnsurePowerUp() error {
return nil
}
func (self *SBaremetalTaskBase) EnsureSSHReboot() error {
if err := self.Baremetal.SSHReboot(); err != nil {
func (self *SBaremetalTaskBase) EnsureSSHReboot(ctx context.Context) error {
if err := self.Baremetal.SSHReboot(ctx); err != nil {
return errors.Wrap(err, "Ensure ssh reboot")
}
@@ -425,7 +425,7 @@ func (self *SBaremetalPXEBootTaskBase) InitPXEBootTask(ctx context.Context, args
if !self.Baremetal.HasBMC() {
// Try remote ssh reboot
if err := self.Baremetal.SSHReboot(); err != nil {
if err := self.Baremetal.SSHReboot(ctx); err != nil {
return errors.Wrap(err, "Try ssh reboot")
}
} else {
@@ -491,6 +491,6 @@ func (self *SBaremetalPXEBootTaskBase) GetName() string {
return "BaremetalPXEBootTaskBase"
}
func AdjustUEFIBootOrder(term *ssh.Client, bm IBaremetal) error {
return bm.AdjustUEFICurrentBootOrder(term)
func AdjustUEFIBootOrder(ctx context.Context, term *ssh.Client, bm IBaremetal) error {
return bm.AdjustUEFICurrentBootOrder(ctx, term)
}
+4 -4
View File
@@ -107,7 +107,7 @@ func (self *SBaremetalServerBaseDeployTask) OnPXEBoot(ctx context.Context, term
return errors.Wrap(err, "Do deploy")
}
if err := AdjustUEFIBootOrder(term, self.Baremetal); err != nil {
if err := AdjustUEFIBootOrder(ctx, term, self.Baremetal); err != nil {
return errors.Wrap(err, "Adjust UEFI boot order")
}
@@ -134,7 +134,7 @@ func (self *SBaremetalServerBaseDeployTask) OnPXEBoot(ctx context.Context, term
return errors.Wrap(err, "Ensure power up")
}
}
self.Baremetal.AutoSyncAllStatus()
self.Baremetal.AutoSyncAllStatus(ctx)
} else {
if onFinishAction == "shutdown" {
log.Infof("None BMC baremetal can't shutdown when deploying")
@@ -147,12 +147,12 @@ func (self *SBaremetalServerBaseDeployTask) OnPXEBoot(ctx context.Context, term
// do restart
// hack: ssh reboot to disk
self.needPXEBoot = false
if err := self.EnsureSSHReboot(); err != nil {
if err := self.EnsureSSHReboot(ctx); err != nil {
return errors.Wrap(err, "Try ssh reboot")
}
}
}
self.Baremetal.SyncAllStatus(types.POWER_STATUS_ON)
self.Baremetal.SyncAllStatus(ctx, types.POWER_STATUS_ON)
}
SetTaskComplete(self, result)
return nil
+32 -26
View File
@@ -15,6 +15,7 @@
package tasks
import (
"context"
"fmt"
"net"
"strings"
@@ -30,6 +31,7 @@ import (
"yunion.io/x/onecloud/pkg/apis"
api "yunion.io/x/onecloud/pkg/apis/compute"
baremetalapi "yunion.io/x/onecloud/pkg/apis/compute/baremetal"
o "yunion.io/x/onecloud/pkg/baremetal/options"
"yunion.io/x/onecloud/pkg/baremetal/profiles"
"yunion.io/x/onecloud/pkg/baremetal/utils/detect_storages"
@@ -169,7 +171,7 @@ func (task *sBaremetalPrepareTask) prepareBaremetalInfo(cli *ssh.Client) (*barem
return prepareInfo, nil
}
func (task *sBaremetalPrepareTask) configIPMISetting(cli *ssh.Client, i *baremetalPrepareInfo) error {
func (task *sBaremetalPrepareTask) configIPMISetting(ctx context.Context, cli *ssh.Client, i *baremetalPrepareInfo) error {
if !i.ipmiInfo.Present {
return nil
}
@@ -185,12 +187,16 @@ func (task *sBaremetalPrepareTask) configIPMISetting(cli *ssh.Client, i *baremet
)
sshIPMI := ipmitool.NewSSHIPMI(cli)
setIPMILanPortShared(sshIPMI, sysInfo)
ipmiUser, ipmiPasswd, ipmiIpAddr := task.getIPMIUserPasswd(i.ipmiInfo, sysInfo)
profile, err := profiles.GetProfile(ctx, sysInfo)
if err != nil {
return errors.Wrap(err, "GetProfile")
}
ipmiUser, ipmiPasswd, ipmiIpAddr := task.getIPMIUserPasswd(i.ipmiInfo, profile)
ipmiInfo.Username = ipmiUser
ipmiInfo.Password = ipmiPasswd
var ipmiLanChannel int = -1
for _, lanChannel := range ipmitool.GetLanChannels(sysInfo) {
var ipmiLanChannel uint8 = 0
for _, lanChannel := range profile.LanChannels {
log.Infof("Try lan channel %d ...", lanChannel)
conf, err := ipmitool.GetLanConfig(sshIPMI, lanChannel)
if err != nil {
@@ -207,11 +213,11 @@ func (task *sBaremetalPrepareTask) configIPMISetting(cli *ssh.Client, i *baremet
Speed: 100,
Mtu: 1500,
}
if err := task.sendNicInfo(ipmiNic, -1, api.NIC_TYPE_IPMI, true, "", false); err != nil {
if err := task.sendNicInfo(ctx, ipmiNic, -1, api.NIC_TYPE_IPMI, true, "", false); err != nil {
// ignore the error
log.Errorf("Send IPMI nic %#v info: %v", ipmiNic, err)
}
rootId := ipmitool.GetRootId(sysInfo)
rootId := profile.RootId
err = ipmitool.CreateOrSetAdminUser(sshIPMI, lanChannel, rootId, ipmiUser, ipmiPasswd)
if err != nil {
// ignore the error
@@ -232,7 +238,7 @@ func (task *sBaremetalPrepareTask) configIPMISetting(cli *ssh.Client, i *baremet
}
if len(tryAddrs) > 0 && !o.Options.ForceDhcpProbeIpmi {
for _, tryAddr := range tryAddrs {
tryResult := task.tryLocalIpmiAddr(sshIPMI, ipmiNic, lanChannel,
tryResult := task.tryLocalIpmiAddr(ctx, sshIPMI, ipmiNic, lanChannel,
ipmiUser, ipmiPasswd, tryAddr)
if tryResult {
ipmiInfo.IpAddr = tryAddr
@@ -240,7 +246,7 @@ func (task *sBaremetalPrepareTask) configIPMISetting(cli *ssh.Client, i *baremet
break
}
}
if ipmiLanChannel >= 0 {
if ipmiLanChannel > 0 {
// found and set config on lanChannel
break
}
@@ -309,7 +315,7 @@ func (task *sBaremetalPrepareTask) configIPMISetting(cli *ssh.Client, i *baremet
ipmiInfo.IpAddr = nic.IpAddr
ipmiLanChannel = lanChannel
}
if ipmiLanChannel == -1 {
if ipmiLanChannel == 0 {
return fmt.Errorf("Fail to get IPMI address from DHCP")
}
ipmiInfo.LanChannel = ipmiLanChannel
@@ -317,7 +323,7 @@ func (task *sBaremetalPrepareTask) configIPMISetting(cli *ssh.Client, i *baremet
return nil
}
func (task *sBaremetalPrepareTask) DoPrepare(cli *ssh.Client) error {
func (task *sBaremetalPrepareTask) DoPrepare(ctx context.Context, cli *ssh.Client) error {
infos, err := task.prepareBaremetalInfo(cli)
if err != nil {
logclient.AddActionLogWithStartable(task, task.baremetal, logclient.ACT_PREPARE, err, task.userCred, false)
@@ -325,12 +331,12 @@ func (task *sBaremetalPrepareTask) DoPrepare(cli *ssh.Client) error {
}
// set ipmi nic address and user password
if err = task.configIPMISetting(cli, infos); err != nil {
if err = task.configIPMISetting(ctx, cli, infos); err != nil {
logclient.AddActionLogWithStartable(task, task.baremetal, logclient.ACT_PREPARE, err, task.userCred, false)
return errors.Wrap(err, "Config IPMI setting")
}
if err = task.updateBmInfo(cli, infos); err != nil {
if err = task.updateBmInfo(ctx, cli, infos); err != nil {
logclient.AddActionLogWithStartable(task, task.baremetal, logclient.ACT_PREPARE, err, task.userCred, false)
return err
}
@@ -341,7 +347,7 @@ func (task *sBaremetalPrepareTask) DoPrepare(cli *ssh.Client) error {
log.Errorf("SetNTP fail: %s", err)
}
if err = AdjustUEFIBootOrder(cli, task.baremetal); err != nil {
if err = AdjustUEFIBootOrder(ctx, cli, task.baremetal); err != nil {
logclient.AddActionLogWithStartable(task, task.baremetal, logclient.ACT_PREPARE, err, task.userCred, false)
return errors.Wrap(err, "Adjust UEFI boot order")
}
@@ -375,7 +381,7 @@ func (task *sBaremetalPrepareTask) findAdminNic(cli *ssh.Client, nicsInfo []*typ
return -1, nil, errors.Error("admin nic not found???")
}
func (task *sBaremetalPrepareTask) updateBmInfo(cli *ssh.Client, i *baremetalPrepareInfo) error {
func (task *sBaremetalPrepareTask) updateBmInfo(ctx context.Context, cli *ssh.Client, i *baremetalPrepareInfo) error {
adminNic := task.baremetal.GetAdminNic()
if adminNic == nil || (adminNic != nil && !adminNic.LinkUp) {
adminIdx, adminNicDev, err := task.findAdminNic(cli, i.nicsInfo)
@@ -383,7 +389,7 @@ func (task *sBaremetalPrepareTask) updateBmInfo(cli *ssh.Client, i *baremetalPre
return errors.Wrap(err, "task.findAdminNic")
}
accessIp := cli.GetConfig().Host
err = task.sendNicInfo(adminNicDev, adminIdx, api.NIC_TYPE_ADMIN, false, accessIp, true)
err = task.sendNicInfo(ctx, adminNicDev, adminIdx, api.NIC_TYPE_ADMIN, false, accessIp, true)
if err != nil {
return errors.Wrap(err, "send Admin Nic Info")
}
@@ -445,14 +451,14 @@ func (task *sBaremetalPrepareTask) updateBmInfo(cli *ssh.Client, i *baremetalPre
// }
removedMacs := task.removeObsoleteNics(i)
for idx := range removedMacs {
err = task.removeNicInfo(removedMacs[idx])
err = task.removeNicInfo(ctx, removedMacs[idx])
if err != nil {
log.Errorf("Fail to remove Netif %s: %s", removedMacs[idx], err)
return errors.Wrap(err, "task.removeNicInfo")
}
}
for idx := range i.nicsInfo {
err = task.sendNicInfo(i.nicsInfo[idx], idx, "", false, "", false)
err = task.sendNicInfo(ctx, i.nicsInfo[idx], idx, "", false, "", false)
if err != nil {
log.Errorf("Send nicinfo idx: %d, %#v error: %v", idx, i.nicsInfo[idx], err)
return errors.Wrap(err, "task.sendNicInfo")
@@ -494,7 +500,7 @@ func (task *sBaremetalPrepareTask) removeObsoleteNics(i *baremetalPrepareInfo) [
return removes
}
func (task *sBaremetalPrepareTask) tryLocalIpmiAddr(sshIPMI *ipmitool.SSHIPMI, ipmiNic *types.SNicDevInfo, lanChannel int, ipmiUser, ipmiPasswd, tryAddr string) bool {
func (task *sBaremetalPrepareTask) tryLocalIpmiAddr(ctx context.Context, sshIPMI *ipmitool.SSHIPMI, ipmiNic *types.SNicDevInfo, lanChannel uint8, ipmiUser, ipmiPasswd, tryAddr string) bool {
log.Infof("IP addr found in IPMI config, try use %s as IPMI address", tryAddr)
ipConf, err := task.getIPMIIPConfig(tryAddr)
if err != nil {
@@ -548,7 +554,7 @@ func (task *sBaremetalPrepareTask) tryLocalIpmiAddr(sshIPMI *ipmitool.SSHIPMI, i
if tried < maxTries {
// make sure the ipaddr is a IPMI address
// enable the netif
err := task.sendNicInfo(ipmiNic, -1, api.NIC_TYPE_IPMI, false, tryAddr, true)
err := task.sendNicInfo(ctx, ipmiNic, -1, api.NIC_TYPE_IPMI, false, tryAddr, true)
if err != nil {
log.Errorf("Fail to set existing BMC IP address to %s", tryAddr)
} else {
@@ -558,14 +564,14 @@ func (task *sBaremetalPrepareTask) tryLocalIpmiAddr(sshIPMI *ipmitool.SSHIPMI, i
return false
}
func (task *sBaremetalPrepareTask) getIPMIUserPasswd(oldIPMIConf *types.SIPMIInfo, sysInfo *types.SSystemInfo) (string, string, string) {
func (task *sBaremetalPrepareTask) getIPMIUserPasswd(oldIPMIConf *types.SIPMIInfo, profile *baremetalapi.BaremetalProfileSpec) (string, string, string) {
var (
ipmiUser string
ipmiPasswd string
ipmiIpAddr string
)
ipmiUser = profiles.GetRootName(sysInfo)
isStrongPass := profiles.IsStrongPass(sysInfo)
ipmiUser = profile.RootName
isStrongPass := profile.StrongPass
if !isStrongPass && o.Options.DefaultIpmiPassword != "" {
ipmiPasswd = o.Options.DefaultIpmiPassword
} else if isStrongPass && o.Options.DefaultStrongIpmiPassword != "" {
@@ -785,7 +791,7 @@ func isIPMIEnable(cli *ssh.Client) (bool, error) {
return sysutils.ParseDMIIPMIInfo(ret), nil
}
func (task *sBaremetalPrepareTask) removeNicInfo(mac string) error {
func (task *sBaremetalPrepareTask) removeNicInfo(ctx context.Context, mac string) error {
params := jsonutils.NewDict()
params.Add(jsonutils.NewString(mac), "mac")
resp, err := modules.Hosts.PerformAction(
@@ -797,13 +803,13 @@ func (task *sBaremetalPrepareTask) removeNicInfo(mac string) error {
if err != nil {
return err
}
return task.baremetal.SaveDesc(resp)
return task.baremetal.SaveDesc(ctx, resp)
}
func (task *sBaremetalPrepareTask) sendNicInfo(
func (task *sBaremetalPrepareTask) sendNicInfo(ctx context.Context,
nic *types.SNicDevInfo, idx int, nicType compute.TNicType, reset bool, ipAddr string, reserve bool,
) error {
return task.baremetal.SendNicInfo(nic, idx, nicType, reset, ipAddr, reserve)
return task.baremetal.SendNicInfo(ctx, nic, idx, nicType, reset, ipAddr, reserve)
}
func (task *sBaremetalPrepareTask) sendStorageInfo(size int64) error {
+34 -28
View File
@@ -22,9 +22,11 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
o "yunion.io/x/onecloud/pkg/baremetal/options"
"yunion.io/x/onecloud/pkg/baremetal/profiles"
"yunion.io/x/onecloud/pkg/baremetal/utils/ipmitool"
"yunion.io/x/onecloud/pkg/cloudcommon/types"
"yunion.io/x/onecloud/pkg/mcclient"
@@ -49,7 +51,7 @@ type sBaremetalRegisterTask struct {
IpmiIpAddr string
IpmiMac net.HardwareAddr
IpmiLanChannel int
IpmiLanChannel uint8
AdminWire string
IpmiWire string
@@ -60,7 +62,7 @@ type sBaremetalRegisterTask struct {
func NewBaremetalRegisterTask(
userCred mcclient.TokenCredential, bmManager IBmManager, sshCli *ssh.Client,
hostname, remoteIp, ipmiUsername, ipmiPassword, ipmiIpAddr string,
ipmiMac net.HardwareAddr, ipmiLanChannel int, adminWire, ipmiWire string) *sBaremetalRegisterTask {
ipmiMac net.HardwareAddr, ipmiLanChannel uint8, adminWire, ipmiWire string) *sBaremetalRegisterTask {
return &sBaremetalRegisterTask{
sBaremetalPrepareTask: sBaremetalPrepareTask{userCred: userCred},
BmManager: bmManager,
@@ -112,7 +114,7 @@ func (s *sBaremetalRegisterTask) getAccessDevMacAddr(ip string) (string, error)
return segs[1], nil
}
func (s *sBaremetalRegisterTask) CreateBaremetal() (string, error) {
func (s *sBaremetalRegisterTask) CreateBaremetal(ctx context.Context) (string, error) {
zoneId := s.BmManager.GetZoneId()
ret, err := s.SshCli.Run("/lib/mos/lsnic")
if err != nil {
@@ -148,24 +150,24 @@ func (s *sBaremetalRegisterTask) CreateBaremetal() (string, error) {
if err != nil {
return "", fmt.Errorf("Create baremetal failed: %s", err)
}
pxeBm, err := s.BmManager.AddBaremetal(res)
pxeBm, err := s.BmManager.AddBaremetal(ctx, res)
if err != nil {
return "", fmt.Errorf("BmManager add baremetal failed: %s", err)
}
err = pxeBm.InitAdminNetif(
err = pxeBm.InitAdminNetif(ctx,
s.accessNic.Mac, s.AdminWire, api.NIC_TYPE_ADMIN, api.NETWORK_TYPE_PXE, true, s.RemoteIp)
if err != nil {
return "", fmt.Errorf("BmManager add admin netif failed: %s", err)
}
err = pxeBm.InitAdminNetif(
err = pxeBm.InitAdminNetif(ctx,
s.IpmiMac, s.IpmiWire, api.NIC_TYPE_IPMI, api.NETWORK_TYPE_IPMI, true, s.IpmiIpAddr)
if err != nil {
return "", fmt.Errorf("BmManager add ipmi netif failed: %s", err)
}
for _, nic := range nicinfo {
if nic.Dev != s.accessNic.Dev {
pxeBm.RegisterNetif(nic.Mac, s.AdminWire)
pxeBm.RegisterNetif(ctx, nic.Mac, s.AdminWire)
}
}
s.baremetal = pxeBm.(IBaremetal)
@@ -173,14 +175,14 @@ func (s *sBaremetalRegisterTask) CreateBaremetal() (string, error) {
return bmInstanceId, nil
}
func (s *sBaremetalRegisterTask) UpdateBaremetal() (string, error) {
func (s *sBaremetalRegisterTask) UpdateBaremetal(ctx context.Context) (string, error) {
accessMac, err := s.getAccessDevMacAddr(s.RemoteIp)
if err != nil {
return "", err
return "", errors.Wrap(err, "getAccessDevMacAddr")
}
accessMacAddr, err := net.ParseMAC(accessMac)
if err != nil {
return "", fmt.Errorf("Failed parse access mac %s", accessMac)
return "", errors.Wrapf(err, "Failed parse access mac %s", accessMac)
}
params := jsonutils.NewDict()
@@ -188,14 +190,14 @@ func (s *sBaremetalRegisterTask) UpdateBaremetal() (string, error) {
params.Set("scope", jsonutils.NewString("system"))
res, err := modules.Hosts.List(s.BmManager.GetClientSession(), params)
if err != nil {
return "", fmt.Errorf("Fetch baremetal failed %s", err)
return "", errors.Wrap(err, "Fetch baremetal failed")
}
if len(res.Data) == 0 {
return "", fmt.Errorf("Cann't find baremetal by access mac %s", accessMacAddr)
return "", errors.Wrapf(errors.ErrNotFound, "Cann't find baremetal by access mac %s", accessMacAddr)
}
pxeBm, err := s.BmManager.AddBaremetal(res.Data[0])
pxeBm, err := s.BmManager.AddBaremetal(ctx, res.Data[0])
if err != nil {
return "", fmt.Errorf("BmManager add baremetal failed: %s", err)
return "", errors.Wrap(err, "BmManager add baremetal failed")
}
s.baremetal = pxeBm.(IBaremetal)
@@ -229,12 +231,12 @@ func (s *sBaremetalRegisterTask) DoPrepare(ctx context.Context, cli *ssh.Client,
infos.ipmiInfo.RedfishApi = redfishSupport
infos.ipmiInfo.CdromBoot = cdromSupport
s.updateIpmiInfo(cli)
s.updateIpmiInfo(ctx, cli)
return s.updateBmInfo(cli, infos, registered)
return s.updateBmInfo(ctx, cli, infos, registered)
}
func (s *sBaremetalRegisterTask) updateIpmiInfo(cli *ssh.Client) {
func (s *sBaremetalRegisterTask) updateIpmiInfo(ctx context.Context, cli *ssh.Client) {
ipmiTool := ipmitool.NewSSHIPMI(cli)
sysInfo, err := ipmitool.GetSysInfo(ipmiTool)
if err == nil && o.Options.IpmiLanPortShared {
@@ -253,21 +255,25 @@ func (s *sBaremetalRegisterTask) updateIpmiInfo(cli *ssh.Client) {
}
var conf *types.SIPMILanConfig
for _, lanChannel := range ipmitool.GetLanChannels(sysInfo) {
conf, _ = ipmitool.GetLanConfig(ipmiTool, lanChannel)
if conf == nil || len(conf.Mac) == 0 {
continue
profile, err := profiles.GetProfile(ctx, sysInfo)
if profile != nil {
for _, lanChannel := range profile.LanChannels {
conf, _ = ipmitool.GetLanConfig(ipmiTool, lanChannel)
if conf == nil || len(conf.Mac) == 0 {
continue
}
}
}
if conf == nil || len(conf.Mac) == 0 {
log.Errorln("Fail to get IPMI lan config !!!")
} else {
nic.Mac = conf.Mac
}
s.sendNicInfo(nic, -1, api.NIC_TYPE_IPMI, false, "", false)
s.sendNicInfo(ctx, nic, -1, api.NIC_TYPE_IPMI, false, "", false)
}
func (s *sBaremetalRegisterTask) updateBmInfo(cli *ssh.Client, i *baremetalPrepareInfo, registered bool) error {
func (s *sBaremetalRegisterTask) updateBmInfo(ctx context.Context, cli *ssh.Client, i *baremetalPrepareInfo, registered bool) error {
updateInfo := make(map[string]interface{})
updateInfo["access_ip"] = s.RemoteIp
updateInfo["cpu_count"] = i.cpuInfo.Count
@@ -293,7 +299,7 @@ func (s *sBaremetalRegisterTask) updateBmInfo(cli *ssh.Client, i *baremetalPrepa
log.Errorf("sendStorageInfo error: %v", err)
}
for idx := range i.nicsInfo {
err = s.sendNicInfo(i.nicsInfo[idx], idx, "", false, "", false)
err = s.sendNicInfo(ctx, i.nicsInfo[idx], idx, "", false, "", false)
if err != nil {
log.Errorf("Send nicinfo idx: %d, %#v error: %v", idx, i.nicsInfo[idx], err)
}
@@ -301,20 +307,20 @@ func (s *sBaremetalRegisterTask) updateBmInfo(cli *ssh.Client, i *baremetalPrepa
if registered {
return nil
}
return s.initBaremetalServer()
return s.initBaremetalServer(ctx)
}
func (s *sBaremetalRegisterTask) initBaremetalServer() error {
func (s *sBaremetalRegisterTask) initBaremetalServer(ctx context.Context) error {
if err := s.baremetal.InitializeServer(s.getSession(), s.Hostname); err != nil {
return fmt.Errorf("Baremteal Create Server Failed %s", err)
}
// if err := s.baremetal.SaveSSHConfig("", ""); err != nil {
// log.Errorf("Save ssh config failed %s", err)
// }
if err := s.baremetal.ServerLoadDesc(); err != nil {
if err := s.baremetal.ServerLoadDesc(ctx); err != nil {
log.Errorf("Server load desc failed %s", err)
}
s.baremetal.SyncStatus("running", "Register success")
s.baremetal.SyncStatus(ctx, "running", "Register success")
log.Infof("%s Load baremetal info success ...", s.baremetal.GetId())
return nil
}
+2 -2
View File
@@ -106,7 +106,7 @@ func (self *SBaremetalCdromTask) DoInsertISO(ctx context.Context, args interface
if err != nil {
return errors.Wrap(err, "MountVirtualCdrom")
}
self.Baremetal.AutoSyncStatus()
self.Baremetal.AutoSyncStatus(ctx)
SetTaskComplete(self, nil)
return nil
}
@@ -120,7 +120,7 @@ func (self *SBaremetalCdromTask) DoEjectISO(ctx context.Context, args interface{
if err != nil {
return errors.Wrap(err, "UmountVirtualCdrom")
}
self.Baremetal.AutoSyncStatus()
self.Baremetal.AutoSyncStatus(ctx)
SetTaskComplete(self, nil)
return nil
}
+9 -8
View File
@@ -15,6 +15,7 @@
package tasks
import (
"context"
"time"
"yunion.io/x/jsonutils"
@@ -50,32 +51,32 @@ func (self *SBaremetalServerCreateTask) RemoveEFIOSEntry() bool {
return true
}
func (self *SBaremetalServerCreateTask) DoDeploys(term *ssh.Client) (jsonutils.JSONObject, error) {
func (self *SBaremetalServerCreateTask) DoDeploys(ctx context.Context, term *ssh.Client) (jsonutils.JSONObject, error) {
// Build raid
tool, err := self.Baremetal.GetServer().DoDiskConfig(term)
if err != nil {
return nil, self.onError(term, err)
return nil, self.onError(ctx, term, err)
}
time.Sleep(2 * time.Second)
if err := self.Baremetal.GetServer().DoEraseDisk(term); err != nil {
return nil, self.onError(term, err)
return nil, self.onError(ctx, term, err)
}
time.Sleep(2 * time.Second)
parts, err := self.Baremetal.GetServer().DoPartitionDisk(tool, term, self.IsDisableImageCache())
if err != nil {
return nil, self.onError(term, err)
return nil, self.onError(ctx, term, err)
}
data := jsonutils.NewDict()
disks, err := self.Baremetal.GetServer().SyncPartitionSize(term, parts)
if err != nil {
return nil, self.onError(term, err)
return nil, self.onError(ctx, term, err)
}
data.Add(jsonutils.Marshal(disks), "disks")
rootImageId := self.Baremetal.GetServer().GetRootTemplateId()
if len(rootImageId) > 0 {
deployInfo, err := self.Baremetal.GetServer().DoDeploy(tool, term, self.data, true)
if err != nil {
return nil, self.onError(term, err)
return nil, self.onError(ctx, term, err)
}
if deployInfo != nil {
data.Update(deployInfo)
@@ -100,11 +101,11 @@ func (self *SBaremetalServerCreateTask) PostDeploys(term *ssh.Client) error {
return nil
}
func (self *SBaremetalServerCreateTask) onError(term *ssh.Client, err error) error {
func (self *SBaremetalServerCreateTask) onError(ctx context.Context, term *ssh.Client, err error) error {
log.Errorf("Create server error: %+v", err)
if err1 := self.Baremetal.GetServer().DoEraseDisk(term); err1 != nil {
log.Warningf("EraseDisk error: %v", err1)
}
self.Baremetal.AutoSyncStatus()
self.Baremetal.AutoSyncStatus(ctx)
return err
}
+11 -10
View File
@@ -15,6 +15,7 @@
package tasks
import (
"context"
"net"
"yunion.io/x/cloudmux/pkg/apis/compute"
@@ -39,7 +40,7 @@ type IBaremetal interface {
GetAdminNic() *types.SNic
GetName() string
GetClientSession() *mcclient.ClientSession
SaveDesc(desc jsonutils.JSONObject) error
SaveDesc(ctx context.Context, desc jsonutils.JSONObject) error
GetNics() []types.SNic
GetNicByMac(net.HardwareAddr) *types.SNic
GetRawIPMIConfig() *types.SIPMIInfo
@@ -47,10 +48,10 @@ type IBaremetal interface {
SetExistingIPMIIPAddr(ipAddr string)
GetServer() baremetaltypes.IBaremetalServer
SyncStatus(status, reason string)
AutoSyncStatus()
SyncAllStatus(status string)
AutoSyncAllStatus()
SyncStatus(ctx context.Context, status, reason string)
AutoSyncStatus(ctx context.Context)
SyncAllStatus(ctx context.Context, status string)
AutoSyncAllStatus(ctx context.Context)
GetPowerStatus() (string, error)
DoPowerShutdown(soft bool) error
@@ -61,25 +62,25 @@ type IBaremetal interface {
GetAccessIp() string
EnablePxeBoot() bool
GenerateBootISO() error
SendNicInfo(nic *types.SNicDevInfo, idx int, nicType compute.TNicType, reset bool, ipAddr string, reserve bool) error
SendNicInfo(ctx context.Context, nic *types.SNicDevInfo, idx int, nicType compute.TNicType, reset bool, ipAddr string, reserve bool) error
DoNTPConfig() error
GetImageUrl(needImageCache bool) string
RemoveServer()
InitializeServer(session *mcclient.ClientSession, name string) error
SaveSSHConfig(remoteAddr string, key string) error
ServerLoadDesc() error
ServerLoadDesc(ctx context.Context) error
GetDHCPServerIP() (net.IP, error)
HasBMC() bool
SSHReachable() (bool, error)
SSHReboot() error
SSHReboot(ctx context.Context) error
SSHShutdown() error
AdjustUEFICurrentBootOrder(cli *ssh.Client) error
AdjustUEFICurrentBootOrder(ctx context.Context, cli *ssh.Client) error
}
type IBmManager interface {
GetZoneId() string
AddBaremetal(jsonutils.JSONObject) (pxe.IBaremetalInstance, error)
AddBaremetal(context.Context, jsonutils.JSONObject) (pxe.IBaremetalInstance, error)
GetClientSession() *mcclient.ClientSession
}
+19 -11
View File
@@ -23,7 +23,9 @@ import (
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
baremetalapi "yunion.io/x/onecloud/pkg/apis/compute/baremetal"
o "yunion.io/x/onecloud/pkg/baremetal/options"
"yunion.io/x/onecloud/pkg/baremetal/profiles"
"yunion.io/x/onecloud/pkg/baremetal/utils/ipmitool"
"yunion.io/x/onecloud/pkg/cloudcommon/types"
"yunion.io/x/onecloud/pkg/httperrors"
@@ -97,7 +99,7 @@ func (self *SBaremetalIpmiProbeTask) doRedfishIpmiProbe(ctx context.Context, drv
if len(confs) == 0 {
return false, errors.Wrap(httperrors.ErrNotFound, "no IPMI lan")
}
err = self.sendIpmiNicInfo(&confs[0])
err = self.sendIpmiNicInfo(ctx, &confs[0])
if err != nil {
return false, errors.Wrap(err, "self.sendIpmiNicInfo")
}
@@ -143,18 +145,18 @@ func (self *SBaremetalIpmiProbeTask) doRedfishIpmiProbe(ctx context.Context, drv
for i := range sysInfo.EthernetNICs {
mac, err := net.ParseMAC(sysInfo.EthernetNICs[i])
if err == nil {
err = self.sendNicInfo(i, mac)
err = self.sendNicInfo(ctx, i, mac)
if err != nil {
return true, errors.Wrapf(err, "sendNicInfo %d %s", i, mac)
}
}
}
self.Baremetal.SyncStatus("", "Probe Redfish finished")
self.Baremetal.SyncStatus(ctx, "", "Probe Redfish finished")
SetTaskComplete(self, nil)
return true, nil
}
func (self *SBaremetalIpmiProbeTask) sendIpmiNicInfo(lanConf *types.SIPMILanConfig) error {
func (self *SBaremetalIpmiProbeTask) sendIpmiNicInfo(ctx context.Context, lanConf *types.SIPMILanConfig) error {
speed := lanConf.SpeedMbps
if speed <= 0 {
speed = 100
@@ -166,18 +168,18 @@ func (self *SBaremetalIpmiProbeTask) sendIpmiNicInfo(lanConf *types.SIPMILanConf
Speed: speed,
Mtu: 1500,
}
err := self.Baremetal.SendNicInfo(ipmiNic, -1, api.NIC_TYPE_IPMI, true, lanConf.IPAddr, true)
err := self.Baremetal.SendNicInfo(ctx, ipmiNic, -1, api.NIC_TYPE_IPMI, true, lanConf.IPAddr, true)
if err != nil {
return errors.Wrap(err, "SendNicInfo")
}
return nil
}
func (self *SBaremetalIpmiProbeTask) sendNicInfo(index int, mac net.HardwareAddr) error {
func (self *SBaremetalIpmiProbeTask) sendNicInfo(ctx context.Context, index int, mac net.HardwareAddr) error {
nicInfo := &types.SNicDevInfo{
Mac: mac,
}
err := self.Baremetal.SendNicInfo(nicInfo, index, "", false, "", false)
err := self.Baremetal.SendNicInfo(ctx, nicInfo, index, "", false, "", false)
if err != nil {
return errors.Wrap(err, "SendNicInfo")
}
@@ -186,14 +188,20 @@ func (self *SBaremetalIpmiProbeTask) sendNicInfo(index int, mac net.HardwareAddr
func (self *SBaremetalIpmiProbeTask) doRawIpmiProbe(ctx context.Context, cli ipmitool.IPMIExecutor) error {
sysInfo, err := ipmitool.GetSysInfo(cli)
var profile *baremetalapi.BaremetalProfileSpec
if err != nil {
// ignore error for qemu
log.Errorf("ipmitool.GetSysInfo error %s", err)
} else {
profile, err = profiles.GetProfile(ctx, sysInfo)
if err != nil {
return errors.Wrap(err, "GetProfile")
}
}
guid := ipmitool.GetSysGuid(cli)
var conf *types.SIPMILanConfig
var channel int
for _, lanChannel := range ipmitool.GetLanChannels(sysInfo) {
var channel uint8
for _, lanChannel := range profile.LanChannels {
conf, err = ipmitool.GetLanConfig(cli, lanChannel)
if err != nil {
// ignore error
@@ -206,7 +214,7 @@ func (self *SBaremetalIpmiProbeTask) doRawIpmiProbe(ctx context.Context, cli ipm
if conf == nil {
return errors.Wrap(httperrors.ErrNotFound, "no IPMI lan")
}
err = self.sendIpmiNicInfo(conf)
err = self.sendIpmiNicInfo(ctx, conf)
if err != nil {
return errors.Wrap(err, "self.sendIpmiNicInfo")
}
@@ -244,7 +252,7 @@ func (self *SBaremetalIpmiProbeTask) doRawIpmiProbe(ctx context.Context, cli ipm
if err != nil {
return errors.Wrap(err, "modules.Hosts.Update")
}
self.Baremetal.SyncStatus("", "Probie IPMI finished")
self.Baremetal.SyncStatus(ctx, "", "Probie IPMI finished")
SetTaskComplete(self, nil)
return nil
}
+1 -1
View File
@@ -51,7 +51,7 @@ func (self *SBaremetalMaintenanceTask) OnPXEBoot(ctx context.Context, term *ssh.
if jsonutils.QueryBoolean(self.data, "guest_running", false) {
dataObj["guest_running"] = true
}
self.Baremetal.AutoSyncStatus()
self.Baremetal.AutoSyncStatus(ctx)
SetTaskComplete(self, jsonutils.Marshal(dataObj))
return nil
}
+3 -3
View File
@@ -49,13 +49,13 @@ func (self *SBaremetalServerPrepareTask) GetName() string {
// OnPXEBootRequest called by notify api handler
func (self *SBaremetalServerPrepareTask) OnPXEBootRequest(ctx context.Context, cli *ssh.Client, args interface{}) error {
err := newBaremetalPrepareTask(self.Baremetal, self.userCred).DoPrepare(cli)
err := newBaremetalPrepareTask(self.Baremetal, self.userCred).DoPrepare(ctx, cli)
if err != nil {
log.Errorf("Prepare failed: %v", err)
self.Baremetal.SyncStatus(status.PREPARE_FAIL, err.Error())
self.Baremetal.SyncStatus(ctx, status.PREPARE_FAIL, err.Error())
return err
}
self.Baremetal.AutoSyncStatus()
self.Baremetal.AutoSyncStatus(ctx)
SetTaskComplete(self, nil)
return nil
}
+6 -4
View File
@@ -15,6 +15,8 @@
package tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient"
@@ -43,13 +45,13 @@ func (self *SBaremetalReprepareTask) GetName() string {
return "BaremetalReprepareTask"
}
func (self *SBaremetalReprepareTask) DoDeploys(term *ssh.Client) (jsonutils.JSONObject, error) {
func (self *SBaremetalReprepareTask) DoDeploys(ctx context.Context, term *ssh.Client) (jsonutils.JSONObject, error) {
task := newBaremetalPrepareTask(self.Baremetal, self.userCred)
err := task.DoPrepare(term)
err := task.DoPrepare(ctx, term)
return nil, err
}
func (self *SBaremetalReprepareTask) PostDeploys(term *ssh.Client) error {
self.Baremetal.AutoSyncStatus()
func (self *SBaremetalReprepareTask) PostDeploys(ctx context.Context, term *ssh.Client) error {
self.Baremetal.AutoSyncStatus(ctx)
return nil
}
+2 -2
View File
@@ -58,7 +58,7 @@ func (self *SBaremetalServerStartTask) DoBoot(ctx context.Context, args interfac
}
}
} else {
if err := self.Baremetal.SSHReboot(); err != nil {
if err := self.Baremetal.SSHReboot(ctx); err != nil {
return errors.Wrap(err, "Try reboot")
}
}
@@ -85,7 +85,7 @@ func (self *SBaremetalServerStartTask) WaitForStart(ctx context.Context, args in
}
func (self *SBaremetalServerStartTask) OnStartComplete(ctx context.Context, args interface{}) error {
self.Baremetal.SyncAllStatus(types.POWER_STATUS_ON)
self.Baremetal.SyncAllStatus(ctx, types.POWER_STATUS_ON)
SetTaskComplete(self, nil)
return nil
}
+3 -3
View File
@@ -58,12 +58,12 @@ func (task *SBaremetalUnmaintenanceTask) DoUnmaintenance(ctx context.Context, ar
}
} else {
if task.Baremetal.GetServer() != nil {
if err := task.EnsureSSHReboot(); err != nil {
if err := task.EnsureSSHReboot(ctx); err != nil {
return errors.Wrap(err, "Do unmaintenance for none BMC server")
}
}
}
task.Baremetal.SyncStatus(baremetalstatus.RUNNING, "")
task.Baremetal.SyncStatus(ctx, baremetalstatus.RUNNING, "")
SetTaskComplete(task, nil)
return nil
}
@@ -89,7 +89,7 @@ func (self *SBaremetalUnmaintenanceTask) WaitForStop(ctx context.Context, args i
}
func (self *SBaremetalUnmaintenanceTask) OnStopComplete(ctx context.Context, args interface{}) error {
self.Baremetal.SyncStatus(baremetalstatus.READY, "")
self.Baremetal.SyncStatus(ctx, baremetalstatus.READY, "")
SetTaskComplete(self, nil)
return nil
}
+13 -15
View File
@@ -22,15 +22,13 @@ import (
"strings"
"time"
"github.com/pkg/errors"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/tristate"
"yunion.io/x/pkg/util/stringutils"
"yunion.io/x/pkg/utils"
"yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/baremetal/profiles"
"yunion.io/x/onecloud/pkg/cloudcommon/types"
"yunion.io/x/onecloud/pkg/util/procutils"
"yunion.io/x/onecloud/pkg/util/ssh"
@@ -197,7 +195,7 @@ func GetSysInfo(exector IPMIExecutor) (*types.SSystemInfo, error) {
return &info, err
}
func GetLanChannels(sysinfo *types.SSystemInfo) []int {
/*func GetLanChannels(sysinfo *types.SSystemInfo) []int {
return profiles.GetLanChannel(sysinfo)
}
@@ -207,9 +205,9 @@ func GetDefaultLanChannel(sysinfo *types.SSystemInfo) int {
func GetRootId(sysinfo *types.SSystemInfo) int {
return profiles.GetRootId(sysinfo)
}
}*/
func GetLanConfig(exector IPMIExecutor, channel int) (*types.SIPMILanConfig, error) {
func GetLanConfig(exector IPMIExecutor, channel uint8) (*types.SIPMILanConfig, error) {
args := newArgs("lan", "print", channel)
lines, err := ExecuteCommands(exector, args)
if err != nil {
@@ -278,14 +276,14 @@ func doActions(exector IPMIExecutor, actionName string, args ...Args) error {
return nil
}
func SetLanDHCP(exector IPMIExecutor, lanChannel int) error {
func SetLanDHCP(exector IPMIExecutor, lanChannel uint8) error {
args := newArgs("lan", "set", lanChannel, "ipsrc", "dhcp")
return doActions(exector, "set_lan_dhcp", args)
}
func SetLanStatic(
exector IPMIExecutor,
channel int,
channel uint8,
ip string,
mask string,
gateway string,
@@ -313,12 +311,12 @@ func SetLanStatic(
return doActions(exector, "set_lan_static", argss...)
}
func SetLanStaticIP(exector IPMIExecutor, channel int, ip string) error {
func SetLanStaticIP(exector IPMIExecutor, channel uint8, ip string) error {
args := newArgs("lan", "set", channel, "ipaddr", ip)
return doActions(exector, "set_lan_static_ip", args)
}
func setLanAccess(exector IPMIExecutor, channel int, access string) error {
func setLanAccess(exector IPMIExecutor, channel uint8, access string) error {
args := []Args{
newArgs("lan", "set", channel, "access", access),
// newArgs("lan", "set", channel, "auth", "ADMIN", "MD5"),
@@ -326,11 +324,11 @@ func setLanAccess(exector IPMIExecutor, channel int, access string) error {
return doActions(exector, "set_lan_access", args...)
}
func EnableLanAccess(exector IPMIExecutor, channel int) error {
func EnableLanAccess(exector IPMIExecutor, channel uint8) error {
return setLanAccess(exector, channel, "on")
}
func ListLanUsers(exector IPMIExecutor, channel int) ([]compute.IPMIUser, error) {
func ListLanUsers(exector IPMIExecutor, channel uint8) ([]compute.IPMIUser, error) {
args := newArgs("user", "list", channel)
ret, err := ExecuteCommands(exector, args)
if err != nil {
@@ -339,7 +337,7 @@ func ListLanUsers(exector IPMIExecutor, channel int) ([]compute.IPMIUser, error)
return sysutils.ParseIPMIUser(ret), nil
}
func CreateOrSetAdminUser(exector IPMIExecutor, channel int, rootId int, username string, password string) error {
func CreateOrSetAdminUser(exector IPMIExecutor, channel uint8, rootId int, username string, password string) error {
users, err := ListLanUsers(exector, channel)
if err != nil {
return errors.Wrap(err, "List users")
@@ -372,7 +370,7 @@ func CreateOrSetAdminUser(exector IPMIExecutor, channel int, rootId int, usernam
return SetLanUserAdminPasswd(exector, channel, foundUser.Id, password)
}
func SetLanUserAdminPasswd(exector IPMIExecutor, channel int, id int, password string) error {
func SetLanUserAdminPasswd(exector IPMIExecutor, channel uint8, id int, password string) error {
var err error
password, err = stringutils2.EscapeEchoString(password)
if err != nil {
@@ -403,7 +401,7 @@ func SetLanUserAdminPasswd(exector IPMIExecutor, channel int, id int, password s
return doActions(exector, "set_lan_user_password3", args...)
}
func SetIdUserPasswd(exector IPMIExecutor, channel int, id int, user string, password string) error {
func SetIdUserPasswd(exector IPMIExecutor, channel uint8, id int, user string, password string) error {
args := newArgs("user", "set", "name", id, user)
if err := doActions(exector, fmt.Sprintf("set_id%d_name", id), args); err != nil {
return errors.Wrapf(err, "change root id %d to name %s", id, user)
+1 -1
View File
@@ -26,7 +26,7 @@ type SIPMIInfo struct {
Password string `json:"password,omitempty"`
IpAddr string `json:"ip_addr,omitempty"`
Present bool `json:"present,omitempty"`
LanChannel int `json:"lan_channel,omitzero"`
LanChannel uint8 `json:"lan_channel,omitzero"`
Verified bool `json:"verified,omitfalse"`
RedfishApi bool `json:"redfish_api,omitfalse"`
CdromBoot bool `json:"cdrom_boot,omitfalse"`
+15
View File
@@ -0,0 +1,15 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package baremetal // import "yunion.io/x/onecloud/pkg/compute/models/baremetal"
+227
View File
@@ -0,0 +1,227 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package baremetal
import (
"context"
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/sqlchemy"
baremetalapi "yunion.io/x/onecloud/pkg/apis/compute/baremetal"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SBaremetalProfileManager struct {
db.SStandaloneAnonResourceBaseManager
}
type SBaremetalProfile struct {
db.SStandaloneAnonResourceBase
// 品牌名称(English)
OemName string `width:"64" charset:"ascii" nullable:"false" default:"" index:"true" list:"user" create:"required"`
Model string `width:"64" charset:"utf8" list:"user" create:"optional"`
LanChannel uint8 `list:"user" update:"user" create:"optional"`
LanChannel2 uint8 `list:"user" update:"user" create:"optional"`
LanChannel3 uint8 `list:"user" update:"user" create:"optional"`
// BMC Root账号名称,默认为 root
RootName string `width:"64" charset:"ascii" nullable:"false" list:"user" update:"user" create:"required" default:"root"`
// BMC Root账号ID,默认为 2
RootId int `list:"user" update:"user" create:"optional" default:"2"`
// 是否要求强密码
StrongPass bool `list:"user" update:"user" create:"optional"`
}
var BaremetalProfileManager *SBaremetalProfileManager
func init() {
BaremetalProfileManager = &SBaremetalProfileManager{
SStandaloneAnonResourceBaseManager: db.NewStandaloneAnonResourceBaseManager(
SBaremetalProfile{},
"baremetal_profiles_tbl",
"baremetal_profile",
"baremetal_profiles",
),
}
BaremetalProfileManager.SetVirtualObject(BaremetalProfileManager)
}
func (bpm *SBaremetalProfileManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query baremetalapi.BaremetalProfileListInput,
) (*sqlchemy.SQuery, error) {
q, err := bpm.SStandaloneAnonResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StandaloneAnonResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStandaloneAnonResourceBaseManager.ListItemFilter")
}
query.Normalize()
if len(query.OemName) > 0 {
q = q.In("oem_name", query.OemName)
}
if len(query.Model) > 0 {
q = q.In("model", query.Model)
}
return q, nil
}
func (bpm *SBaremetalProfileManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query baremetalapi.BaremetalProfileListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = bpm.SStandaloneAnonResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StandaloneAnonResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStandaloneAnonResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (bpm *SBaremetalProfileManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = bpm.SStandaloneAnonResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, nil
}
func (bpm *SBaremetalProfileManager) ListItemExportKeys(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, keys stringutils2.SSortedStrings) (*sqlchemy.SQuery, error) {
var err error
q, err = bpm.SStandaloneAnonResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SVirtualResourceBaseManager.ListItemExportKeys")
}
return q, nil
}
func (bpm *SBaremetalProfileManager) InitializeData() error {
for _, spec := range baremetalapi.PredefinedProfiles {
bp := SBaremetalProfile{}
bp.Id = strings.ToLower(spec.OemName)
if len(bp.Id) == 0 {
bp.Id = baremetalapi.DefaultBaremetalProfileId
}
bp.OemName = strings.ToLower(spec.OemName)
if len(spec.LanChannels) > 0 {
bp.LanChannel = spec.LanChannels[0]
}
if len(spec.LanChannels) > 1 {
bp.LanChannel2 = spec.LanChannels[1]
}
if len(spec.LanChannels) > 2 {
bp.LanChannel3 = spec.LanChannels[2]
}
bp.RootName = spec.RootName
bp.RootId = spec.RootId
bp.StrongPass = spec.StrongPass
bp.SetModelManager(bpm, &bp)
err := bpm.TableSpec().InsertOrUpdate(context.Background(), &bp)
if err != nil {
return errors.Wrapf(err, "insert default baremetal profile %s", jsonutils.Marshal(bp))
}
}
return nil
}
func (bpm *SBaremetalProfileManager) ValidateCreateData(
ctx context.Context,
userCred mcclient.TokenCredential,
ownerId mcclient.IIdentityProvider,
query jsonutils.JSONObject,
input baremetalapi.BaremetalProfileCreateInput,
) (baremetalapi.BaremetalProfileCreateInput, error) {
var err error
input.StandaloneAnonResourceCreateInput, err = bpm.SStandaloneAnonResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.StandaloneAnonResourceCreateInput)
if err != nil {
return input, errors.Wrap(err, "StandaloneAnonResourceBaseManager.ValidateCreateData")
}
input.OemName = strings.ToLower(strings.TrimSpace(input.OemName))
input.Model = strings.ToLower(strings.TrimSpace(input.Model))
// ensure uniquess
uniqQuery := bpm.fetchByOemNameAndModelQuery(input.OemName, input.Model, true)
cnt, err := uniqQuery.CountWithError()
if err != nil {
return input, errors.Wrap(err, "CountWithError")
}
if cnt > 0 {
return input, errors.Wrapf(httperrors.ErrConflict, "%s/%s already exists", input.OemName, input.Model)
}
if input.LanChannel == 0 {
return input, errors.Wrap(httperrors.ErrInputParameter, "lan_channel must be set")
}
if len(input.RootName) == 0 {
return input, errors.Wrap(httperrors.ErrInputParameter, "root_name must be set")
}
return input, nil
}
func (bpm *SBaremetalProfileManager) fetchByOemNameAndModelQuery(oemName, model string, exact bool) *sqlchemy.SQuery {
q := bpm.Query()
if exact {
q = q.Equals("oem_name", oemName)
} else {
q = q.Filter(sqlchemy.OR(
sqlchemy.IsEmpty(q.Field("oem_name")),
sqlchemy.Equals(q.Field("oem_name"), oemName),
))
}
if exact {
q = q.Equals("model", model)
} else {
q = q.Filter(sqlchemy.OR(
sqlchemy.IsEmpty(q.Field("model")),
sqlchemy.Equals(q.Field("model"), model),
))
}
return q
}
func (bp *SBaremetalProfile) ValidateUpdateData(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
input baremetalapi.BaremetalProfileUpdateInput,
) (baremetalapi.BaremetalProfileUpdateInput, error) {
var err error
input.StandaloneAnonResourceBaseUpdateInput, err = bp.SStandaloneAnonResourceBase.ValidateUpdateData(ctx, userCred, query, input.StandaloneAnonResourceBaseUpdateInput)
if err != nil {
return input, errors.Wrap(err, "SStandaloneAnonResourceBase.ValidateUpdateData")
}
return input, nil
}
+3
View File
@@ -22,6 +22,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/proxy"
"yunion.io/x/onecloud/pkg/compute/models/baremetal"
)
func InitDB() error {
@@ -78,6 +79,8 @@ func InitDB() error {
GroupnetworkManager,
ElasticcacheManager,
baremetal.BaremetalProfileManager,
} {
now := time.Now()
err := manager.InitializeData()
+3
View File
@@ -25,6 +25,7 @@ import (
"yunion.io/x/onecloud/pkg/compute/capabilities"
"yunion.io/x/onecloud/pkg/compute/misc"
"yunion.io/x/onecloud/pkg/compute/models"
baremetalmodels "yunion.io/x/onecloud/pkg/compute/models/baremetal"
"yunion.io/x/onecloud/pkg/compute/options"
"yunion.io/x/onecloud/pkg/compute/specs"
"yunion.io/x/onecloud/pkg/compute/sshkeys"
@@ -243,6 +244,8 @@ func InitHandlers(app *appsrv.Application) {
models.MiscResourceManager,
models.SSLCertificateManager,
baremetalmodels.BaremetalProfileManager,
} {
db.RegisterModelManager(manager)
handler := db.NewModelHandler(manager)
+2 -1
View File
@@ -15,6 +15,7 @@
package hostdhcp
import (
"context"
"fmt"
"net"
"strconv"
@@ -83,7 +84,7 @@ func (r *SDHCPRelay) Setup(addr string) error {
return nil
}
func (r *SDHCPRelay) ServeDHCP(pkt dhcp.Packet, addr *net.UDPAddr, intf *net.Interface) (dhcp.Packet, []string, error) {
func (r *SDHCPRelay) ServeDHCP(ctx context.Context, pkt dhcp.Packet, addr *net.UDPAddr, intf *net.Interface) (dhcp.Packet, []string, error) {
pkg, err := r.serveDHCPInternal(pkt, addr, intf)
return pkg, nil, err
}
+2 -1
View File
@@ -15,6 +15,7 @@
package hostdhcp
import (
"context"
"fmt"
"net"
"strings"
@@ -237,7 +238,7 @@ func (s *SGuestDHCPServer) IsDhcpPacket(pkt dhcp.Packet) bool {
return pkt != nil && (pkt.Type() == dhcp.Request || pkt.Type() == dhcp.Discover)
}
func (s *SGuestDHCPServer) ServeDHCP(pkt dhcp.Packet, addr *net.UDPAddr, intf *net.Interface) (dhcp.Packet, []string, error) {
func (s *SGuestDHCPServer) ServeDHCP(ctx context.Context, pkt dhcp.Packet, addr *net.UDPAddr, intf *net.Interface) (dhcp.Packet, []string, error) {
pkg, err := s.serveDHCPInternal(pkt, addr, intf)
return pkg, nil, err
}
@@ -0,0 +1,15 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package baremetal // import "yunion.io/x/onecloud/pkg/mcclient/modules/compute/baremetal"
@@ -0,0 +1,78 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package baremetal
import (
"sort"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
baremetalapi "yunion.io/x/onecloud/pkg/apis/compute/baremetal"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
"yunion.io/x/onecloud/pkg/mcclient/modules"
baremetaloptions "yunion.io/x/onecloud/pkg/mcclient/options/compute/baremetal"
)
type BaremetalProfileManager struct {
modulebase.ResourceManager
}
func (m *BaremetalProfileManager) GetMatchProfiles(s *mcclient.ClientSession, oemName string, model string) ([]baremetalapi.BaremetalProfileSpec, error) {
params := baremetaloptions.BaremetalProfileListOptions{}
limit := 0
params.Limit = &limit
params.OemName = []string{"", oemName}
if len(model) > 0 {
params.Model = []string{"", model}
}
results, err := m.List(s, jsonutils.Marshal(params))
if err != nil {
return nil, errors.Wrap(err, "List")
}
ret := make([]baremetalapi.BaremetalProfileSpec, 0)
for i := range results.Data {
details := baremetalapi.BaremetalProfileDetails{}
err := results.Data[i].Unmarshal(&details)
if err != nil {
return nil, errors.Wrap(err, "Unmarshal")
}
ret = append(ret, details.ToSpec())
}
sort.Sort(baremetalapi.BaremetalProfileSpecs(ret))
return ret, nil
}
var (
BaremetalProfiles BaremetalProfileManager
)
func init() {
BaremetalProfiles = BaremetalProfileManager{modules.NewComputeManager("baremetal_profile", "baremetal_profiles",
[]string{
"oem_name",
"model",
"lan_channel",
"root_id",
"root_name",
"string_pass",
},
[]string{},
)}
modules.RegisterCompute(&BaremetalProfiles)
}
@@ -0,0 +1,15 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package baremetal // import "yunion.io/x/onecloud/pkg/mcclient/options/compute/baremetal"
@@ -0,0 +1,36 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package baremetal
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
type BaremetalProfileListOptions struct {
options.BaseListOptions
OemName []string
Model []string
}
func (opts *BaremetalProfileListOptions) Params() (jsonutils.JSONObject, error) {
return options.ListStructToParams(opts)
}
type BaremetalProfileIdOptions struct {
options.BaseIdOptions
}
+4 -2
View File
@@ -15,6 +15,7 @@
package dhcp
import (
"context"
"fmt"
"net"
"runtime/debug"
@@ -88,7 +89,7 @@ func NewDHCPServer2(iface string, dhcpServerPort, dhcpRelayPort uint16) (*DHCPSe
}
type DHCPHandler interface {
ServeDHCP(pkt Packet, addr *net.UDPAddr, intf *net.Interface) (Packet, []string, error)
ServeDHCP(ctx context.Context, pkt Packet, addr *net.UDPAddr, intf *net.Interface) (Packet, []string, error)
}
func (s *DHCPServer) ListenAndServe(handler DHCPHandler) error {
@@ -101,6 +102,7 @@ func (s *DHCPServer) GetConn() *Conn {
}
func (s *DHCPServer) serveDHCP(handler DHCPHandler) error {
ctx := context.WithValue(context.Background(), "dhcp_server", s)
for {
pkt, addr, mac, intf, err := s.conn.RecvDHCP()
if err != nil {
@@ -119,7 +121,7 @@ func (s *DHCPServer) serveDHCP(handler DHCPHandler) error {
}
}()
resp, targets, err := handler.ServeDHCP(pkt, addr, intf)
resp, targets, err := handler.ServeDHCP(ctx, pkt, addr, intf)
if err != nil {
log.Warningf("[DHCP] handler serve error: %v", err)
return
+1 -1
View File
@@ -23,7 +23,7 @@ import (
func init() {
type LanOptions struct {
CHANNEL int `help:"lan channel"`
CHANNEL uint8 `help:"lan channel"`
}
shellutils.R(&LanOptions{}, "set-lan-dhcp", "Set lan channel DHCP", func(client ipmitool.IPMIExecutor, args *LanOptions) error {
return ipmitool.SetLanDHCP(client, args.CHANNEL)
+1
View File
@@ -131,6 +131,7 @@ class ModelAPI(FuncDispatcher):
run_swagger_gen(['yunion.io/x/cloudmux/pkg/cloudprovider'], 'yunion.io/x/onecloud/pkg/apis/cloudprovider')
self.run(pkg=["keystone", "models"], out=["identity"])
self.run_model("compute")
self.run(pkg=["compute", "models", "baremetal"], out=["compute", "baremetal"])
self.run_model("image")
self.run_model("cloudid")
self.run_model("notify")