mirror of
https://git.asonix.dog/asonix/pict-rs
synced 2024-12-22 19:31:35 +00:00
Migrate from 0.32.0-rc1
This commit is contained in:
parent
7dd23396a0
commit
510f955cc0
5 changed files with 186 additions and 27 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -1891,9 +1891,9 @@ checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sled"
|
name = "sled"
|
||||||
version = "0.32.0-rc1"
|
version = "0.32.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49d0ada816c19135ab4644d908b896a76e43d9d7e45bed6b25c486ac692afd7e"
|
checksum = "cdad3dc85d888056d3bd9954ffdf22d8a22701b6cd3aca4f6df4c436111898c4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
|
|
|
@ -27,7 +27,7 @@ rexiv2 = { version = "0.9.0", git = "https://git.asonix.dog/asonix/rexiv2" }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
sha2 = "0.9.0"
|
sha2 = "0.9.0"
|
||||||
sled = "0.32.0-rc1"
|
sled = "0.32.0"
|
||||||
structopt = "0.3.14"
|
structopt = "0.3.14"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
tracing = "0.1.15"
|
tracing = "0.1.15"
|
||||||
|
|
|
@ -16,6 +16,7 @@ use tracing_subscriber::EnvFilter;
|
||||||
mod config;
|
mod config;
|
||||||
mod error;
|
mod error;
|
||||||
mod middleware;
|
mod middleware;
|
||||||
|
mod migrate;
|
||||||
mod processor;
|
mod processor;
|
||||||
mod upload_manager;
|
mod upload_manager;
|
||||||
mod validate;
|
mod validate;
|
||||||
|
|
173
src/migrate.rs
Normal file
173
src/migrate.rs
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
use crate::UploadError;
|
||||||
|
use sled as sled032;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use tracing::{debug, info, warn};
|
||||||
|
|
||||||
|
const SLED_032: &str = "db-0.32";
|
||||||
|
const SLED_0320_RC1: &str = "db";
|
||||||
|
|
||||||
|
pub(crate) struct LatestDb {
|
||||||
|
root_dir: PathBuf,
|
||||||
|
version: DbVersion,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LatestDb {
|
||||||
|
pub(crate) fn exists(root_dir: PathBuf) -> Self {
|
||||||
|
let version = DbVersion::exists(root_dir.clone());
|
||||||
|
|
||||||
|
LatestDb { root_dir, version }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn migrate(self) -> Result<sled032::Db, UploadError> {
|
||||||
|
let LatestDb { root_dir, version } = self;
|
||||||
|
|
||||||
|
version.migrate(root_dir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum DbVersion {
|
||||||
|
Sled0320Rc1,
|
||||||
|
Sled032,
|
||||||
|
Fresh,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DbVersion {
|
||||||
|
fn exists(root: PathBuf) -> Self {
|
||||||
|
let mut sled_dir = root.clone();
|
||||||
|
sled_dir.push("sled");
|
||||||
|
sled_dir.push(SLED_032);
|
||||||
|
if std::fs::metadata(sled_dir).is_ok() {
|
||||||
|
return DbVersion::Sled032;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut sled_dir = root;
|
||||||
|
sled_dir.push(SLED_0320_RC1);
|
||||||
|
if std::fs::metadata(sled_dir).is_ok() {
|
||||||
|
return DbVersion::Sled0320Rc1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DbVersion::Fresh
|
||||||
|
}
|
||||||
|
|
||||||
|
fn migrate(self, root: PathBuf) -> Result<sled032::Db, UploadError> {
|
||||||
|
match self {
|
||||||
|
DbVersion::Sled0320Rc1 => migrate_0_32_0_rc1(root),
|
||||||
|
DbVersion::Sled032 | DbVersion::Fresh => {
|
||||||
|
let mut sled_dir = root;
|
||||||
|
sled_dir.push("sled");
|
||||||
|
sled_dir.push(SLED_032);
|
||||||
|
Ok(sled032::open(sled_dir)?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn migrate_0_32_0_rc1(root: PathBuf) -> Result<sled032::Db, UploadError> {
|
||||||
|
info!("Migrating database from 0.32.0-rc1 to 0.32.0");
|
||||||
|
let mut sled_dir = root.clone();
|
||||||
|
sled_dir.push("db");
|
||||||
|
|
||||||
|
let mut new_sled_dir = root;
|
||||||
|
new_sled_dir.push("sled");
|
||||||
|
new_sled_dir.push(SLED_032);
|
||||||
|
|
||||||
|
let old_db = sled032::open(sled_dir)?;
|
||||||
|
let new_db = sled032::open(new_sled_dir)?;
|
||||||
|
|
||||||
|
let old_alias_tree = old_db.open_tree("alias")?;
|
||||||
|
let new_alias_tree = new_db.open_tree("alias")?;
|
||||||
|
|
||||||
|
let old_fname_tree = old_db.open_tree("filename")?;
|
||||||
|
let new_fname_tree = new_db.open_tree("filename")?;
|
||||||
|
|
||||||
|
for res in old_alias_tree.iter().keys() {
|
||||||
|
let k = res?;
|
||||||
|
if let Some(v) = old_alias_tree.get(&k)? {
|
||||||
|
if !k.contains(&b"/"[0]) {
|
||||||
|
// k is an alias
|
||||||
|
migrate_main_tree(&k, &v, &old_db, &new_db)?;
|
||||||
|
debug!(
|
||||||
|
"Moving alias -> hash for alias {}",
|
||||||
|
String::from_utf8_lossy(k.as_ref()),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
debug!(
|
||||||
|
"Moving {}, {}",
|
||||||
|
String::from_utf8_lossy(k.as_ref()),
|
||||||
|
String::from_utf8_lossy(v.as_ref())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
new_alias_tree.insert(k, v)?;
|
||||||
|
} else {
|
||||||
|
warn!("MISSING {}", String::from_utf8_lossy(k.as_ref()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for res in old_fname_tree.iter().keys() {
|
||||||
|
let k = res?;
|
||||||
|
if let Some(v) = old_fname_tree.get(&k)? {
|
||||||
|
debug!(
|
||||||
|
"Moving file -> hash for file {}",
|
||||||
|
String::from_utf8_lossy(k.as_ref()),
|
||||||
|
);
|
||||||
|
new_fname_tree.insert(&k, &v)?;
|
||||||
|
} else {
|
||||||
|
warn!("MISSING {}", String::from_utf8_lossy(k.as_ref()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(new_db) as Result<sled032::Db, UploadError>
|
||||||
|
}
|
||||||
|
|
||||||
|
fn migrate_main_tree(
|
||||||
|
alias: &sled032::IVec,
|
||||||
|
hash: &sled032::IVec,
|
||||||
|
old_db: &sled032::Db,
|
||||||
|
new_db: &sled032::Db,
|
||||||
|
) -> Result<(), UploadError> {
|
||||||
|
debug!(
|
||||||
|
"Migrating files for {}",
|
||||||
|
String::from_utf8_lossy(alias.as_ref())
|
||||||
|
);
|
||||||
|
if let Some(v) = old_db.get(&hash)? {
|
||||||
|
new_db.insert(&hash, v)?;
|
||||||
|
} else {
|
||||||
|
warn!("Missing filename");
|
||||||
|
}
|
||||||
|
|
||||||
|
let (start, end) = alias_key_bounds(&hash);
|
||||||
|
for res in old_db.range(start..end) {
|
||||||
|
let (k, v) = res?;
|
||||||
|
debug!("Moving alias {}", String::from_utf8_lossy(v.as_ref()));
|
||||||
|
new_db.insert(k, v)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let (start, end) = variant_key_bounds(&hash);
|
||||||
|
for res in old_db.range(start..end) {
|
||||||
|
let (k, v) = res?;
|
||||||
|
debug!("Moving variant {}", String::from_utf8_lossy(v.as_ref()));
|
||||||
|
new_db.insert(k, v)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn alias_key_bounds(hash: &[u8]) -> (Vec<u8>, Vec<u8>) {
|
||||||
|
let mut start = hash.to_vec();
|
||||||
|
start.extend(&[0]);
|
||||||
|
|
||||||
|
let mut end = hash.to_vec();
|
||||||
|
end.extend(&[1]);
|
||||||
|
|
||||||
|
(start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn variant_key_bounds(hash: &[u8]) -> (Vec<u8>, Vec<u8>) {
|
||||||
|
let mut start = hash.to_vec();
|
||||||
|
start.extend(&[2]);
|
||||||
|
|
||||||
|
let mut end = hash.to_vec();
|
||||||
|
end.extend(&[3]);
|
||||||
|
|
||||||
|
(start, end)
|
||||||
|
}
|
|
@ -1,4 +1,10 @@
|
||||||
use crate::{config::Format, error::UploadError, to_ext, validate::validate_image};
|
use crate::{
|
||||||
|
config::Format,
|
||||||
|
error::UploadError,
|
||||||
|
migrate::{alias_key_bounds, variant_key_bounds, LatestDb},
|
||||||
|
to_ext,
|
||||||
|
validate::validate_image,
|
||||||
|
};
|
||||||
use actix_web::web;
|
use actix_web::web;
|
||||||
use futures::stream::{Stream, StreamExt, TryStreamExt};
|
use futures::stream::{Stream, StreamExt, TryStreamExt};
|
||||||
use sha2::Digest;
|
use sha2::Digest;
|
||||||
|
@ -84,10 +90,9 @@ impl UploadManager {
|
||||||
mut root_dir: PathBuf,
|
mut root_dir: PathBuf,
|
||||||
format: Option<Format>,
|
format: Option<Format>,
|
||||||
) -> Result<Self, UploadError> {
|
) -> Result<Self, UploadError> {
|
||||||
let mut sled_dir = root_dir.clone();
|
let root_clone = root_dir.clone();
|
||||||
sled_dir.push("db");
|
|
||||||
// sled automatically creates it's own directories
|
// sled automatically creates it's own directories
|
||||||
let db = web::block(move || sled::open(sled_dir)).await?;
|
let db = web::block(move || LatestDb::exists(root_clone).migrate()).await?;
|
||||||
|
|
||||||
root_dir.push("files");
|
root_dir.push("files");
|
||||||
|
|
||||||
|
@ -684,16 +689,6 @@ fn alias_key(hash: &[u8], id: &str) -> Vec<u8> {
|
||||||
key
|
key
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alias_key_bounds(hash: &[u8]) -> (Vec<u8>, Vec<u8>) {
|
|
||||||
let mut start = hash.to_vec();
|
|
||||||
start.extend(&[0]);
|
|
||||||
|
|
||||||
let mut end = hash.to_vec();
|
|
||||||
end.extend(&[1]);
|
|
||||||
|
|
||||||
(start, end)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn alias_id_key(alias: &str) -> String {
|
fn alias_id_key(alias: &str) -> String {
|
||||||
format!("{}/id", alias)
|
format!("{}/id", alias)
|
||||||
}
|
}
|
||||||
|
@ -708,13 +703,3 @@ fn variant_key(hash: &[u8], path: &str) -> Vec<u8> {
|
||||||
key.extend(path.as_bytes());
|
key.extend(path.as_bytes());
|
||||||
key
|
key
|
||||||
}
|
}
|
||||||
|
|
||||||
fn variant_key_bounds(hash: &[u8]) -> (Vec<u8>, Vec<u8>) {
|
|
||||||
let mut start = hash.to_vec();
|
|
||||||
start.extend(&[2]);
|
|
||||||
|
|
||||||
let mut end = hash.to_vec();
|
|
||||||
end.extend(&[3]);
|
|
||||||
|
|
||||||
(start, end)
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue