Skip to content

make pvc count in group configurable #803

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions cmd/manager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ func main() {
flag.BoolVar(&showVersion, "version", false, "Print Version details")
flag.StringVar(&cfg.SchedulePrecedence, "schedule-precedence", "", "The order of precedence in which schedule of reclaimspace and keyrotation is considered. Possible values are sc-only")
flag.BoolVar(&enableAuth, "enable-auth", true, "Enables TLS and adds bearer token to the headers (enabled by default)")
flag.IntVar(&cfg.MaxGroupPVC, "max-group-pvc", cfg.MaxGroupPVC, "Maximum number of PVCs allowed in a volume group")
opts := zap.Options{
Development: true,
TimeEncoder: zapcore.ISO8601TimeEncoder,
Expand Down Expand Up @@ -244,9 +245,10 @@ func main() {
}

if err = (&replicationController.VolumeGroupReplicationReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Recorder: mgr.GetEventRecorderFor("volumegroupreplication-controller"),
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Recorder: mgr.GetEventRecorderFor("volumegroupreplication-controller"),
MaxGroupPVCCount: cfg.MaxGroupPVC,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "VolumeGroupReplication")
os.Exit(1)
Expand Down
1 change: 1 addition & 0 deletions deploy/controller/csi-addons-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ metadata:
data:
"reclaim-space-timeout": "3m"
"max-concurrent-reconciles": "100"
"max-group-pvcs": "100"
11 changes: 7 additions & 4 deletions docs/csi-addons-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ CSI-Addons Operator can consume configuration from a ConfigMap named `csi-addons
in the same namespace as the operator. This enables configuration of the operator to persist across
upgrades. The ConfigMap can support the following configuration options:

| Option | Default value | Description |
| --------------------------- | ------------- | --------------------------------------- |
| `reclaim-space-timeout` | `"3m"` | Timeout for reclaimspace operation |
| `max-concurrent-reconciles` | `"100"` | Maximum number of concurrent reconciles |
| Option | Default value | Description |
| --------------------------- | ------------- | ------------------------------------------------ |
| `reclaim-space-timeout` | `"3m"` | Timeout for reclaimspace operation |
| `max-concurrent-reconciles` | `"100"` | Maximum number of concurrent reconciles |
| `max-group-pvcs` | `"100"` | Maximum number of PVCs allowed in a volume group |

[`csi-addons-config` ConfigMap](../deploy/controller/csi-addons-config.yaml) is provided as an example.

> Note: The operator pod needs to be restarted for any change in configuration to take effect.
>
> Note: `max-group-pvcs` default value is set based on ceph's support/testing. User can tweak this value based on the supported count for their storage vendor.
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,11 @@ const (
// VolumeGroupReplicationReconciler reconciles a VolumeGroupReplication object
type VolumeGroupReplicationReconciler struct {
client.Client
Scheme *runtime.Scheme
ctx context.Context
log logr.Logger
Recorder record.EventRecorder
Scheme *runtime.Scheme
ctx context.Context
log logr.Logger
Recorder record.EventRecorder
MaxGroupPVCCount int
}

//+kubebuilder:rbac:groups="",resources=events,verbs=create;patch
Expand Down Expand Up @@ -162,9 +163,9 @@ func (r *VolumeGroupReplicationReconciler) Reconcile(ctx context.Context, req ct
_ = r.setGroupReplicationFailure(instance, err)
return reconcile.Result{}, err
}
if len(pvcList) > 100 {
err = fmt.Errorf("more than 100 PVCs match the given selector")
r.log.Error(err, "only 100 PVCs are allowed for volume group replication")
if len(pvcList) > r.MaxGroupPVCCount {
err = fmt.Errorf("more than %q PVCs match the given selector", r.MaxGroupPVCCount)
r.log.Error(err, "only %q PVCs are allowed for volume group replication", r.MaxGroupPVCCount)
_ = r.setGroupReplicationFailure(instance, err)
return reconcile.Result{}, err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,11 @@ func createFakeVolumeGroupReplicationReconciler(t *testing.T, obj ...runtime.Obj
reconcilerCtx := context.TODO()

return VolumeGroupReplicationReconciler{
Client: client,
Scheme: scheme,
log: logger,
ctx: reconcilerCtx,
Client: client,
Scheme: scheme,
log: logger,
ctx: reconcilerCtx,
MaxGroupPVCCount: 100,
}
}

Expand Down
15 changes: 15 additions & 0 deletions internal/util/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type Config struct {
ReclaimSpaceTimeout time.Duration
MaxConcurrentReconciles int
SchedulePrecedence string
MaxGroupPVC int
}

const (
Expand All @@ -45,6 +46,8 @@ const (
defaultReclaimSpaceTimeout = time.Minute * 3
SchedulePrecedenceKey = "schedule-precedence"
ScheduleSCOnly = "sc-only"
MaxGroupPVCKey = "max-group-pvcs"
defaultMaxGroupPVC = 100 // based on ceph's support/testing
)

// NewConfig returns a new Config object with default values.
Expand All @@ -54,6 +57,7 @@ func NewConfig() Config {
ReclaimSpaceTimeout: defaultReclaimSpaceTimeout,
MaxConcurrentReconciles: defaultMaxConcurrentReconciles,
SchedulePrecedence: "",
MaxGroupPVC: defaultMaxGroupPVC,
}
}

Expand Down Expand Up @@ -99,6 +103,17 @@ func (cfg *Config) readConfig(dataMap map[string]string) error {
}
cfg.SchedulePrecedence = val

case MaxGroupPVCKey:
maxGroupPVCs, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("failed to parse key %q value %q as int: %w",
MaxGroupPVCKey, val, err)
}
if maxGroupPVCs <= 0 || maxGroupPVCs > 100 {
return fmt.Errorf("invalid value %q for key %q", val, MaxGroupPVCKey)
}
cfg.MaxGroupPVC = maxGroupPVCs

default:
return fmt.Errorf("unknown config key %q", key)
}
Expand Down
53 changes: 53 additions & 0 deletions internal/util/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func TestConfigReadConfigFile(t *testing.T) {
ReclaimSpaceTimeout: defaultReclaimSpaceTimeout,
MaxConcurrentReconciles: defaultMaxConcurrentReconciles,
SchedulePrecedence: "",
MaxGroupPVC: 100,
},
wantErr: false,
},
Expand All @@ -49,6 +50,7 @@ func TestConfigReadConfigFile(t *testing.T) {
ReclaimSpaceTimeout: defaultReclaimSpaceTimeout,
MaxConcurrentReconciles: defaultMaxConcurrentReconciles,
SchedulePrecedence: "",
MaxGroupPVC: 100,
},
wantErr: false,
},
Expand All @@ -62,6 +64,7 @@ func TestConfigReadConfigFile(t *testing.T) {
ReclaimSpaceTimeout: time.Minute * 10,
MaxConcurrentReconciles: defaultMaxConcurrentReconciles,
SchedulePrecedence: "",
MaxGroupPVC: 100,
},
wantErr: false,
},
Expand All @@ -75,6 +78,7 @@ func TestConfigReadConfigFile(t *testing.T) {
ReclaimSpaceTimeout: defaultReclaimSpaceTimeout,
MaxConcurrentReconciles: defaultMaxConcurrentReconciles,
SchedulePrecedence: "",
MaxGroupPVC: 100,
},
wantErr: true,
},
Expand All @@ -88,6 +92,7 @@ func TestConfigReadConfigFile(t *testing.T) {
ReclaimSpaceTimeout: defaultReclaimSpaceTimeout,
MaxConcurrentReconciles: 1,
SchedulePrecedence: "",
MaxGroupPVC: 100,
},
wantErr: false,
},
Expand All @@ -101,6 +106,7 @@ func TestConfigReadConfigFile(t *testing.T) {
ReclaimSpaceTimeout: defaultReclaimSpaceTimeout,
MaxConcurrentReconciles: defaultMaxConcurrentReconciles,
SchedulePrecedence: "",
MaxGroupPVC: 100,
},
wantErr: true,
},
Expand All @@ -115,6 +121,7 @@ func TestConfigReadConfigFile(t *testing.T) {
ReclaimSpaceTimeout: time.Minute * 10,
MaxConcurrentReconciles: 5,
SchedulePrecedence: "",
MaxGroupPVC: 100,
},
wantErr: false,
},
Expand All @@ -128,6 +135,7 @@ func TestConfigReadConfigFile(t *testing.T) {
ReclaimSpaceTimeout: defaultReclaimSpaceTimeout,
MaxConcurrentReconciles: defaultMaxConcurrentReconciles,
SchedulePrecedence: "",
MaxGroupPVC: 100,
},
wantErr: true,
},
Expand All @@ -141,6 +149,7 @@ func TestConfigReadConfigFile(t *testing.T) {
ReclaimSpaceTimeout: defaultReclaimSpaceTimeout,
MaxConcurrentReconciles: defaultMaxConcurrentReconciles,
SchedulePrecedence: ScheduleSCOnly,
MaxGroupPVC: 100,
},
wantErr: false,
},
Expand All @@ -154,6 +163,7 @@ func TestConfigReadConfigFile(t *testing.T) {
ReclaimSpaceTimeout: defaultReclaimSpaceTimeout,
MaxConcurrentReconciles: defaultMaxConcurrentReconciles,
SchedulePrecedence: "",
MaxGroupPVC: 100,
},
wantErr: true,
},
Expand All @@ -167,6 +177,49 @@ func TestConfigReadConfigFile(t *testing.T) {
ReclaimSpaceTimeout: defaultReclaimSpaceTimeout,
MaxConcurrentReconciles: defaultMaxConcurrentReconciles,
SchedulePrecedence: "",
MaxGroupPVC: 100,
},
wantErr: true,
},
{
name: "config file has empty max-group-pvcs",
dataMap: map[string]string{
"max-group-pvcs": "",
},
newConfig: Config{
Namespace: defaultNamespace,
ReclaimSpaceTimeout: defaultReclaimSpaceTimeout,
MaxConcurrentReconciles: defaultMaxConcurrentReconciles,
SchedulePrecedence: "",
MaxGroupPVC: 100,
},
wantErr: true,
},
{
name: "config file modifies max-group-pvcs",
dataMap: map[string]string{
"max-group-pvcs": "25",
},
newConfig: Config{
Namespace: defaultNamespace,
ReclaimSpaceTimeout: defaultReclaimSpaceTimeout,
MaxConcurrentReconciles: defaultMaxConcurrentReconciles,
SchedulePrecedence: "",
MaxGroupPVC: 25,
},
wantErr: false,
},
{
name: "config file has invalid max-group-pvcs",
dataMap: map[string]string{
"max-group-pvcs": "200",
},
newConfig: Config{
Namespace: defaultNamespace,
ReclaimSpaceTimeout: defaultReclaimSpaceTimeout,
MaxConcurrentReconciles: defaultMaxConcurrentReconciles,
SchedulePrecedence: "",
MaxGroupPVC: 100,
},
wantErr: true,
},
Expand Down