mirror of
https://gitee.com/rainbond/Rainbond.git
synced 2024-12-02 03:37:46 +08:00
update volume
This commit is contained in:
parent
e9f5b0f456
commit
6e989d95be
@ -42,7 +42,6 @@ type TenantInterface interface {
|
||||
GetManyDeployVersion(w http.ResponseWriter, r *http.Request)
|
||||
LimitTenantMemory(w http.ResponseWriter, r *http.Request)
|
||||
TenantResourcesStatus(w http.ResponseWriter, r *http.Request)
|
||||
GetVolumesStatus(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
//ServiceInterface ServiceInterface
|
||||
|
@ -201,7 +201,6 @@ func (v2 *V2) serviceRouter() chi.Router {
|
||||
r.Post("/volumes", middleware.WrapEL(controller.AddVolume, dbmodel.TargetTypeService, "add-service-volume", dbmodel.SYNEVENTTYPE))
|
||||
r.Put("/volumes", middleware.WrapEL(controller.GetManager().UpdVolume, dbmodel.TargetTypeService, "update-service-volume", dbmodel.SYNEVENTTYPE))
|
||||
r.Get("/volumes", controller.GetVolume)
|
||||
r.Get("/volumes-status", controller.GetManager().GetVolumesStatus)
|
||||
r.Delete("/volumes/{volume_name}", middleware.WrapEL(controller.DeleteVolume, dbmodel.TargetTypeService, "delete-service-volume", dbmodel.SYNEVENTTYPE))
|
||||
r.Post("/depvolumes", middleware.WrapEL(controller.AddVolumeDependency, dbmodel.TargetTypeService, "add-service-depvolume", dbmodel.SYNEVENTTYPE))
|
||||
r.Delete("/depvolumes", middleware.WrapEL(controller.DeleteVolumeDependency, dbmodel.TargetTypeService, "delete-service-depvolume", dbmodel.SYNEVENTTYPE))
|
||||
|
@ -21,7 +21,6 @@ package controller
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
@ -29,119 +28,10 @@ import (
|
||||
"github.com/goodrain/rainbond/api/handler"
|
||||
"github.com/goodrain/rainbond/api/middleware"
|
||||
api_model "github.com/goodrain/rainbond/api/model"
|
||||
"github.com/goodrain/rainbond/api/util"
|
||||
dbmodel "github.com/goodrain/rainbond/db/model"
|
||||
httputil "github.com/goodrain/rainbond/util/http"
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
// VolumeOptions list volume option
|
||||
func VolumeOptions(w http.ResponseWriter, r *http.Request) {
|
||||
// swagger:operation POST /v2/volume-options v2 volumeOptions
|
||||
//
|
||||
// 查询可用存储驱动模型列表
|
||||
//
|
||||
// get volume-options
|
||||
//
|
||||
// ---
|
||||
// consumes:
|
||||
// - application/json
|
||||
// - application/x-protobuf
|
||||
//
|
||||
// produces:
|
||||
// - application/json
|
||||
// - application/xml
|
||||
//
|
||||
// responses:
|
||||
// default:
|
||||
// schema:
|
||||
// description: 统一返回格式
|
||||
|
||||
storageClasses, err := handler.GetVolumeTypeHandler().GetAllStorageClasses()
|
||||
if err != nil {
|
||||
httputil.ReturnError(r, w, 500, err.Error())
|
||||
return
|
||||
}
|
||||
var optionList []api_model.VolumeOptionsStruct
|
||||
|
||||
volumeTypeMap := make(map[string]*dbmodel.TenantServiceVolumeType)
|
||||
volumeTypes, err := handler.GetVolumeTypeHandler().GetAllVolumeTypes()
|
||||
if err != nil {
|
||||
logrus.Errorf("get all volumeTypes error: %s", err.Error())
|
||||
httputil.ReturnError(r, w, 500, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
for _, vt := range volumeTypes {
|
||||
volumeTypeMap[vt.VolumeType] = vt
|
||||
}
|
||||
|
||||
for _, sc := range storageClasses {
|
||||
vt := util.ParseVolumeOptionType(sc)
|
||||
opt := api_model.VolumeOptionsStruct{}
|
||||
opt.VolumeType = vt // volumeType is storageclass's name, but share-file/memoryfs/local
|
||||
if dbvt, ok := volumeTypeMap[opt.VolumeType]; ok {
|
||||
util.HackVolumeOptionDetailFromDB(&opt, dbvt)
|
||||
} else {
|
||||
util.HackVolumeOptionDetail(vt, &opt, sc.GetName(), sc.GetReclaimPolicy(), sc.VolumeBindingMode, sc.AllowVolumeExpansion)
|
||||
}
|
||||
|
||||
optionList = append(optionList, opt)
|
||||
}
|
||||
// TODO 管理后台支持自定义StorageClass,则内容与db中的数据进行融合,进行更多的业务逻辑
|
||||
memoryVolumeType := api_model.VolumeOptionsStruct{VolumeType: dbmodel.MemoryFSVolumeType.String(), NameShow: "内存文件存储"}
|
||||
util.HackVolumeOptionDetailFromDB(&memoryVolumeType, volumeTypeMap["memoryfs"])
|
||||
optionList = append(optionList, memoryVolumeType)
|
||||
httputil.ReturnSuccess(r, w, optionList)
|
||||
}
|
||||
|
||||
// GetVolumesStatus getvolume status
|
||||
func (t *TenantStruct) GetVolumesStatus(w http.ResponseWriter, r *http.Request) {
|
||||
// swagger:operation POST /v2/tenants/{tenant_name}/volumes-status v2 GetVolumesStatus
|
||||
//
|
||||
// 查询组件存储状态
|
||||
//
|
||||
// post volumes-status
|
||||
//
|
||||
// ---
|
||||
// consumes:
|
||||
// - application/json
|
||||
// - application/x-protobuf
|
||||
//
|
||||
// produces:
|
||||
// - application/json
|
||||
// - application/xml
|
||||
//
|
||||
// responses:
|
||||
// default:
|
||||
// schema:
|
||||
// description: 统一返回格式
|
||||
serviceID := r.Context().Value(middleware.ContextKey("service_id")).(string)
|
||||
volumes, handlerErr := handler.GetServiceManager().GetVolumes(serviceID)
|
||||
if handlerErr != nil && handlerErr.Error() != gorm.ErrRecordNotFound.Error() {
|
||||
httputil.ReturnError(r, w, 500, handlerErr.Error())
|
||||
return
|
||||
}
|
||||
var err error
|
||||
volumeStatusList, err := t.StatusCli.GetAppVolumeStatus(serviceID)
|
||||
if err != nil {
|
||||
logrus.Warnf("get volume status error: %s", err.Error())
|
||||
}
|
||||
ret := api_model.VolumeWithStatusResp{Status: make(map[string]string)}
|
||||
if volumeStatusList != nil && volumeStatusList.GetStatus() != nil {
|
||||
volumeStatus := volumeStatusList.GetStatus()
|
||||
status := make(map[string]string)
|
||||
for _, volume := range volumes {
|
||||
volumeID := strconv.FormatInt(int64(volume.ID), 10)
|
||||
if phrase, ok := volumeStatus[volumeID]; ok {
|
||||
status[volume.VolumeName] = phrase.String()
|
||||
}
|
||||
}
|
||||
ret.Status = status
|
||||
}
|
||||
httputil.ReturnSuccess(r, w, ret)
|
||||
}
|
||||
|
||||
//VolumeDependency VolumeDependency
|
||||
func (t *TenantStruct) VolumeDependency(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
|
56
api/controller/volume_type.go
Normal file
56
api/controller/volume_type.go
Normal file
@ -0,0 +1,56 @@
|
||||
// Copyright (C) 2014-2018 Goodrain Co., Ltd.
|
||||
// RAINBOND, Application Management Platform
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version. For any non-GPL usage of Rainbond,
|
||||
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
|
||||
// must be obtained first.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package controller
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/goodrain/rainbond/api/handler"
|
||||
httputil "github.com/goodrain/rainbond/util/http"
|
||||
)
|
||||
|
||||
// VolumeOptions list volume option
|
||||
func VolumeOptions(w http.ResponseWriter, r *http.Request) {
|
||||
// swagger:operation POST /v2/volume-options v2 volumeOptions
|
||||
//
|
||||
// 查询可用存储驱动模型列表
|
||||
//
|
||||
// get volume-options
|
||||
//
|
||||
// ---
|
||||
// consumes:
|
||||
// - application/json
|
||||
// - application/x-protobuf
|
||||
//
|
||||
// produces:
|
||||
// - application/json
|
||||
// - application/xml
|
||||
//
|
||||
// responses:
|
||||
// default:
|
||||
// schema:
|
||||
// description: 统一返回格式
|
||||
|
||||
volumetypeOptions, err := handler.GetVolumeTypeHandler().GetAllVolumeTypes()
|
||||
if err != nil {
|
||||
httputil.ReturnError(r, w, 500, err.Error())
|
||||
return
|
||||
}
|
||||
httputil.ReturnSuccess(r, w, volumetypeOptions)
|
||||
}
|
35
api/db/db.go
35
api/db/db.go
@ -167,23 +167,24 @@ func dbInit() error {
|
||||
if err := begin.Where("class_level=? and prefix=?", "server_source", "/v2/show").Find(&rac).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
data := map[string]string{
|
||||
"/v2/show": "server_source",
|
||||
"/v2/opentsdb": "server_source",
|
||||
"/v2/resources": "server_source",
|
||||
"/v2/builder": "server_source",
|
||||
"/v2/tenants": "server_source",
|
||||
"/v2/app": "server_source",
|
||||
"/v2/port": "server_source",
|
||||
"/api/v1": "server_source",
|
||||
"/v2/events": "server_source",
|
||||
"/v2/gateway/ips": "server_source",
|
||||
"/v2/gateway/ports": "server_source",
|
||||
"/v2/nodes": "node_manager",
|
||||
"/v2/job": "node_manager",
|
||||
"/v2/tasks": "node_manager",
|
||||
"/v2/taskgroups": "node_manager",
|
||||
"/v2/tasktemps": "node_manager",
|
||||
"/v2/configs": "node_manager",
|
||||
"/v2/show": "server_source",
|
||||
"/v2/opentsdb": "server_source",
|
||||
"/v2/resources": "server_source",
|
||||
"/v2/builder": "server_source",
|
||||
"/v2/tenants": "server_source",
|
||||
"/v2/app": "server_source",
|
||||
"/v2/port": "server_source",
|
||||
"/v2/volume-options": "server_source",
|
||||
"/api/v1": "server_source",
|
||||
"/v2/events": "server_source",
|
||||
"/v2/gateway/ips": "server_source",
|
||||
"/v2/gateway/ports": "server_source",
|
||||
"/v2/nodes": "node_manager",
|
||||
"/v2/job": "node_manager",
|
||||
"/v2/tasks": "node_manager",
|
||||
"/v2/taskgroups": "node_manager",
|
||||
"/v2/tasktemps": "node_manager",
|
||||
"/v2/configs": "node_manager",
|
||||
}
|
||||
tx := begin
|
||||
var rollback bool
|
||||
|
@ -20,6 +20,8 @@ package handler
|
||||
|
||||
import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
api_model "github.com/goodrain/rainbond/api/model"
|
||||
"github.com/goodrain/rainbond/api/util"
|
||||
"github.com/goodrain/rainbond/db"
|
||||
dbmodel "github.com/goodrain/rainbond/db/model"
|
||||
"github.com/goodrain/rainbond/worker/client"
|
||||
@ -30,9 +32,11 @@ import (
|
||||
//VolumeTypeHandler LicenseAction
|
||||
type VolumeTypeHandler interface {
|
||||
VolumeTypeVar(action string, vtm *dbmodel.TenantServiceVolumeType) error
|
||||
GetAllVolumeTypes() ([]*dbmodel.TenantServiceVolumeType, error)
|
||||
GetAllVolumeTypes() ([]*api_model.VolumeTypeOptionsStruct, error)
|
||||
GetVolumeTypeByType(volumeType string) (*dbmodel.TenantServiceVolumeType, error)
|
||||
GetAllStorageClasses() ([]*pb.StorageClassDetail, error)
|
||||
VolumeTypeAction(action, volumeTypeID string) error
|
||||
DeleteVolumeType(volumeTypeID string) error
|
||||
}
|
||||
|
||||
var defaultVolumeTypeHandler VolumeTypeHandler
|
||||
@ -64,8 +68,40 @@ func (vta *VolumeTypeAction) VolumeTypeVar(action string, vtm *dbmodel.TenantSer
|
||||
}
|
||||
|
||||
// GetAllVolumeTypes get all volume types
|
||||
func (vta *VolumeTypeAction) GetAllVolumeTypes() ([]*dbmodel.TenantServiceVolumeType, error) {
|
||||
return db.GetManager().VolumeTypeDao().GetAllVolumeTypes()
|
||||
func (vta *VolumeTypeAction) GetAllVolumeTypes() ([]*api_model.VolumeTypeOptionsStruct, error) {
|
||||
storageClasses, err := vta.GetAllStorageClasses()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var optionList []*api_model.VolumeTypeOptionsStruct
|
||||
volumeTypeMap := make(map[string]*dbmodel.TenantServiceVolumeType)
|
||||
volumeTypes, err := db.GetManager().VolumeTypeDao().GetAllVolumeTypes()
|
||||
if err != nil {
|
||||
logrus.Errorf("get all volumeTypes error: %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, vt := range volumeTypes {
|
||||
volumeTypeMap[vt.VolumeType] = vt
|
||||
}
|
||||
|
||||
for _, sc := range storageClasses {
|
||||
vt := util.ParseVolumeTypeOption(sc)
|
||||
opt := &api_model.VolumeTypeOptionsStruct{}
|
||||
opt.VolumeType = vt // volumeType is storageclass's name, but share-file/memoryfs/local
|
||||
if dbvt, ok := volumeTypeMap[opt.VolumeType]; ok {
|
||||
util.HackVolumeOptionDetailFromDB(opt, dbvt)
|
||||
} else {
|
||||
util.HackVolumeOptionDetail(vt, opt, sc.GetName(), sc.GetReclaimPolicy(), sc.VolumeBindingMode, sc.AllowVolumeExpansion)
|
||||
}
|
||||
|
||||
optionList = append(optionList, opt)
|
||||
}
|
||||
// TODO 管理后台支持自定义StorageClass,则内容与db中的数据进行融合,进行更多的业务逻辑
|
||||
memoryVolumeType := &api_model.VolumeTypeOptionsStruct{VolumeType: dbmodel.MemoryFSVolumeType.String(), NameShow: "内存文件存储"}
|
||||
util.HackVolumeOptionDetailFromDB(memoryVolumeType, volumeTypeMap["memoryfs"])
|
||||
optionList = append(optionList, memoryVolumeType)
|
||||
return optionList, nil
|
||||
}
|
||||
|
||||
// GetVolumeTypeByType get volume type by type
|
||||
@ -81,3 +117,14 @@ func (vta *VolumeTypeAction) GetAllStorageClasses() ([]*pb.StorageClassDetail, e
|
||||
}
|
||||
return sces.List, nil
|
||||
}
|
||||
|
||||
// VolumeTypeAction open volme type or close it
|
||||
func (vta *VolumeTypeAction) VolumeTypeAction(action, volumeTypeID string) error {
|
||||
// TODO 开启驱动或者关闭驱动,关闭之前需要确定该驱动是否可以因为已经绑定了存储而不能直接关闭
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteVolumeType delte volume type
|
||||
func (vta *VolumeTypeAction) DeleteVolumeType(volumeTypeID string) error {
|
||||
return nil
|
||||
}
|
||||
|
@ -1473,13 +1473,46 @@ func (s *ServiceAction) UpdVolume(sid string, req *api_model.UpdVolumeReq) error
|
||||
}
|
||||
|
||||
//GetVolumes 获取应用全部存储
|
||||
func (s *ServiceAction) GetVolumes(serviceID string) ([]*dbmodel.TenantServiceVolume, *util.APIHandleError) {
|
||||
dbManager := db.GetManager()
|
||||
vs, err := dbManager.TenantServiceVolumeDao().GetTenantServiceVolumesByServiceID(serviceID)
|
||||
func (s *ServiceAction) GetVolumes(serviceID string) ([]*api_model.VolumeWithStatusStruct, *util.APIHandleError) {
|
||||
volumeWithStatusList := make([]*api_model.VolumeWithStatusStruct, 0)
|
||||
vs, err := db.GetManager().TenantServiceVolumeDao().GetTenantServiceVolumesByServiceID(serviceID)
|
||||
if err != nil && err.Error() != gorm.ErrRecordNotFound.Error() {
|
||||
return nil, util.CreateAPIHandleErrorFromDBError("get volumes", err)
|
||||
}
|
||||
return vs, nil
|
||||
|
||||
volumeStatusList, err := s.statusCli.GetAppVolumeStatus(serviceID)
|
||||
if err != nil {
|
||||
logrus.Warnf("get volume status error: %s", err.Error())
|
||||
}
|
||||
|
||||
if volumeStatusList != nil && volumeStatusList.GetStatus() != nil {
|
||||
volumeStatus := volumeStatusList.GetStatus()
|
||||
for _, volume := range vs {
|
||||
vws := &api_model.VolumeWithStatusStruct{
|
||||
ServiceID: volume.ServiceID,
|
||||
Category: volume.Category,
|
||||
VolumeType: volume.VolumeType,
|
||||
VolumeName: volume.VolumeName,
|
||||
HostPath: volume.HostPath,
|
||||
VolumePath: volume.VolumePath,
|
||||
IsReadOnly: volume.IsReadOnly,
|
||||
VolumeCapacity: volume.VolumeCapacity,
|
||||
AccessMode: volume.AccessMode,
|
||||
SharePolicy: volume.SharePolicy,
|
||||
BackupPolicy: volume.BackupPolicy,
|
||||
ReclaimPolicy: volume.ReclaimPolicy,
|
||||
AllowExpansion: volume.AllowExpansion,
|
||||
VolumeProviderName: volume.VolumeProviderName,
|
||||
}
|
||||
volumeID := strconv.FormatInt(int64(volume.ID), 10)
|
||||
if phrase, ok := volumeStatus[volumeID]; ok {
|
||||
vws.Status = phrase.String()
|
||||
}
|
||||
volumeWithStatusList = append(volumeWithStatusList, vws)
|
||||
}
|
||||
}
|
||||
|
||||
return volumeWithStatusList, nil
|
||||
}
|
||||
|
||||
//VolumeDependency VolumeDependency
|
||||
|
@ -54,7 +54,7 @@ type ServiceHandler interface {
|
||||
UpdVolume(sid string, req *api_model.UpdVolumeReq) error
|
||||
VolumeDependency(tsr *dbmodel.TenantServiceMountRelation, action string) *util.APIHandleError
|
||||
GetDepVolumes(serviceID string) ([]*dbmodel.TenantServiceMountRelation, *util.APIHandleError)
|
||||
GetVolumes(serviceID string) ([]*dbmodel.TenantServiceVolume, *util.APIHandleError)
|
||||
GetVolumes(serviceID string) ([]*api_model.VolumeWithStatusStruct, *util.APIHandleError)
|
||||
ServiceProbe(tsp *dbmodel.TenantServiceProbe, action string) error
|
||||
RollBack(rs *api_model.RollbackStruct) error
|
||||
GetStatus(serviceID string) (*api_model.StatusList, error)
|
||||
|
@ -18,50 +18,6 @@
|
||||
|
||||
package model
|
||||
|
||||
// VolumeBestReqStruct request for volumebest
|
||||
type VolumeBestReqStruct struct {
|
||||
VolumeType string `json:"volume_type" validate:"volume_type|required|in:share-file,local,memoryfs,config-file,ceph-rbd"`
|
||||
AccessMode string `json:"access_mode"`
|
||||
SharePolicy string `json:"share_policy"`
|
||||
BackupPolicy string `json:"backup_policy"`
|
||||
}
|
||||
|
||||
// VolumeBestRespStruct response for volumebest
|
||||
type VolumeBestRespStruct struct {
|
||||
Changed bool `json:"changed"`
|
||||
VolumeType string `json:"volume_type"`
|
||||
}
|
||||
|
||||
// VolumeOptionsStruct volume option struct
|
||||
type VolumeOptionsStruct struct {
|
||||
VolumeType string `json:"volume_type"`
|
||||
NameShow string `json:"name_show"`
|
||||
VolumeProviderName string `json:"volume_provider_name"`
|
||||
CapacityValidation map[string]interface{} `json:"capacity_validation"`
|
||||
Description string `json:"description"`
|
||||
AccessMode []string `json:"access_mode"`
|
||||
SharePolicy []string `json:"share_policy"` //共享模式
|
||||
BackupPolicy []string `json:"backup_policy"` // 备份策略
|
||||
ReclaimPolicy string `json:"reclaim_policy"` // 回收策略,delete, retain, recyle
|
||||
VolumeBindingMode string `json:"volume_binding_mode"` // 绑定模式,Immediate,WaitForFirstConsumer
|
||||
AllowVolumeExpansion *bool `json:"allow_volume_expansion"` // 是否支持扩展
|
||||
Sort int `json:"sort"` // 排序
|
||||
}
|
||||
|
||||
// VolumeProviderDetail volume provider detail
|
||||
// Attention accessMode/sharerPolicy/backupPolicy都是结合业务进行添加字段,需自己补充
|
||||
// Provisioner/reclaimPolicy/volumeBindingMode/allowVolumeExpansion为StorageClass内置参数
|
||||
type VolumeProviderDetail struct {
|
||||
Name string `json:"name"` //StorageClass名字
|
||||
Provisioner string `json:"provisioner"` //提供者,如ceph.com/rbd、kubernetes.io/rbd
|
||||
VolumeBindingMode string `json:"volume_binding_mode"` // 绑定模式,Immediate,WaitForFirstConsumer
|
||||
AllowVolumeExpansion *bool `json:"allow_volume_expansion"` // 是否支持扩展
|
||||
AccessMode []string `json:"access_mode"` // 读写模式(Important! A volume can only be mounted using one access mode at a time, even if it supports many. For example, a GCEPersistentDisk can be mounted as ReadWriteOnce by a single node or ReadOnlyMany by many nodes, but not at the same time. #https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes)
|
||||
SharePolicy []string `json:"share_policy"` //共享模式
|
||||
BackupPolicy []string `json:"backup_policy"` // 备份策略
|
||||
ReclaimPolicy string `json:"reclaim_policy"` // 回收策略,delete, retain, recyle
|
||||
}
|
||||
|
||||
//AddVolumeStruct AddVolumeStruct
|
||||
//swagger:parameters addVolumes
|
||||
type AddVolumeStruct struct {
|
||||
@ -295,3 +251,35 @@ type VolumeWithStatusResp struct {
|
||||
//存储名称
|
||||
Status map[string]string `json:"status"`
|
||||
}
|
||||
|
||||
// VolumeWithStatusStruct volume with status struct
|
||||
type VolumeWithStatusStruct struct {
|
||||
ServiceID string `json:"service_id"`
|
||||
//服务类型
|
||||
Category string `json:"category"`
|
||||
//存储类型(share,local,tmpfs)
|
||||
VolumeType string `json:"volume_type"`
|
||||
//存储名称
|
||||
VolumeName string `json:"volume_name"`
|
||||
//主机地址
|
||||
HostPath string `json:"host_path"`
|
||||
//挂载地址
|
||||
VolumePath string `json:"volume_path"`
|
||||
//是否只读
|
||||
IsReadOnly bool `json:"is_read_only"`
|
||||
// VolumeCapacity 存储大小
|
||||
VolumeCapacity int64 `json:"volume_capacity"`
|
||||
// AccessMode 读写模式(Important! A volume can only be mounted using one access mode at a time, even if it supports many. For example, a GCEPersistentDisk can be mounted as ReadWriteOnce by a single node or ReadOnlyMany by many nodes, but not at the same time. #https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes)
|
||||
AccessMode string `json:"access_mode"`
|
||||
// SharePolicy 共享模式
|
||||
SharePolicy string `json:"share_policy"`
|
||||
// BackupPolicy 备份策略
|
||||
BackupPolicy string `json:"backup_policy"`
|
||||
// ReclaimPolicy 回收策略
|
||||
ReclaimPolicy string `json:"reclaim_policy"`
|
||||
// AllowExpansion 是否支持扩展
|
||||
AllowExpansion bool `json:"allow_expansion"`
|
||||
// VolumeProviderName 使用的存储驱动别名
|
||||
VolumeProviderName string `json:"volume_provider_name"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
63
api/model/volume_type.go
Normal file
63
api/model/volume_type.go
Normal file
@ -0,0 +1,63 @@
|
||||
// Copyright (C) 2014-2018 Goodrain Co., Ltd.
|
||||
// RAINBOND, Application Management Platform
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version. For any non-GPL usage of Rainbond,
|
||||
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
|
||||
// must be obtained first.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package model
|
||||
|
||||
// VolumeBestReqStruct request for volumebest
|
||||
type VolumeBestReqStruct struct {
|
||||
VolumeType string `json:"volume_type" validate:"volume_type|required|in:share-file,local,memoryfs,config-file,ceph-rbd"`
|
||||
AccessMode string `json:"access_mode"`
|
||||
SharePolicy string `json:"share_policy"`
|
||||
BackupPolicy string `json:"backup_policy"`
|
||||
}
|
||||
|
||||
// VolumeBestRespStruct response for volumebest
|
||||
type VolumeBestRespStruct struct {
|
||||
Changed bool `json:"changed"`
|
||||
VolumeType string `json:"volume_type"`
|
||||
}
|
||||
|
||||
// VolumeTypeOptionsStruct volume option struct
|
||||
type VolumeTypeOptionsStruct struct {
|
||||
VolumeType string `json:"volume_type"`
|
||||
NameShow string `json:"name_show"`
|
||||
VolumeProviderName string `json:"volume_provider_name"`
|
||||
CapacityValidation map[string]interface{} `json:"capacity_validation"`
|
||||
Description string `json:"description"`
|
||||
AccessMode []string `json:"access_mode"`
|
||||
SharePolicy []string `json:"share_policy"` //共享模式
|
||||
BackupPolicy []string `json:"backup_policy"` // 备份策略
|
||||
ReclaimPolicy string `json:"reclaim_policy"` // 回收策略,delete, retain, recyle
|
||||
VolumeBindingMode string `json:"volume_binding_mode"` // 绑定模式,Immediate,WaitForFirstConsumer
|
||||
AllowVolumeExpansion *bool `json:"allow_volume_expansion"` // 是否支持扩展
|
||||
Sort int `json:"sort"` // 排序
|
||||
}
|
||||
|
||||
// VolumeProviderDetail volume provider detail
|
||||
// Attention accessMode/sharerPolicy/backupPolicy都是结合业务进行添加字段,需自己补充
|
||||
// Provisioner/reclaimPolicy/volumeBindingMode/allowVolumeExpansion为StorageClass内置参数
|
||||
type VolumeProviderDetail struct {
|
||||
Name string `json:"name"` //StorageClass名字
|
||||
Provisioner string `json:"provisioner"` //提供者,如ceph.com/rbd、kubernetes.io/rbd
|
||||
VolumeBindingMode string `json:"volume_binding_mode"` // 绑定模式,Immediate,WaitForFirstConsumer
|
||||
AllowVolumeExpansion *bool `json:"allow_volume_expansion"` // 是否支持扩展
|
||||
AccessMode []string `json:"access_mode"` // 读写模式(Important! A volume can only be mounted using one access mode at a time, even if it supports many. For example, a GCEPersistentDisk can be mounted as ReadWriteOnce by a single node or ReadOnlyMany by many nodes, but not at the same time. #https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes)
|
||||
SharePolicy []string `json:"share_policy"` //共享模式
|
||||
BackupPolicy []string `json:"backup_policy"` // 备份策略
|
||||
ReclaimPolicy string `json:"reclaim_policy"` // 回收策略,delete, retain, recyle
|
||||
}
|
@ -37,9 +37,9 @@ func SetVolumeDefaultValue(info *dbmodel.TenantServiceVolume) {
|
||||
}
|
||||
}
|
||||
|
||||
// ParseVolumeOptionType parse volume Option name show and volume type
|
||||
func ParseVolumeOptionType(detail *pb.StorageClassDetail) string {
|
||||
volumeType := transferVolumeOptionType(detail.Name, detail.Provisioner, detail.Parameters)
|
||||
// ParseVolumeTypeOption parse volume Option name show and volume type
|
||||
func ParseVolumeTypeOption(detail *pb.StorageClassDetail) string {
|
||||
volumeType := transferVolumeTypeOption(detail.Name, detail.Provisioner, detail.Parameters)
|
||||
if volumeType != nil {
|
||||
return volumeType.String()
|
||||
}
|
||||
@ -47,7 +47,7 @@ func ParseVolumeOptionType(detail *pb.StorageClassDetail) string {
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
func transferVolumeOptionType(name string, opts ...interface{}) *dbmodel.VolumeType {
|
||||
func transferVolumeTypeOption(name string, opts ...interface{}) *dbmodel.VolumeType {
|
||||
if name == v1.RainbondStatefuleShareStorageClass {
|
||||
return &dbmodel.ShareFileVolumeType
|
||||
}
|
||||
@ -79,7 +79,7 @@ func transferCustomVolumeOptionName2Kind(opts ...interface{}) *dbmodel.VolumeTyp
|
||||
}
|
||||
|
||||
// HackVolumeOptionDetailFromDB hack volumeOptionDetail from db
|
||||
func HackVolumeOptionDetailFromDB(detail *api_model.VolumeOptionsStruct, data *dbmodel.TenantServiceVolumeType) {
|
||||
func HackVolumeOptionDetailFromDB(detail *api_model.VolumeTypeOptionsStruct, data *dbmodel.TenantServiceVolumeType) {
|
||||
if data != nil {
|
||||
detail.Description = data.Description
|
||||
detail.NameShow = data.NameShow
|
||||
@ -108,7 +108,7 @@ func init() {
|
||||
}
|
||||
|
||||
// HackVolumeOptionDetail hack volume Option detail, like accessMode, sharePolicy, backupPolicy
|
||||
func HackVolumeOptionDetail(volumeType string, detail *api_model.VolumeOptionsStruct, more ...interface{}) {
|
||||
func HackVolumeOptionDetail(volumeType string, detail *api_model.VolumeTypeOptionsStruct, more ...interface{}) {
|
||||
/*
|
||||
RWO - ReadWriteOnce
|
||||
ROX - ReadOnlyMany
|
||||
|
@ -479,6 +479,7 @@ func (b *BackupAPPRestore) restoreMetadata(appSnapshot *AppSnapshot) error {
|
||||
case dbmodel.LocalVolumeType.String():
|
||||
a.HostPath = fmt.Sprintf("%s/tenant/%s/service/%s%s", localPath, b.TenantID, a.ServiceID, a.VolumePath)
|
||||
}
|
||||
// TODO 其他存储类型的备份与恢复
|
||||
if err := db.GetManager().TenantServiceVolumeDaoTransactions(tx).AddModel(a); err != nil {
|
||||
tx.Rollback()
|
||||
return fmt.Errorf("create app volume when restore backup error. %s", err.Error())
|
||||
|
@ -33,10 +33,10 @@ type OtherVolume struct {
|
||||
|
||||
// CreateVolume ceph rbd volume create volume
|
||||
func (v *OtherVolume) CreateVolume(define *Define) error {
|
||||
if v.svm.VolumeCapacity <= 0 {
|
||||
if v.svm.VolumeCapacity <= 0 { // TODO 文件类型 是否可以为不限制大小
|
||||
return fmt.Errorf("volume capcacity is %d, must be greater than zero", v.svm.VolumeCapacity)
|
||||
}
|
||||
volumeMountName := fmt.Sprintf("manual%d", v.svm.ID)
|
||||
volumeMountName := fmt.Sprintf("manual%d", v.svm.ID) // TODO 名字是否会重复
|
||||
volumeMountPath := v.svm.VolumePath
|
||||
volumeReadOnly := v.svm.IsReadOnly
|
||||
labels := v.as.GetCommonLabels(map[string]string{"volume_name": v.svm.VolumeName, "version": v.as.DeployVersion, "reclaim_policy": v.svm.ReclaimPolicy})
|
||||
|
@ -481,6 +481,8 @@ func (r *RuntimeServer) GetAppVolumeStatus(ctx context.Context, re *pb.ServiceRe
|
||||
logrus.Warnf("get volume status error : %s", err.Error())
|
||||
return ret, nil
|
||||
}
|
||||
// TODO 多个pod,正在更新中的pod
|
||||
// TODO 不严谨,不应该单纯的使用volume确定挂载状态
|
||||
for _, pod := range appPodList.GetNewPods() {
|
||||
for _, volumeName := range pod.PodVolumes {
|
||||
prefix := "manual"
|
||||
|
Loading…
Reference in New Issue
Block a user