Merge pull request #25 in YUNIONIO/onecloud from ~QIUJIAN/onecloud:hotfix/qj-misc-bugfix-20180808 to release/2.0.0

* commit '1585d24302c5f0bfe28f769ad2aeef86a8afed9c':
  修正:阿里云回收站主机恢复后无系统盘
  修正:1. 删除VPC导致hostwire数据不一致问题 2. 阿里云主机无操作系统信息 3. 其他一些BUGfix
  temp commit
  temporary commit
This commit is contained in:
邱剑
2018-08-10 11:38:23 +08:00
24 changed files with 423 additions and 66 deletions
+4
View File
@@ -142,6 +142,7 @@ func init() {
type CloudproviderSyncOptions struct {
ID string `help:"ID or Name of cloud provider"`
Force bool `help:"Force sync no matter what"`
FullSync bool `help:"Synchronize everything"`
Region []string `help:"region to sync"`
Zone []string `help:"region to sync"`
Host []string `help:"region to sync"`
@@ -151,6 +152,9 @@ func init() {
if args.Force {
params.Add(jsonutils.JSONTrue, "force")
}
if args.FullSync {
params.Add(jsonutils.JSONTrue, "full_sync")
}
if len(args.Region) > 0 {
params.Add(jsonutils.NewStringArray(args.Region), "region")
}
+4 -1
View File
@@ -5,6 +5,7 @@ import (
"github.com/yunionio/log"
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
"database/sql"
)
const (
@@ -37,7 +38,9 @@ func (manager *SSubTaskmanager) GetSubTask(ptaskId string, subtaskId string) *SS
subtask := SSubTask{}
err := manager.Query().Equals("task_id", ptaskId).Equals("subtask_id", subtaskId).First(&subtask)
if err != nil {
log.Errorf("GetSubTask fail %s", err)
if err != sql.ErrNoRows {
log.Errorf("GetSubTask fail %s", err)
}
return nil
}
return &subtask
+4
View File
@@ -256,6 +256,10 @@ func (model *SVirtualResourceBase) AllowPerformCancelDelete(ctx context.Context,
return false
}
/*func DoCancelPendingDelete(model IVirtualModel, ctx context.Context, userCred mcclient.TokenCredential) error {
return model.DoCancelPendingDelete(ctx, userCred)
}*/
func (model *SVirtualResourceBase) PerformCancelDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
if model.PendingDeleted {
err := model.DoCancelPendingDelete(ctx, userCred)
+16 -2
View File
@@ -9,13 +9,13 @@ import (
"github.com/yunionio/log"
"github.com/yunionio/onecloud/pkg/httperrors"
"github.com/yunionio/onecloud/pkg/mcclient"
"github.com/yunionio/pkg/util/seclib"
"github.com/yunionio/pkg/utils"
"github.com/yunionio/onecloud/pkg/cloudcommon/db"
"github.com/yunionio/onecloud/pkg/cloudcommon/db/taskman"
"github.com/yunionio/onecloud/pkg/cloudprovider"
"github.com/yunionio/onecloud/pkg/compute/models"
"github.com/yunionio/onecloud/pkg/util/seclib2"
)
type SAliyunGuestDriver struct {
@@ -62,6 +62,8 @@ func (self *SAliyunGuestDriver) ValidateCreateData(ctx context.Context, userCred
type SAliyunVMCreateConfig struct {
Name string
ExternalImageId string
OsDistribution string
OsVersion string
Cpu int
Memory int
ExternalNetworkId string
@@ -101,6 +103,11 @@ func (self *SAliyunGuestDriver) GetJsonDescAtHost(ctx context.Context, guest *mo
imageId := disk.GetTemplateId()
scimg := models.StoragecachedimageManager.GetStoragecachedimage(cache.Id, imageId)
config.ExternalImageId = scimg.ExternalId
img := scimg.GetCachedimage()
config.OsDistribution, _ = img.Info.GetString("properties", "os_distribution")
config.OsVersion, _ = img.Info.GetString("properties", "os_version")
config.SysDiskSize = disk.DiskSize / 1024 // MB => GB
} else {
config.DataDisks[i-1] = disk.DiskSize / 1024 // MB => GB
@@ -143,7 +150,7 @@ func (self *SAliyunGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gu
}
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
passwd := seclib.RandomPassword(12)
passwd := seclib2.RandomPassword2(12)
iVM, err := ihost.CreateVM(desc.Name, desc.ExternalImageId, desc.SysDiskSize, desc.Cpu, desc.Memory, desc.ExternalNetworkId,
desc.IpAddr, desc.Description, passwd, desc.StorageType, desc.DataDisks, desc.PublicKey)
@@ -180,6 +187,13 @@ func (self *SAliyunGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gu
data.Add(jsonutils.NewString("root"), "account")
data.Add(jsonutils.NewString(encpasswd), "key")
if len(desc.OsDistribution) > 0 {
data.Add(jsonutils.NewString(desc.OsDistribution), "distro")
}
if len(desc.OsVersion) > 0 {
data.Add(jsonutils.NewString(desc.OsVersion), "version")
}
idisks, err := iVM.GetIDisks()
if err != nil {
+16 -1
View File
@@ -111,8 +111,23 @@ func (self *SManagedVirtualizedGuestDriver) RequestSyncstatusOnHost(ctx context.
log.Errorf("fail to find ivm by id %s", err)
return nil, err
}
status := ivm.GetStatus()
switch status {
case models.VM_RUNNING:
status = cloudprovider.CloudVMStatusRunning
case models.VM_READY:
status = cloudprovider.CloudVMStatusStopped
case models.VM_STARTING:
status = cloudprovider.CloudVMStatusStopped
case models.VM_STOPPING:
status = cloudprovider.CloudVMStatusRunning
default:
status = cloudprovider.CloudVMStatusOther
}
body := jsonutils.NewDict()
body.Add(jsonutils.NewString(ivm.GetStatus()), "status")
body.Add(jsonutils.NewString(status), "status")
return body, nil
}
+9 -1
View File
@@ -6,6 +6,7 @@ import (
"regexp"
"github.com/yunionio/jsonutils"
"github.com/yunionio/log"
"github.com/yunionio/onecloud/pkg/httperrors"
"github.com/yunionio/onecloud/pkg/mcclient"
@@ -41,11 +42,18 @@ func (self *SVirtualizedGuestDriver) Attach2RandomNetwork(guest *models.SGuest,
if len(netConfig.Wire) > 0 {
wirePattern = regexp.MustCompile(netConfig.Wire)
}
hostwires := host.GetWires()
hostwires := host.GetHostwires()
netsAvaiable := make([]models.SNetwork, 0)
for i := 0; i < len(hostwires); i += 1 {
hostwire := hostwires[i]
wire := hostwire.GetWire()
if wire == nil {
continue
}
log.Debugf("Wire %#v", wire)
if wirePattern != nil && !wirePattern.MatchString(wire.Id) && wirePattern.MatchString(wire.Name) {
continue
}
+113 -8
View File
@@ -52,7 +52,7 @@ type SCloudprovider struct {
LastSync time.Time `get:"admin" list:"admin"` // = Column(DateTime, nullable=True)
// Version string `width:"32" charset:"ascii" nullable:"true" list:"admin"` // Column(VARCHAR(32, charset='ascii'), nullable=True)
Version string `width:"32" charset:"ascii" nullable:"true" list:"admin"` // Column(VARCHAR(32, charset='ascii'), nullable=True)
Sysinfo jsonutils.JSONObject `get:"admin"` // Column(JSONEncodedDict, nullable=True)
@@ -123,10 +123,21 @@ func (self *SCloudprovider) PostCreate(ctx context.Context, userCred mcclient.To
}
func (self *SCloudprovider) savePassword(secret string) error {
sec, err := utils.EncryptAESBase64(self.Id, self.Secret)
sec, err := utils.EncryptAESBase64(self.Id, secret)
if err != nil {
return err
}
/*log.Debugf("savePassword %s => %s", secret, sec)
newsec, err := utils.DescryptAESBase64(self.Id, sec)
if err != nil {
return err
}
if newsec != secret {
log.Errorf("Encrypt/Descrypt mismatch!!")
return fmt.Errorf("Encrypt/Descrypt mismatch!!")
}*/
_, err = self.GetModelManager().TableSpec().Update(self, func() error {
self.Secret = sec
return nil
@@ -151,10 +162,94 @@ func (self *SCloudprovider) CanSync() bool {
}
type SSyncRange struct {
Force bool
Region []string
Zone []string
Host []string
Force bool
FullSync bool
Region []string
Zone []string
Host []string
}
func (sr *SSyncRange) NeedSyncInfo() bool {
if sr.FullSync {
return true
}
if sr.Region != nil && len(sr.Region) > 0 {
return true
}
if sr.Zone != nil && len(sr.Zone) > 0 {
return true
}
if sr.Host != nil && len(sr.Host) > 0 {
return true
}
return false
}
func (sr *SSyncRange) normalizeRegionIds() error {
for i := 0; i < len(sr.Region); i += 1 {
obj, err := CloudregionManager.FetchByIdOrName("", sr.Region[i])
if err != nil {
if err == sql.ErrNoRows {
return httperrors.NewResourceNotFoundError("Region %s not found", sr.Region[i])
} else {
return err
}
}
sr.Region[i] = obj.GetId()
}
return nil
}
func (sr *SSyncRange) normalizeZoneIds() error {
for i := 0; i < len(sr.Zone); i += 1 {
obj, err := ZoneManager.FetchByIdOrName("", sr.Zone[i])
if err != nil {
if err == sql.ErrNoRows {
return httperrors.NewResourceNotFoundError("Zone %s not found", sr.Zone[i])
} else {
return err
}
}
sr.Zone[i] = obj.GetId()
}
return nil
}
func (sr *SSyncRange) normalizeHostIds() error {
for i := 0; i < len(sr.Host); i += 1 {
obj, err := HostManager.FetchByIdOrName("", sr.Host[i])
if err != nil {
if err == sql.ErrNoRows {
return httperrors.NewResourceNotFoundError("Host %s not found", sr.Host[i])
} else {
return err
}
}
sr.Host[i] = obj.GetId()
}
return nil
}
func (sr *SSyncRange) Normalize() error {
if sr.Region != nil && len(sr.Region) > 0 {
err := sr.normalizeRegionIds()
if err != nil {
return err
}
}
if sr.Zone != nil && len(sr.Zone) > 0 {
err := sr.normalizeZoneIds()
if err != nil {
return err
}
}
if sr.Host != nil && len(sr.Host) > 0 {
err := sr.normalizeHostIds()
if err != nil {
return err
}
}
return nil
}
func (self *SCloudprovider) AllowPerformSync(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
@@ -162,10 +257,13 @@ func (self *SCloudprovider) AllowPerformSync(ctx context.Context, userCred mccli
}
func (self *SCloudprovider) PerformSync(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
if ! self.Enabled {
return nil, httperrors.NewInvalidStatusError("Cloudprovider disabled")
}
syncRange := SSyncRange{}
err := data.Unmarshal(&syncRange)
if err != nil {
return nil, httperrors.NewInputParameterError("invalud input %s", err)
return nil, httperrors.NewInputParameterError("invalid input %s", err)
}
if self.CanSync() || syncRange.Force {
err = self.startSyncCloudProviderInfoTask(ctx, userCred, &syncRange, "")
@@ -178,6 +276,10 @@ func (self *SCloudprovider) AllowPerformUpdateCredential(ctx context.Context, us
}
func (self *SCloudprovider) PerformUpdateCredential(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
if ! self.Enabled {
return nil, httperrors.NewInvalidStatusError("Cloudprovider disabled")
}
var err error
changed := false
secret, _ := data.GetString("secret")
@@ -215,7 +317,7 @@ func (self *SCloudprovider) PerformUpdateCredential(ctx context.Context, userCre
}
changed = true
}
if changed && self.CanSync() {
if changed {
self.SetStatus(userCred, CLOUD_PROVIDER_INIT, "Change credential")
self.startSyncCloudProviderInfoTask(ctx, userCred, nil, "")
}
@@ -252,10 +354,13 @@ func (self *SCloudprovider) GetDriver() (cloudprovider.ICloudProvider, error) {
if !self.Enabled {
return nil, fmt.Errorf("Cloud provider is not enabled")
}
secret, err := self.getPassword()
if err != nil {
return nil, fmt.Errorf("Invalid password %s", err)
}
// log.Debugf("XXXXX secret: %s", secret)
return cloudprovider.GetProvider(self.Id, self.Name, self.AccessUrl, self.Account, secret, self.Provider)
}
+14 -1
View File
@@ -486,7 +486,8 @@ func (self *SDisk) fetchDiskInfo(diskConfig *SDiskConfig) {
if len(diskConfig.ImageId) > 0 {
self.TemplateId = diskConfig.ImageId
self.DiskType = DISK_TYPE_SYS
} else if len(diskConfig.Fs) > 0 {
}
if len(diskConfig.Fs) > 0 {
self.FsFormat = diskConfig.Fs
}
if self.FsFormat == "swap" {
@@ -619,3 +620,15 @@ func (self *SDisk) isReady() bool {
func (self *SDisk) isInit() bool {
return self.Status == DISK_INIT
}
func (model *SDisk) AllowPerformCancelDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return userCred.IsSystemAdmin()
}
func (self *SDisk) PerformCancelDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
if self.PendingDeleted {
err := self.DoCancelPendingDelete(ctx, userCred)
return nil, err
}
return nil, nil
}
+21 -9
View File
@@ -1953,7 +1953,7 @@ func (self *SGuest) DoPendingDelete(ctx context.Context, userCred mcclient.Token
for _, guestdisk := range self.GetDisks() {
disk := guestdisk.GetDisk()
storage := disk.GetStorage()
if utils.IsInStringArray(storage.StorageType, sysutils.LOCAL_STORAGE_TYPES) || disk.DiskType == DISK_TYPE_SYS || disk.DiskType == DISK_TYPE_SWAP {
if utils.IsInStringArray(storage.StorageType, sysutils.LOCAL_STORAGE_TYPES) || disk.DiskType == DISK_TYPE_SYS || disk.DiskType == DISK_TYPE_SWAP || self.Hypervisor == HYPERVISOR_ALIYUN {
disk.DoPendingDelete(ctx, userCred)
} else {
self.detachDisk(ctx, disk, userCred)
@@ -1962,6 +1962,26 @@ func (self *SGuest) DoPendingDelete(ctx context.Context, userCred mcclient.Token
self.SVirtualResourceBase.DoPendingDelete(ctx, userCred)
}
func (model *SGuest) AllowPerformCancelDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return userCred.IsSystemAdmin()
}
func (self *SGuest) PerformCancelDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
if self.PendingDeleted {
err := self.DoCancelPendingDelete(ctx, userCred)
return nil, err
}
return nil, nil
}
func (self *SGuest) DoCancelPendingDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
for _, guestdisk := range self.GetDisks() {
disk := guestdisk.GetDisk()
disk.DoCancelPendingDelete(ctx, userCred)
}
return self.SVirtualResourceBase.DoCancelPendingDelete(ctx, userCred)
}
func (self *SGuest) StartUndeployGuestTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string, targetHostId string) error {
data := jsonutils.NewDict()
if len(targetHostId) > 0 {
@@ -2548,10 +2568,6 @@ func (self *SGuest) GetDetailsVnc(ctx context.Context, userCred mcclient.TokenCr
}
}
func (model *SGuestManager) AllowPerformCancelDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return userCred.IsSystemAdmin()
}
func (self *SGuest) GetKeypairPublicKey() string {
keypair := self.getKeypair()
if keypair != nil {
@@ -2560,10 +2576,6 @@ func (self *SGuest) GetKeypairPublicKey() string {
return ""
}
func (model *SGuest) AllowPerformCancelDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return userCred.IsSystemAdmin()
}
func (manager *SGuestManager) GetIpInProjectWithName(projectId, name string, isExitOnly bool) []string {
guestnics := GuestnetworkManager.Query().SubQuery()
guests := manager.Query().SubQuery()
+30 -5
View File
@@ -344,8 +344,9 @@ func (self *SHost) RealDelete(ctx context.Context, userCred mcclient.TokenCreden
for _, netif := range self.GetNetInterfaces() {
netif.Remove(ctx, userCred)
}
for _, hostwire := range self.GetWires() {
hostwire.Delete(ctx, userCred)
for _, hostwire := range self.GetHostwires() {
hostwire.Detach(ctx, userCred)
// hostwire.Delete(ctx, userCred)
}
return self.SEnabledStatusStandaloneResourceBase.Delete(ctx, userCred)
}
@@ -572,7 +573,7 @@ func (self *SHost) GetWireCount() int {
return self.GetWiresQuery().Count()
}
func (self *SHost) GetWires() []SHostwire {
func (self *SHost) GetHostwires() []SHostwire {
hw := make([]SHostwire, 0)
q := self.GetWiresQuery()
err := db.FetchModelObjects(HostwireManager, q, &hw)
@@ -897,7 +898,19 @@ func (manager *SHostManager) newFromCloudHost(extHost cloudprovider.ICloudHost,
func (self *SHost) SyncHostStorages(ctx context.Context, userCred mcclient.TokenCredential, storages []cloudprovider.ICloudStorage) compare.SyncResult {
syncResult := compare.SyncResult{}
dbStorages := self._getAttachedStorages(tristate.None, tristate.None)
dbStorages := make([]SStorage, 0)
hostStorages := self.GetHoststorages()
for i := 0; i < len(hostStorages); i += 1 {
storage := hostStorages[i].GetStorage()
if storage == nil {
hostStorages[i].Delete(ctx, userCred)
} else {
dbStorages = append(dbStorages, *storage)
}
}
// dbStorages := self._getAttachedStorages(tristate.None, tristate.None)
removed := make([]SStorage, 0)
commondb := make([]SStorage, 0)
@@ -980,7 +993,19 @@ func (self *SHost) newCloudHostStorage(ctx context.Context, userCred mcclient.To
func (self *SHost) SyncHostWires(ctx context.Context, userCred mcclient.TokenCredential, wires []cloudprovider.ICloudWire) compare.SyncResult {
syncResult := compare.SyncResult{}
dbWires := self.getAttachedWires()
dbWires := make([]SWire, 0)
hostWires := self.GetHostwires()
for i := 0; i < len(hostWires); i += 1 {
wire := hostWires[i].GetWire()
if wire == nil {
hostWires[i].Delete(ctx, userCred)
} else {
dbWires = append(dbWires, *wire)
}
}
// dbWires := self.getAttachedWires()
removed := make([]SWire, 0)
commondb := make([]SWire, 0)
+10 -3
View File
@@ -41,6 +41,7 @@ const (
NETWORK_STATUS_PENDING = "pending"
NETWORK_STATUS_AVAILABLE = "available"
NETWORK_STATUS_FAILED = "failed"
NETWORK_STATUS_UNKNOWN = "unknown"
NETWORK_STATUS_START_DELETE = "start_delete"
NETWORK_STATUS_DELETING = "deleting"
NETWORK_STATUS_DELETED = "deleted"
@@ -413,7 +414,7 @@ func (manager *SNetworkManager) SyncNetworks(ctx context.Context, userCred mccli
}
for i := 0; i < len(removed); i += 1 {
err = removed[i].ValidateDeleteCondition(ctx)
/*err = removed[i].ValidateDeleteCondition(ctx)
if err != nil { // cannot delete
syncResult.DeleteError(err)
} else {
@@ -423,6 +424,12 @@ func (manager *SNetworkManager) SyncNetworks(ctx context.Context, userCred mccli
} else {
syncResult.Delete()
}
}*/
err = removed[i].SetStatus(userCred, NETWORK_STATUS_UNKNOWN, "Sync to remove")
if err != nil {
syncResult.DeleteError(err)
} else {
syncResult.Delete()
}
}
for i := 0; i < len(commondb); i += 1 {
@@ -834,7 +841,7 @@ func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred
maskLen64 = int64(prefix.MaskLen)
} else {
ipStartStr, _ := data.GetString("guest_ip_start")
ipEndStr, _ := data.GetString("guest_ip_start")
ipEndStr, _ := data.GetString("guest_ip_end")
startIp, err = netutils.NewIPV4Addr(ipStartStr)
if err != nil {
return nil, httperrors.NewInputParameterError("Invalid start ip: %s %s", ipStartStr, err)
@@ -971,7 +978,7 @@ func (self *SNetwork) ValidateUpdateData(ctx context.Context, userCred mcclient.
var err error
ipStartStr, _ := data.GetString("guest_ip_start")
ipEndStr, _ := data.GetString("guest_ip_start")
ipEndStr, _ := data.GetString("guest_ip_end")
if len(ipStartStr) > 0 || len(ipEndStr) > 0 {
if self.isManaged() {
+7 -7
View File
@@ -87,7 +87,7 @@ func (manager *SStoragecachedimageManager) AllowListDescendent(ctx context.Conte
return userCred.IsSystemAdmin()
}
func (self *SStoragecachedimage) getCachedimage() *SCachedimage {
func (self *SStoragecachedimage) GetCachedimage() *SCachedimage {
cachedImage, _ := CachedimageManager.FetchById(self.CachedimageId)
if cachedImage != nil {
return cachedImage.(*SCachedimage)
@@ -95,7 +95,7 @@ func (self *SStoragecachedimage) getCachedimage() *SCachedimage {
return nil
}
func (self *SStoragecachedimage) getStoragecache() *SStoragecache {
func (self *SStoragecachedimage) GetStoragecache() *SStoragecache {
cache, _ := StoragecacheManager.FetchById(self.StoragecacheId)
if cache != nil {
return cache.(*SStoragecache)
@@ -104,11 +104,11 @@ func (self *SStoragecachedimage) getStoragecache() *SStoragecache {
}
func (self *SStoragecachedimage) getExtraDetails(extra *jsonutils.JSONDict) *jsonutils.JSONDict {
storagecache := self.getStoragecache()
storagecache := self.GetStoragecache()
if storagecache != nil {
extra.Add(jsonutils.NewStringArray(storagecache.getStorageNames()), "storages")
}
cachedImage := self.getCachedimage()
cachedImage := self.GetCachedimage()
if cachedImage != nil {
extra.Add(jsonutils.NewString(cachedImage.getName()), "image")
extra.Add(jsonutils.NewInt(cachedImage.Size), "size")
@@ -167,7 +167,7 @@ func (self *SStoragecachedimage) ValidateDeleteCondition(ctx context.Context) er
if !self.isDownloadSessionExpire() {
return httperrors.NewResourceBusyError("Active download session not expired")
}
image := self.getCachedimage()
image := self.GetCachedimage()
if !image.canDeleteLastCache() {
return httperrors.NewResourceBusyError("Cannot delete the last cache")
}
@@ -188,8 +188,8 @@ func (self *SStoragecachedimage) markDeleting(ctx context.Context, userCred mccl
return err
}
cache := self.getStoragecache()
image := self.getCachedimage()
cache := self.GetStoragecache()
image := self.GetCachedimage()
lockman.LockJointObject(ctx, cache, image)
defer lockman.ReleaseJointObject(ctx, cache, image)
+1 -1
View File
@@ -136,7 +136,7 @@ func (self *SStoragecache) getCachedImageSize() int64 {
}
var size int64 = 0
for _, img := range images {
imginfo := img.getCachedimage()
imginfo := img.GetCachedimage()
size += imginfo.Size
}
return size
+31 -18
View File
@@ -25,6 +25,7 @@ const (
VPC_STATUS_DELETING = "deleting"
VPC_STATUS_DELETE_FAILED = "delete_failed"
VPC_STATUS_DELETED = "deleted"
VPC_STATUS_UNKNOWN = "unknown"
MAX_VPC_PER_REGION = 3
)
@@ -189,25 +190,26 @@ func (manager *SVpcManager) SyncVPCs(ctx context.Context, userCred mcclient.Toke
}
for i := 0; i < len(removed); i += 1 {
err = removed[i].ValidateDeleteCondition(ctx)
if err != nil { // cannot delete
_, err = removed[i].PerformDisable(ctx, userCred, nil, nil)
if err == nil {
err = removed[i].SetStatus(userCred, VPC_STATUS_PENDING, "sync to delete")
}
if err != nil {
syncResult.DeleteError(err)
} else {
syncResult.Delete()
}
} else {
err = removed[i].Delete(ctx, userCred)
if err != nil {
syncResult.DeleteError(err)
} else {
syncResult.Delete()
}
// err = removed[i].ValidateDeleteCondition(ctx)
// if err != nil { // cannot delete
removed[i].markAllNetworksUnknown(userCred)
_, err = removed[i].PerformDisable(ctx, userCred, nil, nil)
if err == nil {
err = removed[i].SetStatus(userCred, VPC_STATUS_UNKNOWN, "sync to delete")
}
if err != nil {
syncResult.DeleteError(err)
} else {
syncResult.Delete()
}
// } else {
// err = removed[i].Delete(ctx, userCred)
// if err != nil {
// syncResult.DeleteError(err)
// } else {
// syncResult.Delete()
// }
// }
}
for i := 0; i < len(commondb); i += 1 {
err = commondb[i].SyncWithCloudVpc(commonext[i])
@@ -274,6 +276,17 @@ func (manager *SVpcManager) newFromCloudVpc(extVPC cloudprovider.ICloudVpc, regi
return &vpc, nil
}
func (self *SVpc) markAllNetworksUnknown(userCred mcclient.TokenCredential) error {
wires := self.GetWires()
if wires == nil || len(wires) == 0 {
return nil
}
for i := 0; i <= len(wires); i += 1 {
wires[i].markNetworkUnknown(userCred)
}
return nil
}
func (manager *SVpcManager) InitializeData() error {
vpcObj, err := manager.FetchById("default")
if err != nil {
+44 -3
View File
@@ -83,11 +83,25 @@ func (wire *SWire) ValidateDeleteCondition(ctx context.Context) error {
return wire.SStandaloneResourceBase.ValidateDeleteCondition(ctx)
}
func (wire *SWire) getHostwireQuery() *sqlchemy.SQuery {
return HostwireManager.Query().Equals("wire_id", wire.Id)
}
func (wire *SWire) HostCount() int {
q := HostwireManager.Query().Equals("wire_id", wire.Id)
q := wire.getHostwireQuery()
return q.Count()
}
func (wire *SWire) GetHostwires() ([]SHostwire, error) {
q := wire.getHostwireQuery()
hostwires := make([]SHostwire, 0)
err := db.FetchModelObjects(HostwireManager, q, &hostwires)
if err != nil {
return nil, err
}
return hostwires, nil
}
func (wire *SWire) NetworkCount() int {
q := NetworkManager.Query().Equals("wire_id", wire.Id)
return q.Count()
@@ -141,7 +155,13 @@ func (manager *SWireManager) SyncWires(ctx context.Context, userCred mcclient.To
}
for i := 0; i < len(removed); i += 1 {
err = removed[i].ValidateDeleteCondition(ctx)
err = removed[i].markNetworkUnknown(userCred)
if err != nil { // cannot delete
syncResult.DeleteError(err)
} else {
syncResult.Delete()
}
/* err = removed[i].ValidateDeleteCondition(ctx)
if err != nil { // cannot delete
syncResult.DeleteError(err)
} else {
@@ -151,7 +171,7 @@ func (manager *SWireManager) SyncWires(ctx context.Context, userCred mcclient.To
} else {
syncResult.Delete()
}
}
}*/
}
for i := 0; i < len(commondb); i += 1 {
err = commondb[i].syncWithCloudWire(commonext[i])
@@ -192,6 +212,17 @@ func (self *SWire) syncWithCloudWire(extWire cloudprovider.ICloudWire) error {
return err
}
func (self *SWire) markNetworkUnknown(userCred mcclient.TokenCredential) error {
nets, err := self.getNetworks()
if err != nil {
return err
}
for i := 0; i < len(nets); i += 1 {
nets[i].SetStatus(userCred, NETWORK_STATUS_UNKNOWN, "wire sync to remove")
}
return nil
}
func (manager *SWireManager) newFromCloudWire(extWire cloudprovider.ICloudWire, vpc *SVpc) (*SWire, error) {
wire := SWire{}
wire.SetModelManager(manager)
@@ -303,6 +334,16 @@ func (self *SWire) getNetworkQuery() *sqlchemy.SQuery {
return NetworkManager.Query().Equals("wire_id", self.Id)
}
func (self *SWire) getNetworks() ([]SNetwork, error) {
q := self.getNetworkQuery()
nets := make([]SNetwork, 0)
err := db.FetchModelObjects(NetworkManager, q, &nets)
if err != nil {
return nil, err
}
return nets, nil
}
func (self *SWire) getGatewayNetworkQuery() *sqlchemy.SQuery {
q := self.getNetworkQuery()
q = q.IsNotNull("guest_gateway").IsNotEmpty("guest_gateway")
@@ -52,7 +52,8 @@ func (self *CloudProviderSyncInfoTask) OnInit(ctx context.Context, obj db.IStand
if syncRangeJson != nil {
syncRange := models.SSyncRange{}
err = syncRangeJson.Unmarshal(&syncRange)
if err == nil {
if err == nil && syncRange.NeedSyncInfo() {
syncRange.Normalize()
syncCloudProviderInfo(ctx, provider, self, driver, &syncRange)
}
}
@@ -80,7 +81,7 @@ func syncCloudProviderInfo(ctx context.Context, provider *models.SCloudprovider,
db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, msg, task.UserCred)
for i := 0; i < len(localRegions); i += 1 {
if len(syncRange.Region) > 0 && !utils.IsInStringArray(remoteRegions[i].GetId(), syncRange.Region) {
if len(syncRange.Region) > 0 && !utils.IsInStringArray(localRegions[i].Id, syncRange.Region) {
continue
}
@@ -91,7 +92,7 @@ func syncCloudProviderInfo(ctx context.Context, provider *models.SCloudprovider,
if localZones != nil && remoteZones != nil {
for j := 0; j < len(localZones); j += 1 {
if len(syncRange.Zone) > 0 && !utils.IsInStringArray(remoteZones[j].GetId(), syncRange.Zone) {
if len(syncRange.Zone) > 0 && !utils.IsInStringArray(localZones[j].Id, syncRange.Zone) {
continue
}
syncZoneStorages(ctx, provider, task, &localZones[j], remoteZones[j])
@@ -258,7 +259,7 @@ func syncZoneHosts(ctx context.Context, provider *models.SCloudprovider, task *C
db.OpsLog.LogEvent(provider, db.ACT_SYNC_HOST_COMPLETE, msg, task.UserCred)
for i := 0; i < len(localHosts); i += 1 {
if len(syncRange.Host) > 0 && !utils.IsInStringArray(remoteHosts[i].GetGlobalId(), syncRange.Host) {
if len(syncRange.Host) > 0 && !utils.IsInStringArray(localHosts[i].Id, syncRange.Host) {
continue
}
syncHostStorages(ctx, provider, task, &localHosts[i], remoteHosts[i])
@@ -23,6 +23,7 @@ func (self *GuestSyncstatusTask) OnInit(ctx context.Context, obj db.IStandaloneM
guest := obj.(*models.SGuest)
host := guest.GetHost()
if host == nil || host.HostStatus == models.HOST_OFFLINE {
log.Errorf("host is not reachable")
guest.SetStatus(self.UserCred, models.VM_UNKNOWN, "Host not responding")
self.SetStageComplete(ctx, nil)
return
+4
View File
@@ -60,6 +60,10 @@ func (self *VpcDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel,
wires := vpc.GetWires()
if wires != nil {
for i := 0; i < len(wires); i += 1 {
hws, _ := wires[i].GetHostwires()
for j := 0; hws != nil && j < len(hws); j += 1 {
hws[j].Detach(ctx, self.UserCred)
}
wires[i].Delete(ctx, self.UserCred)
}
}
+4 -1
View File
@@ -14,6 +14,8 @@ const (
CLOUD_PROVIDER_ALIYUN_CN = "阿里云"
ALIYUN_DEFAULT_REGION = "cn-hangzhou"
ALIYUN_API_VERSION = "2014-05-26"
)
type SAliyunClient struct {
@@ -36,7 +38,7 @@ func NewAliyunClient(providerId string, providerName string, accessKey string, s
func jsonRequest(client *sdk.Client, apiName string, params map[string]string) (jsonutils.JSONObject, error) {
req := requests.NewCommonRequest()
req.Domain = "ecs.aliyuncs.com"
req.Version = "2014-05-26"
req.Version = ALIYUN_API_VERSION
req.ApiName = apiName
if params != nil {
for k, v := range params {
@@ -72,6 +74,7 @@ func (self *SAliyunClient) jsonRequest(apiName string, params map[string]string)
func (self *SAliyunClient) fetchRegions() error {
body, err := self.jsonRequest("DescribeRegions", nil)
if err != nil {
log.Errorf("fetchRegions fail %s", err)
return err
}
+5 -1
View File
@@ -343,7 +343,11 @@ func (self *SRegion) CreateInstance(name string, imageId string, instanceType st
params["InternetMaxBandwidthIn"] = "200"
params["InternetMaxBandwidthOut"] = "100"
params["HostName"] = name
params["Password"] = passwd
if len(passwd) > 0 {
params["Password"] = passwd
} else {
params["PasswordInherit"] = "True"
}
params["IoOptimized"] = "optimized"
for i, d := range disks {
if i == 0 {
+1
View File
@@ -55,6 +55,7 @@ func (self *SAliyunProvider) GetSysInfo() (jsonutils.JSONObject, error) {
regions := self.client.GetIRegions()
info := jsonutils.NewDict()
info.Add(jsonutils.NewInt(int64(len(regions))), "region_count")
info.Add(jsonutils.NewString(aliyun.ALIYUN_API_VERSION), "api_version")
return info, nil
}
+23
View File
@@ -541,3 +541,26 @@ func (self *SRegion) GetIStoragecacheById(id string) (cloudprovider.ICloudStorag
}
return nil, cloudprovider.ErrNotFound
}
func (self *SRegion) updateInstance(instId string, name, desc, passwd, hostname string) error {
params := make(map[string]string)
params["InstanceId"] = instId
if len(name) > 0 {
params["InstanceName"] = name
}
if len(desc) > 0 {
params["Description"] = desc
}
if len(passwd) > 0 {
params["Password"] = passwd
}
if len(hostname) > 0 {
params["HostName"] = hostname
}
_, err := self.ecsRequest("ModifyInstanceAttribute", params)
return err
}
func (self *SRegion) UpdateInstancePassword(instId string, passwd string) error {
return self.updateInstance(instId, "", "", passwd, "")
}
+9
View File
@@ -80,4 +80,13 @@ func init() {
}
return nil
})
type InstanceUpdatePasswordOptions struct {
ID string `help:"Instance ID"`
PASSWD string `help:"new password"`
}
shellutils.R(&InstanceUpdatePasswordOptions{}, "instance-update-password", "Update instance password", func(cli *aliyun.SRegion, args *InstanceUpdatePasswordOptions) error {
err := cli.UpdateInstancePassword(args.ID, args.PASSWD)
return err
})
}
+47
View File
@@ -0,0 +1,47 @@
package seclib2
import (
"fmt"
"strings"
"bytes"
"math/rand"
)
const (
DIGITS = "23456789"
LETTERS = "abcdefghjkmnpqrstuvwxyz"
PUNC = "()~@#$%^&*-+={}[]:;<>,.?/"
)
var CHARS = fmt.Sprintf("%s%s%s%s", DIGITS, LETTERS, strings.ToUpper(LETTERS), PUNC)
func RandomPassword2(width int) string {
if width < 6 {
width = 6
}
for {
var buf bytes.Buffer
digitsCnt := 0
letterCnt := 0
upperCnt := 0
puncCnt := 0
for i := 0; i < width; i += 1 {
index := rand.Intn(len(CHARS))
ch := CHARS[index]
if strings.IndexByte(DIGITS, ch) >= 0 {
digitsCnt += 1
} else if strings.IndexByte(LETTERS, ch) >= 0 {
letterCnt += 1
} else if strings.IndexByte(LETTERS, ch+32) >= 0 {
upperCnt += 1
} else if strings.IndexByte(PUNC, ch) >= 0 {
puncCnt += 1
}
buf.WriteByte(ch)
}
if digitsCnt > 1 && letterCnt > 1 && upperCnt > 1 && puncCnt >=1 && puncCnt <= 2 {
return buf.String()
}
}
return ""
}