Skip to content

Conversation

@muhamadazmy
Copy link
Contributor

@muhamadazmy muhamadazmy commented Nov 26, 2025

[restatectl] metadata migrate command

Summary:
A CLI interface to the metadata migration API.

  • Accepts new metadata store config with either --toml or --json flags
  • Run the migration against the API

Stack created with Sapling. Best reviewed with ReviewStack.

Summary:
In this PR we add support to migrate to a new metadata store

Includes:
- Introduce `--metadata-migration-mode`. For the migration to pass, all nodes must be started with this mode set. This mode makes sure the cluster metadata
becomes immutable during the migration process. This of course implies a downtime.
- Introduce the Admi API to do the migration. The migration process first
  - Sanity check of the cluster state, makes sure all alive nodes are running with proper migration mode
  - Creates a client instance of the target store
  - Copies all well know metadata keys from current to target store

Fixes restatedev/internal#76
Summary:
A CLI interface to the metadata migration API.
- Accepts new metadata store config with either --toml or --json flags
- Run the migration against the API
@muhamadazmy muhamadazmy marked this pull request as ready for review November 26, 2025 09:05
Copy link
Contributor

@tillrohrmann tillrohrmann left a comment

Choose a reason for hiding this comment

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

Thanks a lot for exposing the metadata migration via restatectl @muhamadazmy. The changes look good to me. I left a few minor comments. +1 for merging if you've tested things (e.g. from replicated to DynamoDB).

(Some(json), None) => serde_json::from_reader(json.clone().into_reader()?)
.context("Failed to load provider config from json input")?,
(None, Some(toml_input)) => toml::from_str(toml_input.clone().contents()?.as_str())
.context("Failed to load provider config from json input")?,
Copy link
Contributor

Choose a reason for hiding this comment

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

s/json/toml/

Comment on lines +639 to +641
pub fn iter(&self) -> impl Iterator<Item = (&AdvertisedAddress<FabricPort>, &SimpleStatus)> {
self.node_status.iter().map(|a| (&a.0, &a.1))
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Are you using this method anywhere in the PR?

Comment on lines +34 to +40
/// The TOML configuration of the target metadata store
#[arg(long)]
toml: Option<FileOrStdin>,

/// The Json configuration of the target metadata store
#[arg(long, conflicts_with = "toml")]
json: Option<FileOrStdin>,
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we stick with one way to provide the configuration? Otherwise, we give users different ways to do the same thing and we need to explain how to specify MetadataClientOptions in json and in toml. Maybe sticking with toml is the easiest since users already use it when configuring Restate via the config.toml?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants