diff --git a/Gopkg.lock b/Gopkg.lock index ae9292deba..c74cc2e2c3 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -1368,11 +1368,11 @@ [[projects]] branch = "master" - digest = "1:66b13d3803b8ff8f26c3ca0422fb18ca0362dff62240e436b0aa0a921f833bb9" + digest = "1:5a3958d2f3c6c6510cc6b0e754cc45f6e98d8f8780ea04c1232a8f22fd6d91fc" name = "yunion.io/x/sqlchemy" packages = ["."] pruneopts = "UT" - revision = "7de55aae3ef9b019c47d21ff8fa4add1a9c80eb7" + revision = "30271a36b97155505642d6d3709a37600aade302" [[projects]] branch = "master" diff --git a/pkg/cloudcommon/db/enabledstatusstandalone.go b/pkg/cloudcommon/db/enabledstatusstandalone.go index 6a456a429b..faffc888c0 100644 --- a/pkg/cloudcommon/db/enabledstatusstandalone.go +++ b/pkg/cloudcommon/db/enabledstatusstandalone.go @@ -5,7 +5,9 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/log" + "yunion.io/x/onecloud/pkg/mcclient" + "yunion.io/x/onecloud/pkg/util/logclient" ) type SEnabledStatusStandaloneResourceBase struct { @@ -37,6 +39,7 @@ func (self *SEnabledStatusStandaloneResourceBase) PerformEnable(ctx context.Cont return nil, err } OpsLog.LogEvent(self, ACT_ENABLE, "", userCred) + logclient.AddActionLog(self, logclient.ACT_ENABLE, nil, userCred, true) } return nil, nil } @@ -56,6 +59,7 @@ func (self *SEnabledStatusStandaloneResourceBase) PerformDisable(ctx context.Con return nil, err } OpsLog.LogEvent(self, ACT_DISABLE, "", userCred) + logclient.AddActionLog(self, logclient.ACT_DISABLE, nil, userCred, true) } return nil, nil } diff --git a/pkg/cloudcommon/db/standalone.go b/pkg/cloudcommon/db/standalone.go index ee24698c55..a64bb57211 100644 --- a/pkg/cloudcommon/db/standalone.go +++ b/pkg/cloudcommon/db/standalone.go @@ -201,10 +201,10 @@ func (model *SStandaloneResourceBase) PerformMetadata(ctx context.Context, userC } dictStore := make(map[string]interface{}) for k, v := range dictMap { - dictStore[k] = v + dictStore[k], _ = v.GetString() } - model.SetAllMetadata(ctx, dictStore, userCred) - return nil, nil + err = model.SetAllMetadata(ctx, dictStore, userCred) + return nil, err } func (model *SStandaloneResourceBase) GetCustomizeColumns(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) *jsonutils.JSONDict { diff --git a/pkg/cloudcommon/db/taskman/tasks.go b/pkg/cloudcommon/db/taskman/tasks.go index 6cf259966f..d879d5ac5a 100644 --- a/pkg/cloudcommon/db/taskman/tasks.go +++ b/pkg/cloudcommon/db/taskman/tasks.go @@ -654,9 +654,7 @@ func (self *STask) GetObjects() []db.IStandaloneModel { } func (task *STask) GetTaskRequestHeader() http.Header { - header := http.Header{} - header.Set(mcclient.AUTH_TOKEN, task.GetUserCred().GetTokenString()) + header := mcclient.GetTokenHeaders(task.GetUserCred()) header.Set(mcclient.TASK_ID, task.GetTaskId()) - header.Set(mcclient.REGION_VERSION, "v2") return header } diff --git a/pkg/cloudprovider/resources.go b/pkg/cloudprovider/resources.go index b98bac1b41..ed2bbd7e6e 100644 --- a/pkg/cloudprovider/resources.go +++ b/pkg/cloudprovider/resources.go @@ -1,12 +1,14 @@ package cloudprovider import ( + "context" "time" - "context" "yunion.io/x/jsonutils" - "yunion.io/x/onecloud/pkg/mcclient" + "yunion.io/x/pkg/tristate" "yunion.io/x/pkg/util/secrules" + + "yunion.io/x/onecloud/pkg/mcclient" ) type ICloudResource interface { @@ -356,7 +358,7 @@ type ICloudHostNetInterface interface { GetDriver() string GetMac() string GetIndex() int8 - IsLinkUp() bool + IsLinkUp() tristate.TriState GetIpAddr() string GetMtu() int16 GetNicType() string diff --git a/pkg/compute/guestdrivers/baremetals.go b/pkg/compute/guestdrivers/baremetals.go index 240ccbf2c4..28965bb65c 100644 --- a/pkg/compute/guestdrivers/baremetals.go +++ b/pkg/compute/guestdrivers/baremetals.go @@ -3,7 +3,6 @@ package guestdrivers import ( "context" "fmt" - "net/http" "regexp" "strings" @@ -168,9 +167,7 @@ func (self *SBaremetalGuestDriver) RequestStartOnHost(ctx context.Context, guest desc := guest.GetJsonDescAtBaremetal(ctx, host) config := jsonutils.NewDict() config.Set("desc", desc) - headers := http.Header{} - headers.Set("X-Auth-Token", task.GetUserCred().GetTokenString()) - headers.Set("X-Task-Id", task.GetTaskId()) + headers := task.GetTaskRequestHeader() url := fmt.Sprintf("/baremetals/%s/servers/%s/start", host.Id, guest.Id) return host.BaremetalSyncRequest(ctx, "POST", url, headers, config) } @@ -208,9 +205,7 @@ func (self *SBaremetalGuestDriver) RequestStopOnHost(ctx context.Context, guest timeout = 0 } body.Set("timeout", jsonutils.NewInt(timeout)) - headers := http.Header{} - headers.Set("X-Auth-Token", task.GetUserCred().GetTokenString()) - headers.Set("X-Task-Id", task.GetTaskId()) + headers := task.GetTaskRequestHeader() url := fmt.Sprintf("/baremetals/%s/servers/%s/stop", host.Id, guest.Id) _, err = host.BaremetalSyncRequest(ctx, "POST", url, headers, body) return err @@ -227,9 +222,7 @@ func (self *SBaremetalGuestDriver) StartGuestStopTask(guest *models.SGuest, ctx func (self *SBaremetalGuestDriver) RequestUndeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error { url := fmt.Sprintf("/baremetals/%s/servers/%s", host.Id, guest.Id) - headers := http.Header{} - headers.Set("X-Auth-Token", task.GetUserCred().GetTokenString()) - headers.Set("X-Task-Id", task.GetTaskId()) + headers := task.GetTaskRequestHeader() _, err := host.BaremetalSyncRequest(ctx, "DELETE", url, headers, nil) return err } @@ -361,9 +354,7 @@ func (self *SBaremetalGuestDriver) RequestDeployGuestOnHost(ctx context.Context, config.Set("on_finish", jsonutils.NewString("restart")) } url := fmt.Sprintf("/baremetals/%s/servers/%s/%s", host.Id, guest.Id, val) - headers := http.Header{} - headers.Set("X-Auth-Token", task.GetUserCred().GetTokenString()) - headers.Set("X-Task-Id", task.GetTaskId()) + headers := task.GetTaskRequestHeader() _, err := host.BaremetalSyncRequest(ctx, "POST", url, headers, config) return err } diff --git a/pkg/compute/models/hosts.go b/pkg/compute/models/hosts.go index 077fdf8e2e..44f30955c7 100644 --- a/pkg/compute/models/hosts.go +++ b/pkg/compute/models/hosts.go @@ -135,7 +135,7 @@ type SHost struct { StorageSize int `nullable:"true" list:"admin" update:"admin" create:"admin_optional"` // Column(Integer, nullable=True) # storage size in MB StorageType string `width:"20" charset:"ascii" nullable:"true" list:"admin" update:"admin" create:"admin_optional"` // Column(VARCHAR(20, charset='ascii'), nullable=True) - StorageDriver string `width:"20" charset:"ascii" nullable:"true" update:"admin" create:"admin_optional"` // Column(VARCHAR(20, charset='ascii'), nullable=True) + StorageDriver string `width:"20" charset:"ascii" nullable:"true" get:"admin" update:"admin" create:"admin_optional"` // Column(VARCHAR(20, charset='ascii'), nullable=True) StorageInfo jsonutils.JSONObject `nullable:"true" get:"admin" update:"admin" create:"admin_optional"` // Column(JSONEncodedDict, nullable=True) IpmiInfo jsonutils.JSONObject `nullable:"true" get:"admin" update:"admin" create:"admin_optional"` // Column(JSONEncodedDict, nullable=True) @@ -507,6 +507,79 @@ func (self *SHost) GetBaremetalstorage() *SHoststorage { return nil } +func (self *SHost) SaveCleanUpdates(doUpdate func() error) (map[string]sqlchemy.SUpdateDiff, error) { + return self.saveUpdates(doUpdate, true) +} + +func (self *SHost) SaveUpdates(doUpdate func() error) (map[string]sqlchemy.SUpdateDiff, error) { + return self.saveUpdates(doUpdate, false) +} + +func (self *SHost) saveUpdates(doUpdate func() error, doSchedClean bool) (map[string]sqlchemy.SUpdateDiff, error) { + diff, err := self.GetModelManager().TableSpec().Update(self, doUpdate) + if err == nil && doSchedClean { + self.ClearSchedDescCache() + } + return diff, err +} + +func (self *SHost) AllowPerformUpdateStorage( + ctx context.Context, + userCred mcclient.TokenCredential, + query jsonutils.JSONObject, + data jsonutils.JSONObject, +) bool { + return db.IsAdminAllowPerform(userCred, self, "update-storage") +} + +func (self *SHost) PerformUpdateStorage( + ctx context.Context, + userCred mcclient.TokenCredential, + query jsonutils.JSONObject, + data jsonutils.JSONObject, +) (jsonutils.JSONObject, error) { + bs := self.GetBaremetalstorage() + capacity, _ := data.Int("capacity") + zoneId, _ := data.GetString("zone_id") + if bs == nil { + // 1. create storage + storage := SStorage{} + storage.Name = fmt.Sprintf("storage%s", self.GetName()) + storage.Capacity = int(capacity) + storage.StorageType = STORAGE_BAREMETAL + storage.MediumType = self.StorageType + storage.Cmtbound = 1.0 + storage.Status = STORAGE_ONLINE + storage.ZoneId = zoneId + err := StorageManager.TableSpec().Insert(&storage) + if err != nil { + return nil, fmt.Errorf("Create baremetal storage error: %v", err) + } + // 2. create host storage + bmStorage := SHoststorage{} + bmStorage.HostId = self.Id + bmStorage.StorageId = storage.Id + bmStorage.RealCapacity = int(capacity) + bmStorage.MountPoint = "" + err = HoststorageManager.TableSpec().Insert(&bmStorage) + if err != nil { + return nil, fmt.Errorf("Create baremetal hostStorage error: %v", err) + } + return nil, nil + } + storage := bs.GetStorage() + if capacity != int64(storage.Capacity) { + _, err := storage.GetModelManager().TableSpec().Update(storage, func() error { + storage.Capacity = int(capacity) + return nil + }) + if err != nil { + return nil, fmt.Errorf("Update baremetal storage error: %v", err) + } + } + return nil, nil +} + func (self *SHost) GetFetchUrl() string { managerUrl, err := url.Parse(self.ManagerUri) if err != nil { @@ -568,6 +641,15 @@ func (self *SHost) SyncAttachedStorageStatus() { } } +func (self *SHostManager) IsNewNameUnique(name string, userCred mcclient.TokenCredential, kwargs *jsonutils.JSONDict) bool { + q := self.Query().Equals("name", name) + if kwargs != nil && kwargs.Contains("zone_id") { + zoneId, _ := kwargs.GetString("zone_id") + q.Equals("zone_id", zoneId) + } + return q.Count() == 0 +} + func (self *SHostManager) AllowGetPropertyBmStartRegisterScript(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool { return true } @@ -1053,7 +1135,7 @@ func (manager *SHostManager) SyncHosts(ctx context.Context, userCred mcclient.To } func (self *SHost) syncWithCloudHost(extHost cloudprovider.ICloudHost, projectSync bool) error { - _, err := self.GetModelManager().TableSpec().Update(self, func() error { + _, err := self.SaveUpdates(func() error { self.Name = extHost.GetName() self.Status = extHost.GetStatus() @@ -1963,7 +2045,7 @@ func (self *SHost) PostCreate(ctx context.Context, userCred mcclient.TokenCreden return } if ipmiInfo.Length() > 0 { - _, err := HostManager.TableSpec().Update(self, func() error { + _, err := self.SaveUpdates(func() error { self.IpmiInfo = ipmiInfo return nil }) @@ -2031,7 +2113,7 @@ func (manager *SHostManager) ValidateCreateData(ctx context.Context, userCred mc } accessMac, err := data.GetString("access_mac") if err == nil { - count := manager.TableSpec().Query().Equals("access_mac", accessMac).Count() + count := HostManager.Query().Equals("access_mac", accessMac).Count() if count > 0 { return nil, httperrors.NewDuplicateResourceError("Duplicate access_mac %s", accessMac) } @@ -2097,7 +2179,7 @@ func (self *SHost) ValidateUpdateData(ctx context.Context, userCred mcclient.Tok val := jsonutils.NewDict() val.Update(self.IpmiInfo) val.Update(ipmiInfo) - data.Set("impi_info", val) + data.Set("ipmi_info", val) } data, err = self.SEnabledStatusStandaloneResourceBase.ValidateUpdateData(ctx, userCred, query, data) if err != nil { @@ -2145,9 +2227,10 @@ func (self *SHost) FetchIpmiInfo(data *jsonutils.JSONDict) (*jsonutils.JSONDict, IPMI_KEY_PERFIX := "ipmi_" ipmiInfo := jsonutils.NewDict() kv, _ := data.GetMap() + var err error for key := range kv { - value, err := ipmiInfo.GetString(key) - if strings.HasPrefix(value, IPMI_KEY_PERFIX) { + if strings.HasPrefix(key, IPMI_KEY_PERFIX) { + value, _ := data.GetString(key) subkey := key[len(IPMI_KEY_PERFIX):] data.Remove(key) if subkey == "password" { @@ -2156,8 +2239,13 @@ func (self *SHost) FetchIpmiInfo(data *jsonutils.JSONDict) (*jsonutils.JSONDict, log.Errorf("encrypt password failed %s", err) return nil, err } + } else if subkey == "ip_addr" { + if !regutils.MatchIP4Addr(value) { + log.Errorf("%s: %s not match ip address", key, value) + continue + } } - ipmiInfo.Set(key, jsonutils.NewString(value)) + ipmiInfo.Set(subkey, jsonutils.NewString(value)) } } return ipmiInfo, nil @@ -2359,12 +2447,16 @@ func (self *SHost) AllowPerformOffline(ctx context.Context, func (self *SHost) PerformOffline(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { if self.HostStatus != HOST_OFFLINE { - self.GetModelManager().TableSpec().Update(self, func() error { + _, err := self.SaveUpdates(func() error { self.HostStatus = HOST_OFFLINE return nil }) + if err != nil { + return nil, err + } db.OpsLog.LogEvent(self, db.ACT_OFFLINE, "", userCred) logclient.AddActionLog(self, logclient.ACT_ONLINE, nil, userCred, true) + self.SyncAttachedStorageStatus() } return nil, nil } @@ -2378,7 +2470,7 @@ func (self *SHost) AllowPerformOnline(ctx context.Context, func (self *SHost) PerformOnline(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { if self.HostStatus != HOST_ONLINE { - _, err := self.GetModelManager().TableSpec().Update(self, func() error { + _, err := self.SaveUpdates(func() error { self.LastPingAt = time.Now() self.HostStatus = HOST_ONLINE self.Status = BAREMETAL_RUNNING @@ -2416,7 +2508,7 @@ func (self *SHost) PerformPing(ctx context.Context, userCred mcclient.TokenCrede if self.HostStatus != HOST_ONLINE { self.PerformOnline(ctx, userCred, query, data) } else { - self.GetModelManager().TableSpec().Update(self, func() error { + self.SaveUpdates(func() error { self.LastPingAt = time.Now() return nil }) @@ -2493,18 +2585,26 @@ func (self *SHost) PerformAddNetif(ctx context.Context, userCred mcclient.TokenC reserve := jsonutils.QueryBoolean(data, "reserve", false) requireDesignatedIp := jsonutils.QueryBoolean(data, "require_designated_ip", false) - err := self.addNetif(ctx, userCred, mac, wire, ipAddr, int(rate), nicType, int8(index), utils.ToBool(linkUp), + isLinkUp := tristate.None + if linkUp != "" { + if utils.ToBool(linkUp) { + isLinkUp = tristate.True + } else { + isLinkUp = tristate.False + } + } + + err := self.addNetif(ctx, userCred, mac, wire, ipAddr, int(rate), nicType, int8(index), isLinkUp, int16(mtu), reset, strInterface, bridge, reserve, requireDesignatedIp) return nil, err } func (self *SHost) addNetif(ctx context.Context, userCred mcclient.TokenCredential, mac string, wire string, ipAddr string, - rate int, nicType string, index int8, linkUp bool, mtu int16, + rate int, nicType string, index int8, linkUp tristate.TriState, mtu int16, reset bool, strInterface string, bridge string, reserve bool, requireDesignatedIp bool, ) error { - var sw *SWire if len(wire) > 0 && len(ipAddr) == 0 { iWire, err := WireManager.FetchByIdOrName(userCred, wire) @@ -2539,7 +2639,9 @@ func (self *SHost) addNetif(ctx context.Context, userCred mcclient.TokenCredenti netif.Rate = rate netif.NicType = nicType netif.Index = index - netif.LinkUp = linkUp + if !linkUp.IsNone() { + netif.LinkUp = linkUp.Bool() + } netif.Mtu = mtu err = NetInterfaceManager.TableSpec().Insert(netif) if err != nil { @@ -2556,25 +2658,20 @@ func (self *SHost) addNetif(ctx context.Context, userCred mcclient.TokenCredenti changed = true netif.WireId = sw.Id } - if rate != netif.Rate { - changed = true - netif.Rate = int(rate) + if rate > 0 && rate != netif.Rate { + netif.Rate = rate } - if nicType != netif.NicType { - changed = true + if nicType != "" && nicType != netif.NicType { netif.NicType = nicType } if index >= 0 && index != netif.Index { - changed = true - netif.Index = int8(index) + netif.Index = index } - if linkUp != netif.LinkUp { - changed = true - netif.LinkUp = linkUp + if !linkUp.IsNone() && linkUp.Bool() != netif.LinkUp { + netif.LinkUp = linkUp.Bool() } - if mtu != netif.Mtu { - changed = true - netif.Mtu = int16(mtu) + if mtu > 0 && mtu != netif.Mtu { + netif.Mtu = mtu } return nil }) @@ -2870,24 +2967,46 @@ func (self *SHost) PerformRemoveAllNetifs(ctx context.Context, userCred mcclient return nil, nil } -func (self *SHost) AllowPerformDisable(ctx context.Context, +func (self *SHost) AllowPerformEnable( + ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, - data jsonutils.JSONObject) bool { - return db.IsAdminAllowPerform(userCred, self, "disable") + data jsonutils.JSONObject, +) bool { + return self.SEnabledStatusStandaloneResourceBase.AllowPerformEnable(ctx, userCred, query, data) +} + +func (self *SHost) PerformEnable( + ctx context.Context, + userCred mcclient.TokenCredential, + query jsonutils.JSONObject, + data jsonutils.JSONObject, +) (jsonutils.JSONObject, error) { + if !self.Enabled { + _, err := self.SEnabledStatusStandaloneResourceBase.PerformEnable(ctx, userCred, query, data) + if err != nil { + return nil, err + } + self.SyncAttachedStorageStatus() + } + return nil, nil +} + +func (self *SHost) AllowPerformDisable( + ctx context.Context, + userCred mcclient.TokenCredential, + query jsonutils.JSONObject, + data jsonutils.JSONObject, +) bool { + return self.SEnabledStatusStandaloneResourceBase.AllowPerformDisable(ctx, userCred, query, data) } func (self *SHost) PerformDisable(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { if self.Enabled { - _, err := self.GetModelManager().TableSpec().Update(self, func() error { - self.Enabled = false - return nil - }) + _, err := self.SEnabledStatusStandaloneResourceBase.PerformDisable(ctx, userCred, query, data) if err != nil { return nil, err } - db.OpsLog.LogEvent(self, db.ACT_DISABLE, "", userCred) - logclient.AddActionLog(self, logclient.ACT_DISABLE, nil, userCred, true) self.SyncAttachedStorageStatus() } return nil, nil diff --git a/pkg/compute/models/hoststorages.go b/pkg/compute/models/hoststorages.go index 2c2481fc67..48a6873bbe 100644 --- a/pkg/compute/models/hoststorages.go +++ b/pkg/compute/models/hoststorages.go @@ -3,7 +3,6 @@ package models import ( "context" "fmt" - "net/http" "yunion.io/x/jsonutils" "yunion.io/x/log" @@ -110,8 +109,7 @@ func (self *SHoststorage) PostCreate(ctx context.Context, userCred mcclient.Toke host := storage.GetMasterHost() log.Infof("Attach SharedStorage[%s] on host %s ...", storage.Name, host.Name) url := fmt.Sprintf("%s/storages/attach", host.ManagerUri) - headers := http.Header{} - headers.Set("X-Auth-Token", userCred.GetTokenString()) + headers := mcclient.GetTokenHeaders(userCred) body := jsonutils.NewDict() body.Set("mount_point", jsonutils.NewString(self.MountPoint)) body.Set("name", jsonutils.NewString(storage.Name)) @@ -142,8 +140,7 @@ func (self *SHoststorage) PreDelete(ctx context.Context, userCred mcclient.Token host := storage.GetMasterHost() log.Infof("Attach SharedStorage[%s] on host %s ...", storage.Name, host.Name) url := fmt.Sprintf("%s/storages/detach", host.ManagerUri) - headers := http.Header{} - headers.Set("X-Auth-Token", userCred.GetTokenString()) + headers := mcclient.GetTokenHeaders(userCred) body := jsonutils.NewDict() body.Set("mount_point", jsonutils.NewString(self.MountPoint)) body.Set("name", jsonutils.NewString(storage.Name)) diff --git a/pkg/compute/tasks/baremetal_delete_task.go b/pkg/compute/tasks/baremetal_delete_task.go index 08dd848847..cdbb887fbd 100644 --- a/pkg/compute/tasks/baremetal_delete_task.go +++ b/pkg/compute/tasks/baremetal_delete_task.go @@ -3,7 +3,6 @@ package tasks import ( "context" "fmt" - "net/http" "yunion.io/x/jsonutils" "yunion.io/x/log" @@ -29,9 +28,7 @@ func (self *BaremetalDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneM return } url := fmt.Sprintf("/baremetals/%s/delete", baremetal.Id) - headers := http.Header{} - headers.Set("X-Auth-Token", self.UserCred.GetTokenString()) - headers.Set("X-Task-Id", self.GetTaskId()) + headers := self.GetTaskRequestHeader() self.SetStage("OnDeleteBaremetalComplete", nil) _, err := baremetal.BaremetalSyncRequest(ctx, "POST", url, headers, nil) if err != nil { diff --git a/pkg/compute/tasks/baremetal_maintenance_task.go b/pkg/compute/tasks/baremetal_maintenance_task.go index 4575d9c82f..23c50a49ea 100644 --- a/pkg/compute/tasks/baremetal_maintenance_task.go +++ b/pkg/compute/tasks/baremetal_maintenance_task.go @@ -3,7 +3,6 @@ package tasks import ( "context" "fmt" - "net/http" "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudcommon/db" @@ -23,9 +22,7 @@ func init() { func (self *BaremetalMaintenanceTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) { baremetal := obj.(*models.SHost) url := fmt.Sprintf("/baremetals/%s/maintenance", baremetal.Id) - headers := http.Header{} - headers.Set("X-Auth-Token", self.UserCred.GetTokenString()) - headers.Set("X-Task-Id", self.GetTaskId()) + headers := self.GetTaskRequestHeader() self.SetStage("OnEnterMaintenantModeSucc", nil) _, err := baremetal.BaremetalSyncRequest(ctx, "POST", url, headers, self.Params) if err != nil { diff --git a/pkg/compute/tasks/baremetal_prepare_task.go b/pkg/compute/tasks/baremetal_prepare_task.go index 83b9615021..79cd189345 100644 --- a/pkg/compute/tasks/baremetal_prepare_task.go +++ b/pkg/compute/tasks/baremetal_prepare_task.go @@ -3,7 +3,6 @@ package tasks import ( "context" "fmt" - "net/http" "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudcommon/db" @@ -22,9 +21,7 @@ func init() { func (self *BaremetalPrepareTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) { baremetal := obj.(*models.SHost) url := fmt.Sprintf("/baremetals/%s/prepare", baremetal.Id) - headers := http.Header{} - headers.Set("X-Auth-Token", self.UserCred.GetTokenString()) - headers.Set("X-Task-Id", self.GetTaskId()) + headers := self.GetTaskRequestHeader() self.SetStage("OnSyncConfigComplete", nil) _, err := baremetal.BaremetalSyncRequest(ctx, "POST", url, headers, self.Params) if err != nil { diff --git a/pkg/compute/tasks/baremetal_server_reset_task.go b/pkg/compute/tasks/baremetal_server_reset_task.go index 1f5f623163..af3f90945a 100644 --- a/pkg/compute/tasks/baremetal_server_reset_task.go +++ b/pkg/compute/tasks/baremetal_server_reset_task.go @@ -3,7 +3,6 @@ package tasks import ( "context" "fmt" - "net/http" "yunion.io/x/jsonutils" "yunion.io/x/log" @@ -23,8 +22,7 @@ func (self *BaremetalServerResetTask) OnInit(ctx context.Context, obj db.IStanda return } url := fmt.Sprintf("/baremetals/%s/servers/%s/reset", baremetal.Id, guest.Id) - headers := http.Header{} - headers.Set("X-Auth-Token", self.UserCred.GetTokenString()) + headers := self.GetTaskRequestHeader() _, err := baremetal.BaremetalSyncRequest(ctx, "POST", url, headers, nil) if err != nil { log.Errorf(err.Error()) diff --git a/pkg/compute/tasks/baremetal_server_start_task.go b/pkg/compute/tasks/baremetal_server_start_task.go index 90b43230c0..29c567b2f8 100644 --- a/pkg/compute/tasks/baremetal_server_start_task.go +++ b/pkg/compute/tasks/baremetal_server_start_task.go @@ -3,7 +3,6 @@ package tasks import ( "context" "fmt" - "net/http" "yunion.io/x/jsonutils" "yunion.io/x/log" @@ -33,9 +32,7 @@ func (self *BaremetalServerStartTask) OnInit(ctx context.Context, obj db.IStanda config := jsonutils.NewDict() config.Set("desc", desc) url := fmt.Sprintf("/baremetals/%s/servers/%s/start", baremetal.Id, guest.Id) - headers := http.Header{} - headers.Set("X-Auth-Token", self.UserCred.GetTokenString()) - headers.Set("X-Task-Id", self.GetTaskId()) + headers := self.GetTaskRequestHeader() self.SetStage("OnStartComplete", nil) _, err := baremetal.BaremetalSyncRequest(ctx, "POST", url, headers, config) if err != nil { diff --git a/pkg/compute/tasks/baremetal_server_stop_task.go b/pkg/compute/tasks/baremetal_server_stop_task.go index 40258c42fd..a963c147e1 100644 --- a/pkg/compute/tasks/baremetal_server_stop_task.go +++ b/pkg/compute/tasks/baremetal_server_stop_task.go @@ -3,7 +3,6 @@ package tasks import ( "context" "fmt" - "net/http" "yunion.io/x/jsonutils" "yunion.io/x/log" @@ -39,9 +38,7 @@ func (self *BaremetalServerStopTask) OnInit(ctx context.Context, obj db.IStandal } params.Set("timeout", jsonutils.NewInt(timeout)) url := fmt.Sprintf("/baremetals/%s/servers/%s/stop", baremetal.Id, guest.Id) - headers := http.Header{} - headers.Set("X-Auth-Token", self.UserCred.GetTokenString()) - headers.Set("X-Task-Id", self.GetTaskId()) + headers := self.GetTaskRequestHeader() self.SetStage("OnGuestStopTaskComplete", nil) _, err = baremetal.BaremetalSyncRequest(ctx, "POST", url, headers, params) if err != nil { diff --git a/pkg/compute/tasks/baremetal_server_sync_status_task.go b/pkg/compute/tasks/baremetal_server_sync_status_task.go index 8e07cb1ce2..db2aa58874 100644 --- a/pkg/compute/tasks/baremetal_server_sync_status_task.go +++ b/pkg/compute/tasks/baremetal_server_sync_status_task.go @@ -3,7 +3,6 @@ package tasks import ( "context" "fmt" - "net/http" "yunion.io/x/jsonutils" "yunion.io/x/log" @@ -31,9 +30,7 @@ func (self *BaremetalServerSyncStatusTask) OnInit(ctx context.Context, obj db.IS return } url := fmt.Sprintf("/baremetals/%s/servers/%s/status", baremetal.Id, guest.Id) - headers := http.Header{} - headers.Set("X-Auth-Token", self.GetUserCred().GetTokenString()) - headers.Set("X-Task-Id", self.GetId()) + headers := self.GetTaskRequestHeader() self.SetStage("OnGuestStatusTaskComplete", nil) _, err := baremetal.BaremetalSyncRequest(ctx, "POST", url, headers, nil) if err != nil { diff --git a/pkg/compute/tasks/baremetal_sync_status_task.go b/pkg/compute/tasks/baremetal_sync_status_task.go index 0fbaf408d1..e94303a4ea 100644 --- a/pkg/compute/tasks/baremetal_sync_status_task.go +++ b/pkg/compute/tasks/baremetal_sync_status_task.go @@ -3,12 +3,12 @@ package tasks import ( "context" "fmt" - "net/http" "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/onecloud/pkg/util/logclient" ) type BaremetalSyncStatusTask struct { @@ -26,8 +26,7 @@ func (self *BaremetalSyncStatusTask) OnInit(ctx context.Context, obj db.IStandal func (self *BaremetalSyncStatusTask) DoSyncStatus(ctx context.Context, baremetal *models.SHost) { url := fmt.Sprintf("/baremetals/%s/syncstatus", baremetal.Id) - headers := http.Header{} - headers.Set("X-Auth-Token", self.UserCred.GetTokenString()) + headers := self.GetTaskRequestHeader() _, err := baremetal.BaremetalSyncRequest(ctx, "POST", url, headers, nil) if err == nil { self.SetStageComplete(ctx, nil) @@ -44,7 +43,33 @@ func (self *BaremetalSyncAllGuestsStatusTask) OnInit(ctx context.Context, obj db baremetal := obj.(*models.SHost) guest := baremetal.GetBaremetalServer() if guest != nil { - + var first bool + if !guest.IsSystem { + first = true + } + guest.GetModelManager().TableSpec().Update(guest, func() error { + guest.IsSystem = true + guest.VmemSize = 0 + guest.VcpuCount = 0 + return nil + }) + bs := baremetal.GetBaremetalstorage().GetStorage() + bs.SetStatus(self.UserCred, models.STORAGE_OFFLINE, "") + if first && baremetal.Name != guest.Name { + baremetal.GetModelManager().TableSpec().Update(baremetal, func() error { + if models.HostManager.IsNewNameUnique(guest.Name, self.UserCred, nil) { + baremetal.Name = guest.Name + } else { + baremetal.Name = db.GenerateName(baremetal.GetModelManager(), + self.UserCred.GetTokenString(), guest.Name) + } + return nil + }) + } + if first { + db.OpsLog.LogEvent(guest, db.ACT_CONVERT_COMPLETE, "", self.UserCred) + logclient.AddActionLog(guest, logclient.ACT_BM_CONVERT_HYPER, "", self.UserCred, true) + } } self.SetStage("OnGuestSyncStatusComplete", nil) self.OnGuestSyncStatusComplete(ctx, baremetal, nil) diff --git a/pkg/compute/tasks/baremetal_unmaintenance_task.go b/pkg/compute/tasks/baremetal_unmaintenance_task.go index 992dd07c70..456e0b7335 100644 --- a/pkg/compute/tasks/baremetal_unmaintenance_task.go +++ b/pkg/compute/tasks/baremetal_unmaintenance_task.go @@ -3,7 +3,6 @@ package tasks import ( "context" "fmt" - "net/http" "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudcommon/db" @@ -23,9 +22,7 @@ func init() { func (self *BaremetalUnmaintenanceTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) { baremetal := obj.(*models.SHost) url := fmt.Sprintf("/baremetals/%s/unmaintenance", baremetal.Id) - headers := http.Header{} - headers.Set("X-Auth-Token", self.UserCred.GetTokenString()) - headers.Set("X-Task-Id", self.GetTaskId()) + headers := self.GetTaskRequestHeader() self.SetStage("OnUnmaintenantComplete", nil) action := self.Action() _, err := baremetal.BaremetalSyncRequest(ctx, "POST", url, headers, self.Params) diff --git a/pkg/compute/tasks/guest_delete_task.go b/pkg/compute/tasks/guest_delete_task.go index 73d527cdb6..8c5811b710 100644 --- a/pkg/compute/tasks/guest_delete_task.go +++ b/pkg/compute/tasks/guest_delete_task.go @@ -5,6 +5,7 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/log" + "yunion.io/x/pkg/utils" "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" @@ -12,7 +13,6 @@ import ( "yunion.io/x/onecloud/pkg/compute/models" "yunion.io/x/onecloud/pkg/compute/options" "yunion.io/x/onecloud/pkg/util/logclient" - "yunion.io/x/pkg/utils" ) type GuestDeleteTask struct { @@ -27,6 +27,7 @@ func (self *GuestDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel guest := obj.(*models.SGuest) host := guest.GetHost() if guest.Hypervisor == models.HYPERVISOR_BAREMETAL && host.HostType != models.HOST_TYPE_BAREMETAL { + // if a fake server for converted hypervisor, then just skip stop self.OnGuestStopComplete(ctx, obj, data) return } diff --git a/pkg/compute/tasks/guest_live_migrate_task.go b/pkg/compute/tasks/guest_live_migrate_task.go index d94d0de4c3..62ff078a1c 100644 --- a/pkg/compute/tasks/guest_live_migrate_task.go +++ b/pkg/compute/tasks/guest_live_migrate_task.go @@ -3,7 +3,6 @@ package tasks import ( "context" "fmt" - "net/http" "yunion.io/x/jsonutils" "yunion.io/x/pkg/utils" @@ -95,10 +94,7 @@ func (self *GuestMigrateTask) SaveScheduleResult(ctx context.Context, obj ISched // For local storage get disk info func (self *GuestMigrateTask) OnCachedImageComplete(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) { - header := http.Header{} - header.Set("X-Auth-Token", self.GetUserCred().GetTokenString()) - header.Set("X-Task-Id", self.GetTaskId()) - header.Set("X-Region-Version", "v2") + header := self.GetTaskRequestHeader() body := jsonutils.NewDict() guestStatus, _ := self.Params.GetString("guest_status") if !jsonutils.QueryBoolean(self.Params, "is_rescue_mode", false) && (guestStatus == models.VM_RUNNING || guestStatus == models.VM_SUSPEND) { @@ -138,10 +134,7 @@ func (self *GuestMigrateTask) OnSrcPrepareComplete(ctx context.Context, guest *m body.Set("live_migrate", jsonutils.JSONTrue) } - headers := http.Header{} - headers.Set("X-Auth-Token", self.GetUserCred().GetTokenString()) - headers.Set("X-Task-Id", self.GetTaskId()) - headers.Set("X-Region-Version", "v2") + headers := self.GetTaskRequestHeader() url := fmt.Sprintf("%s/servers/%s/dest-prepare-migrate", targetHost.ManagerUri, guest.Id) self.SetStage("OnMigrateConfAndDiskComplete", nil) @@ -266,10 +259,7 @@ func (self *GuestLiveMigrateTask) OnStartDestComplete(ctx context.Context, guest body.Set("live_migrate_dest_port", liveMigrateDestPort) body.Set("dest_ip", jsonutils.NewString(targetHost.AccessIp)) - headers := http.Header{} - headers.Set("X-Auth-Token", self.GetUserCred().GetTokenString()) - headers.Set("X-Task-Id", self.GetTaskId()) - headers.Set("X-Region-Version", "v2") + headers := self.GetTaskRequestHeader() host := guest.GetHost() url := fmt.Sprintf("%s/servers/%s/live-migrate", host.ManagerUri, guest.Id) @@ -325,10 +315,7 @@ func (self *GuestLiveMigrateTask) OnLiveMigrateCompleteFailed(ctx context.Contex } func (self *GuestLiveMigrateTask) OnLiveMigrateComplete(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) { - headers := http.Header{} - headers.Set("X-Auth-Token", self.GetUserCred().GetTokenString()) - headers.Set("X-Task-Id", self.GetTaskId()) - headers.Set("X-Region-Version", "v2") + headers := self.GetTaskRequestHeader() body := jsonutils.NewDict() body.Set("live_migrate", jsonutils.JSONTrue) targetHostId, _ := self.Params.GetString("target_host_id") diff --git a/pkg/mcclient/session.go b/pkg/mcclient/session.go index 2bbcaf57f9..f4e92b53a0 100644 --- a/pkg/mcclient/session.go +++ b/pkg/mcclient/session.go @@ -47,6 +47,13 @@ func populateHeader(self *http.Header, update http.Header) { } } +func GetTokenHeaders(userCred TokenCredential) http.Header { + headers := http.Header{} + headers.Set(AUTH_TOKEN, userCred.GetTokenString()) + headers.Set(REGION_VERSION, "v2") + return headers +} + func SplitVersionedURL(url string) (string, string) { endidx := len(url) - 1 for ; endidx >= 0 && url[endidx] == '/'; endidx-- { diff --git a/pkg/scheduler/algorithm/predicates/baremetal/network_predicate.go b/pkg/scheduler/algorithm/predicates/baremetal/network_predicate.go index c569a8397e..45f73219e7 100644 --- a/pkg/scheduler/algorithm/predicates/baremetal/network_predicate.go +++ b/pkg/scheduler/algorithm/predicates/baremetal/network_predicate.go @@ -5,10 +5,11 @@ import ( "strings" "sync" + "yunion.io/x/pkg/utils" + "yunion.io/x/onecloud/pkg/scheduler/algorithm/predicates" "yunion.io/x/onecloud/pkg/scheduler/api" "yunion.io/x/onecloud/pkg/scheduler/core" - "yunion.io/x/pkg/utils" ) type NetworkPredicate struct { diff --git a/pkg/util/esxi/hostnic.go b/pkg/util/esxi/hostnic.go index 242c7ae76b..7c9be2a39a 100644 --- a/pkg/util/esxi/hostnic.go +++ b/pkg/util/esxi/hostnic.go @@ -1,5 +1,9 @@ package esxi +import ( + "yunion.io/x/pkg/tristate" +) + type SHostNicInfo struct { Dev string Driver string @@ -27,8 +31,11 @@ func (nic *SHostNicInfo) GetIndex() int8 { return nic.Index } -func (nic *SHostNicInfo) IsLinkUp() bool { - return nic.LinkUp +func (nic *SHostNicInfo) IsLinkUp() tristate.TriState { + if nic.LinkUp { + return tristate.True + } + return tristate.False } func (nic *SHostNicInfo) GetIpAddr() string { diff --git a/vendor/yunion.io/x/sqlchemy/update.go b/vendor/yunion.io/x/sqlchemy/update.go index f88e1a6bde..43ac815135 100644 --- a/vendor/yunion.io/x/sqlchemy/update.go +++ b/vendor/yunion.io/x/sqlchemy/update.go @@ -83,10 +83,7 @@ func (us *SUpdateSession) saveUpdate(dt interface{}) (map[string]SUpdateDiff, er setters := make(map[string]SUpdateDiff) for _, c := range us.tableSpec.columns { k := c.Name() - of, ok := ofields[k] - if !ok { - continue - } + of := ofields[k] nf := fields[k] if c.IsPrimary() && !c.IsZero(of) { // skip update primary key primaries[k] = of