baremetal register optimize

This commit is contained in:
wanyaoqi
2019-11-13 19:42:42 +08:00
parent 4f97130c95
commit 428f70ebfc
5 changed files with 94 additions and 43 deletions
+1 -1
View File
@@ -54,7 +54,7 @@ func AddHandler2(app *appsrv.Application, method string, prefix string,
func customizeHandlerInfo(info *appsrv.SHandlerInfo) {
if info.GetName(nil) == "baremetal-register" {
info.SetProcessTimeout(time.Second * 180).SetWorkerManager(registerWorkMan)
info.SetProcessTimeout(time.Second * 300).SetWorkerManager(registerWorkMan)
}
}
+1 -7
View File
@@ -176,13 +176,8 @@ func bmRegisterMiddleware(h bmRegisterFunc) appsrv.FilterHandler {
newCtx.ResponseError(httperrors.NewMissingParameterError("password"))
return
}
ipAddr, err := newCtx.Data().GetString("ip_addr")
if err != nil {
newCtx.ResponseError(httperrors.NewMissingParameterError("ip_addr"))
return
}
ctx, cancel := context.WithTimeout(ctx, time.Second*175)
ctx, cancel := context.WithTimeout(ctx, time.Second*298)
defer cancel()
data := &baremetal.BmRegisterInput{
@@ -196,7 +191,6 @@ func bmRegisterMiddleware(h bmRegisterFunc) appsrv.FilterHandler {
RemoteIp: remoteIp,
Username: username,
Password: password,
IpAddr: ipAddr,
}
h(newCtx, data)
+37 -15
View File
@@ -40,7 +40,6 @@ import (
"yunion.io/x/pkg/utils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/appsrv"
o "yunion.io/x/onecloud/pkg/baremetal/options"
"yunion.io/x/onecloud/pkg/baremetal/profiles"
"yunion.io/x/onecloud/pkg/baremetal/pxe"
@@ -265,10 +264,8 @@ type BmRegisterInput struct {
IpAddr string
}
func (i *BmRegisterInput) responseOk() {
obj := jsonutils.NewDict()
obj.Add(jsonutils.NewString("ok"), "result")
appsrv.SendJSON(i.W, obj)
func (i *BmRegisterInput) responseSucc(bmId string) {
fmt.Fprintf(i.W, bmId)
close(i.C)
}
@@ -295,6 +292,25 @@ func (m *SBaremetalManager) RegisterBaremetal(ctx context.Context, input *BmRegi
input.responseErr(httperrors.NewBadRequestError("Verify network failed: %s", err))
return
}
sshCli, err := m.checkSshInfo(input)
if input.isTimeout() {
return
} else if err != nil {
input.responseErr(httperrors.NewBadRequestError("SSH verify failed: %s", err))
return
}
input.IpAddr, err = m.fetchIpmiIp(sshCli)
if input.isTimeout() {
return
} else if err != nil {
input.responseErr(httperrors.NewBadRequestError("Fetch ipmi address failed: %s", err))
return
}
log.Infof("Find ipmi address %s", input.IpAddr)
ipmiWire, err := m.checkNetworkFromIp(input.IpAddr)
if input.isTimeout() {
return
@@ -311,14 +327,6 @@ func (m *SBaremetalManager) RegisterBaremetal(ctx context.Context, input *BmRegi
return
}
sshCli, err := m.checkSshInfo(input)
if input.isTimeout() {
return
} else if err != nil {
input.responseErr(httperrors.NewBadRequestError("SSH verify failed: %s", err))
return
}
err = m.verifyMacAddr(sshCli)
if input.isTimeout() {
return
@@ -332,7 +340,7 @@ func (m *SBaremetalManager) RegisterBaremetal(ctx context.Context, input *BmRegi
input.Username, input.Password, input.IpAddr,
ipmiMac, ipmiLanChannel, adminWire, ipmiWire,
)
err = registerTask.CreateBaremetal()
bmId, err := registerTask.CreateBaremetal()
if input.isTimeout() {
return
} else if err != nil {
@@ -340,10 +348,24 @@ func (m *SBaremetalManager) RegisterBaremetal(ctx context.Context, input *BmRegi
return
}
input.responseOk()
input.responseSucc(bmId)
registerTask.DoPrepare(ctx, sshCli)
}
func (m *SBaremetalManager) fetchIpmiIp(sshCli *ssh.Client) (string, error) {
res, err := sshCli.RawRun(`/usr/bin/ipmitool lan print | grep "IP Address "`)
if err != nil {
return "", err
}
if len(res) == 1 {
segs := strings.Fields(res[0])
if len(segs) == 4 {
return strings.TrimSpace(segs[3]), nil
}
}
return "", fmt.Errorf("Failed to find ipmi ip address")
}
func (m *SBaremetalManager) checkNetworkFromIp(ip string) (string, error) {
params := jsonutils.NewDict()
params.Set("ip", jsonutils.NewString(ip))
+50 -15
View File
@@ -73,24 +73,57 @@ func NewBaremetalRegisterTask(bmManager IBmManager, sshCli *ssh.Client,
}
}
func (s *sBaremetalRegisterTask) CreateBaremetal() error {
func (s *sBaremetalRegisterTask) getAccessDevMacAddr(ip string) (string, error) {
nicsRet, err := s.SshCli.Run("/sbin/ip -o -4 addr show")
if err != nil {
return "", fmt.Errorf("Failed get access nic %s", err)
}
var dev string
for i := 0; i < len(nicsRet); i++ {
if strings.Contains(nicsRet[i], ip+"/") {
segs := strings.Split(nicsRet[i], " ")
if len(segs) > 1 {
dev = segs[1]
break
}
}
}
if len(dev) == 0 {
return "", fmt.Errorf("Can't get access dev")
}
log.Infof("Access dev is %s", dev)
macRet, err := s.SshCli.Run("/sbin/ip a show " + dev)
if err != nil || len(macRet) < 2 {
return "", fmt.Errorf("Failed get access nic mac address %s", err)
}
segs := strings.Fields(macRet[1])
if len(segs) < 2 {
return "", fmt.Errorf("Failed to find mac address")
}
return segs[1], nil
}
func (s *sBaremetalRegisterTask) CreateBaremetal() (string, error) {
zoneId := s.BmManager.GetZoneId()
ret, err := s.SshCli.Run("/lib/mos/lsnic")
if err != nil {
return fmt.Errorf("Register baremeatl failed on lsnic: %s", err)
return "", fmt.Errorf("Register baremeatl failed on lsnic: %s", err)
}
accessMac, err := s.getAccessDevMacAddr(s.RemoteIp)
if err != nil {
return "", err
}
accessMacAddr, err := net.ParseMAC(accessMac)
if err != nil {
return "", fmt.Errorf("Failed parse access mac %s", accessMac)
}
nicinfo := sysutils.ParseNicInfo(ret)
for _, nic := range nicinfo {
ret, err := s.SshCli.RawRun("/sbin/ip a show " + nic.Dev)
if err != nil {
return fmt.Errorf("Register baremeatl failed on ip command: %s", err)
}
if strings.Index(ret[0], s.RemoteIp) >= 0 {
if nic.Mac.String() == accessMacAddr.String() {
s.accessNic = nic
break
} else {
continue
}
}
if s.accessNic == nil {
@@ -105,21 +138,22 @@ func (s *sBaremetalRegisterTask) CreateBaremetal() error {
params.Set("is_import", jsonutils.JSONTrue)
res, err := modules.Hosts.CreateInContext(s.BmManager.GetClientSession(), params, &modules.Zones, zoneId)
if err != nil {
return fmt.Errorf("Create baremetal failed: %s", err)
return "", fmt.Errorf("Create baremetal failed: %s", err)
}
pxeBm, err := s.BmManager.AddBaremetal(res)
if err != nil {
return fmt.Errorf("BmManager add baremetal failed: %s", err)
return "", fmt.Errorf("BmManager add baremetal failed: %s", err)
}
err = pxeBm.InitAdminNetif(
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)
return "", fmt.Errorf("BmManager add admin netif failed: %s", err)
}
err = pxeBm.InitAdminNetif(
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)
return "", fmt.Errorf("BmManager add ipmi netif failed: %s", err)
}
for _, nic := range nicinfo {
if nic.Dev != s.accessNic.Dev {
@@ -127,7 +161,8 @@ func (s *sBaremetalRegisterTask) CreateBaremetal() error {
}
}
s.baremetal = pxeBm.(IBaremetal)
return nil
bmInstanceId, _ := res.GetString("id")
return bmInstanceId, nil
}
func (s *sBaremetalRegisterTask) update() {
+5 -5
View File
@@ -17,6 +17,7 @@ package misc
import (
"context"
"fmt"
"net"
"net/http"
"yunion.io/x/log"
@@ -43,18 +44,17 @@ func addHandler(method, prefix string, f appsrv.FilterHandler, app *appsrv.Appli
}
func getBmAgentUrl(ctx context.Context, w http.ResponseWriter, r *http.Request) {
_, query, _ := appsrv.FetchEnv(ctx, w, r)
ipAddr, err := query.GetString("ip")
ipAddr, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
httperrors.MissingParameterError(w, "ip")
httperrors.NewInternalServerError("Parse remote ip error %s", err)
return
}
n, _ := models.NetworkManager.GetOnPremiseNetworkOfIP(
ipAddr, compute.NETWORK_TYPE_IPMI, tristate.None)
ipAddr, compute.NETWORK_TYPE_BAREMETAL, tristate.None)
if n == nil {
n, _ = models.NetworkManager.GetOnPremiseNetworkOfIP(
ipAddr, compute.NETWORK_TYPE_BAREMETAL, tristate.None)
ipAddr, compute.NETWORK_TYPE_IPMI, tristate.None)
}
if n == nil {
httperrors.NotFoundError(w, "Network not found")