fix(inkless:migration): fix classic-to-diskless migration validation#558
fix(inkless:migration): fix classic-to-diskless migration validation#558giuseppelillo merged 1 commit intomainfrom
Conversation
ac977fa to
7add542
Compare
There was a problem hiding this comment.
Pull request overview
Fixes diskless config validation for classic-to-diskless migrations by changing the migration detection logic to use a state-transition check (diskless newly enabled while remote storage was already enabled), and expands CI coverage to reduce regression risk.
Changes:
- Update
LogConfig.validateDisklessto detect classic-to-diskless migration based on existing vs new state rather than “remote.storage.enable not explicitly set”. - Update
LogConfigTestto reflect the controller’s merged-props behavior when validating migration. - Extend Inkless PR and nightly GitHub Actions workflows to include additional diskless/log-config related test patterns.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| storage/src/main/java/org/apache/kafka/storage/internals/log/LogConfig.java | Adjusts migration detection logic in diskless validation. |
| core/src/test/scala/unit/kafka/log/LogConfigTest.scala | Updates unit test to match merged-props controller flow for migration validation. |
| .github/workflows/inkless.yml | Adds additional :core:test filters (Inkless/Diskless + LogConfigTest). |
| .github/workflows/inkless-nightly.yml | Adds additional :core:test filters to include kafka.log.* nightly. |
Comments suppressed due to low confidence (1)
storage/src/main/java/org/apache/kafka/storage/internals/log/LogConfig.java:537
isClassicToDisklessMigrationcurrently only checks that remote storage was enabled in the existing config, but it does not verify thatremote.storage.enableremains enabled in the new (merged) config. This means a request could enablediskless.enable=truewhile simultaneously settingremote.storage.enable=false(and potentiallyremote.log.delete.on.disable=true), which would incorrectly bypass the mutual-exclusion validation even though both configs are explicitly set. Consider requiringremote.storage.enableto betrueinnewConfigs(or otherwise ensuring the new remote-storage state is enabled) as part of the migration detection.
final boolean wasRemoteStorageEnabled = Boolean.parseBoolean(existingConfigs.getOrDefault(TopicConfig.REMOTE_LOG_STORAGE_ENABLE_CONFIG, "false"));
final boolean isClassicToDisklessMigration = isDisklessAllowFromClassicEnabled
&& isDisklessEnabled && !wasDisklessEnabled
&& wasRemoteStorageExplicitlySet && wasRemoteStorageEnabled;
if (!isClassicToDisklessMigration) {
final boolean hasExplicitDiskless = isDisklessExplicitlySet || wasDisklessExplicitlySet;
final boolean hasExplicitRemoteStorage = isRemoteStorageExplicitlySet || wasRemoteStorageExplicitlySet;
validateDisklessAndRemoteStorageMutualExclusion(isDisklessExplicitlySet, isRemoteStorageExplicitlySet, hasExplicitDiskless, hasExplicitRemoteStorage);
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
7add542 to
ddb59ad
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
2f04473 to
8f03f4b
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
8f03f4b to
b3eb14d
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…and add LogConfigTest to CI The isClassicToDisklessMigration detection in LogConfig.validateDiskless was dead code: it required !isRemoteStorageExplicitlySet, but in the real controller path (ConfigurationControlManager.validateAlterConfig), props is the merged state of existing overrides + requested changes, so remote.storage.enable is always present. Fix by detecting migration via state transition instead: diskless newly enabled (!wasDisklessEnabled) while remote storage was already enabled in existing config. Also add LogConfigTest to inkless PR CI and kafka.log.* to nightly CI to prevent regressions in diskless config validation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
b3eb14d to
e478ad4
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| && wasRemoteStorageExplicitlySet && wasRemoteStorageEnabled; | ||
| if (!isClassicToDisklessMigration) { | ||
| final boolean requestedRemoteStorageEnabled = (Boolean) newConfigs.get(TopicConfig.REMOTE_LOG_STORAGE_ENABLE_CONFIG); | ||
| final boolean isDisklessWithRemoteStorageLegacy = isDisklessAllowFromClassicEnabled |
There was a problem hiding this comment.
I'm not getting why this is called Legacy
There was a problem hiding this comment.
Agree. Maybe isMigratedFromClassicWithRemoteStorage or similar is better. @viktorsomogyi maybe this can be fixed as part of #556?
giuseppelillo
left a comment
There was a problem hiding this comment.
LGTM, just one small comment about a variable name that can be fixed later.
…and add LogConfigTest to CI (#558) The isClassicToDisklessMigration detection in LogConfig.validateDiskless was dead code: it required !isRemoteStorageExplicitlySet, but in the real controller path (ConfigurationControlManager.validateAlterConfig), props is the merged state of existing overrides + requested changes, so remote.storage.enable is always present. Fix by detecting migration via state transition instead: diskless newly enabled (!wasDisklessEnabled) while remote storage was already enabled in existing config. Also add LogConfigTest to inkless PR CI and kafka.log.* to nightly CI to prevent regressions in diskless config validation. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…and add LogConfigTest to CI (#558) The isClassicToDisklessMigration detection in LogConfig.validateDiskless was dead code: it required !isRemoteStorageExplicitlySet, but in the real controller path (ConfigurationControlManager.validateAlterConfig), props is the merged state of existing overrides + requested changes, so remote.storage.enable is always present. Fix by detecting migration via state transition instead: diskless newly enabled (!wasDisklessEnabled) while remote storage was already enabled in existing config. Also add LogConfigTest to inkless PR CI and kafka.log.* to nightly CI to prevent regressions in diskless config validation. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
The
isClassicToDisklessMigrationdetection inLogConfig.validateDisklesswas dead code: it required!isRemoteStorageExplicitlySet, but in the real controller path (ConfigurationControlManager.validateAlterConfig), props is the merged state of existing overrides + requested changes, soremote.storage.enableisalways present.
Fix by detecting migration via state transition instead: diskless newly enabled (
!wasDisklessEnabled) while remote storage was already enabled in existing config.Also add LogConfigTest to inkless PR CI and
kafka.log.*to nightly CI to prevent regressions in diskless config validation.