Skip to content

Commit 1e95ce6

Browse files
committed
chore: add support for ReadWriteOncePod access mode
Signed-off-by: William Phetsinorath <[email protected]>
1 parent e7db6e7 commit 1e95ce6

File tree

6 files changed

+56
-9
lines changed

6 files changed

+56
-9
lines changed

csi/controller_server.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ func NewControllerServer(apiClient *longhornclient.RancherClient, nodeID string)
6969
accessModes: getVolumeCapabilityAccessModes(
7070
[]csi.VolumeCapability_AccessMode_Mode{
7171
csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
72+
csi.VolumeCapability_AccessMode_SINGLE_NODE_SINGLE_WRITER,
73+
csi.VolumeCapability_AccessMode_SINGLE_NODE_MULTI_WRITER,
7274
csi.VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER,
7375
}),
7476
log: logrus.StandardLogger().WithField("component", "csi-controller-server"),
@@ -220,6 +222,10 @@ func (cs *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
220222
volumeParameters["share"] = "true"
221223
break
222224
}
225+
if requireExclusiveAccess(nil, cap) {
226+
volumeParameters["exclusive"] = "true"
227+
break
228+
}
223229
}
224230

225231
vol, err := getVolumeOptions(volumeID, volumeParameters)
@@ -454,6 +460,13 @@ func (cs *ControllerServer) ControllerPublishVolume(ctx context.Context, req *cs
454460
}
455461
}
456462

463+
if requireExclusiveAccess(volume, volumeCapability) {
464+
volume, err = cs.updateVolumeAccessMode(volume, longhorn.AccessModeReadWriteOncePod)
465+
if err != nil {
466+
return nil, err
467+
}
468+
}
469+
457470
// TODO: JM Restore should be handled by the volume attach call, consider returning `codes.Aborted`
458471
// TODO: JM should readiness be handled by the caller?
459472
// Most of the readiness conditions are covered by the attach, except auto attachment which requires changes to the design

csi/util.go

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,26 @@ func getVolumeOptions(volumeID string, volOptions map[string]string) (*longhornc
115115

116116
if isShared {
117117
vol.AccessMode = string(longhorn.AccessModeReadWriteMany)
118-
} else {
119-
vol.AccessMode = string(longhorn.AccessModeReadWriteOnce)
120118
}
121119
}
122120

121+
if exclusive, ok := volOptions["exclusive"]; ok {
122+
isExclusive, err := strconv.ParseBool(exclusive)
123+
if err != nil {
124+
return nil, errors.Wrap(err, "invalid parameter exclusive")
125+
}
126+
if isExclusive && vol.AccessMode == string(longhorn.AccessModeReadWriteMany) {
127+
return nil, errors.New("cannot set both share and exclusive to true")
128+
}
129+
if isExclusive {
130+
vol.AccessMode = string(longhorn.AccessModeReadWriteOncePod)
131+
}
132+
}
133+
134+
if vol.AccessMode == "" {
135+
vol.AccessMode = string(longhorn.AccessModeReadWriteOnce)
136+
}
137+
123138
if migratable, ok := volOptions["migratable"]; ok {
124139
isMigratable, err := strconv.ParseBool(migratable)
125140
if err != nil {
@@ -453,6 +468,20 @@ func requiresSharedAccess(vol *longhornclient.Volume, cap *csi.VolumeCapability)
453468
mode == csi.VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER
454469
}
455470

471+
func requireExclusiveAccess(vol *longhornclient.Volume, cap *csi.VolumeCapability) bool {
472+
isExclusive := false
473+
if vol != nil {
474+
isExclusive = vol.AccessMode == string(longhorn.AccessModeReadWriteOncePod)
475+
}
476+
477+
mode := csi.VolumeCapability_AccessMode_UNKNOWN
478+
if cap != nil {
479+
mode = cap.AccessMode.Mode
480+
}
481+
482+
return isExclusive || mode == csi.VolumeCapability_AccessMode_SINGLE_NODE_SINGLE_WRITER
483+
}
484+
456485
func getStageBlockVolumePath(stagingTargetPath, volumeID string) string {
457486
return filepath.Join(stagingTargetPath, volumeID)
458487
}

datastore/kubernetes.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1015,8 +1015,11 @@ func NewPVManifest(size int64, pvName, volumeName, storageClassName, fsType stri
10151015
// NewPVCManifestForVolume returns a new PersistentVolumeClaim object for a longhorn volume
10161016
func NewPVCManifestForVolume(v *longhorn.Volume, pvName, ns, pvcName, storageClassName string) *corev1.PersistentVolumeClaim {
10171017
accessMode := corev1.ReadWriteOnce
1018-
if v.Spec.AccessMode == longhorn.AccessModeReadWriteMany {
1018+
switch v.Spec.AccessMode {
1019+
case longhorn.AccessModeReadWriteMany:
10191020
accessMode = corev1.ReadWriteMany
1021+
case longhorn.AccessModeReadWriteOncePod:
1022+
accessMode = corev1.ReadWriteOncePod
10201023
}
10211024

10221025
return NewPVCManifest(v.Spec.Size, pvName, ns, pvcName, storageClassName, accessMode)

k8s/pkg/apis/longhorn/v1beta1/volume.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,9 @@ const (
5959
type AccessMode string
6060

6161
const (
62-
AccessModeReadWriteOnce = AccessMode("rwo")
63-
AccessModeReadWriteMany = AccessMode("rwx")
62+
AccessModeReadWriteOnce = AccessMode("rwo")
63+
AccessModeReadWriteOncePod = AccessMode("rwop")
64+
AccessModeReadWriteMany = AccessMode("rwx")
6465
)
6566

6667
type ReplicaAutoBalance string

k8s/pkg/apis/longhorn/v1beta2/volume.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,13 @@ const (
5353
DataLocalityStrictLocal = DataLocality("strict-local")
5454
)
5555

56-
// +kubebuilder:validation:Enum=rwo;rwx
56+
// +kubebuilder:validation:Enum=rwo;rwop;rwx
5757
type AccessMode string
5858

5959
const (
60-
AccessModeReadWriteOnce = AccessMode("rwo")
61-
AccessModeReadWriteMany = AccessMode("rwx")
60+
AccessModeReadWriteOnce = AccessMode("rwo")
61+
AccessModeReadWriteOncePod = AccessMode("rwop")
62+
AccessModeReadWriteMany = AccessMode("rwx")
6263
)
6364

6465
// +kubebuilder:validation:Enum=ignored;disabled;least-effort;best-effort

types/types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -844,7 +844,7 @@ func ValidateDataLocality(mode longhorn.DataLocality) error {
844844
}
845845

846846
func ValidateAccessMode(mode longhorn.AccessMode) error {
847-
if mode != longhorn.AccessModeReadWriteMany && mode != longhorn.AccessModeReadWriteOnce {
847+
if mode != longhorn.AccessModeReadWriteMany && mode != longhorn.AccessModeReadWriteOnce && mode != longhorn.AccessModeReadWriteOncePod {
848848
return fmt.Errorf("invalid access mode: %v", mode)
849849
}
850850
return nil

0 commit comments

Comments
 (0)