diff --git a/pkg/baremetal/manager.go b/pkg/baremetal/manager.go index 1d8ddd3148..14d3625a66 100644 --- a/pkg/baremetal/manager.go +++ b/pkg/baremetal/manager.go @@ -331,7 +331,7 @@ func (m *SBaremetalManager) RegisterBaremetal(ctx context.Context, input *BmRegi return } - err = m.verifyMacAddr(sshCli) + err, registered := m.verifyMacAddr(sshCli) if input.isTimeout() { return } else if err != nil { @@ -344,16 +344,19 @@ func (m *SBaremetalManager) RegisterBaremetal(ctx context.Context, input *BmRegi input.Username, input.Password, input.IpAddr, ipmiMac, ipmiLanChannel, adminWire, ipmiWire, ) - bmId, err := registerTask.CreateBaremetal() - if input.isTimeout() { - return - } else if err != nil { + var bmId string + if !registered { + bmId, err = registerTask.CreateBaremetal() + } else { + bmId, err = registerTask.UpdateBaremetal() + } + if err != nil { input.responseErr(httperrors.NewInternalServerError(err.Error())) return } input.responseSucc(bmId) - registerTask.DoPrepare(ctx, sshCli) + registerTask.DoPrepare(ctx, sshCli, registered) } func (m *SBaremetalManager) fetchIpmiIp(sshCli *ssh.Client) (string, error) { @@ -384,31 +387,31 @@ func (m *SBaremetalManager) checkNetworkFromIp(ip string) (string, error) { return res.Data[0].GetString("wire_id") } -func (m *SBaremetalManager) verifyMacAddr(sshCli *ssh.Client) error { +func (m *SBaremetalManager) verifyMacAddr(sshCli *ssh.Client) (error, bool) { output, err := sshCli.Run("/lib/mos/lsnic") if err != nil { - return err + return err, false } nicinfo := sysutils.ParseNicInfo(output) if len(nicinfo) == 0 { - return fmt.Errorf("Can't get nic info") + return fmt.Errorf("Can't get nic info"), false } + var registered bool params := jsonutils.NewDict() for _, nic := range nicinfo { - if nic.Up && len(nic.Mac) > 0 { + if len(nic.Mac) > 0 { params.Set("any_mac", jsonutils.NewString(nic.Mac.String())) + res, err := modules.Hosts.List(m.GetClientSession(), params) + if err != nil { + return fmt.Errorf("Get hosts info failed: %s", err), false + } + if len(res.Data) > 0 { + registered = true + } } } - res, err := modules.Hosts.List(m.GetClientSession(), params) - if err != nil { - return fmt.Errorf("Get hosts info failed: %s", err) - } - if len(res.Data) > 0 { - return fmt.Errorf("Address has been registerd: %s", params.String()) - } else { - return nil - } + return nil, registered } func (m *SBaremetalManager) checkSshInfo(input *BmRegisterInput) (*ssh.Client, error) { diff --git a/pkg/baremetal/tasks/bm_register.go b/pkg/baremetal/tasks/bm_register.go index 21ad7e86c1..20c093643a 100644 --- a/pkg/baremetal/tasks/bm_register.go +++ b/pkg/baremetal/tasks/bm_register.go @@ -165,8 +165,32 @@ func (s *sBaremetalRegisterTask) CreateBaremetal() (string, error) { return bmInstanceId, nil } -func (s *sBaremetalRegisterTask) update() { +func (s *sBaremetalRegisterTask) UpdateBaremetal() (string, error) { + 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) + } + params := jsonutils.NewDict() + params.Set("any_mac", jsonutils.NewString(accessMacAddr.String())) + res, err := modules.Hosts.List(s.BmManager.GetClientSession(), params) + if err != nil { + return "", fmt.Errorf("Fetch baremetal failed %s", err) + } + if len(res.Data) == 0 { + return "", fmt.Errorf("Cann't find baremetal by access mac %s", accessMacAddr) + } + pxeBm, err := s.BmManager.AddBaremetal(res.Data[0]) + if err != nil { + return "", fmt.Errorf("BmManager add baremetal failed: %s", err) + } + + s.baremetal = pxeBm.(IBaremetal) + return s.baremetal.GetId(), nil } func (s *sBaremetalRegisterTask) doRedfishProbe(ctx context.Context) (redfishSupport bool, cdromBoot bool) { @@ -179,7 +203,7 @@ func (s *sBaremetalRegisterTask) doRedfishProbe(ctx context.Context) (redfishSup return } -func (s *sBaremetalRegisterTask) DoPrepare(ctx context.Context, cli *ssh.Client) error { +func (s *sBaremetalRegisterTask) DoPrepare(ctx context.Context, cli *ssh.Client, registered bool) error { infos, err := s.prepareBaremetalInfo(cli) if err != nil { return err @@ -198,7 +222,7 @@ func (s *sBaremetalRegisterTask) DoPrepare(ctx context.Context, cli *ssh.Client) s.updateIpmiInfo(cli) - return s.updateBmInfo(cli, infos) + return s.updateBmInfo(cli, infos, registered) } func (s *sBaremetalRegisterTask) updateIpmiInfo(cli *ssh.Client) { @@ -233,7 +257,7 @@ func (s *sBaremetalRegisterTask) updateIpmiInfo(cli *ssh.Client) { s.sendNicInfo(nic, -1, api.NIC_TYPE_IPMI, false, "", false) } -func (s *sBaremetalRegisterTask) updateBmInfo(cli *ssh.Client, i *baremetalPrepareInfo) error { +func (s *sBaremetalRegisterTask) updateBmInfo(cli *ssh.Client, i *baremetalPrepareInfo, registered bool) error { updateInfo := make(map[string]interface{}) updateInfo["access_ip"] = s.RemoteIp updateInfo["cpu_count"] = i.cpuInfo.Count @@ -264,6 +288,13 @@ func (s *sBaremetalRegisterTask) updateBmInfo(cli *ssh.Client, i *baremetalPrepa log.Errorf("Send nicinfo idx: %d, %#v error: %v", idx, i.nicsInfo[idx], err) } } + if registered { + return nil + } + return s.initBaremetalServer() +} + +func (s *sBaremetalRegisterTask) initBaremetalServer() error { if err := s.baremetal.InitializeServer(s.Hostname); err != nil { return fmt.Errorf("Baremteal Create Server Failed %s", err) }