Skip to content

Commit

Permalink
Add migration for bork-generated update seed to be u32
Browse files Browse the repository at this point in the history
  • Loading branch information
tjkirch committed Oct 21, 2019
1 parent 1b855ef commit 3ee3f89
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 9 deletions.
2 changes: 1 addition & 1 deletion packages/workspaces/data-store-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.0
0.1
16 changes: 9 additions & 7 deletions workspaces/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion workspaces/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ members = [

# Migrations will be listed here. They won't need to be listed as a
# workspace member when we add cross-workspace dependencies.
"api/migration/migrations/v1.1/testmigration",
"api/migration/migrations/v0.1/borkseed",

"preinit/laika",

Expand Down
11 changes: 11 additions & 0 deletions workspaces/api/migration/migrations/v0.1/borkseed/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "borkseed-migration"
version = "0.1.0"
authors = ["Tom Kirchner <[email protected]>"]
edition = "2018"
publish = false

[dependencies]
migration-helpers = { path = "../../../migration-helpers" }
serde_json = "1.0"
snafu = "0.5"
84 changes: 84 additions & 0 deletions workspaces/api/migration/migrations/v0.1/borkseed/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#![deny(rust_2018_idioms)]

use migration_helpers::{error, migrate, Migration, MigrationData, Result};
use std::convert::TryFrom;

/// We moved from String to u32 for the seed value generated by bork and used by updog.
struct BorkSeedIntMigration;

impl Migration for BorkSeedIntMigration {
fn forward(&mut self, mut input: MigrationData) -> Result<MigrationData> {
if let Some(seed_val) = input.data.get_mut("settings.updates.seed") {
// We have the seed setting; check its type to see what we can do.
if let Some(seed_str) = seed_val.as_str() {
// Confirm the string is a valid u32.
let seed: u32 = seed_str.parse().or_else(|e| {
error::Migration {
msg: format!("Existing update seed string is not a valid u32: {}", e),
}
.fail()
})?;
*seed_val = serde_json::Value::Number(seed.into());
} else if let Some(seed_num) = seed_val.as_u64() {
// We shouldn't find a number because the migration should only run against a
// version with a String seed, but... as long as it's a valid u32, allow it.
let seed = u32::try_from(seed_num).or_else(|e| {
error::Migration {
msg: format!("Existing update seed number(!) is not a valid u32: {}", e),
}
.fail()
})?;
*seed_val = serde_json::Value::Number(seed.into());
} else {
// Other type, shouldn't happen, error.
return error::Migration {
msg: format!("Unsupported type of existing update seed: '{:?}'", seed_val),
}
.fail();
}
} else {
// If they don't have a seed, one will be generated on startup.
}
Ok(input)
}

fn backward(&mut self, mut input: MigrationData) -> Result<MigrationData> {
if let Some(seed_val) = input.data.get_mut("settings.updates.seed") {
// We have the seed setting; check its type to see what we can do.
if let Some(seed_num) = seed_val.as_u64() {
// Number back to string, just serialize.
let seed_str = serde_json::to_string(&seed_num).or_else(|e| {
error::Migration {
msg: format!("Existing update seed number failed serialization: {}", e),
}
.fail()
})?;
*seed_val = serde_json::Value::String(seed_str);
} else if let Some(seed_str) = seed_val.as_str() {
// We shouldn't find a string because the migration should only run against a
// version with a number seed, but... as long as it's a valid u32, allow it.
// JUST FOR VALIDATION:
let _seed: u32 = seed_str.parse().or_else(|e| {
error::Migration {
msg: format!("Existing update seed string(!) is not a valid u32: {}", e),
}
.fail()
})?;
// Do nothing; keep the original (valid) string.
} else {
// Other type, shouldn't happen, error.
return error::Migration {
msg: format!("Unsupported type of existing update seed: '{:?}'", seed_val),
}
.fail();
}
} else {
// If they don't have a seed, one will be generated on startup.
}
Ok(input)
}
}

fn main() -> Result<()> {
migrate(BorkSeedIntMigration)
}
1 change: 1 addition & 0 deletions workspaces/deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ skip = [
{ name = "apiserver", licenses = [] },
{ name = "block-party", licenses = [] },
{ name = "bork", licenses = [] },
{ name = "borkseed-migration", licenses = [] },
{ name = "data_store_version", licenses = [] },
{ name = "growpart", licenses = [] },
{ name = "host-containers", licenses = [] },
Expand Down

0 comments on commit 3ee3f89

Please sign in to comment.