mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 10:46:58 +08:00
Merge pull request #6621 from wanyaoqi/bugfix/wyq/host-storage-misc-fix
host storage misc fix:
This commit is contained in:
@@ -234,6 +234,20 @@ func init() {
|
||||
return nil
|
||||
})
|
||||
|
||||
type StorageForceDetachHost struct {
|
||||
ID string `help:"ID or name of storage" json:"-"`
|
||||
Host string `help:"ID or name of host"`
|
||||
}
|
||||
R(&StorageForceDetachHost{}, "storage-public", "Force detach host", func(s *mcclient.ClientSession, args *StorageForceDetachHost) error {
|
||||
params := jsonutils.Marshal(args)
|
||||
result, err := modules.Storages.PerformAction(s, args.ID, "force-detach-host", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type StoragePublicOptions struct {
|
||||
ID string `help:"ID or name of storage" json:"-"`
|
||||
Scope string `help:"sharing scope" choices:"system|domain"`
|
||||
|
||||
@@ -224,6 +224,11 @@ type PerformEnableInput struct {
|
||||
type PerformDisableInput struct {
|
||||
}
|
||||
|
||||
type StorageForceDetachHostInput struct {
|
||||
// Host id or name
|
||||
Host string `json:"host"`
|
||||
}
|
||||
|
||||
type InfrasResourceBaseCreateInput struct {
|
||||
DomainLevelResourceCreateInput
|
||||
|
||||
|
||||
@@ -1549,3 +1549,36 @@ func (manager *SStorageManager) ListItemExportKeys(ctx context.Context,
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (storage *SStorage) AllowPerformForceDetachHost(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return db.IsAdminAllowPerform(userCred, storage, "force-detach-host")
|
||||
}
|
||||
|
||||
func (storage *SStorage) PerformForceDetachHost(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.StorageForceDetachHostInput) (jsonutils.JSONObject, error) {
|
||||
if storage.Enabled.Bool() {
|
||||
return nil, httperrors.NewBadRequestError("storage is enabled")
|
||||
}
|
||||
iHost, err := HostManager.FetchByIdOrName(userCred, input.Host)
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewNotFoundError("host %s not found", input.Host)
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
host := iHost.(*SHost)
|
||||
if host.Status == api.HOST_ONLINE {
|
||||
return nil, httperrors.NewBadRequestError("can't detach host in status online")
|
||||
}
|
||||
iHostStorage, err := db.FetchJointByIds(HoststorageManager, host.GetId(), storage.Id, nil)
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, httperrors.NewNotFoundError("host %s storage %s not found", input.Host, storage.Name)
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hostStorage := iHostStorage.(*SHoststorage)
|
||||
hostStorage.SetModelManager(HoststorageManager, hostStorage)
|
||||
err = hostStorage.Delete(ctx, userCred)
|
||||
if err == nil {
|
||||
db.OpsLog.LogDetachEvent(ctx, hostStorage.Master(), hostStorage.Slave(), userCred, jsonutils.NewString("force detach"))
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1261,6 +1261,9 @@ func (h *SHostInfo) onGetStorageInfoSucc(hoststorages []jsonutils.JSONObject) {
|
||||
storage.SetStoragecacheId(storagecacheId)
|
||||
storage.SetStorageInfo(storageId, storageName, storageConf)
|
||||
storageManager.Storages = append(storageManager.Storages, storage)
|
||||
if err := storage.Accessible(); err != nil {
|
||||
h.onFail(err)
|
||||
}
|
||||
storageManager.InitSharedStorageImageCache(
|
||||
storagetype, storagecacheId, imagecachePath, storage)
|
||||
}
|
||||
|
||||
@@ -65,12 +65,14 @@ func NewStorageManager(host hostutils.IHost) (*SStorageManager, error) {
|
||||
|
||||
for i, d := range options.HostOptions.LocalImagePath {
|
||||
s := NewLocalStorage(ret, d, i)
|
||||
if s.Accessible() {
|
||||
if err := s.Accessible(); err == nil {
|
||||
StartSnapshotRecycle(s)
|
||||
ret.Storages = append(ret.Storages, s)
|
||||
if allFull && s.GetFreeSizeMb() > MINIMAL_FREE_SPACE {
|
||||
allFull = false
|
||||
}
|
||||
} else {
|
||||
log.Errorf("storage %s not accessible", s.Path)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,8 +43,14 @@ const (
|
||||
_RECYCLE_BIN_ = "recycle_bin"
|
||||
_IMGSAVE_BACKUPS_ = "imgsave_backups"
|
||||
_SNAPSHOT_PATH_ = "snapshots"
|
||||
|
||||
ErrStorageTimeout = constError("storage accessible check timeout")
|
||||
)
|
||||
|
||||
type constError string
|
||||
|
||||
func (e constError) Error() string { return string(e) }
|
||||
|
||||
var DELETEING_SNAPSHOTS = sync.Map{}
|
||||
|
||||
type IStorageFactory interface {
|
||||
@@ -115,6 +121,8 @@ type IStorage interface {
|
||||
|
||||
DestinationPrepareMigrate(ctx context.Context, liveMigrate bool, disksUri string, snapshotsUri string,
|
||||
desc, disksBackingFile, srcSnapshots jsonutils.JSONObject, rebaseDisks bool) error
|
||||
|
||||
Accessible() error
|
||||
}
|
||||
|
||||
type SBaseStorage struct {
|
||||
|
||||
@@ -146,17 +146,32 @@ func (s *SLocalStorage) CreateDisk(diskId string) IDisk {
|
||||
return disk
|
||||
}
|
||||
|
||||
func (s *SLocalStorage) Accessible() bool {
|
||||
if !fileutils2.Exists(s.Path) {
|
||||
if err := procutils.NewCommand("mkdir", "-p", s.Path).Run(); err != nil {
|
||||
log.Errorln(err)
|
||||
func (s *SLocalStorage) Accessible() error {
|
||||
var c = make(chan error)
|
||||
go func() {
|
||||
if !fileutils2.Exists(s.Path) {
|
||||
if err := procutils.NewCommand("mkdir", "-p", s.Path).Run(); err != nil {
|
||||
c <- err
|
||||
return
|
||||
}
|
||||
}
|
||||
if !fileutils2.IsDir(s.Path) {
|
||||
c <- fmt.Errorf("path %s isn't directory", s.Path)
|
||||
}
|
||||
if !fileutils2.Writable(s.Path) {
|
||||
c <- fmt.Errorf("dir %s not writable", s.Path)
|
||||
}
|
||||
c <- nil
|
||||
}()
|
||||
var err error
|
||||
select {
|
||||
case err = <-c:
|
||||
break
|
||||
case <-time.After(time.Second * 10):
|
||||
err = ErrStorageTimeout
|
||||
}
|
||||
if fileutils2.IsDir(s.Path) && fileutils2.Writable(s.Path) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
return err
|
||||
|
||||
}
|
||||
|
||||
func (s *SLocalStorage) DeleteDiskfile(diskpath string) error {
|
||||
|
||||
@@ -622,11 +622,22 @@ func (s *SRbdStorage) CreateDisk(diskId string) IDisk {
|
||||
return disk
|
||||
}
|
||||
|
||||
func (s *SRbdStorage) Accessible() bool {
|
||||
_, err := s.withCluster(func(conn *rados.Conn) (interface{}, error) {
|
||||
return conn.ListPools()
|
||||
})
|
||||
return err == nil
|
||||
func (s *SRbdStorage) Accessible() error {
|
||||
var c = make(chan error)
|
||||
go func() {
|
||||
_, err := s.withCluster(func(conn *rados.Conn) (interface{}, error) {
|
||||
return conn.ListPools()
|
||||
})
|
||||
c <- err
|
||||
}()
|
||||
var err error
|
||||
select {
|
||||
case err = <-c:
|
||||
break
|
||||
case <-time.After(time.Second * 10):
|
||||
err = ErrStorageTimeout
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *SRbdStorage) SaveToGlance(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
|
||||
|
||||
Reference in New Issue
Block a user