diff --git a/pkg/baremetal/agent.go b/pkg/baremetal/agent.go index 83df8476b5..e15abb5575 100644 --- a/pkg/baremetal/agent.go +++ b/pkg/baremetal/agent.go @@ -94,6 +94,12 @@ func (agent *SBaremetalAgent) GetDHCPServerListenIP() (net.IP, error) { } func (agent *SBaremetalAgent) GetAccessIP() (net.IP, error) { + if o.Options.AccessAddress != "" && o.Options.AccessAddress != "0.0.0.0" { + return net.ParseIP(o.Options.AccessAddress), nil + } + if o.Options.Address != "" && o.Options.Address != "0.0.0.0" { + return net.ParseIP(o.Options.Address), nil + } return agent.FindAccessIP(o.Options.AccessAddress) } diff --git a/pkg/baremetal/manager.go b/pkg/baremetal/manager.go index 6d3c5ad949..240dd836af 100644 --- a/pkg/baremetal/manager.go +++ b/pkg/baremetal/manager.go @@ -20,6 +20,7 @@ import ( "io/ioutil" "net" "net/http" + "net/url" "os" "path/filepath" "reflect" @@ -917,7 +918,7 @@ func (b *SBaremetalInstance) getDHCPConfig( } func (b *SBaremetalInstance) GetNotifyUrl() string { - return fmt.Sprintf("%s/baremetals/%s/notify", b.manager.Agent.GetManagerUri(), b.GetId()) + return fmt.Sprintf("%s/baremetals/%s/notify", b.manager.Agent.GetListenUri(), b.GetId()) } func (b *SBaremetalInstance) getTftpFileUrl(filename string) string { @@ -1534,15 +1535,30 @@ func (s *SBaremetalServer) DoEraseDisk(term *ssh.Client) error { return err } +func replaceHostAddr(urlStr string, addr string) string { + urlComp, _ := url.Parse(urlStr) + commaPos := strings.IndexByte(urlComp.Host, ':') + if commaPos >= 0 { + urlComp.Host = addr + urlComp.Host[commaPos:] + } else { + urlComp.Host = addr + } + return urlComp.String() +} + func (s *SBaremetalServer) doCreateRoot(term *ssh.Client, devName string) error { session := s.baremetal.GetClientSession() token := session.GetToken().GetTokenString() - url, err := session.GetServiceURL("image", "internalURL") + urlStr, err := session.GetServiceURL("image", "internalURL") if err != nil { return err } + // this is hackish, url should point to an image proxy + // XXX + listenIp, _ := s.baremetal.manager.Agent.GetListenIP() + urlStr = replaceHostAddr(urlStr, listenIp.String()) imageId := s.GetRootTemplateId() - cmd := fmt.Sprintf("/lib/mos/rootcreate.sh %s %s %s %s", token, url, imageId, devName) + cmd := fmt.Sprintf("/lib/mos/rootcreate.sh %s %s %s %s", token, urlStr, imageId, devName) log.Infof("rootcreate cmd: %q", cmd) if _, err := term.Run(cmd); err != nil { return fmt.Errorf("Root create fail: %v", err) diff --git a/pkg/baremetal/manager_test.go b/pkg/baremetal/manager_test.go new file mode 100644 index 0000000000..5b1360885a --- /dev/null +++ b/pkg/baremetal/manager_test.go @@ -0,0 +1,30 @@ +package baremetal + +import ( + "testing" +) + +func TestReplaceHostAddr(t *testing.T) { + cases := []struct { + In string + Addr string + Want string + }{ + { + In: "https://www.sina.com.cn", + Addr: "118.187.65.237", + Want: "https://118.187.65.237", + }, + { + In: "https://192.168.223.22:9292/v1/images", + Addr: "10.168.24.23", + Want: "https://10.168.24.23:9292/v1/images", + }, + } + for _, c := range cases { + got := replaceHostAddr(c.In, c.Addr) + if got != c.Want { + t.Errorf("In: %s Addr: %s Got: %s Want: %s", c.In, c.Addr, got, c.Want) + } + } +} diff --git a/pkg/baremetal/utils/raid/hpssactl/hpssactl.go b/pkg/baremetal/utils/raid/hpssactl/hpssactl.go index 6bbddc9fe3..88887d2f38 100644 --- a/pkg/baremetal/utils/raid/hpssactl/hpssactl.go +++ b/pkg/baremetal/utils/raid/hpssactl/hpssactl.go @@ -207,10 +207,11 @@ func (adapter *HPSARaidAdaptor) conf2Params(conf *api.BaremetalDiskConfig) []str func (adapter *HPSARaidAdaptor) getLastArray() (string, error) { cmd := GetCommand("controller", fmt.Sprintf("slot=%d", adapter.index), "logicaldrive", "all", "show") - ret, err := adapter.raid.term.Run(cmd) - if err != nil { - return "", err - } + ret, _ := adapter.raid.term.Run(cmd) + // ignore errors + // if err != nil { + // return "", err + // } var lastArray string for _, line := range ret { m := regutils2.SubGroupMatch(`array\s+(?P\w+)`, line) @@ -299,10 +300,11 @@ func (adapter *HPSARaidAdaptor) removeLogicVolume(idx int) error { func (adapter *HPSARaidAdaptor) GetLogicVolumes() ([]*raid.RaidLogicalVolume, error) { cmd := GetCommand("controller", fmt.Sprintf("slot=%d", adapter.index), "logicaldrive", "all", "show") - ret, err := adapter.raid.term.Run(cmd) - if err != nil { - return nil, err - } + ret, _ := adapter.raid.term.Run(cmd) + // ignore error + // if err != nil { + // return nil, err + // } return adapter.parseLogicalVolumes(ret) } diff --git a/pkg/cloudcommon/agent/agent.go b/pkg/cloudcommon/agent/agent.go index 0f083f9380..612b37c847 100644 --- a/pkg/cloudcommon/agent/agent.go +++ b/pkg/cloudcommon/agent/agent.go @@ -287,6 +287,15 @@ func (agent *SBaseAgent) GetManagerUri() string { return fmt.Sprintf("%s://%s:%d", proto, accessIP, agent.IAgent().GetPort()) } +func (agent *SBaseAgent) GetListenUri() string { + listenIP, _ := agent.IAgent().GetListenIP() + proto := "http" + if agent.IAgent().GetEnableSsl() { + proto = "https" + } + return fmt.Sprintf("%s://%s:%d", proto, listenIP, agent.IAgent().GetPort()) +} + func (agent *SBaseAgent) getCreateUpdateInfo() (jsonutils.JSONObject, error) { accessIP, err := agent.IAgent().GetAccessIP() if err != nil { diff --git a/pkg/compute/models/hosts.go b/pkg/compute/models/hosts.go index 887c62a2a2..172196bdba 100644 --- a/pkg/compute/models/hosts.go +++ b/pkg/compute/models/hosts.go @@ -27,6 +27,7 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/log" + "yunion.io/x/pkg/errors" "yunion.io/x/pkg/tristate" "yunion.io/x/pkg/util/compare" "yunion.io/x/pkg/util/fileutils" @@ -3129,6 +3130,10 @@ func (self *SHost) addNetif(ctx context.Context, userCred mcclient.TokenCredenti } netif, err := NetInterfaceManager.FetchByMac(mac) if err != nil { + if err != sql.ErrNoRows { + return httperrors.NewInternalServerError("fail to fetch netif by mac %s: %s", mac, err) + } + // else not found netif = &SNetInterface{} netif.Mac = mac netif.BaremetalId = self.Id @@ -3177,7 +3182,7 @@ func (self *SHost) addNetif(ctx context.Context, userCred mcclient.TokenCredenti return nil }) if err != nil { - return err + return errors.Wrap(err, "db.Update") } if changed || reset { self.DisableNetif(ctx, userCred, netif, false) @@ -3193,8 +3198,11 @@ func (self *SHost) addNetif(ctx context.Context, userCred mcclient.TokenCredenti bridge = fmt.Sprintf("br%s", sw.GetName()) } var isMaster = netif.NicType == api.NIC_TYPE_ADMIN - hw, err := HostwireManager.FetchByIdsAndMac(self.Id, sw.Id, mac) + hw, err := HostwireManager.FetchByHostIdAndMac(self.Id, mac) if err != nil { + if err != sql.ErrNoRows { + return httperrors.NewInternalServerError("fail to fetch hostwire by mac %s: %s", mac, err) + } hw = &SHostwire{} hw.Bridge = bridge hw.Interface = strInterface @@ -3211,6 +3219,7 @@ func (self *SHost) addNetif(ctx context.Context, userCred mcclient.TokenCredenti hw.Bridge = bridge hw.Interface = strInterface // hw.MacAddr = mac + hw.WireId = sw.Id hw.IsMaster = isMaster return nil }) @@ -3278,8 +3287,11 @@ func (self *SHost) EnableNetif(ctx context.Context, userCred mcclient.TokenCrede if wire == nil { return fmt.Errorf("No wire attached") } - hw, err := HostwireManager.FetchByIdsAndMac(self.Id, wire.Id, netif.Mac) - if hw == nil { + hw, err := HostwireManager.FetchByHostIdAndMac(self.Id, netif.Mac) + if err != nil { + return err + } + if hw.WireId != wire.Id { return fmt.Errorf("host not attach to this wire") } if net == nil { @@ -3404,7 +3416,7 @@ func (self *SHost) RemoveNetif(ctx context.Context, userCred mcclient.TokenCrede log.Infof("Remove wire") others := self.GetNetifsOnWire(wire) if len(others) == 0 { - hw, _ := HostwireManager.FetchByIdsAndMac(self.Id, wire.Id, netif.Mac) + hw, _ := HostwireManager.FetchByHostIdAndMac(self.Id, netif.Mac) if hw != nil { db.OpsLog.LogDetachEvent(ctx, self, wire, userCred, jsonutils.NewString(fmt.Sprintf("disable netif %s", self.AccessMac))) log.Infof("Detach host wire because of remove netif %s", netif.Mac) diff --git a/pkg/compute/models/hostwires.go b/pkg/compute/models/hostwires.go index 11a393e5f7..993e5496f0 100644 --- a/pkg/compute/models/hostwires.go +++ b/pkg/compute/models/hostwires.go @@ -156,12 +156,15 @@ func (manager *SHostwireManager) FilterByParams(q *sqlchemy.SQuery, params jsonu return q } -func (manager *SHostwireManager) FetchByIdsAndMac(hostId string, wireId string, mac string) (*SHostwire, error) { - query := jsonutils.NewDict() - query.Add(jsonutils.NewString(mac), "mac_addr") - ihw, err := db.FetchJointByIds(manager, hostId, wireId, query) +func (manager *SHostwireManager) FetchByHostIdAndMac(hostId string, mac string) (*SHostwire, error) { + hw, err := db.NewModelObject(manager) if err != nil { return nil, err } - return ihw.(*SHostwire), nil + q := manager.Query().Equals("host_id", hostId).Equals("mac_addr", mac) + err = q.First(hw) + if err != nil { + return nil, err + } + return hw.(*SHostwire), nil } diff --git a/pkg/compute/models/netinterfaces.go b/pkg/compute/models/netinterfaces.go index 5ba880856f..35c3a90b9b 100644 --- a/pkg/compute/models/netinterfaces.go +++ b/pkg/compute/models/netinterfaces.go @@ -17,6 +17,7 @@ package models import ( "context" "database/sql" + "fmt" "yunion.io/x/jsonutils" "yunion.io/x/log" @@ -235,16 +236,17 @@ func (self *SNetInterface) Remove(ctx context.Context, userCred mcclient.TokenCr host := self.GetBaremetal() wire := self.GetWire() if host != nil && wire != nil { - hw, err := HostwireManager.FetchByIdsAndMac(host.Id, wire.Id, self.Mac) + hw, err := HostwireManager.FetchByHostIdAndMac(host.Id, self.Mac) if err != nil { log.Errorf("NetInterface remove HostwireManager.FetchByIds error %s", err) return err } - if hw != nil { - err := hw.Delete(ctx, userCred) - if err != nil { - return err - } + if hw.WireId != wire.Id { + return fmt.Errorf("NetInterface not attached to this wire???") + } + err = hw.Delete(ctx, userCred) + if err != nil { + return err } } _, err := db.Update(self, func() error {