Skip to content

Commit

Permalink
feat(region,host): clvm support (#18979)
Browse files Browse the repository at this point in the history
  • Loading branch information
wanyaoqi authored Dec 14, 2023
1 parent f71fcf8 commit f8ce36f
Show file tree
Hide file tree
Showing 16 changed files with 605 additions and 47 deletions.
2 changes: 2 additions & 0 deletions pkg/apis/compute/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ type StorageCreateInput struct {

// swagger:ignore
HardwareInfo *StorageHardwareInfo `json:"hardware_info"`
// CLVM VG Name
CLVMVgName string
}

type RbdTimeoutInput struct {
Expand Down
7 changes: 4 additions & 3 deletions pkg/apis/compute/storage_const.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const (
STORAGE_NVME_PT = "nvme_pt" // nvme passthrough
STORAGE_NVME = "nvme" // nvme sriov
STORAGE_LVM = "lvm"
STORAGE_CLVM = "clvm" // clustered lvm

STORAGE_PUBLIC_CLOUD = compute.STORAGE_PUBLIC_CLOUD
STORAGE_CLOUD_EFFICIENCY = compute.STORAGE_CLOUD_EFFICIENCY
Expand Down Expand Up @@ -167,7 +168,7 @@ var (
STORAGE_OPENSTACK_ISCSI, STORAGE_UCLOUD_CLOUD_NORMAL, STORAGE_UCLOUD_CLOUD_SSD,
STORAGE_UCLOUD_LOCAL_NORMAL, STORAGE_UCLOUD_LOCAL_SSD, STORAGE_UCLOUD_EXCLUSIVE_LOCAL_DISK,
STORAGE_ZSTACK_LOCAL_STORAGE, STORAGE_ZSTACK_CEPH, STORAGE_GPFS, STORAGE_CIFS,
STORAGE_NVME_PT, STORAGE_NVME, STORAGE_LVM,
STORAGE_NVME_PT, STORAGE_NVME, STORAGE_LVM, STORAGE_CLVM,
}

HOST_STORAGE_LOCAL_TYPES = []string{STORAGE_LOCAL, STORAGE_BAREMETAL, STORAGE_ZSTACK_LOCAL_STORAGE, STORAGE_OPENSTACK_NOVA}
Expand All @@ -177,8 +178,8 @@ var (
SHARED_FILE_STORAGE = []string{STORAGE_NFS, STORAGE_GPFS}
FIEL_STORAGE = []string{STORAGE_LOCAL, STORAGE_NFS, STORAGE_GPFS}

// 目前来说只支持这些
SHARED_STORAGE = []string{STORAGE_NFS, STORAGE_GPFS, STORAGE_RBD}
// supported shared storage types
SHARED_STORAGE = []string{STORAGE_NFS, STORAGE_GPFS, STORAGE_RBD, STORAGE_CLVM}
)

func IsDiskTypeMatch(t1, t2 string) bool {
Expand Down
69 changes: 48 additions & 21 deletions pkg/compute/hostdrivers/kvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,51 @@ func (self *SKVMHostDriver) GetHypervisor() string {
return api.HYPERVISOR_KVM
}

func (self *SKVMHostDriver) validateGPFS(ctx context.Context, userCred mcclient.TokenCredential, host *models.SHost, input api.HostStorageCreateInput) (api.HostStorageCreateInput, error) {
header := http.Header{}
header.Set(mcclient.AUTH_TOKEN, userCred.GetTokenString())
header.Set(mcclient.REGION_VERSION, "v2")
params := jsonutils.NewDict()
params.Set("mount_point", jsonutils.NewString(input.MountPoint))
urlStr := fmt.Sprintf("%s/storages/is-mount-point?%s", host.ManagerUri, params.QueryString())
_, res, err := httputils.JSONRequest(httputils.GetDefaultClient(), ctx, "GET", urlStr, header, nil, false)
if err != nil {
return input, err
}
if !jsonutils.QueryBoolean(res, "is_mount_point", false) {
return input, httperrors.NewBadRequestError("%s is not mount point %s", input.MountPoint, res)
}
urlStr = fmt.Sprintf("%s/storages/is-local-mount-point?%s", host.ManagerUri, params.QueryString())
_, res, err = httputils.JSONRequest(httputils.GetDefaultClient(), ctx, "GET", urlStr, header, nil, false)
if err != nil {
return input, err
}
if jsonutils.QueryBoolean(res, "is_local_mount_point", false) {
return input, httperrors.NewBadRequestError("%s is local storage mount point", input.MountPoint)
}
return input, nil
}

func (self *SKVMHostDriver) validateCLVM(ctx context.Context, userCred mcclient.TokenCredential, host *models.SHost, storage *models.SStorage, input api.HostStorageCreateInput) (api.HostStorageCreateInput, error) {
vgName, _ := storage.StorageConf.GetString("clvm_vg_name")
if vgName == "" {
return input, httperrors.NewInternalServerError("storage has no clvm_vg_name")
}
input.MountPoint = vgName

header := http.Header{}
header.Set(mcclient.AUTH_TOKEN, userCred.GetTokenString())
header.Set(mcclient.REGION_VERSION, "v2")
params := jsonutils.NewDict()
params.Set("vg_name", jsonutils.NewString(input.MountPoint))
urlStr := fmt.Sprintf("%s/storages/is-vg-exist?%s", host.ManagerUri, params.QueryString())
_, _, err := httputils.JSONRequest(httputils.GetDefaultClient(), ctx, "GET", urlStr, header, nil, false)
if err != nil {
return input, err
}
return input, nil
}

func (self *SKVMHostDriver) ValidateAttachStorage(ctx context.Context, userCred mcclient.TokenCredential, host *models.SHost, storage *models.SStorage, input api.HostStorageCreateInput) (api.HostStorageCreateInput, error) {
if !utils.IsInStringArray(storage.StorageType, append([]string{api.STORAGE_LOCAL, api.STORAGE_NVME_PT, api.STORAGE_NVME, api.STORAGE_LVM}, api.SHARED_STORAGE...)) {
return input, httperrors.NewUnsupportOperationError("Unsupport attach %s storage for %s host", storage.StorageType, host.HostType)
Expand All @@ -84,28 +129,10 @@ func (self *SKVMHostDriver) ValidateAttachStorage(ctx context.Context, userCred
return input, httperrors.NewInvalidStatusError("Attach nfs storage require host status is online")
}
if storage.StorageType == api.STORAGE_GPFS {
header := http.Header{}
header.Set(mcclient.AUTH_TOKEN, userCred.GetTokenString())
header.Set(mcclient.REGION_VERSION, "v2")
params := jsonutils.NewDict()
params.Set("mount_point", jsonutils.NewString(input.MountPoint))
urlStr := fmt.Sprintf("%s/storages/is-mount-point?%s", host.ManagerUri, params.QueryString())
_, res, err := httputils.JSONRequest(httputils.GetDefaultClient(), ctx, "GET", urlStr, header, nil, false)
if err != nil {
return input, err
}
if !jsonutils.QueryBoolean(res, "is_mount_point", false) {
return input, httperrors.NewBadRequestError("%s is not mount point %s", input.MountPoint, res)
}
urlStr = fmt.Sprintf("%s/storages/is-local-mount-point?%s", host.ManagerUri, params.QueryString())
_, res, err = httputils.JSONRequest(httputils.GetDefaultClient(), ctx, "GET", urlStr, header, nil, false)
if err != nil {
return input, err
}
if jsonutils.QueryBoolean(res, "is_local_mount_point", false) {
return input, httperrors.NewBadRequestError("%s is local storage mount point", input.MountPoint)
}
return self.validateGPFS(ctx, userCred, host, input)
}
} else if storage.StorageType == api.STORAGE_CLVM {
return self.validateCLVM(ctx, userCred, host, storage, input)
}
return input, nil
}
Expand Down
80 changes: 80 additions & 0 deletions pkg/compute/storagedrivers/clvm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package storagedrivers

import (
"context"
"strings"
"time"

"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"

api "yunion.io/x/onecloud/pkg/apis/compute"
"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 SCLVMStorageDriver struct {
SBaseStorageDriver
}

func init() {
driver := SCLVMStorageDriver{}
models.RegisterStorageDriver(&driver)
}

func (s *SCLVMStorageDriver) GetStorageType() string {
return api.STORAGE_CLVM
}

func (s *SCLVMStorageDriver) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, input *api.StorageCreateInput) error {
input.CLVMVgName = strings.TrimSpace(input.CLVMVgName)
if len(input.CLVMVgName) == 0 {
return httperrors.NewMissingParameterError("clvm_vg_name")
}
input.StorageConf = jsonutils.NewDict()
input.StorageConf.Set("clvm_vg_name", jsonutils.NewString(input.CLVMVgName))
return nil
}

func (self *SCLVMStorageDriver) ValidateSnapshotDelete(ctx context.Context, snapshot *models.SSnapshot) error {
return nil
}

func (s *SCLVMStorageDriver) ValidateCreateSnapshotData(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, input *api.SnapshotCreateInput) error {
return errors.Errorf("lvm storage unsupported create snapshot")
}

func (s *SCLVMStorageDriver) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, storage *models.SStorage, data jsonutils.JSONObject) {
sc := &models.SStoragecache{}
sc.ExternalId = storage.Id
sc.Name = "clvm-" + storage.Name + time.Now().Format("2006-01-02 15:04:05")
if err := models.StoragecacheManager.TableSpec().Insert(ctx, sc); err != nil {
log.Errorf("insert storagecache for storage %s error: %v", storage.Name, err)
return
}
_, err := db.Update(storage, func() error {
storage.StoragecacheId = sc.Id
storage.Status = api.STORAGE_ONLINE
return nil
})
if err != nil {
log.Errorf("update storagecache info for storage %s error: %v", storage.Name, err)
}
}
4 changes: 4 additions & 0 deletions pkg/compute/storagedrivers/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ func (self *SLVMStorageDriver) ValidateCreateSnapshotData(ctx context.Context, u
return errors.Errorf("lvm storage unsupported create snapshot")
}

func (self *SLVMStorageDriver) ValidateSnapshotDelete(ctx context.Context, snapshot *models.SSnapshot) error {
return nil
}

type SNVMEPassthroughStorageDriver struct {
SBaseStorageDriver
}
Expand Down
27 changes: 24 additions & 3 deletions pkg/hostman/storageman/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ type SStorageManager struct {
// AgentStorageImagecacheManager IImageCacheManger

LVMStorageImagecacheManagers map[string]IImageCacheManger
CLVMStorageImagecacheManagers map[string]IImageCacheManger
RbdStorageImagecacheManagers map[string]IImageCacheManger
SharedFileStorageImagecacheManagers map[string]IImageCacheManger
}
Expand Down Expand Up @@ -91,8 +92,8 @@ func NewStorageManager(host hostutils.IHost) (*SStorageManager, error) {
}
}

for i, d := range options.HostOptions.LVMVolumeGroups {
s := NewLVMStorage(ret, d, i)
for _, d := range options.HostOptions.LVMVolumeGroups {
s := NewLVMStorage(ret, d)
if err := s.Accessible(); err == nil {
ret.Storages = append(ret.Storages, s)
if allFull && s.GetFreeSizeMb() > MINIMAL_FREE_SPACE {
Expand Down Expand Up @@ -134,6 +135,8 @@ func (s *SStorageManager) Remove(storage IStorage) {
delete(s.RbdStorageImagecacheManagers, storage.GetStoragecacheId())
} else if storage.StorageType() == api.STORAGE_LVM {
delete(s.LVMStorageImagecacheManagers, storage.GetStoragecacheId())
} else if storage.StorageType() == api.STORAGE_CLVM {
delete(s.CLVMStorageImagecacheManagers, storage.GetStoragecacheId())
}
for index, iS := range s.Storages {
if iS.GetId() == storage.GetId() {
Expand Down Expand Up @@ -298,6 +301,10 @@ func (s *SStorageManager) GetStoragecacheById(scId string) IImageCacheManger {
if sc, ok := s.LVMStorageImagecacheManagers[scId]; ok {
return sc
}
if sc, ok := s.CLVMStorageImagecacheManagers[scId]; ok {
return sc
}

return nil
}

Expand All @@ -309,9 +316,13 @@ func (s *SStorageManager) InitSharedStorageImageCache(storageType, storagecacheI
if utils.IsInStringArray(storageType, api.SHARED_FILE_STORAGE) {
s.InitSharedFileStorageImagecache(storagecacheId, imagecachePath)
} else if storageType == api.STORAGE_RBD {
if rbdStorage := s.GetStoragecacheById(storagecacheId); rbdStorage == nil {
if rbdStorageCache := s.GetStoragecacheById(storagecacheId); rbdStorageCache == nil {
s.AddRbdStorageImagecache(imagecachePath, storage, storagecacheId)
}
} else if storageType == api.STORAGE_CLVM {
if clvmStorageCache := s.GetStoragecacheById(storagecacheId); clvmStorageCache == nil {
s.AddCLVMStorageImagecache(storage.GetPath(), storage, storagecacheId)
}
}
}

Expand Down Expand Up @@ -339,6 +350,16 @@ func (s *SStorageManager) InitSharedFileStorageImagecache(storagecacheId, path s
}
}

func (s *SStorageManager) AddCLVMStorageImagecache(imagecachePath string, storage IStorage, storagecacheId string) {
if s.CLVMStorageImagecacheManagers == nil {
s.CLVMStorageImagecacheManagers = map[string]IImageCacheManger{}
}
if _, ok := s.RbdStorageImagecacheManagers[storagecacheId]; !ok {
imagecache := NewLVMImageCacheManager(s, imagecachePath, storagecacheId)
s.CLVMStorageImagecacheManagers[storagecacheId] = imagecache
}
}

func (s *SStorageManager) AddRbdStorageImagecache(imagecachePath string, storage IStorage, storagecacheId string) {
if s.RbdStorageImagecacheManagers == nil {
s.RbdStorageImagecacheManagers = map[string]IImageCacheManger{}
Expand Down
Loading

0 comments on commit f8ce36f

Please sign in to comment.