Merge pull request #1207 in YUNIONIO/onecloud from ~QIUJIAN/onecloud:feature/qj-nic-bongding-support-region to release/2.6.0

* commit '2552c658c47f58fcee7e563471da6811a815ac97':
  fix: recode host.getWiresOfId
  Make minimal sysdisk size to 10G
  feature: nic bonding/teaming support on region
This commit is contained in:
邱剑
2019-03-11 14:54:00 +08:00
18 changed files with 431 additions and 154 deletions
+2 -1
View File
@@ -8,12 +8,13 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/utils"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/billing"
"yunion.io/x/pkg/utils"
)
type SAwsGuestDriver struct {
+51 -10
View File
@@ -104,22 +104,41 @@ func (self *SBaremetalGuestDriver) ValidateResizeDisk(guest *models.SGuest, disk
return httperrors.NewUnsupportOperationError("Cannot resize disk for baremtal")
}
func (self *SBaremetalGuestDriver) GetNamedNetworkConfiguration(guest *models.SGuest, userCred mcclient.TokenCredential, host *models.SHost, netConfig *models.SNetworkConfig) (*models.SNetwork, string, int8, models.IPAddlocationDirection) {
netif, net := host.GetNetinterfaceWithIdAndCredential(netConfig.Network, userCred, netConfig.Reserved)
if netif != nil {
return net, netif.Mac, netif.Index, models.IPAllocationStepup
func (self *SBaremetalGuestDriver) GetNamedNetworkConfiguration(guest *models.SGuest, userCred mcclient.TokenCredential, host *models.SHost, netConfig *models.SNetworkConfig) (*models.SNetwork, []models.SNicConfig, models.IPAddlocationDirection) {
netifs, net := host.GetNetinterfacesWithIdAndCredential(netConfig.Network, userCred, netConfig.Reserved)
if netifs != nil {
nicCnt := 1
if netConfig.RequireTeaming || netConfig.TryTeaming {
nicCnt = 2
}
if len(netifs) < nicCnt {
if netConfig.RequireTeaming {
return net, nil, ""
}
nicCnt = len(netifs)
}
nicConfs := make([]models.SNicConfig, 0)
for i := 0; i < nicCnt; i += 1 {
nicConf := models.SNicConfig{
Mac: netifs[i].Mac,
Index: netifs[i].Index,
Ifname: "",
}
nicConfs = append(nicConfs, nicConf)
}
return net, nicConfs, models.IPAllocationStepup
}
return net, "", -1, ""
return net, nil, ""
}
func (self *SBaremetalGuestDriver) GetRandomNetworkTypes() []string {
return []string{models.NETWORK_TYPE_BAREMETAL, models.NETWORK_TYPE_GUEST}
}
func (self *SBaremetalGuestDriver) Attach2RandomNetwork(guest *models.SGuest, ctx context.Context, userCred mcclient.TokenCredential, host *models.SHost, netConfig *models.SNetworkConfig, pendingUsage quotas.IQuota) (*models.SGuestnetwork, error) {
func (self *SBaremetalGuestDriver) Attach2RandomNetwork(guest *models.SGuest, ctx context.Context, userCred mcclient.TokenCredential, host *models.SHost, netConfig *models.SNetworkConfig, pendingUsage quotas.IQuota) ([]models.SGuestnetwork, error) {
netifs := host.GetNetInterfaces()
netsAvaiable := make([]models.SNetwork, 0)
netifIndexs := make(map[string]*models.SNetInterface, 0)
netifIndexs := make(map[string][]models.SNetInterface, 0)
netTypes := guest.GetDriver().GetRandomNetworkTypes()
if len(netConfig.NetType) > 0 {
@@ -148,7 +167,10 @@ func (self *SBaremetalGuestDriver) Attach2RandomNetwork(guest *models.SGuest, ct
}
if net != nil {
netsAvaiable = append(netsAvaiable, *net)
netifIndexs[net.Id] = &netifs[idx]
if _, exist := netifIndexs[net.Id]; !exist {
netifIndexs[net.Id] = make([]models.SNetInterface, 0)
}
netifIndexs[net.Id] = append(netifIndexs[net.Id], netifs[idx])
}
}
if len(netsAvaiable) == 0 {
@@ -156,8 +178,27 @@ func (self *SBaremetalGuestDriver) Attach2RandomNetwork(guest *models.SGuest, ct
}
net := models.ChooseCandidateNetworks(netsAvaiable, netConfig.Exit, netTypes)
if net != nil {
netif := netifIndexs[net.Id]
return guest.Attach2Network(ctx, userCred, net, pendingUsage, "", netif.Mac, netConfig.Driver, netConfig.BwLimit, netConfig.Vip, netif.Index, false, models.IPAllocationStepup, false, "")
netifs := netifIndexs[net.Id]
nicConfs := make([]models.SNicConfig, 0)
nicCnt := 1
if netConfig.RequireTeaming || netConfig.TryTeaming {
nicCnt = 2
}
if len(netifs) < nicCnt {
if netConfig.RequireTeaming {
return nil, fmt.Errorf("not enough network interfaces, want %d got %d", nicCnt, len(netifs))
}
nicCnt = len(netifs)
}
for i := 0; i < nicCnt; i += 1 {
nicConf := models.SNicConfig{
Mac: netifs[i].Mac,
Index: netifs[i].Index,
Ifname: "",
}
nicConfs = append(nicConfs, nicConf)
}
return guest.Attach2Network(ctx, userCred, net, pendingUsage, "", netConfig.Driver, netConfig.BwLimit, netConfig.Vip, false, models.IPAllocationStepup, false, nicConfs)
}
return nil, fmt.Errorf("No appropriate host virtual network...")
}
+2 -1
View File
@@ -7,12 +7,13 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/utils"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/billing"
"yunion.io/x/pkg/utils"
)
type SHuaweiGuestDriver struct {
+2 -1
View File
@@ -7,6 +7,8 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
@@ -15,7 +17,6 @@ import (
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/billing"
"yunion.io/x/pkg/util/compare"
)
type SOpenStackGuestDriver struct {
+32 -4
View File
@@ -32,16 +32,30 @@ func (self *SVirtualizedGuestDriver) PrepareDiskRaidConfig(host *models.SHost, p
return nil
}
func (self *SVirtualizedGuestDriver) GetNamedNetworkConfiguration(guest *models.SGuest, userCred mcclient.TokenCredential, host *models.SHost, netConfig *models.SNetworkConfig) (*models.SNetwork, string, int8, models.IPAddlocationDirection) {
func (self *SVirtualizedGuestDriver) GetNamedNetworkConfiguration(guest *models.SGuest, userCred mcclient.TokenCredential, host *models.SHost, netConfig *models.SNetworkConfig) (*models.SNetwork, []models.SNicConfig, models.IPAddlocationDirection) {
net, _ := host.GetNetworkWithIdAndCredential(netConfig.Network, userCred, netConfig.Reserved)
return net, netConfig.Mac, -1, models.IPAllocationStepdown
nicConfs := []models.SNicConfig{
{
Mac: netConfig.Mac,
Index: -1,
Ifname: netConfig.Ifname,
},
}
if netConfig.RequireTeaming || netConfig.TryTeaming {
nicConfs = append(nicConfs, models.SNicConfig{
Mac: "",
Index: -1,
Ifname: "",
})
}
return net, nicConfs, models.IPAllocationStepdown
}
func (self *SVirtualizedGuestDriver) GetRandomNetworkTypes() []string {
return []string{models.NETWORK_TYPE_GUEST}
}
func (self *SVirtualizedGuestDriver) Attach2RandomNetwork(guest *models.SGuest, ctx context.Context, userCred mcclient.TokenCredential, host *models.SHost, netConfig *models.SNetworkConfig, pendingUsage quotas.IQuota) (*models.SGuestnetwork, error) {
func (self *SVirtualizedGuestDriver) Attach2RandomNetwork(guest *models.SGuest, ctx context.Context, userCred mcclient.TokenCredential, host *models.SHost, netConfig *models.SNetworkConfig, pendingUsage quotas.IQuota) ([]models.SGuestnetwork, error) {
var wirePattern *regexp.Regexp
if len(netConfig.Wire) > 0 {
wirePattern = regexp.MustCompile(netConfig.Wire)
@@ -83,7 +97,21 @@ func (self *SVirtualizedGuestDriver) Attach2RandomNetwork(guest *models.SGuest,
if selNet == nil {
return nil, fmt.Errorf("Not enough address in virtual network")
}
gn, err := guest.Attach2Network(ctx, userCred, selNet, pendingUsage, netConfig.Address, netConfig.Mac, netConfig.Driver, netConfig.BwLimit, netConfig.Vip, -1, netConfig.Reserved, models.IPAllocationDefault, false, netConfig.Ifname)
nicConfs := make([]models.SNicConfig, 1)
nicConfs[0] = models.SNicConfig{
Mac: netConfig.Mac,
Index: -1,
Ifname: netConfig.Ifname,
}
if netConfig.RequireTeaming || netConfig.TryTeaming {
nicConf := models.SNicConfig{
Mac: "",
Index: -1,
Ifname: "",
}
nicConfs = append(nicConfs, nicConf)
}
gn, err := guest.Attach2Network(ctx, userCred, selNet, pendingUsage, netConfig.Address, netConfig.Driver, netConfig.BwLimit, netConfig.Vip, netConfig.Reserved, models.IPAllocationDefault, false, nicConfs)
return gn, err
}
+1 -1
View File
@@ -386,7 +386,7 @@ func (self *SKVMHostDriver) PrepareConvert(host *models.SHost, image, raid strin
if wire == nil {
return nil, fmt.Errorf("No master wire?")
}
params.Set("net.0", jsonutils.NewString(fmt.Sprintf("wire=%s:[private]", wire.GetName())))
params.Set("net.0", jsonutils.NewString(fmt.Sprintf("wire=%s:[private]:[try-teaming]", wire.GetName())))
}
params.Set("deploy.0.path", jsonutils.NewString("/etc/sysconfig/yunionauth"))
params.Set("deploy.0.action", jsonutils.NewString("create"))
+14 -7
View File
@@ -344,9 +344,16 @@ func (self *SGuest) PerformDeploy(ctx context.Context, userCred mcclient.TokenCr
}
}
resetPasswd := jsonutils.QueryBoolean(kwargs, "reset_password", false)
if resetPasswd {
kwargs.Set("reset_password", jsonutils.JSONTrue)
} else {
kwargs.Set("reset_password", jsonutils.JSONFalse)
}
// 变更密码/密钥时需要Restart才能生效。更新普通字段不需要Restart, Azure需要在运行状态下操作
doRestart := false
if resetPasswd, _ := kwargs.Bool("reset_password"); resetPasswd {
if resetPasswd {
doRestart = self.GetDriver().IsNeedRestartForResetLoginInfo()
}
@@ -1321,7 +1328,7 @@ func (self *SGuest) AllowPerformChangeIpaddr(ctx context.Context, userCred mccli
func (self *SGuest) findGuestnetworkByInfo(ipStr string, macStr string, index int64) (*SGuestnetwork, error) {
if len(ipStr) > 0 {
gn, err := self.GetNetworkByIp(ipStr)
gn, err := self.GetGuestnetworkByIp(ipStr)
if err != nil {
if err == sql.ErrNoRows {
return nil, httperrors.NewNotFoundError("ip %s not found", ipStr)
@@ -1330,7 +1337,7 @@ func (self *SGuest) findGuestnetworkByInfo(ipStr string, macStr string, index in
}
return gn, nil
} else if len(macStr) > 0 {
gn, err := self.GetNetworkByMac(macStr)
gn, err := self.GetGuestnetworkByMac(macStr)
if err != nil {
if err == sql.ErrNoRows {
return nil, httperrors.NewNotFoundError("mac %s not found", macStr)
@@ -1382,7 +1389,7 @@ func (self *SGuest) PerformChangeIpaddr(ctx context.Context, userCred mcclient.T
}
host := self.GetHost()
ngn, err := func() (*SGuestnetwork, error) {
ngn, err := func() ([]SGuestnetwork, error) {
lockman.LockRawObject(ctx, GuestnetworkManager.KeywordPlural(), "")
defer lockman.ReleaseRawObject(ctx, GuestnetworkManager.KeywordPlural(), "")
@@ -1428,7 +1435,7 @@ func (self *SGuest) PerformChangeIpaddr(ctx context.Context, userCred mcclient.T
notes.Add(jsonutils.NewString(gn.IpAddr), "prev_ip")
}
if ngn != nil {
notes.Add(jsonutils.NewString(ngn.IpAddr), "ip")
notes.Add(jsonutils.NewString(ngn[0].IpAddr), "ip")
}
logclient.AddActionLogWithContext(ctx, self, logclient.ACT_VM_CHANGE_NIC, notes, userCred, true)
@@ -1464,7 +1471,7 @@ func (self *SGuest) PerformDetachnetwork(ctx context.Context, userCred mcclient.
}
ipStr, _ := data.GetString("ip_addr")
if len(ipStr) > 0 {
gn, err := self.GetNetworkByIp(ipStr)
gn, err := self.GetGuestnetworkByIp(ipStr)
if err != nil {
if err == sql.ErrNoRows {
return nil, httperrors.NewNotFoundError("ip %s not found", ipStr)
@@ -1476,7 +1483,7 @@ func (self *SGuest) PerformDetachnetwork(ctx context.Context, userCred mcclient.
}
macStr, _ := data.GetString("mac")
if len(macStr) > 0 {
gn, err := self.GetNetworkByMac(macStr)
gn, err := self.GetGuestnetworkByMac(macStr)
if err != nil {
if err == sql.ErrNoRows {
return nil, httperrors.NewNotFoundError("mac %s not found", macStr)
+2 -2
View File
@@ -37,9 +37,9 @@ type IGuestDriver interface {
PrepareDiskRaidConfig(host *SHost, params *jsonutils.JSONDict) error
GetNamedNetworkConfiguration(guest *SGuest, userCred mcclient.TokenCredential, host *SHost, netConfig *SNetworkConfig) (*SNetwork, string, int8, IPAddlocationDirection)
GetNamedNetworkConfiguration(guest *SGuest, userCred mcclient.TokenCredential, host *SHost, netConfig *SNetworkConfig) (*SNetwork, []SNicConfig, IPAddlocationDirection)
Attach2RandomNetwork(guest *SGuest, ctx context.Context, userCred mcclient.TokenCredential, host *SHost, netConfig *SNetworkConfig, pendingUsage quotas.IQuota) (*SGuestnetwork, error)
Attach2RandomNetwork(guest *SGuest, ctx context.Context, userCred mcclient.TokenCredential, host *SHost, netConfig *SNetworkConfig, pendingUsage quotas.IQuota) ([]SGuestnetwork, error)
GetRandomNetworkTypes() []string
ChooseHostStorage(host *SHost, backend string) *SStorage
+74 -57
View File
@@ -60,6 +60,8 @@ type SGuestnetwork struct {
Index int8 `nullable:"false" default:"0" list:"user" update:"user"` // Column(TINYINT, nullable=False, default=0)
Virtual bool `default:"false" list:"user"` // Column(Boolean, default=False)
Ifname string `width:"16" charset:"ascii" nullable:"true" list:"user" update:"user"` // Column(VARCHAR(16, charset='ascii'), nullable=True)
TeamWith string `width:"32" charset:"ascii" nullable:"false" list:"user"`
}
func (joint *SGuestnetwork) Master() db.IStandaloneModel {
@@ -121,7 +123,7 @@ func (manager *SGuestnetworkManager) GenerateMac(netId string, suggestion string
func (manager *SGuestnetworkManager) newGuestNetwork(ctx context.Context, userCred mcclient.TokenCredential, guest *SGuest, network *SNetwork,
index int8, address string, mac string, driver string, bwLimit int, virtual bool, reserved bool,
allocDir IPAddlocationDirection, requiredDesignatedIp bool, ifName string) (*SGuestnetwork, error) {
allocDir IPAddlocationDirection, requiredDesignatedIp bool, ifName string, teamWithMac string) (*SGuestnetwork, error) {
gn := SGuestnetwork{}
gn.SetModelManager(GuestnetworkManager)
@@ -170,6 +172,7 @@ func (manager *SGuestnetworkManager) newGuestNetwork(ctx context.Context, userCr
ifName = gn.GetFreeIfname(network, ifTable)
}
gn.Ifname = ifName
gn.TeamWith = teamWithMac
err := manager.TableSpec().Insert(&gn)
if err != nil {
return nil, err
@@ -237,17 +240,45 @@ func (gn *SGuestnetwork) GetNetwork() *SNetwork {
return nil
}
func (self *SGuestnetwork) GetJsonDescAtHost(host *SHost) jsonutils.JSONObject {
network := self.GetNetwork()
hostwire := host.getHostwireOfId(network.WireId)
func (self *SGuestnetwork) GetTeamGuestnetwork() (*SGuestnetwork, error) {
if len(self.TeamWith) > 0 {
return GuestnetworkManager.FetchByIdsAndIpMac(self.GuestId, self.NetworkId, "", self.TeamWith)
}
return nil, nil
}
func (self *SGuestnetwork) getJsonDescAtBaremetal(host *SHost) jsonutils.JSONObject {
network := self.GetNetwork()
hostwire := host.getHostwireOfIdAndMac(network.WireId, self.MacAddr)
return self.getGeneralJsonDesc(host, network, hostwire)
}
func (self *SGuestnetwork) getJsonDescAtHost(host *SHost) jsonutils.JSONObject {
network := self.GetNetwork()
hostwires := host.getHostwiresOfId(network.WireId)
if len(hostwires) > 1 {
log.Warningf("host attach to wire multiple times: %d", len(hostwires))
}
return self.getGeneralJsonDesc(host, network, &hostwires[0])
}
func (self *SGuestnetwork) getGeneralJsonDesc(host *SHost, network *SNetwork, hostwire *SHostwire) jsonutils.JSONObject {
desc := jsonutils.NewDict()
desc.Add(jsonutils.NewString(network.Name), "net")
desc.Add(jsonutils.NewString(self.NetworkId), "net_id")
desc.Add(jsonutils.NewString(self.MacAddr), "mac")
if self.Virtual {
desc.Add(jsonutils.JSONTrue, "virtual")
desc.Add(jsonutils.NewString(network.GetNetAddr().String()), "ip")
if len(self.TeamWith) > 0 {
teamGN, _ := self.GetTeamGuestnetwork()
if teamGN != nil {
log.Debugf("%#v", teamGN)
desc.Add(jsonutils.NewString(teamGN.IpAddr), "ip")
}
} else {
desc.Add(jsonutils.NewString(network.GetNetAddr().String()), "ip")
}
} else {
desc.Add(jsonutils.JSONFalse, "virtual")
desc.Add(jsonutils.NewString(self.IpAddr), "ip")
@@ -258,7 +289,7 @@ func (self *SGuestnetwork) GetJsonDescAtHost(host *SHost) jsonutils.JSONObject {
desc.Add(jsonutils.NewString(network.GetDNS()), "dns")
desc.Add(jsonutils.NewString(network.GetDomain()), "domain")
routes := network.GetRoutes()
if len(routes) > 0 {
if routes != nil && len(routes) > 0 {
desc.Add(jsonutils.Marshal(routes), "routes")
}
desc.Add(jsonutils.NewString(self.GetIfname()), "ifname")
@@ -277,10 +308,16 @@ func (self *SGuestnetwork) GetJsonDescAtHost(host *SHost) jsonutils.JSONObject {
if len(network.ExternalId) > 0 {
desc.Add(jsonutils.NewString(network.ExternalId), "external_id")
}
guest := self.GetGuest()
if len(self.TeamWith) > 0 {
desc.Add(jsonutils.NewString(self.TeamWith), "team_with")
}
guest := self.getGuest()
if guest.GetHypervisor() != HYPERVISOR_KVM {
desc.Add(jsonutils.JSONTrue, "manual")
}
return desc
}
@@ -520,56 +557,6 @@ func (self *SGuestnetwork) GetIfname() string {
return self.Ifname
}
func (self *SGuestnetwork) getJsonDescAtHost(host *SHost) jsonutils.JSONObject {
desc := jsonutils.NewDict()
network := self.GetNetwork()
hostwire := host.getHostwireOfId(network.WireId)
desc.Add(jsonutils.NewString(network.Name), "net")
desc.Add(jsonutils.NewString(self.NetworkId), "net_id")
desc.Add(jsonutils.NewString(self.MacAddr), "mac")
if self.Virtual {
desc.Add(jsonutils.JSONTrue, "virtual")
desc.Add(jsonutils.NewString(network.GetNetAddr().String()), "ip")
} else {
desc.Add(jsonutils.JSONFalse, "virtual")
desc.Add(jsonutils.NewString(self.IpAddr), "ip")
}
if len(network.GuestGateway) > 0 {
desc.Add(jsonutils.NewString(network.GuestGateway), "gateway")
}
desc.Add(jsonutils.NewString(network.GetDNS()), "dns")
desc.Add(jsonutils.NewString(network.GetDomain()), "domain")
routes := network.GetRoutes()
if routes != nil && len(routes) > 0 {
desc.Add(jsonutils.Marshal(routes), "routes")
}
desc.Add(jsonutils.NewString(self.GetIfname()), "ifname")
desc.Add(jsonutils.NewInt(int64(network.GuestIpMask)), "masklen")
desc.Add(jsonutils.NewString(self.Driver), "driver")
desc.Add(jsonutils.NewString(hostwire.Bridge), "bridge")
desc.Add(jsonutils.NewString(hostwire.WireId), "wire_id")
desc.Add(jsonutils.NewInt(int64(network.VlanId)), "vlan")
desc.Add(jsonutils.NewString(hostwire.Interface), "interface")
desc.Add(jsonutils.NewInt(int64(self.getBandwidth())), "bw")
desc.Add(jsonutils.NewInt(int64(self.Index)), "index")
vips := self.GetVirtualIPs()
if len(vips) > 0 {
desc.Add(jsonutils.NewStringArray(vips), "virtual_ips")
}
if len(network.ExternalId) > 0 {
desc.Add(jsonutils.NewString(network.ExternalId), "external_id")
}
guest := self.getGuest()
if guest.GetHypervisor() != HYPERVISOR_KVM {
desc.Add(jsonutils.JSONTrue, "manual")
}
return desc
}
func (manager *SGuestnetworkManager) getRecentlyReleasedIPAddresses(networkId string, recentDuration time.Duration) map[string]bool {
if recentDuration == 0 {
return nil
@@ -612,3 +599,33 @@ func (manager *SGuestnetworkManager) FilterByParams(q *sqlchemy.SQuery, params j
}
return q
}
func (manager *SGuestnetworkManager) FetchByIdsAndIpMac(guestId string, netId string, ipAddr string, mac string) (*SGuestnetwork, error) {
query := jsonutils.NewDict()
if len(mac) > 0 {
query.Add(jsonutils.NewString(mac), "mac_addr")
}
if len(ipAddr) > 0 {
query.Add(jsonutils.NewString(ipAddr), "ip_addr")
}
ign, err := db.FetchJointByIds(manager, guestId, netId, query)
if err != nil {
return nil, err
}
return ign.(*SGuestnetwork), nil
}
func (self *SGuestnetwork) GetShortDesc(ctx context.Context) *jsonutils.JSONDict {
desc := jsonutils.NewDict()
if len(self.IpAddr) > 0 {
desc.Add(jsonutils.NewString(self.IpAddr), "ip_addr")
}
if len(self.Ip6Addr) > 0 {
desc.Add(jsonutils.NewString(self.Ip6Addr), "ip6_addr")
}
desc.Add(jsonutils.NewString(self.MacAddr), "mac")
if len(self.TeamWith) > 0 {
desc.Add(jsonutils.NewString(self.TeamWith), "team_with")
}
return desc
}
+68 -39
View File
@@ -33,6 +33,7 @@ import (
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/util/billing"
"yunion.io/x/onecloud/pkg/util/netutils2"
"yunion.io/x/onecloud/pkg/util/seclib2"
)
@@ -631,7 +632,7 @@ func (guest *SGuest) GetNetworks(netId string) ([]SGuestnetwork, error) {
return guestnics, nil
}
func (guest *SGuest) getNetworkByIpOrMac(ipAddr string, macAddr string) (*SGuestnetwork, error) {
func (guest *SGuest) getGuestnetworkByIpOrMac(ipAddr string, macAddr string) (*SGuestnetwork, error) {
q := guest.GetNetworksQuery("")
if len(ipAddr) > 0 {
q = q.Equals("ip_addr", ipAddr)
@@ -649,12 +650,12 @@ func (guest *SGuest) getNetworkByIpOrMac(ipAddr string, macAddr string) (*SGuest
return &guestnic, nil
}
func (guest *SGuest) GetNetworkByIp(ipAddr string) (*SGuestnetwork, error) {
return guest.getNetworkByIpOrMac(ipAddr, "")
func (guest *SGuest) GetGuestnetworkByIp(ipAddr string) (*SGuestnetwork, error) {
return guest.getGuestnetworkByIpOrMac(ipAddr, "")
}
func (guest *SGuest) GetNetworkByMac(macAddr string) (*SGuestnetwork, error) {
return guest.getNetworkByIpOrMac("", macAddr)
func (guest *SGuest) GetGuestnetworkByMac(macAddr string) (*SGuestnetwork, error) {
return guest.getGuestnetworkByIpOrMac("", macAddr)
}
func (guest *SGuest) IsNetworkAllocated() bool {
@@ -2089,16 +2090,48 @@ func (self *SGuest) getOSProfile() osprofile.SOSProfile {
func (self *SGuest) Attach2Network(ctx context.Context, userCred mcclient.TokenCredential, network *SNetwork,
pendingUsage quotas.IQuota,
address string, mac string, driver string, bwLimit int, virtual bool, index int8,
reserved bool, allocDir IPAddlocationDirection, requireDesignatedIP bool, ifName string) (*SGuestnetwork, error) {
address string,
driver string, bwLimit int, virtual bool,
reserved bool, allocDir IPAddlocationDirection, requireDesignatedIP bool,
nicConfs []SNicConfig) ([]SGuestnetwork, error) {
firstNic, err := self.attach2NetworkOnce(ctx, userCred, network, pendingUsage, address, driver, bwLimit, virtual,
reserved, allocDir, requireDesignatedIP, nicConfs[0], "")
if err != nil {
return nil, err
}
retNics := []SGuestnetwork{*firstNic}
if len(nicConfs) > 1 {
firstMac, _ := netutils2.ParseMac(firstNic.MacAddr)
for i := 1; i < len(nicConfs); i += 1 {
if len(nicConfs[i].Mac) == 0 {
nicConfs[i].Mac = firstMac.Add(i).String()
}
gn, err := self.attach2NetworkOnce(ctx, userCred, network, pendingUsage, "", firstNic.Driver, 0, true,
false, allocDir, false, nicConfs[i], firstNic.MacAddr)
if err != nil {
return retNics, err
}
retNics = append(retNics, *gn)
}
}
return retNics, nil
}
func (self *SGuest) attach2NetworkOnce(ctx context.Context, userCred mcclient.TokenCredential, network *SNetwork,
pendingUsage quotas.IQuota,
address string,
driver string, bwLimit int, virtual bool,
reserved bool, allocDir IPAddlocationDirection, requireDesignatedIP bool,
nicConf SNicConfig, teamWithMac string) (*SGuestnetwork, error) {
/*
allow a guest attach to a network 2 times
*/
if self.getAttach2NetworkCount(network) > MAX_GUESTNIC_TO_SAME_NETWORK {
/*if self.getAttach2NetworkCount(network) > MAX_GUESTNIC_TO_SAME_NETWORK {
return nil, fmt.Errorf("Guest has been attached to network %s", network.Name)
}
if index < 0 {
index = self.getMaxNicIndex()
}*/
if nicConf.Index < 0 {
nicConf.Index = self.getMaxNicIndex()
}
if len(driver) == 0 {
osProf := self.getOSProfile()
@@ -2108,15 +2141,15 @@ func (self *SGuest) Attach2Network(ctx context.Context, userCred mcclient.TokenC
defer lockman.ReleaseClass(ctx, QuotaManager, self.ProjectId)
guestnic, err := GuestnetworkManager.newGuestNetwork(ctx, userCred, self, network,
index, address, mac, driver, bwLimit, virtual, reserved,
allocDir, requireDesignatedIP, ifName)
nicConf.Index, address, nicConf.Mac, driver, bwLimit, virtual, reserved,
allocDir, requireDesignatedIP, nicConf.Ifname, teamWithMac)
if err != nil {
return nil, err
}
network.updateDnsRecord(guestnic, true)
network.updateGuestNetmap(guestnic)
bwLimit = guestnic.getBandwidth()
if pendingUsage != nil {
if pendingUsage != nil && len(teamWithMac) == 0 {
cancelUsage := SQuota{}
if network.IsExitNetwork() {
cancelUsage.Eport = 1
@@ -2130,12 +2163,10 @@ func (self *SGuest) Attach2Network(ctx context.Context, userCred mcclient.TokenC
log.Warningf("QuotaManager.CancelPendingUsage fail %s", err)
}
}
notes := jsonutils.NewDict()
if len(address) == 0 {
address = guestnic.IpAddr
}
notes.Add(jsonutils.NewString(address), "ip_addr")
db.OpsLog.LogAttachEvent(ctx, self, network, userCred, notes)
db.OpsLog.LogAttachEvent(ctx, self, network, userCred, guestnic.GetShortDesc(ctx))
return guestnic, nil
}
@@ -2255,8 +2286,13 @@ func (self *SGuest) SyncVMNics(ctx context.Context, userCred mcclient.TokenCrede
continue
}
}
nicConf := SNicConfig{
Mac: add.nic.GetMAC(),
Index: -1,
Ifname: "",
}
_, err = self.Attach2Network(ctx, userCred, add.net, nil, add.nic.GetIP(),
add.nic.GetMAC(), add.nic.GetDriver(), 0, false, -1, add.reserve, IPAllocationDefault, true, "")
add.nic.GetDriver(), 0, false, add.reserve, IPAllocationDefault, true, []SNicConfig{nicConf})
if err != nil {
result.AddError(err)
} else {
@@ -2502,17 +2538,6 @@ func (self *SGuest) getDefaultNetworkConfig() *SNetworkConfig {
func (self *SGuest) CreateNetworksOnHost(ctx context.Context, userCred mcclient.TokenCredential, host *SHost, data *jsonutils.JSONDict, pendingUsage quotas.IQuota) error {
netJsonArray := jsonutils.GetArrayOfPrefix(data, "net")
/* idx := 0
for idx = 0; data.Contains(fmt.Sprintf("net.%d", idx)); idx += 1 {
netJson, err := data.Get(fmt.Sprintf("net.%d", idx))
if err != nil {
return err
}
if netJson == jsonutils.JSONNull {
break
}
}*/
if len(netJsonArray) == 0 {
netConfig := self.getDefaultNetworkConfig()
_, err := self.attach2RandomNetwork(ctx, userCred, host, netConfig, pendingUsage)
@@ -2531,18 +2556,18 @@ func (self *SGuest) CreateNetworksOnHost(ctx context.Context, userCred mcclient.
return nil
}
func (self *SGuest) attach2NetworkDesc(ctx context.Context, userCred mcclient.TokenCredential, host *SHost, netConfig *SNetworkConfig, pendingUsage quotas.IQuota) (*SGuestnetwork, error) {
var gn *SGuestnetwork
func (self *SGuest) attach2NetworkDesc(ctx context.Context, userCred mcclient.TokenCredential, host *SHost, netConfig *SNetworkConfig, pendingUsage quotas.IQuota) ([]SGuestnetwork, error) {
var gns []SGuestnetwork
var err1, err2 error
if len(netConfig.Network) > 0 {
gn, err1 = self.attach2NamedNetworkDesc(ctx, userCred, host, netConfig, pendingUsage)
gns, err1 = self.attach2NamedNetworkDesc(ctx, userCred, host, netConfig, pendingUsage)
if err1 == nil {
return gn, nil
return gns, nil
}
}
gn, err2 = self.attach2RandomNetwork(ctx, userCred, host, netConfig, pendingUsage)
gns, err2 = self.attach2RandomNetwork(ctx, userCred, host, netConfig, pendingUsage)
if err2 == nil {
return gn, nil
return gns, nil
}
if err1 != nil {
return nil, fmt.Errorf("%s/%s", err1, err2)
@@ -2551,12 +2576,16 @@ func (self *SGuest) attach2NetworkDesc(ctx context.Context, userCred mcclient.To
}
}
func (self *SGuest) attach2NamedNetworkDesc(ctx context.Context, userCred mcclient.TokenCredential, host *SHost, netConfig *SNetworkConfig, pendingUsage quotas.IQuota) (*SGuestnetwork, error) {
func (self *SGuest) attach2NamedNetworkDesc(ctx context.Context, userCred mcclient.TokenCredential, host *SHost, netConfig *SNetworkConfig, pendingUsage quotas.IQuota) ([]SGuestnetwork, error) {
driver := self.GetDriver()
net, mac, idx, allocDir := driver.GetNamedNetworkConfiguration(self, userCred, host, netConfig)
net, nicConfs, allocDir := driver.GetNamedNetworkConfiguration(self, userCred, host, netConfig)
if net != nil {
gn, err := self.Attach2Network(ctx, userCred, net, pendingUsage, netConfig.Address, mac, netConfig.Driver, netConfig.BwLimit, netConfig.Vip, idx, netConfig.Reserved, allocDir, false, netConfig.Ifname)
if len(nicConfs) == 0 {
return nil, fmt.Errorf("no avaialble network interface?")
}
gn, err := self.Attach2Network(ctx, userCred, net, pendingUsage, netConfig.Address, netConfig.Driver, netConfig.BwLimit, netConfig.Vip, netConfig.Reserved, allocDir, false, nicConfs)
if err != nil {
log.Errorf("Attach2Network fail %s", err)
return nil, err
} else {
return gn, nil
@@ -2566,7 +2595,7 @@ func (self *SGuest) attach2NamedNetworkDesc(ctx context.Context, userCred mcclie
}
}
func (self *SGuest) attach2RandomNetwork(ctx context.Context, userCred mcclient.TokenCredential, host *SHost, netConfig *SNetworkConfig, pendingUsage quotas.IQuota) (*SGuestnetwork, error) {
func (self *SGuest) attach2RandomNetwork(ctx context.Context, userCred mcclient.TokenCredential, host *SHost, netConfig *SNetworkConfig, pendingUsage quotas.IQuota) ([]SGuestnetwork, error) {
driver := self.GetDriver()
return driver.Attach2RandomNetwork(self, ctx, userCred, host, netConfig, pendingUsage)
}
+32 -13
View File
@@ -1084,14 +1084,27 @@ func (self *SHost) GetMasterWire() *SWire {
return &wire
}
func (self *SHost) getHostwireOfId(wireId string) *SHostwire {
func (self *SHost) getHostwiresOfId(wireId string) []SHostwire {
hostwires := make([]SHostwire, 0)
q := self.GetWiresQuery().Equals("wire_id", wireId)
err := db.FetchModelObjects(HostwireManager, q, &hostwires)
if err != nil {
log.Errorf("getHostwiresOfId fail %s", err)
return nil
}
return hostwires
}
func (self *SHost) getHostwireOfIdAndMac(wireId string, mac string) *SHostwire {
hostwire := SHostwire{}
hostwire.SetModelManager(HostwireManager)
q := self.GetWiresQuery().Equals("wire_id", wireId)
q = q.Equals("mac_addr", mac)
err := q.First(&hostwire)
if err != nil {
log.Errorf("getHostwireOfId fail %s", err)
log.Errorf("getHostwireOfIdAndMac fail %s", err)
return nil
}
return &hostwire
@@ -1586,12 +1599,14 @@ func (self *SHost) SyncHostWires(ctx context.Context, userCred mcclient.TokenCre
for i := 0; i < len(removed); i += 1 {
log.Infof("host %s not connected with %s any more, to detach...", self.Id, removed[i].Id)
hw := self.getHostwireOfId(removed[i].Id)
err := hw.Detach(ctx, userCred)
if err != nil {
syncResult.DeleteError(err)
} else {
syncResult.Delete()
hws := self.getHostwiresOfId(removed[i].Id)
for i := range hws {
err := hws[i].Detach(ctx, userCred)
if err != nil {
syncResult.DeleteError(err)
} else {
syncResult.Delete()
}
}
}
@@ -1723,7 +1738,7 @@ func (self *SHost) getNetworkOfIPOnHost(ipAddr string) (*SNetwork, error) {
return nil, fmt.Errorf("IP %s not reachable on this host", ipAddr)
}
func (self *SHost) GetNetinterfaceWithIdAndCredential(netId string, userCred mcclient.TokenCredential, reserved bool) (*SNetInterface, *SNetwork) {
func (self *SHost) GetNetinterfacesWithIdAndCredential(netId string, userCred mcclient.TokenCredential, reserved bool) ([]SNetInterface, *SNetwork) {
netObj, err := NetworkManager.FetchById(netId)
if err != nil {
return nil, nil
@@ -1732,15 +1747,20 @@ func (self *SHost) GetNetinterfaceWithIdAndCredential(netId string, userCred mcc
if net.getFreeAddressCount() == 0 && !reserved {
return nil, nil
}
matchNetIfs := make([]SNetInterface, 0)
netifs := self.GetNetInterfaces()
for i := 0; i < len(netifs); i++ {
if !netifs[i].IsUsableServernic() {
continue
}
if netifs[i].WireId == net.WireId {
return &netifs[i], net
matchNetIfs = append(matchNetIfs, netifs[i])
// return &netifs[i], net
}
}
if len(matchNetIfs) > 0 {
return matchNetIfs, net
}
return nil, nil
}
@@ -2907,9 +2927,9 @@ func (self *SHost) addNetif(ctx context.Context, userCred mcclient.TokenCredenti
bridge = fmt.Sprintf("br%s", sw.GetName())
}
var isMaster = netif.NicType == NIC_TYPE_ADMIN
ihw, err := HostwireManager.FetchByIdsAndMac(self.Id, sw.Id, mac)
hw, err := HostwireManager.FetchByIdsAndMac(self.Id, sw.Id, mac)
if err != nil {
hw := &SHostwire{}
hw = &SHostwire{}
hw.Bridge = bridge
hw.Interface = strInterface
hw.HostId = self.Id
@@ -2921,7 +2941,6 @@ func (self *SHost) addNetif(ctx context.Context, userCred mcclient.TokenCredenti
return err
}
} else {
hw := ihw
HostwireManager.TableSpec().Update(hw, func() error {
hw.Bridge = bridge
hw.Interface = strInterface
+12 -16
View File
@@ -93,7 +93,7 @@ func (netif *SNetInterface) GetBaremetalNetwork() *SHostnetwork {
return &bn
}
func (self *SNetInterface) guestNetworkToJson(bn *SGuestnetwork) *jsonutils.JSONDict {
/*func (self *SNetInterface) guestNetworkToJson(bn *SGuestnetwork) *jsonutils.JSONDict {
jsonDesc := jsonutils.Marshal(self)
desc := jsonDesc.(*jsonutils.JSONDict)
@@ -113,7 +113,7 @@ func (self *SNetInterface) hostNetworkToJson(bn *SHostnetwork) *jsonutils.JSONDi
} else {
return self.networkToJson(bn.IpAddr, bn.GetNetwork(), desc)
}
}
}*/
func (self *SNetInterface) networkToJson(ipAddr string, network *SNetwork, desc *jsonutils.JSONDict) *jsonutils.JSONDict {
if len(ipAddr) > 0 {
@@ -170,26 +170,22 @@ func (self *SNetInterface) getServernetwork() *SGuestnetwork {
}
func (self *SNetInterface) getServerJsonDesc() *jsonutils.JSONDict {
bn := self.getServernetwork()
var desc = jsonutils.NewDict()
desc = self.guestNetworkToJson(bn)
if bn != nil {
desc.Add(jsonutils.JSONFalse, "virtual")
desc.Add(jsonutils.NewString(bn.IpAddr), "ip")
desc.Add(jsonutils.NewInt(int64(bn.getBandwidth())), "bw")
desc.Add(jsonutils.NewInt(int64(bn.Index)), "index")
desc.Add(jsonutils.JSONTrue, "manual")
vips := bn.GetVirtualIPs()
if vips != nil && len(vips) > 0 {
desc.Add(jsonutils.NewStringArray(vips), "virtual_ips")
}
desc := jsonutils.Marshal(self).(*jsonutils.JSONDict)
gn := self.getServernetwork()
if gn != nil {
desc.Update(gn.getJsonDescAtBaremetal(self.GetBaremetal()))
}
return desc
}
func (self *SNetInterface) getBaremetalJsonDesc() *jsonutils.JSONDict {
desc := jsonutils.Marshal(self).(*jsonutils.JSONDict)
bn := self.GetBaremetalNetwork()
return self.hostNetworkToJson(bn)
if bn != nil {
return self.networkToJson(bn.IpAddr, bn.GetNetwork(), desc)
} else {
return desc
}
}
/*
+21
View File
@@ -4,6 +4,7 @@ import (
"context"
"database/sql"
"fmt"
"strconv"
"strings"
"time"
@@ -691,6 +692,18 @@ type SNetworkConfig struct {
Reserved bool
Ifname string
NetType string
RequireTeaming bool
TryTeaming bool
StandbyPortCount int
StandbyAddrCount int
}
type SNicConfig struct {
Mac string
Index int8
Ifname string
}
func parseNetworkInfo(userCred mcclient.TokenCredential, info jsonutils.JSONObject) (*SNetworkConfig, error) {
@@ -730,6 +743,14 @@ func parseNetworkInfo(userCred mcclient.TokenCredential, info jsonutils.JSONObje
netConfig.Private = true
} else if p == "[reserved]" {
netConfig.Reserved = true
} else if p == "[teaming]" {
netConfig.RequireTeaming = true
} else if p == "[try-teaming]" {
netConfig.TryTeaming = true
} else if strings.HasPrefix(p, "standby-port=") {
netConfig.StandbyPortCount, _ = strconv.Atoi(p[len("standby-port="):])
} else if strings.HasPrefix(p, "standby-addr=") {
netConfig.StandbyAddrCount, _ = strconv.Atoi(p[len("standby-addr="):])
} else if utils.IsInStringArray(p, []string{"virtio", "e1000", "vmxnet3"}) {
netConfig.Driver = p
} else if regutils.MatchSize(p) {
+1 -1
View File
@@ -20,7 +20,7 @@ type ComputeOptions struct {
DefaultSecurityRules string `help:"Default security rules" default:"allow any"`
DefaultAdminSecurityRules string `help:"Default admin security rules" default:""`
DefaultDiskSizeMB int `default:"30720" help:"Default disk size in MB if not specified, default to 30GiB" json:"default_disk_size"`
DefaultDiskSizeMB int `default:"10240" help:"Default disk size in MB if not specified, default to 10GiB" json:"default_disk_size"`
pending_delete.SPendingDeleteOptions
+1
View File
@@ -0,0 +1 @@
package storagedrivers // import "yunion.io/x/onecloud/pkg/compute/storagedrivers"
+1 -1
View File
@@ -11,7 +11,7 @@ func init() {
[]string{"Guest_ID", "Guest",
"Network_ID", "Network", "Mac_addr",
"IP_addr", "Driver", "BW_limit", "Index",
"Virtual", "Ifname"},
"Virtual", "Ifname", "team_with"},
[]string{},
&Servers,
&Networks)
+60
View File
@@ -0,0 +1,60 @@
package netutils2
import (
"errors"
"fmt"
"strconv"
"strings"
"yunion.io/x/log"
"yunion.io/x/pkg/util/netutils"
)
type SMacAddr [6]byte
func ErrMacFormat(macStr string) error {
return errors.New(fmt.Sprintf("invalid mac format: %s", macStr))
}
func ParseMac(macStr string) (SMacAddr, error) {
mac := SMacAddr{}
macStr = netutils.FormatMacAddr(macStr)
parts := strings.Split(macStr, ":")
if len(parts) != 6 {
return mac, ErrMacFormat(macStr)
}
for i := 0; i < 6; i += 1 {
bt, err := strconv.ParseInt(parts[i], 16, 64)
if err != nil {
return mac, ErrMacFormat(macStr)
}
mac[i] = byte(bt)
}
return mac, nil
}
func (mac SMacAddr) Add(step int) SMacAddr {
mac2 := SMacAddr{}
leftOver := step
for i := 5; i >= 0; i -= 1 { // skip first 2 vendor bytes
newByte := int(mac[i]) + leftOver
res := 0
if newByte < 0 {
log.Debugf("%d %d", mac[i], newByte)
res = ((-newByte) / 0x100) + 1
newByte = newByte + res*0x100
log.Debugf("%d %d", newByte, res)
}
mac2[i] = byte(newByte % 0x100)
leftOver = newByte/0x100 - res
}
return mac2
}
func (mac SMacAddr) String() string {
var parts [6]string
for i := 0; i < len(parts); i += 1 {
parts[i] = fmt.Sprintf("%02x", mac[i])
}
return strings.Join(parts[:], ":")
}
+55
View File
@@ -0,0 +1,55 @@
package netutils2
import (
"testing"
"yunion.io/x/pkg/util/netutils"
)
func TestParseMac(t *testing.T) {
cases := []struct {
In string
Inc int
Want string
}{
{
In: "00:50:56:C0:00:01",
Inc: 1,
Want: "00:50:56:c0:00:02",
},
{
In: "00:50:56:c0:00:01",
Inc: -1,
Want: "00:50:56:c0:00:00",
},
{
In: "00:50:56:c0:00:01",
Inc: 0xff,
Want: "00:50:56:c0:01:00",
},
{
In: "00:50:56:C0:00:01",
Inc: -2,
Want: "00:50:56:bf:ff:ff",
},
{
In: "00:50:56:C0:00:01",
Inc: -0xff,
Want: "00:50:56:bf:ff:02",
},
}
for i, c := range cases {
mac, err := ParseMac(c.In)
if err != nil {
t.Errorf("parse mac errror %s", err)
} else {
mac2 := mac.Add(c.Inc)
if mac2.String() != c.Want {
t.Errorf("%d) %s inc %d want: %s got: %s", i, c.In, c.Inc, c.Want, mac2.String())
}
mac3 := mac2.Add(-c.Inc)
if mac3.String() != netutils.FormatMacAddr(c.In) {
t.Errorf("%d) %s inc %d want: %s got: %s", i, c.In, c.Inc, c.Want, mac2.String())
}
}
}
}