diff --git a/types/types.go b/types/types.go index e3adfd8430..6ab849880e 100644 --- a/types/types.go +++ b/types/types.go @@ -824,6 +824,13 @@ func ValidateDataLocalityAndReplicaCount(mode longhorn.DataLocality, count int) return nil } +func ValidateDataLocalityAndAccessMode(locality longhorn.DataLocality, migratable bool, mode longhorn.AccessMode) error { + if mode == longhorn.AccessModeReadWriteMany && !migratable && locality == longhorn.DataLocalityStrictLocal { + return fmt.Errorf("access mode %v (migratable: %v) is incompatible with data locality %v mode", mode, migratable, longhorn.DataLocalityStrictLocal) + } + return nil +} + func ValidateReplicaAutoBalance(option longhorn.ReplicaAutoBalance) error { switch option { case longhorn.ReplicaAutoBalanceIgnored, diff --git a/webhook/resources/volume/validator.go b/webhook/resources/volume/validator.go index 9e20ec96b6..b476ba2998 100644 --- a/webhook/resources/volume/validator.go +++ b/webhook/resources/volume/validator.go @@ -74,6 +74,10 @@ func (v *volumeValidator) Create(request *admission.Request, newObj runtime.Obje return werror.NewInvalidError(err.Error(), "") } + if err := types.ValidateDataLocalityAndAccessMode(volume.Spec.DataLocality, volume.Spec.Migratable, volume.Spec.AccessMode); err != nil { + return werror.NewInvalidError(err.Error(), "") + } + if err := types.ValidateReplicaAutoBalance(volume.Spec.ReplicaAutoBalance); err != nil { return werror.NewInvalidError(err.Error(), "") }