Skip to content

Commit

Permalink
chore: add support for ReadWriteOncePod access mode
Browse files Browse the repository at this point in the history
Signed-off-by: William Phetsinorath <[email protected]>
  • Loading branch information
shikanime committed Oct 24, 2024
1 parent e7db6e7 commit b76fbc8
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 9 deletions.
13 changes: 13 additions & 0 deletions csi/controller_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ func NewControllerServer(apiClient *longhornclient.RancherClient, nodeID string)
accessModes: getVolumeCapabilityAccessModes(
[]csi.VolumeCapability_AccessMode_Mode{
csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
csi.VolumeCapability_AccessMode_SINGLE_NODE_SINGLE_WRITER,
csi.VolumeCapability_AccessMode_SINGLE_NODE_MULTI_WRITER,
csi.VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER,
}),
log: logrus.StandardLogger().WithField("component", "csi-controller-server"),
Expand Down Expand Up @@ -220,6 +222,10 @@ func (cs *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
volumeParameters["share"] = "true"
break
}
if requireExclusiveAccess(nil, cap) {
volumeParameters["exclusive"] = "true"
break
}
}

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

if requireExclusiveAccess(volume, volumeCapability) {
volume, err = cs.updateVolumeAccessMode(volume, longhorn.AccessModeReadWriteOncePod)
if err != nil {
return nil, err
}
}

// TODO: JM Restore should be handled by the volume attach call, consider returning `codes.Aborted`
// TODO: JM should readiness be handled by the caller?
// Most of the readiness conditions are covered by the attach, except auto attachment which requires changes to the design
Expand Down
33 changes: 31 additions & 2 deletions csi/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,26 @@ func getVolumeOptions(volumeID string, volOptions map[string]string) (*longhornc

if isShared {
vol.AccessMode = string(longhorn.AccessModeReadWriteMany)
} else {
vol.AccessMode = string(longhorn.AccessModeReadWriteOnce)
}
}

if exclusive, ok := volOptions["exclusive"]; ok {
isExclusive, err := strconv.ParseBool(exclusive)
if err != nil {
return nil, errors.Wrap(err, "invalid parameter exclusive")
}
if isExclusive && vol.AccessMode == string(longhorn.AccessModeReadWriteMany) {
return nil, errors.New("cannot set both share and exclusive to true")
}
if isExclusive {
vol.AccessMode = string(longhorn.AccessModeReadWriteOncePod)
}
}

if vol.AccessMode == "" {
vol.AccessMode = string(longhorn.AccessModeReadWriteOnce)
}

if migratable, ok := volOptions["migratable"]; ok {
isMigratable, err := strconv.ParseBool(migratable)
if err != nil {
Expand Down Expand Up @@ -453,6 +468,20 @@ func requiresSharedAccess(vol *longhornclient.Volume, cap *csi.VolumeCapability)
mode == csi.VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER
}

func requireExclusiveAccess(vol *longhornclient.Volume, cap *csi.VolumeCapability) bool {

Check notice on line 471 in csi/util.go

View check run for this annotation

codefactor.io / CodeFactor

csi/util.go#L471

Redefinition of the built-in function cap. (redefines-builtin-id)
isExclusive := false
if vol != nil {
isExclusive = vol.AccessMode == string(longhorn.AccessModeReadWriteOncePod)
}

mode := csi.VolumeCapability_AccessMode_UNKNOWN
if cap != nil {
mode = cap.AccessMode.Mode
}

return isExclusive || mode == csi.VolumeCapability_AccessMode_SINGLE_NODE_SINGLE_WRITER
}

func getStageBlockVolumePath(stagingTargetPath, volumeID string) string {
return filepath.Join(stagingTargetPath, volumeID)
}
5 changes: 4 additions & 1 deletion datastore/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -1015,8 +1015,11 @@ func NewPVManifest(size int64, pvName, volumeName, storageClassName, fsType stri
// NewPVCManifestForVolume returns a new PersistentVolumeClaim object for a longhorn volume
func NewPVCManifestForVolume(v *longhorn.Volume, pvName, ns, pvcName, storageClassName string) *corev1.PersistentVolumeClaim {
accessMode := corev1.ReadWriteOnce
if v.Spec.AccessMode == longhorn.AccessModeReadWriteMany {
switch v.Spec.AccessMode {
case longhorn.AccessModeReadWriteMany:
accessMode = corev1.ReadWriteMany
case longhorn.AccessModeReadWriteOncePod:
accessMode = corev1.ReadWriteOncePod
}

return NewPVCManifest(v.Spec.Size, pvName, ns, pvcName, storageClassName, accessMode)
Expand Down
5 changes: 3 additions & 2 deletions k8s/pkg/apis/longhorn/v1beta1/volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ const (
type AccessMode string

const (
AccessModeReadWriteOnce = AccessMode("rwo")
AccessModeReadWriteMany = AccessMode("rwx")
AccessModeReadWriteOnce = AccessMode("rwo")
AccessModeReadWriteOncePod = AccessMode("rwop")
AccessModeReadWriteMany = AccessMode("rwx")
)

type ReplicaAutoBalance string
Expand Down
7 changes: 4 additions & 3 deletions k8s/pkg/apis/longhorn/v1beta2/volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,13 @@ const (
DataLocalityStrictLocal = DataLocality("strict-local")
)

// +kubebuilder:validation:Enum=rwo;rwx
// +kubebuilder:validation:Enum=rwo;rwop,rwx
type AccessMode string

const (
AccessModeReadWriteOnce = AccessMode("rwo")
AccessModeReadWriteMany = AccessMode("rwx")
AccessModeReadWriteOnce = AccessMode("rwo")
AccessModeReadWriteOncePod = AccessMode("rwop")
AccessModeReadWriteMany = AccessMode("rwx")
)

// +kubebuilder:validation:Enum=ignored;disabled;least-effort;best-effort
Expand Down
2 changes: 1 addition & 1 deletion types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -844,7 +844,7 @@ func ValidateDataLocality(mode longhorn.DataLocality) error {
}

func ValidateAccessMode(mode longhorn.AccessMode) error {
if mode != longhorn.AccessModeReadWriteMany && mode != longhorn.AccessModeReadWriteOnce {
if mode != longhorn.AccessModeReadWriteMany && mode != longhorn.AccessModeReadWriteOnce && mode != longhorn.AccessModeReadWriteOncePod {
return fmt.Errorf("invalid access mode: %v", mode)
}
return nil
Expand Down

0 comments on commit b76fbc8

Please sign in to comment.