Make offline upgrade more flexible

This commit is contained in:
Louis Dureuil 2025-01-20 10:32:20 +01:00
parent 3c9483b6e0
commit 34d8c1a903
No known key found for this signature in database

View File

@ -20,6 +20,34 @@ pub struct OfflineUpgrade {
impl OfflineUpgrade { impl OfflineUpgrade {
pub fn upgrade(self) -> anyhow::Result<()> { pub fn upgrade(self) -> anyhow::Result<()> {
// Adding a version?
//
// 1. Update the LAST_SUPPORTED_UPGRADE_FROM_VERSION and LAST_SUPPORTED_UPGRADE_TO_VERSION.
// 2. Add new version to the upgrade list if necessary
// 3. Use `no_upgrade` as index for versions that are compatible.
if self.current_version == self.target_version {
println!("Database is already at the target version. Exiting.");
return Ok(());
}
if self.current_version > self.target_version {
bail!(
"Cannot downgrade from {}.{}.{} to {}.{}.{}. Downgrade not supported",
self.current_version.0,
self.current_version.1,
self.current_version.2,
self.target_version.0,
self.target_version.1,
self.target_version.2
);
}
const FIRST_SUPPORTED_UPGRADE_FROM_VERSION: &str = "1.9.0";
const LAST_SUPPORTED_UPGRADE_FROM_VERSION: &str = "1.12.5";
const FIRST_SUPPORTED_UPGRADE_TO_VERSION: &str = "1.10.0";
const LAST_SUPPORTED_UPGRADE_TO_VERSION: &str = "1.12.5";
let upgrade_list = [ let upgrade_list = [
( (
v1_9_to_v1_10 as fn(&Path, &str, &str, &str) -> Result<(), anyhow::Error>, v1_9_to_v1_10 as fn(&Path, &str, &str, &str) -> Result<(), anyhow::Error>,
@ -32,6 +60,8 @@ impl OfflineUpgrade {
(v1_12_to_v1_12_3, "1", "12", "3"), (v1_12_to_v1_12_3, "1", "12", "3"),
]; ];
let no_upgrade: usize = upgrade_list.len();
let (current_major, current_minor, current_patch) = &self.current_version; let (current_major, current_minor, current_patch) = &self.current_version;
let start_at = match ( let start_at = match (
@ -43,8 +73,11 @@ impl OfflineUpgrade {
("1", "10", _) => 1, ("1", "10", _) => 1,
("1", "11", _) => 2, ("1", "11", _) => 2,
("1", "12", x) if x == "0" || x == "1" || x == "2" => 3, ("1", "12", x) if x == "0" || x == "1" || x == "2" => 3,
("1", "12", x) if x == "3" || x == "4" || x == "5" => no_upgrade,
_ => { _ => {
bail!("Unsupported current version {current_major}.{current_minor}.{current_patch}. Can only upgrade from v1.9 and v1.10") bail!("Unsupported current version {current_major}.{current_minor}.{current_patch}. Can only upgrade from versions in range [{}-{}]",
FIRST_SUPPORTED_UPGRADE_FROM_VERSION,
LAST_SUPPORTED_UPGRADE_FROM_VERSION);
} }
}; };
@ -54,17 +87,27 @@ impl OfflineUpgrade {
("1", "10", _) => 0, ("1", "10", _) => 0,
("1", "11", _) => 1, ("1", "11", _) => 1,
("1", "12", x) if x == "0" || x == "1" || x == "2" => 2, ("1", "12", x) if x == "0" || x == "1" || x == "2" => 2,
("1", "12", "3") => 3, ("1", "12", x) if x == "3" || x == "4" || x == "5" => 3,
(major, _, _) if major.starts_with('v') => { (major, _, _) if major.starts_with('v') => {
bail!("Target version must not starts with a `v`. Instead of writing `v1.9.0` write `1.9.0` for example.") bail!("Target version must not starts with a `v`. Instead of writing `v1.9.0` write `1.9.0` for example.")
} }
_ => { _ => {
bail!("Unsupported target version {target_major}.{target_minor}.{target_patch}. Can only upgrade to v1.10 and v1.11") bail!("Unsupported target version {target_major}.{target_minor}.{target_patch}. Can only upgrade to versions in range [{}-{}]",
FIRST_SUPPORTED_UPGRADE_TO_VERSION,
LAST_SUPPORTED_UPGRADE_TO_VERSION);
} }
}; };
println!("Starting the upgrade from {current_major}.{current_minor}.{current_patch} to {target_major}.{target_minor}.{target_patch}"); println!("Starting the upgrade from {current_major}.{current_minor}.{current_patch} to {target_major}.{target_minor}.{target_patch}");
if start_at == no_upgrade {
println!("No upgrade operation to perform, writing VERSION file");
create_version_file(&self.db_path, target_major, target_minor, target_patch)
.context("while writing VERSION file after the upgrade")?;
println!("Success");
return Ok(());
}
#[allow(clippy::needless_range_loop)] #[allow(clippy::needless_range_loop)]
for index in start_at..=ends_at { for index in start_at..=ends_at {
let (func, major, minor, patch) = upgrade_list[index]; let (func, major, minor, patch) = upgrade_list[index];