Skip to content

cloud_topics: gate tiered_cloud on full upgrade and add tiered_v1/tiered_v2 storage modes#30966

Open
Lazin wants to merge 5 commits into
redpanda-data:devfrom
Lazin:ct/potato-flag
Open

cloud_topics: gate tiered_cloud on full upgrade and add tiered_v1/tiered_v2 storage modes#30966
Lazin wants to merge 5 commits into
redpanda-data:devfrom
Lazin:ct/potato-flag

Conversation

@Lazin

@Lazin Lazin commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

This PR prepares the tiered_cloud storage mode (Cloud Topics based tiered
storage) for the 26.2 release: it makes the mode safe during rolling
upgrades and introduces the user-facing tiered_v1/tiered_v2 vocabulary
built around a new read-only redpanda.storage.mode.impl topic property.

Upgrade gating. The tiered_cloud_topics feature flag switches from
explicit_only to always, so it activates exactly when every broker runs
v26.2. While the cluster is only partially upgraded, creating a tiered_v2
topic or converting a cloud topic to it is rejected; once the upgrade
completes both operations work with no admin action. The same flag gates
the L0 notifier: the post-compaction set_min_allowed_local_threshold stm
command is new in 26.2 and older replicas cannot apply it, so until the
flag activates every notification attempt is a no-op that reports success.
This is safe because no tiered_v2 topic — the only reader of local data
below the floor — can exist while the flag is inactive, so the compaction
sink can commit normally.

Storage mode vocabulary. redpanda.storage.mode accepts local,
tiered, cloud and (legacy) unset; the internal tiered_cloud
spelling and the implementation names are not valid mode values. The plain
tiered value resolves through the new
default_redpanda_storage_mode_tiered_impl cluster config (tiered_v1 =
classic Tiered Storage, tiered_v2 = Cloud Topics based), which defaults
to tiered_v1 for all clusters — an upgrade never changes what tiered
means, and tiered_v2 as the meaning of tiered is an explicit opt-in.

redpanda.storage.mode.impl. A new companion topic property carries the
exact implementation of every topic's storage mode:

  • On DescribeConfigs it is read-only and always present, with the
    unambiguous vocabulary unset|local|tiered_v1|tiered_v2|cloud; the mode
    itself displays both tiered variants as tiered, so the displayed pair
    is never ambiguous regardless of any cluster's tiered-impl config.
  • On CreateTopics it selects the storage mode precisely — either alone or
    together with a matching redpanda.storage.mode (mismatched pairs are
    rejected).
  • It is rejected by AlterConfigs/IncrementalAlterConfigs; mode changes go
    through the tiered alias resolved via the cluster config.

Shadow linking syncs the (mode, impl) pair and applies the impl value
first, reconstructing the source topic's exact storage mode on the target
instead of re-interpreting the ambiguous tiered string through the
target's own cluster config — with different tiered impls on the two
clusters, a string-only sync could silently turn a Cloud Topics based
topic into a classic tiered one (and crash the target's archiver). The
link's apply path also enforces the storage-mode transition rules.

Ducktape coverage: a mixed-version upgrade test (creation/conversion
rejected mid-upgrade, allowed after full upgrade), a full matrix test of
both tiered impls over every mode/impl input combination (including
impl-only creation, consistency rejections and read-only enforcement),
and a shadow-link sync test over all four source/target tiered-impl
combinations including a mid-flight cloud → tiered_v2 conversion.

Backports Required

  • none - not a bug fix
  • none - this is a backport
  • none - issue does not exist in previous branches
  • none - papercut/not impactful enough to backport
  • v26.1.x
  • v25.3.x
  • v25.2.x

Release Notes

Features

  • New default_redpanda_storage_mode_tiered_impl cluster config
    (tiered_v1 | tiered_v2, default tiered_v1) selects whether the
    tiered value of the redpanda.storage.mode topic property refers to
    classic Tiered Storage or Cloud Topics based tiered storage.
  • New read-only redpanda.storage.mode.impl topic property reports the
    exact implementation of every topic's storage mode
    (unset|local|tiered_v1|tiered_v2|cloud) and can be supplied on topic
    creation — alone or together with a matching redpanda.storage.mode
    to select the storage mode precisely. Topics using the tiered_v2
    implementation (or conversions from cloud) can only be created once
    the whole cluster runs v26.2.

Copilot AI review requested due to automatic review settings June 30, 2026 17:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new cluster feature gate to prevent a 26.2+ leader from replicating the new cloud-topics compaction set_min_allowed_local_threshold (MASH floor) command to pre-26.2 replicas during rolling upgrades, avoiding “unknown command key” failures on older nodes.

Changes:

  • Adds the ctp_min_allowed_local_threshold cluster feature (gated on the 26.2 logical version) and wires it into level_zero_notifier to short-circuit replication until the cluster is fully upgraded.
  • Introduces ctp_stm_api_errc::feature_disabled and threads it through relevant call sites (notifier, frontend, compaction sink) with appropriate retry/logging behavior.
  • Adds/updates unit and rptest coverage and Bazel dependencies to validate the feature gate behavior.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/rptest/tests/cluster_features_test.py Excludes the new feature from an upgrade-status test that doesn’t exercise feature-specific setups.
src/v/features/feature_table.h Registers the new ctp_min_allowed_local_threshold feature and schema entry.
src/v/features/feature_table.cc Adds string conversion for the new feature.
src/v/cloud_topics/reconciler/reconciliation_source.cc Handles the new feature_disabled error code in a switch.
src/v/cloud_topics/level_zero/stm/ctp_stm_api.h Adds ctp_stm_api_errc::feature_disabled and formatting.
src/v/cloud_topics/level_zero/notifier/tests/level_zero_notifier_test.cc Adds a unit test validating notifier gating when the feature is inactive.
src/v/cloud_topics/level_zero/notifier/tests/BUILD Adds Bazel dependency on //src/v/features for the new test.
src/v/cloud_topics/level_zero/notifier/level_zero_notifier.h Extends notifier wiring to accept a feature_table pointer and adds a gate helper.
src/v/cloud_topics/level_zero/notifier/level_zero_notifier.cc Implements feature gate checks and returns feature_disabled when inactive.
src/v/cloud_topics/level_zero/notifier/BUILD Adds Bazel dependency on //src/v/features for notifier feature checks.
src/v/cloud_topics/level_one/maintenance/compaction/compaction_sink.cc Downgrades log severity for expected feature_disabled during upgrades.
src/v/cloud_topics/frontend/frontend.cc Treats feature_disabled like other transient errors in error mapping.
src/v/cloud_topics/app.cc Wires controller feature table into the level-zero notifier construction.

Comment on lines 106 to 108
case ctp_stm_api_errc::failure:
case ctp_stm_api_errc::feature_disabled:
co_return std::unexpected(errc::failure);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^^^ makes sense to me, but I'm not sure how reconciler treats failure vs timeout differently.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the reconciler never replicates the command that can trigger this error

@Lazin Lazin requested review from dotnwat and oleiman June 30, 2026 19:17
@vbotbuildovich

vbotbuildovich commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

CI test results

test results on build#86520
test_status test_class test_method test_arguments test_kind job_url passed reason test_history
FLAKY(PASS) PrefixTruncateRecoveryTest test_prefix_truncate_recovery {"acks": -1, "start_empty": false} integration https://buildkite.com/redpanda/redpanda/builds/86520#019f19c3-a306-411a-8f8e-2206b33e13fd 10/11 Test PASSES after retries.No significant increase in flaky rate(baseline=0.0000, p0=1.0000, reject_threshold=0.0100. adj_baseline=0.1000, p1=0.3487, trust_threshold=0.5000) https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=PrefixTruncateRecoveryTest&test_method=test_prefix_truncate_recovery
FLAKY(PASS) TxAtomicProduceConsumeTest test_basic_tx_consumer_transform_produce {"with_failures": true} integration https://buildkite.com/redpanda/redpanda/builds/86520#019f19c3-a306-411a-8f8e-2206b33e13fd 10/11 Test PASSES after retries.No significant increase in flaky rate(baseline=0.0029, p0=1.0000, reject_threshold=0.0100. adj_baseline=0.1000, p1=0.3487, trust_threshold=0.5000) https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=TxAtomicProduceConsumeTest&test_method=test_basic_tx_consumer_transform_produce
test results on build#86549
test_status test_class test_method test_arguments test_kind job_url passed reason test_history
FLAKY(PASS) ShadowLinkTopicFailoverTests test_producer_ids_failover {"storage_mode": "cloud"} integration https://buildkite.com/redpanda/redpanda/builds/86549#019f1a8d-0294-40b2-b8d2-84defc4bad58 19/21 Test PASSES after retries.No significant increase in flaky rate(baseline=0.0069, p0=0.1293, reject_threshold=0.0100. adj_baseline=0.1000, p1=0.3917, trust_threshold=0.5000) https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=ShadowLinkTopicFailoverTests&test_method=test_producer_ids_failover
FLAKY(PASS) ShadowLinkingReplicationTests test_auto_prefix_trimming {"source_cluster_spec": {"cluster_type": "redpanda"}, "storage_mode": "cloud", "with_failures": true} integration https://buildkite.com/redpanda/redpanda/builds/86549#019f1a8f-e62d-476a-8a2f-43499345668a 36/41 Test PASSES after retries.No significant increase in flaky rate(baseline=0.0406, p0=0.0779, reject_threshold=0.0100. adj_baseline=0.1168, p1=0.4919, trust_threshold=0.5000) https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=ShadowLinkingReplicationTests&test_method=test_auto_prefix_trimming
FLAKY(INCONCLUSIVE) NodeWiseRecoveryTest test_node_wise_recovery {"dead_node_count": 2} integration https://buildkite.com/redpanda/redpanda/builds/86549#019f1a8d-0298-411f-be02-8b543622c80f 17/20 Test is INCONCLUSIVE after retries.Inconclusive result before max retries(baseline=0.0212, p0=0.1926, reject_threshold=0.0100. adj_baseline=0.1000, p1=0.7361, trust_threshold=0.5000) https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=NodeWiseRecoveryTest&test_method=test_node_wise_recovery
test results on build#86734
test_status test_class test_method test_arguments test_kind job_url passed reason test_history
FAIL TSWithAlreadyCompactedTopic test_initial_upload null integration https://buildkite.com/redpanda/redpanda/builds/86734#019f2a13-7f33-49e5-bf1f-6b8f86819069 0/11 Test FAILS after retries.Significant increase in flaky rate(baseline=0.0000, p0=0.0000, reject_threshold=0.0100) https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=TSWithAlreadyCompactedTopic&test_method=test_initial_upload
FAIL ShadowLinkingRandomOpsTest test_node_operations {"failures": false, "workload_set": "flipping"} integration https://buildkite.com/redpanda/redpanda/builds/86734#019f2a13-7f35-45c3-a77a-1e763eee50c4 0/1 https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=ShadowLinkingRandomOpsTest&test_method=test_node_operations
FAIL ShadowLinkingRandomOpsTest test_node_operations {"failures": true, "workload_set": "flipping"} integration https://buildkite.com/redpanda/redpanda/builds/86734#019f2a13-7f37-4b1e-bdc6-ad776bb2c3a5 0/1 https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=ShadowLinkingRandomOpsTest&test_method=test_node_operations
FAIL src/v/security/tests/acl_store_fuzz src/v/security/tests/acl_store_fuzz unit https://buildkite.com/redpanda/redpanda/builds/86734#019f29f5-f8cf-427a-a03e-d02273094b89 0/1
test results on build#86759
test_status test_class test_method test_arguments test_kind job_url passed reason test_history
FLAKY(FAIL) TieredCloudUpgradeTest test_tiered_cloud_gated_in_mixed_cluster null integration https://buildkite.com/redpanda/redpanda/builds/86759#019f381e-33ed-402d-b081-1d5eee42cd9b 2/11 The test was found to be new, and no failures are allowed https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=TieredCloudUpgradeTest&test_method=test_tiered_cloud_gated_in_mixed_cluster
test results on build#86767
test_status test_class test_method test_arguments test_kind job_url passed reason test_history
FLAKY(PASS) ShadowLinkTopicFailoverTests test_producer_ids_failover {"storage_mode": "local"} integration https://buildkite.com/redpanda/redpanda/builds/86767#019f38c0-68b9-4645-a2da-531edbc9722f 10/11 Test PASSES after retries.No significant increase in flaky rate(baseline=0.0055, p0=1.0000, reject_threshold=0.0100. adj_baseline=0.1000, p1=0.3487, trust_threshold=0.5000) https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=ShadowLinkTopicFailoverTests&test_method=test_producer_ids_failover
FLAKY(PASS) IdempotencyWriteCachingTest test_idempotent_producers_write_caching null integration https://buildkite.com/redpanda/redpanda/builds/86767#019f38c0-68bb-438f-9c7c-00640dd7ffa3 10/11 Test PASSES after retries.No significant increase in flaky rate(baseline=0.0028, p0=1.0000, reject_threshold=0.0100. adj_baseline=0.1000, p1=0.3487, trust_threshold=0.5000) https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=IdempotencyWriteCachingTest&test_method=test_idempotent_producers_write_caching
FLAKY(PASS) ShadowLinkingRandomOpsTest test_node_operations {"failures": true, "workload_set": "cloud_combos"} integration https://buildkite.com/redpanda/redpanda/builds/86767#019f38c0-2523-45a2-b5db-d111956e580f 10/11 Test PASSES after retries.No significant increase in flaky rate(baseline=0.0202, p0=1.0000, reject_threshold=0.0100. adj_baseline=0.1000, p1=0.3487, trust_threshold=0.5000) https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=ShadowLinkingRandomOpsTest&test_method=test_node_operations
test results on build#86893
test_status test_class test_method test_arguments test_kind job_url passed reason test_history
FAIL AlterTopicConfiguration test_set_config_from_describe null integration https://buildkite.com/redpanda/redpanda/builds/86893#019f431a-d7b6-4e69-b9b8-da2dab59d1d3 0/11 Test FAILS after retries.Significant increase in flaky rate(baseline=0.0000, p0=0.0000, reject_threshold=0.0100) https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=AlterTopicConfiguration&test_method=test_set_config_from_describe
FAIL AlterTopicConfiguration test_set_config_from_describe null integration https://buildkite.com/redpanda/redpanda/builds/86893#019f431b-7049-4d46-bb20-61f0ccef903e 0/11 Test FAILS after retries.Significant increase in flaky rate(baseline=0.0000, p0=0.0000, reject_threshold=0.0100) https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=AlterTopicConfiguration&test_method=test_set_config_from_describe
FAIL ControllerSnapshotTest test_upgrade_compat null integration https://buildkite.com/redpanda/redpanda/builds/86893#019f431a-d7b5-4c65-ad21-ccb730ea0288 0/11 Test FAILS after retries.Significant increase in flaky rate(baseline=0.0000, p0=0.0000, reject_threshold=0.0100) https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=ControllerSnapshotTest&test_method=test_upgrade_compat
FAIL ControllerSnapshotTest test_upgrade_compat null integration https://buildkite.com/redpanda/redpanda/builds/86893#019f431b-7048-4521-976e-7a62db840031 0/11 Test FAILS after retries.Significant increase in flaky rate(baseline=0.0000, p0=0.0000, reject_threshold=0.0100) https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=ControllerSnapshotTest&test_method=test_upgrade_compat
FLAKY(PASS) IsolatedDecommissionedNodeTest discover_leader_for_topic_test {"isolation_handler_mode": true} integration https://buildkite.com/redpanda/redpanda/builds/86893#019f431b-704b-484c-bcc8-b982250330d6 10/11 Test PASSES after retries.No significant increase in flaky rate(baseline=0.0027, p0=1.0000, reject_threshold=0.0100. adj_baseline=0.1000, p1=0.3487, trust_threshold=0.5000) https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=IsolatedDecommissionedNodeTest&test_method=discover_leader_for_topic_test
FAIL CreateTopicsResponseTest test_create_topic_response_configs null integration https://buildkite.com/redpanda/redpanda/builds/86893#019f431a-d7b6-4e69-b9b8-da2dab59d1d3 0/11 Test FAILS after retries.Significant increase in flaky rate(baseline=0.0000, p0=0.0000, reject_threshold=0.0100) https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=CreateTopicsResponseTest&test_method=test_create_topic_response_configs
FAIL CreateTopicsResponseTest test_create_topic_response_configs null integration https://buildkite.com/redpanda/redpanda/builds/86893#019f431b-7049-4d46-bb20-61f0ccef903e 0/11 Test FAILS after retries.Significant increase in flaky rate(baseline=0.0000, p0=0.0000, reject_threshold=0.0100) https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=CreateTopicsResponseTest&test_method=test_create_topic_response_configs

@Lazin

Lazin commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

force push: rebase with dev

@Lazin Lazin requested a review from WillemKauf July 1, 2026 11:43

@oleiman oleiman left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm modulo open question about how the reconciler should treat the error

Comment on lines 106 to 108
case ctp_stm_api_errc::failure:
case ctp_stm_api_errc::feature_disabled:
co_return std::unexpected(errc::failure);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^^^ makes sense to me, but I'm not sure how reconciler treats failure vs timeout differently.

Comment thread src/v/features/feature_table.h Outdated
shadow_link_sr_api_sync = 1ULL << 16U,
iceberg_extended_mode_config = 1ULL << 17U,
fetch_controller_snapshot_rpc = 1ULL << 18U,
ctp_min_allowed_local_threshold = 1ULL << 21U,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: that's a weird place to put it

@Lazin Lazin requested a review from oleiman July 2, 2026 15:07
# Gates replication of the cloud-topics compaction min-allowed-local-
# threshold command; exercising it needs cloud-topics compaction setup
# orthogonal to the finalization behavior under test.
"ctp_min_allowed_local_threshold",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to either (1) introduce testing for this feature in the context of unfinalized upgrade or (2) explain here why it isn't needed.

@Lazin Lazin closed this Jul 3, 2026
@Lazin Lazin force-pushed the ct/potato-flag branch from c59c254 to 96ee14f Compare July 3, 2026 18:55
@Lazin

Lazin commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

How come that it's closed?

@Lazin

Lazin commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

Reopening

@Lazin Lazin reopened this Jul 3, 2026
@Lazin Lazin requested a review from a team as a code owner July 3, 2026 21:49
@Lazin Lazin changed the title cloud_topics/l0: gate min allowed local threshold replication cloud_topics: gate tiered_cloud on full upgrade and add tiered_v1/tiered_v2 storage modes Jul 3, 2026
@vbotbuildovich

vbotbuildovich commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

Retry command for Build#86734

please wait until all jobs are finished before running the slash command

/ci-repeat 1
skip-redpanda-build
skip-units
skip-rebase
tests/rptest/tests/shadow_linking_rnot_test.py::ShadowLinkingRandomOpsTest.test_node_operations@{"failures":true,"workload_set":"flipping"}
tests/rptest/tests/shadow_linking_rnot_test.py::ShadowLinkingRandomOpsTest.test_node_operations@{"failures":false,"workload_set":"flipping"}
tests/rptest/tests/shadow_indexing_compacted_topic_test.py::TSWithAlreadyCompactedTopic.test_initial_upload

@vbotbuildovich

Copy link
Copy Markdown
Collaborator

Retry command for Build#86759

please wait until all jobs are finished before running the slash command

/ci-repeat 1
skip-redpanda-build
skip-units
skip-rebase
tests/rptest/tests/storage_mode_test.py::TieredCloudUpgradeTest.test_tiered_cloud_gated_in_mixed_cluster

@Lazin Lazin requested a review from dotnwat July 7, 2026 15:19
Comment thread src/v/model/model.cc Outdated
return redpanda_storage_mode_from_string(s);
}

const char* redpanda_storage_mode_user_name(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so am I to undestand that we are still exposing tiered_v1/tiered_v2 details to users when the configured mode doesn't match the cluster default? Was this determined to be acceptable w/r/t the product ask?

@Lazin Lazin force-pushed the ct/potato-flag branch 3 times, most recently from 316abe4 to 45993c3 Compare July 8, 2026 14:42
@Lazin Lazin added this to the v26.2.1-RC3 milestone Jul 8, 2026
Switch the flag from explicit_only to always so it activates as soon
as every node runs v26.2, with no admin action. The create and
alter-config gates keep rejecting cloud-architecture tiered topics
(and cloud -> tiered_cloud conversions) while the cluster is only
partially upgraded, and open automatically once the upgrade completes.

set_feature_active now tolerates always-policy features jumping
straight from unavailable to active without an observable available
state, and the real-upgrade finalization test expects the flag to
auto-activate after finalize.

Signed-off-by: Evgeny Lazin <4lazin@gmail.com>
The set_min_allowed_local_threshold stm command is new in v26.2, so
the compaction sink must not replicate it while pre-v26.2 replicas may
still be in the raft group. Gate the notifier on the
tiered_cloud_topics feature flag: until it activates (the cluster is
fully upgraded to v26.2) every notification attempt reports success
without replicating. This is safe because no cloud-architecture tiered
topic -- the only reader of local data below the floor -- can exist
while the flag is inactive.

Signed-off-by: Evgeny Lazin <4lazin@gmail.com>
@Lazin Lazin force-pushed the ct/potato-flag branch 3 times, most recently from 0f44051 to 39ff8f6 Compare July 8, 2026 18:53
@vbotbuildovich

vbotbuildovich commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Retry command for Build#86893

please wait until all jobs are finished before running the slash command

/ci-repeat 1
skip-redpanda-build
skip-units
skip-rebase
tests/rptest/tests/controller_snapshot_test.py::ControllerSnapshotTest.test_upgrade_compat
tests/rptest/tests/alter_topic_configuration_test.py::AlterTopicConfiguration.test_set_config_from_describe
tests/rptest/tests/topic_creation_test.py::CreateTopicsResponseTest.test_create_topic_response_configs

@Lazin Lazin force-pushed the ct/potato-flag branch from 39ff8f6 to 50ef01e Compare July 8, 2026 20:56
Lazin added 3 commits July 8, 2026 16:57
The tiered_cloud storage mode ships in v26.2 as the second
implementation of tiered storage, so the user surface is reworked
around the 'tiered' name instead of exposing the internal enum:

- redpanda.storage.mode accepts unset/local/tiered/cloud; the
  'tiered_cloud' spelling is no longer a valid value. Both tiered
  variants display as 'tiered' in DescribeConfigs.
- The new default_redpanda_storage_mode_tiered_impl cluster config
  (tiered_v1 = classic Tiered Storage, tiered_v2 = Cloud Topics based)
  selects which implementation 'tiered' refers to. It defaults to
  tiered_v1 for all clusters, so an upgrade never changes what
  'tiered' means and tiered_v2 is an explicit opt-in.
- The new read-only redpanda.storage.mode.impl topic property reports
  the exact implementation of every topic's storage mode
  (unset/local/tiered_v1/tiered_v2/cloud), making the describe output
  unambiguous regardless of the reader's cluster config. On creation
  it selects the storage mode precisely, alone or together with a
  matching redpanda.storage.mode; mismatched pairs are rejected. The
  property is not alterable, although sets that match the current
  value are tolerated as no-ops so that describe-then-alter round
  trips (which replay every config) keep working. It is reported with
  the default config source: the value is derived from the storage
  mode rather than being an explicit override, so config
  backup/replay tooling must not treat it as user-set.

Storage-mode transition errors print the impl names, so a rejected
tiered_v1 to tiered_v2 transition does not read as 'tiered to tiered'.
The tiered_v2 impl keeps the tiered_cloud_topics feature and cloud
storage gates.

Signed-off-by: Evgeny Lazin <4lazin@gmail.com>
The synced describe output shows 'tiered' for both tiered impls, so
the mode string alone is ambiguous. Request the read-only
redpanda.storage.mode.impl property alongside the mode and apply it
first (it is exact and reported for every topic), reconstructing the
source topic's storage mode on the target instead of re-interpreting
'tiered' through the target's own tiered-impl config - with different
configs on the two clusters that could silently turn a
cloud-architecture topic into a classic tiered one and start an
archiver on a partition that has no archival stm. The mode string
remains as a fallback for sources that predate the impl property.

Mirror-topic creation and property updates bypass the kafka handlers,
so this path enforces the guards itself: storage-mode transition rules
(a bad sync becomes a rejected update instead of an applied forbidden
transition) and the tiered_cloud_topics upgrade gate - no mirror topic
is created with or moved to the tiered_v2 impl until the cluster is
fully upgraded to v26.2; creation is skipped and retried once the
feature activates.

Signed-off-by: Evgeny Lazin <4lazin@gmail.com>
TieredCloudUpgradeTest checks the mixed-version behavior: creating a
tiered_v2 topic or converting a cloud topic to it is rejected (or, via
a v26.1 controller that drops the unknown impl property, degrades to a
classic tiered topic) while the cluster is partially upgraded, and
both operations work once every node runs v26.2.

StorageModeAliasMatrixTest covers every mode/impl input combination
under both tiered impls, including impl-only creation, mode/impl
consistency rejections, read-only enforcement and the always-present
describe entry. ShadowLinkStorageModeSyncTest syncs cloud and tiered
topics across all four combinations of source/target tiered impls,
including a mid-flight cloud to tiered_v2 conversion.

TopicSpec spells tiered variants through the new storage_mode_config
helper (mode=tiered plus the impl property, which keeps v26.1 brokers
on a tiered mode instead of silently falling back to the cluster
default), kafka-cli describe output round-trips through the new impl
kwarg, and the describe-topics parser accepts the asterisk kcl appends
to read-only properties. The storage-mode toggle and rnot flipping
tests point the 'tiered' alias at tiered_v2 explicitly, since the
alter path resolves it through the cluster config.

Signed-off-by: Evgeny Lazin <4lazin@gmail.com>
@Lazin Lazin force-pushed the ct/potato-flag branch from 50ef01e to 0312ada Compare July 8, 2026 20:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants