mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-12-18 02:50:30 +00:00
rbd: make pool optional in rbd sc if topologyconstraints are present
if rbd storage class is created with topologyconstraintspools replicated pool was still mandatory, making the pool optional if the topologyconstraintspools is requested Closes: https://github.com/ceph/ceph-csi/issues/4380 Signed-off-by: parth-gr <partharora1010@gmail.com>
This commit is contained in:
parent
5224d58c13
commit
063319f6e5
@ -16,8 +16,10 @@ metadata:
|
|||||||
provisioner: {{ .Values.driverName }}
|
provisioner: {{ .Values.driverName }}
|
||||||
parameters:
|
parameters:
|
||||||
clusterID: {{ .Values.storageClass.clusterID }}
|
clusterID: {{ .Values.storageClass.clusterID }}
|
||||||
pool: {{ .Values.storageClass.pool }}
|
|
||||||
imageFeatures: {{ .Values.storageClass.imageFeatures }}
|
imageFeatures: {{ .Values.storageClass.imageFeatures }}
|
||||||
|
{{- if .Values.storageClass.pool }}
|
||||||
|
pool: {{ .Values.storageClass.pool }}
|
||||||
|
{{- end }}
|
||||||
{{- if .Values.storageClass.tryOtherMounters }}
|
{{- if .Values.storageClass.tryOtherMounters }}
|
||||||
tryOtherMounters: {{ .Values.storageClass.tryOtherMounters | quote}}
|
tryOtherMounters: {{ .Values.storageClass.tryOtherMounters | quote}}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
@ -343,6 +343,7 @@ storageClass:
|
|||||||
dataPool: ""
|
dataPool: ""
|
||||||
|
|
||||||
# (required) Ceph pool into which the RBD image shall be created
|
# (required) Ceph pool into which the RBD image shall be created
|
||||||
|
# (optional) if topologyConstrainedPools is provided
|
||||||
# eg: pool: replicapool
|
# eg: pool: replicapool
|
||||||
pool: replicapool
|
pool: replicapool
|
||||||
|
|
||||||
|
@ -3043,19 +3043,21 @@ var _ = Describe("RBD", func() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
By("ensuring created PV has its CSI journal in the CSI journal specific pool")
|
By("ensuring created PV has its CSI journal in the CSI journal specific pool")
|
||||||
err = checkPVCCSIJournalInPool(f, pvc, "replicapool")
|
err = checkPVCCSIJournalInPool(f, pvc, rbdTopologyPool)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
framework.Failf("failed to check csi journal in pool: %v", err)
|
framework.Failf("failed to check csi journal in pool: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = deleteJournalInfoInPool(f, pvc, "replicapool")
|
err = deleteJournalInfoInPool(f, pvc, rbdTopologyPool)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
framework.Failf("failed to delete omap data: %v", err)
|
framework.Failf("failed to delete omap data: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = deletePVCAndApp("", f, pvc, app)
|
err = deletePVCAndApp("", f, pvc, app)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
framework.Failf("failed to delete PVC and application: %v", err)
|
framework.Failf("failed to delete PVC and application: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
validateRBDImageCount(f, 0, defaultRBDPool)
|
validateRBDImageCount(f, 0, defaultRBDPool)
|
||||||
validateOmapCount(f, 0, rbdType, defaultRBDPool, volumesType)
|
validateOmapCount(f, 0, rbdType, defaultRBDPool, volumesType)
|
||||||
|
|
||||||
@ -3092,7 +3094,7 @@ var _ = Describe("RBD", func() {
|
|||||||
framework.Failf("failed to check data pool for image: %v", err)
|
framework.Failf("failed to check data pool for image: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = deleteJournalInfoInPool(f, pvc, "replicapool")
|
err = deleteJournalInfoInPool(f, pvc, rbdTopologyPool)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
framework.Failf("failed to delete omap data: %v", err)
|
framework.Failf("failed to delete omap data: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,10 @@ func createRBDStorageClass(
|
|||||||
if name != "" {
|
if name != "" {
|
||||||
sc.Name = name
|
sc.Name = name
|
||||||
}
|
}
|
||||||
sc.Parameters["pool"] = defaultRBDPool
|
// add pool only if topologyConstrainedPools is not present
|
||||||
|
if _, ok := parameters["topologyConstrainedPools"]; !ok {
|
||||||
|
sc.Parameters["pool"] = defaultRBDPool
|
||||||
|
}
|
||||||
sc.Parameters["csi.storage.k8s.io/provisioner-secret-namespace"] = cephCSINamespace
|
sc.Parameters["csi.storage.k8s.io/provisioner-secret-namespace"] = cephCSINamespace
|
||||||
sc.Parameters["csi.storage.k8s.io/provisioner-secret-name"] = rbdProvisionerSecretName
|
sc.Parameters["csi.storage.k8s.io/provisioner-secret-name"] = rbdProvisionerSecretName
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ parameters:
|
|||||||
# dataPool: <ec-data-pool>
|
# dataPool: <ec-data-pool>
|
||||||
|
|
||||||
# (required) Ceph pool into which the RBD image shall be created
|
# (required) Ceph pool into which the RBD image shall be created
|
||||||
|
# (optional) If the topologyConstrainedPools is provided
|
||||||
# eg: pool: rbdpool
|
# eg: pool: rbdpool
|
||||||
pool: <rbd-pool-name>
|
pool: <rbd-pool-name>
|
||||||
|
|
||||||
|
@ -76,12 +76,19 @@ func (cs *ControllerServer) validateVolumeReq(ctx context.Context, req *csi.Crea
|
|||||||
}
|
}
|
||||||
options := req.GetParameters()
|
options := req.GetParameters()
|
||||||
if value, ok := options["clusterID"]; !ok || value == "" {
|
if value, ok := options["clusterID"]; !ok || value == "" {
|
||||||
return status.Error(codes.InvalidArgument, "missing or empty cluster ID to provision volume from")
|
return status.Error(codes.InvalidArgument, "empty cluster ID to provision volume from")
|
||||||
}
|
}
|
||||||
if value, ok := options["pool"]; !ok || value == "" {
|
poolValue, poolOK := options["pool"]
|
||||||
|
topologyConstrainedPoolsValue, topologyOK := options["topologyConstrainedPools"]
|
||||||
|
if !poolOK {
|
||||||
|
if topologyOK && topologyConstrainedPoolsValue == "" {
|
||||||
|
return status.Error(codes.InvalidArgument, "empty pool name or topologyConstrainedPools to provision volume")
|
||||||
|
} else if !topologyOK {
|
||||||
|
return status.Error(codes.InvalidArgument, "missing or empty pool name to provision volume from")
|
||||||
|
}
|
||||||
|
} else if poolValue == "" {
|
||||||
return status.Error(codes.InvalidArgument, "missing or empty pool name to provision volume from")
|
return status.Error(codes.InvalidArgument, "missing or empty pool name to provision volume from")
|
||||||
}
|
}
|
||||||
|
|
||||||
if value, ok := options["dataPool"]; ok && value == "" {
|
if value, ok := options["dataPool"]; ok && value == "" {
|
||||||
return status.Error(codes.InvalidArgument, "empty datapool name to provision volume from")
|
return status.Error(codes.InvalidArgument, "empty datapool name to provision volume from")
|
||||||
}
|
}
|
||||||
@ -244,6 +251,7 @@ func buildCreateVolumeResponse(req *csi.CreateVolumeRequest, rbdVol *rbdVolume)
|
|||||||
VolumeContext: volumeContext,
|
VolumeContext: volumeContext,
|
||||||
ContentSource: req.GetVolumeContentSource(),
|
ContentSource: req.GetVolumeContentSource(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if rbdVol.Topology != nil {
|
if rbdVol.Topology != nil {
|
||||||
volume.AccessibleTopology = []*csi.Topology{
|
volume.AccessibleTopology = []*csi.Topology{
|
||||||
{
|
{
|
||||||
@ -341,6 +349,11 @@ func (cs *ControllerServer) CreateVolume(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = updateTopologyConstraints(rbdVol, rbdSnap)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
found, err := rbdVol.Exists(ctx, parentVol)
|
found, err := rbdVol.Exists(ctx, parentVol)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, getGRPCErrorForCreateVolume(err)
|
return nil, getGRPCErrorForCreateVolume(err)
|
||||||
@ -358,7 +371,7 @@ func (cs *ControllerServer) CreateVolume(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = reserveVol(ctx, rbdVol, rbdSnap, cr)
|
err = reserveVol(ctx, rbdVol, cr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, err.Error())
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
}
|
}
|
||||||
|
@ -76,6 +76,10 @@ func validateRbdVol(rbdVol *rbdVolume) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = validateNonEmptyField(rbdVol.JournalPool, "JournalPool", "rbdVolume"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err = validateNonEmptyField(rbdVol.ClusterID, "ClusterID", "rbdVolume"); err != nil {
|
if err = validateNonEmptyField(rbdVol.ClusterID, "ClusterID", "rbdVolume"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -433,6 +437,7 @@ func updateTopologyConstraints(rbdVol *rbdVolume, rbdSnap *rbdSnapshot) error {
|
|||||||
if rbdVol.Topology != nil {
|
if rbdVol.Topology != nil {
|
||||||
rbdVol.Pool = poolName
|
rbdVol.Pool = poolName
|
||||||
rbdVol.DataPool = dataPoolName
|
rbdVol.DataPool = dataPoolName
|
||||||
|
rbdVol.JournalPool = poolName
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -446,6 +451,7 @@ func updateTopologyConstraints(rbdVol *rbdVolume, rbdSnap *rbdSnapshot) error {
|
|||||||
rbdVol.Pool = poolName
|
rbdVol.Pool = poolName
|
||||||
rbdVol.DataPool = dataPoolName
|
rbdVol.DataPool = dataPoolName
|
||||||
rbdVol.Topology = topology
|
rbdVol.Topology = topology
|
||||||
|
rbdVol.JournalPool = poolName
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -453,14 +459,9 @@ func updateTopologyConstraints(rbdVol *rbdVolume, rbdSnap *rbdSnapshot) error {
|
|||||||
|
|
||||||
// reserveVol is a helper routine to request a rbdVolume name reservation and generate the
|
// reserveVol is a helper routine to request a rbdVolume name reservation and generate the
|
||||||
// volume ID for the generated name.
|
// volume ID for the generated name.
|
||||||
func reserveVol(ctx context.Context, rbdVol *rbdVolume, rbdSnap *rbdSnapshot, cr *util.Credentials) error {
|
func reserveVol(ctx context.Context, rbdVol *rbdVolume, cr *util.Credentials) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
err = updateTopologyConstraints(rbdVol, rbdSnap)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
journalPoolID, imagePoolID, err := util.GetPoolIDs(ctx, rbdVol.Monitors, rbdVol.JournalPool, rbdVol.Pool, cr)
|
journalPoolID, imagePoolID, err := util.GetPoolIDs(ctx, rbdVol.Monitors, rbdVol.JournalPool, rbdVol.Pool, cr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1270,9 +1270,12 @@ func genVolFromVolumeOptions(
|
|||||||
)
|
)
|
||||||
|
|
||||||
rbdVol := &rbdVolume{}
|
rbdVol := &rbdVolume{}
|
||||||
|
|
||||||
rbdVol.Pool, ok = volOptions["pool"]
|
rbdVol.Pool, ok = volOptions["pool"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("missing required parameter pool")
|
if _, ok = volOptions["topologyConstrainedPools"]; !ok {
|
||||||
|
return nil, errors.New("empty pool name or topologyConstrainedPools to provision volume")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rbdVol.DataPool = volOptions["dataPool"]
|
rbdVol.DataPool = volOptions["dataPool"]
|
||||||
|
Loading…
Reference in New Issue
Block a user