host支持ceph

This commit is contained in:
屈轩
2019-02-15 17:12:54 +08:00
parent 9cf8417a93
commit 180b7aee4f
10 changed files with 549 additions and 83 deletions
+36
View File
@@ -0,0 +1,36 @@
package models
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/mcclient"
)
type IStorageDriver interface {
GetStorageType() string
ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error)
PostCreate(ctx context.Context, userCred mcclient.TokenCredential, storage *SStorage, data jsonutils.JSONObject)
}
var storageDrivers map[string]IStorageDriver
func init() {
storageDrivers = make(map[string]IStorageDriver)
}
func RegisterStorageDriver(driver IStorageDriver) {
storageDrivers[driver.GetStorageType()] = driver
}
func GetStorageDriver(storageType string) IStorageDriver {
driver, ok := storageDrivers[storageType]
if ok {
return driver
}
log.Fatalf("Unsupported storageType %s", storageType)
return nil
}
+104 -82
View File
@@ -4,8 +4,6 @@ import (
"context"
"fmt"
"path"
"strings"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
@@ -177,11 +175,13 @@ func (self *SStorage) AllowDeleteItem(ctx context.Context, userCred mcclient.Tok
func (manager *SStorageManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
storageType, _ := data.GetString("storage_type")
mediumType, _ := data.GetString("medium_type")
capacity, _ := data.Int("capacity")
if capacity < 0 {
return nil, httperrors.NewInputParameterError("Invalid capacity")
}
data.Set("capacity", jsonutils.NewInt(capacity))
/*
capacity, _ := data.Int("capacity")
if capacity < 0 {
return nil, httperrors.NewInputParameterError("Invalid capacity")
}
data.Set("capacity", jsonutils.NewInt(capacity))
*/
if !utils.IsInStringArray(storageType, STORAGE_TYPES) {
return nil, httperrors.NewInputParameterError("Invalid storage type %s", storageType)
}
@@ -197,23 +197,36 @@ func (manager *SStorageManager) ValidateCreateData(ctx context.Context, userCred
return nil, httperrors.NewResourceNotFoundError("zone %s", zoneId)
}
data.Set("zone_id", jsonutils.NewString(zone.GetId()))
if storageType == STORAGE_RBD {
conf, err := manager.ValidateRbdConfData(data)
if err != nil {
return nil, httperrors.NewBadRequestError("Vaildata rbd conf error: %s", err.Error())
}
data.Set("storage_conf", conf)
// data.Set("capacity", rbdConf)
} else if storageType == STORAGE_NFS {
conf, err := manager.ValidataNfsConfdata(data)
if err != nil {
return nil, httperrors.NewBadRequestError("Vaildata nfs conf error: %s", err.Error())
}
data.Set("storage_conf", conf)
storageDirver := GetStorageDriver(storageType)
if storageDirver == nil {
return nil, httperrors.NewUnsupportOperationError("Not support create %s storage", storageType)
}
data, err = storageDirver.ValidateCreateData(ctx, userCred, data)
if err != nil {
return nil, err
}
/*
if storageType == STORAGE_RBD {
conf, err := manager.ValidateRbdConfData(data)
if err != nil {
return nil, httperrors.NewBadRequestError("Vaildata rbd conf error: %s", err.Error())
}
data.Set("storage_conf", conf)
// data.Set("capacity", rbdConf)
} else if storageType == STORAGE_NFS {
conf, err := manager.ValidataNfsConfdata(data)
if err != nil {
return nil, httperrors.NewBadRequestError("Vaildata nfs conf error: %s", err.Error())
}
data.Set("storage_conf", conf)
}
*/
return manager.SStandaloneResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data)
}
/*
func (manager *SStorageManager) ValidataNfsConfdata(data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
conf := jsonutils.NewDict()
if nfsHost, err := data.GetString("nfs_host"); err != nil {
@@ -228,7 +241,9 @@ func (manager *SStorageManager) ValidataNfsConfdata(data *jsonutils.JSONDict) (*
}
return conf, nil
}
*/
/*
func (manager *SStorageManager) ValidateRbdConfData(data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
conf := jsonutils.NewDict()
for k, v := range data.Value() {
@@ -257,7 +272,7 @@ func (manager *SStorageManager) ValidateRbdConfData(data *jsonutils.JSONDict) (*
}
// TODO??? ensure rbd pool can use and get capacity
return conf, nil
}
}*/
func (self *SStorage) ValidateDeleteCondition(ctx context.Context) error {
if self.GetHostCount() > 0 || self.GetDiskCount() > 0 || self.GetSnapshotCount() > 0 {
@@ -268,74 +283,81 @@ func (self *SStorage) ValidateDeleteCondition(ctx context.Context) error {
func (self *SStorage) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerProjId string, query jsonutils.JSONObject, data jsonutils.JSONObject) {
self.SStandaloneResourceBase.PostCreate(ctx, userCred, ownerProjId, query, data)
storageConf, _ := data.Get("storage_conf")
if storageConf != nil {
_, err := self.GetModelManager().TableSpec().Update(self, func() error {
self.StorageConf = storageConf
return nil
})
if err != nil {
log.Errorln(err)
return
}
storageDriver := GetStorageDriver(self.StorageType)
if storageDriver != nil {
storageDriver.PostCreate(ctx, userCred, self, data)
}
if self.StorageType == STORAGE_RBD {
var storages = make([]SStorage, 0)
err := StorageManager.Query().Equals("storage_type", STORAGE_RBD).All(&storages)
if err != nil {
log.Errorln(err)
return
}
nMonHost, _ := storageConf.GetString("mon_host")
nKey, _ := storageConf.GetString("key")
for i := 0; i < len(storages); i++ {
monHost, _ := storages[i].StorageConf.GetString("mon_host")
key, _ := storages[i].StorageConf.GetString("key")
if monHost == nMonHost && nKey == key {
_, err := self.GetModelManager().TableSpec().Update(self, func() error {
self.StoragecacheId = storages[i].StoragecacheId
return nil
})
if err != nil {
log.Errorln(err)
return
}
break
/*
storageConf, _ := data.Get("storage_conf")
if storageConf != nil {
_, err := self.GetModelManager().TableSpec().Update(self, func() error {
self.StorageConf = storageConf
return nil
})
if err != nil {
log.Errorln(err)
return
}
}
if len(self.StoragecacheId) == 0 {
if self.StorageType == STORAGE_RBD {
var storages = make([]SStorage, 0)
err := StorageManager.Query().Equals("storage_type", STORAGE_RBD).All(&storages)
if err != nil {
log.Errorln(err)
return
}
nMonHost, _ := storageConf.GetString("mon_host")
nKey, _ := storageConf.GetString("key")
for i := 0; i < len(storages); i++ {
monHost, _ := storages[i].StorageConf.GetString("mon_host")
key, _ := storages[i].StorageConf.GetString("key")
if monHost == nMonHost && nKey == key {
_, err := self.GetModelManager().TableSpec().Update(self, func() error {
self.StoragecacheId = storages[i].StoragecacheId
return nil
})
if err != nil {
log.Errorln(err)
return
}
break
}
}
if len(self.StoragecacheId) == 0 {
sc := &SStoragecache{}
sc.SetModelManager(StoragecacheManager)
sc.Name = fmt.Sprintf("imagecache-%s", self.Id)
pool, _ := storageConf.GetString("pool")
sc.Path = fmt.Sprintf("rbd:%s", pool)
err := StorageManager.TableSpec().Insert(sc)
if err != nil {
log.Errorln(err)
}
}
} else if self.StorageType == STORAGE_NFS {
sc := &SStoragecache{}
sc.SetModelManager(StoragecacheManager)
sc.Name = fmt.Sprintf("imagecache-%s", self.Id)
pool, _ := storageConf.GetString("pool")
sc.Path = fmt.Sprintf("rbd:%s", pool)
err := StoragecacheManager.TableSpec().Insert(sc)
sc.Path = options.Options.NfsDefaultImageCacheDir
sc.ExternalId = self.Id
sc.Name = "nfs-" + self.Name + time.Now().Format("2006-01-02 15:04:05")
if err := StoragecacheManager.TableSpec().Insert(sc); err != nil {
log.Errorln(err)
return
}
if err := StoragecacheManager.Query().Equals("external_id", self.Id).First(sc); err != nil {
log.Errorln(err)
return
}
_, err := self.GetModelManager().TableSpec().Update(self, func() error {
self.StoragecacheId = sc.Id
self.Status = STORAGE_ONLINE
return nil
})
if err != nil {
log.Errorln(err)
}
}
} else if self.StorageType == STORAGE_NFS {
sc := &SStoragecache{}
sc.Path = options.Options.NfsDefaultImageCacheDir
sc.ExternalId = self.Id
sc.Name = "nfs-" + self.Name + time.Now().Format("2006-01-02 15:04:05")
if err := StoragecacheManager.TableSpec().Insert(sc); err != nil {
log.Errorln(err)
return
}
if err := StoragecacheManager.Query().Equals("external_id", self.Id).First(sc); err != nil {
log.Errorln(err)
return
}
_, err := self.GetModelManager().TableSpec().Update(self, func() error {
self.StoragecacheId = sc.Id
self.Status = STORAGE_ONLINE
return nil
})
if err != nil {
log.Errorln(err)
}
}
}*/
}
func (self *SStorage) SetStatus(userCred mcclient.TokenCredential, status string, reason string) error {
+1
View File
@@ -11,6 +11,7 @@ import (
_ "yunion.io/x/onecloud/pkg/compute/guestdrivers"
_ "yunion.io/x/onecloud/pkg/compute/hostdrivers"
_ "yunion.io/x/onecloud/pkg/compute/regiondrivers"
_ "yunion.io/x/onecloud/pkg/compute/storagedrivers"
_ "yunion.io/x/onecloud/pkg/compute/tasks"
_ "yunion.io/x/onecloud/pkg/util/aliyun/provider"
_ "yunion.io/x/onecloud/pkg/util/aws/provider"
+21
View File
@@ -0,0 +1,21 @@
package storagedrivers
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SBaseStorageDriver struct {
}
func (self *SBaseStorageDriver) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
return nil, fmt.Errorf("Not Implement ValidateCreateData")
}
func (self *SBaseStorageDriver) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, storage *models.SStorage, data jsonutils.JSONObject) {
}
+30
View File
@@ -0,0 +1,30 @@
package storagedrivers
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SLocalStorageDriver struct {
SBaseStorageDriver
}
func init() {
driver := SLocalStorageDriver{}
models.RegisterStorageDriver(&driver)
}
func (self *SLocalStorageDriver) GetStorageType() string {
return models.STORAGE_LOCAL
}
func (self *SLocalStorageDriver) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
return data, nil
}
func (self *SLocalStorageDriver) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, storage *models.SStorage, data jsonutils.JSONObject) {
}
+60
View File
@@ -0,0 +1,60 @@
package storagedrivers
import (
"context"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/compute/options"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SNfsStorageDriver struct {
SBaseStorageDriver
}
func init() {
driver := SNfsStorageDriver{}
models.RegisterStorageDriver(&driver)
}
func (self *SNfsStorageDriver) GetStorageType() string {
return models.STORAGE_NFS
}
func (self *SNfsStorageDriver) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
conf := jsonutils.NewDict()
for _, v := range []string{"nfs_host", "nfs_shared_dir"} {
value, _ := data.GetString(v)
if len(value) == 0 {
return nil, httperrors.NewMissingParameterError(v)
}
conf.Set(v, jsonutils.NewString(value))
}
data.Set("storage_conf", conf)
return data, nil
}
func (self *SNfsStorageDriver) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, storage *models.SStorage, data jsonutils.JSONObject) {
sc := &models.SStoragecache{}
sc.Path = options.Options.NfsDefaultImageCacheDir
sc.ExternalId = storage.Id
sc.Name = "nfs-" + storage.Name + time.Now().Format("2006-01-02 15:04:05")
if err := models.StoragecacheManager.TableSpec().Insert(sc); err != nil {
log.Errorf("insert storagecache for storage %s error: %v", storage.Name, err)
return
}
_, err := storage.GetModelManager().TableSpec().Update(storage, func() error {
storage.StoragecacheId = sc.Id
storage.Status = models.STORAGE_ONLINE
return nil
})
if err != nil {
log.Errorf("update storagecache info for storage %s error: %v", storage.Name, err)
}
}
+100
View File
@@ -0,0 +1,100 @@
package storagedrivers
import (
"context"
"fmt"
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SRbdStorageDriver struct {
SBaseStorageDriver
}
func init() {
driver := SRbdStorageDriver{}
models.RegisterStorageDriver(&driver)
}
func (self *SRbdStorageDriver) GetStorageType() string {
return models.STORAGE_RBD
}
func (self *SRbdStorageDriver) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
conf := jsonutils.NewDict()
for _, v := range []string{"rbd_mon_host", "rbd_pool"} {
if !data.Contains(v) {
return nil, httperrors.NewMissingParameterError(v)
}
value, _ := data.GetString(v)
conf.Add(jsonutils.NewString(value), strings.TrimLeft(v, "rbd_"))
}
if key, _ := data.GetString("rbd_key"); len(key) > 0 {
conf.Add(jsonutils.NewString(key), "key")
}
storages := []models.SStorage{}
q := models.StorageManager.Query().Equals("storage_type", models.STORAGE_RBD)
if err := db.FetchModelObjects(models.StorageManager, q, &storages); err != nil {
return nil, httperrors.NewGeneralError(err)
}
for i := 0; i < len(storages); i++ {
if conf.Equals(storages[i].StorageConf) {
return nil, httperrors.NewDuplicateResourceError("This RBD Storage[%s/%s] has already exist", storages[i].Name, conf.String())
}
}
data.Set("storage_conf", conf)
return data, nil
}
func (self *SRbdStorageDriver) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, storage *models.SStorage, data jsonutils.JSONObject) {
storages := []models.SStorage{}
q := models.StorageManager.Query().Equals("storage_type", models.STORAGE_RBD)
if err := db.FetchModelObjects(models.StorageManager, q, &storages); err != nil {
log.Errorf("fetch storages error: %v", err)
return
}
newRbdHost, _ := data.GetString("rbd_mon_host")
newRbdKey, _ := data.GetString("rbd_key")
for i := 0; i < len(storages); i++ {
rbdHost, _ := storages[i].StorageConf.GetString("mon_host")
rbdKey, _ := storages[i].StorageConf.GetString("key")
if newRbdHost == rbdHost && newRbdKey == rbdKey {
_, err := storage.GetModelManager().TableSpec().Update(self, func() error {
storage.StoragecacheId = storages[i].StoragecacheId
return nil
})
if err != nil {
log.Errorf("Update storagecacheId error: %v", err)
return
}
}
}
if len(storage.StoragecacheId) == 0 {
sc := &models.SStoragecache{}
sc.SetModelManager(models.StoragecacheManager)
sc.Name = fmt.Sprintf("imagecache-%s", storage.Id)
pool, _ := data.GetString("rbd_pool")
sc.Path = fmt.Sprintf("rbd:%s", pool)
if err := models.StoragecacheManager.TableSpec().Insert(sc); err != nil {
log.Errorf("insert storagecache for storage %s error: %v", storage.Name, err)
return
}
_, err := storage.GetModelManager().TableSpec().Update(storage, func() error {
storage.StoragecacheId = sc.Id
return nil
})
if err != nil {
log.Errorf("update storagecache info for storage %s error: %v", storage.Name, err)
}
}
}
+1 -1
View File
@@ -250,7 +250,7 @@ func (s *SStorageManager) NewSharedStorageInstance(mountPoint, storageType strin
} else if storageType == storagetypes.STORAGE_RBD ||
strings.HasPrefix(mountPoint, storagetypes.STORAGE_RBD) {
// TODO
// return NewRBDStorage(s, mountPoint)
return NewRBDStorage(s, mountPoint)
}
return nil
}
+103
View File
@@ -0,0 +1,103 @@
package storageman
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/cloudcommon/storagetypes"
"yunion.io/x/onecloud/pkg/hostman/guestfs"
)
type SRBDDisk struct {
SBaseDisk
}
func NewRBDDisk(storage IStorage, id string) *SRBDDisk {
var ret = new(SRBDDisk)
ret.SBaseDisk = *NewBaseDisk(storage, id)
return ret
}
func (d *SRBDDisk) GetType() string {
return storagetypes.STORAGE_RBD
}
func (d *SRBDDisk) Probe() error {
return nil
}
func (d *SRBDDisk) GetPath() string {
return ""
}
func (d *SRBDDisk) GetSnapshotDir() string {
return ""
}
func (d *SRBDDisk) GetDiskDesc() jsonutils.JSONObject {
return nil
}
func (d *SRBDDisk) GetDiskSetupScripts(idx int) string {
return ""
}
func (d *SRBDDisk) DeleteAllSnapshot() error {
return nil
}
func (d *SRBDDisk) Delete(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
return nil, nil
}
func (d *SRBDDisk) Resize(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
return nil, nil
}
func (d *SRBDDisk) PrepareSaveToGlance(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
return nil, nil
}
func (d *SRBDDisk) ResetFromSnapshot(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
return nil, nil
}
func (d *SRBDDisk) CleanupSnapshots(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
return nil, nil
}
func (d *SRBDDisk) PrepareMigrate(liveMigrate bool) (string, error) {
return "", nil
}
func (d *SRBDDisk) CreateFromUrl(context.Context, string) error {
return nil
}
func (d *SRBDDisk) CreateFromTemplate(context.Context, string, string, int64) (jsonutils.JSONObject, error) {
return nil, nil
}
func (d *SRBDDisk) CreateFromImageFuse(context.Context, string) error {
return nil
}
func (d *SRBDDisk) CreateRaw(ctx context.Context, sizeMb int, diskFromat string, fsFormat string, encryption bool, diskId string, back string) (jsonutils.JSONObject, error) {
return nil, nil
}
func (d *SRBDDisk) PostCreateFromImageFuse() {
}
func (d *SRBDDisk) CreateSnapshot(snapshotId string) error {
return nil
}
func (d *SRBDDisk) DeleteSnapshot(snapshotId, convertSnapshot string, pendingDelete bool) error {
return nil
}
func (d *SRBDDisk) DeployGuestFs(diskPath string, guestDesc *jsonutils.JSONDict, deployInfo *guestfs.SDeployInfo) (jsonutils.JSONObject, error) {
return nil, nil
}
+93
View File
@@ -0,0 +1,93 @@
package storageman
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/cloudcommon/storagetypes"
)
type SRBDStorage struct {
SBaseStorage
}
func NewRBDStorage(manager *SStorageManager, path string) *SRBDStorage {
var ret = new(SRBDStorage)
ret.SBaseStorage = *NewBaseStorage(manager, path)
return ret
}
func (s *SRBDStorage) StorageType() string {
return storagetypes.STORAGE_RBD
}
func (s *SRBDStorage) GetSnapshotPathByIds(diskId, snapshotId string) string {
return ""
}
func (s *SRBDStorage) GetSnapshotDir() string {
return ""
}
func (s *SRBDStorage) GetFuseTmpPath() string {
return ""
}
func (s *SRBDStorage) GetFuseMountPath() string {
return ""
}
func (s *SRBDStorage) GetImgsaveBackupPath() string {
return ""
}
func (s *SRBDStorage) SyncStorageInfo() (jsonutils.JSONObject, error) {
return nil, nil
}
func (s *SRBDStorage) GetDiskById(diskId string) IDisk {
s.DiskLock.Lock()
defer s.DiskLock.Unlock()
for i := 0; i < len(s.Disks); i++ {
if s.Disks[i].GetId() == diskId {
if s.Disks[i].Probe() == nil {
return s.Disks[i]
}
}
}
var disk = NewRBDDisk(s, diskId)
if disk.Probe() == nil {
s.Disks = append(s.Disks, disk)
return disk
} else {
return nil
}
}
func (s *SRBDStorage) CreateDisk(diskId string) IDisk {
s.DiskLock.Lock()
defer s.DiskLock.Unlock()
disk := NewRBDDisk(s, diskId)
s.Disks = append(s.Disks, disk)
return disk
}
func (s *SRBDStorage) Accessible() bool {
return true
}
func (s *SRBDStorage) DeleteDiskfile(diskpath string) error {
return nil
}
func (s *SRBDStorage) SaveToGlance(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
return nil, nil
}
func (s *SRBDStorage) CreateSnapshotFormUrl(ctx context.Context, snapshotUrl, diskId, snapshotPath string) error {
return nil
}
func (s *SRBDStorage) DeleteSnapshots(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
return nil, nil
}