Skip to content

Commit cb905d5

Browse files
committed
node: Add graphman restore command
Add `graphman restore` CLI with options: --directory Path to dump directory --shard Target shard (default: primary) --name Subgraph name for deployment rule matching --replace Drop and recreate if exists in target shard --add Create copy in a different shard --force Restore regardless of current state
1 parent 47d76a7 commit cb905d5

3 files changed

Lines changed: 97 additions & 0 deletions

File tree

node/src/bin/manager.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,33 @@ pub enum Command {
342342
/// The name of the directory to dump to
343343
directory: String,
344344
},
345+
346+
/// Restore a subgraph deployment from a dump directory
347+
///
348+
/// EXPERIMENTAL - NOT FOR PRODUCTION USE
349+
///
350+
/// Restore a subgraph deployment from a dump created with the `dump`
351+
/// command.
352+
Restore {
353+
/// Path to the dump directory
354+
directory: String,
355+
/// The database shard to restore into (default: primary)
356+
#[clap(long)]
357+
shard: Option<String>,
358+
/// Subgraph name for deployment rule matching and node assignment.
359+
/// If omitted, uses an existing name from the database; errors if none found.
360+
#[clap(long)]
361+
name: Option<String>,
362+
/// Drop and recreate if the deployment already exists in the target shard
363+
#[clap(long, conflicts_with_all = ["add", "force"])]
364+
replace: bool,
365+
/// Create a copy in a shard that doesn't have this deployment (requires --shard)
366+
#[clap(long, conflicts_with_all = ["replace", "force"])]
367+
add: bool,
368+
/// Restore no matter what: replace if exists in target shard, add if not
369+
#[clap(long, conflicts_with_all = ["replace", "add"])]
370+
force: bool,
371+
},
345372
}
346373

347374
impl Command {
@@ -1757,6 +1784,21 @@ async fn main() -> anyhow::Result<()> {
17571784

17581785
commands::dump::run(subgraph_store, primary_pool, deployment, directory).await
17591786
}
1787+
1788+
Restore {
1789+
directory,
1790+
shard,
1791+
name,
1792+
replace,
1793+
add,
1794+
force,
1795+
} => {
1796+
let store = ctx.store().await;
1797+
let subgraph_store = store.subgraph_store();
1798+
1799+
commands::restore::run(subgraph_store, directory, shard, name, replace, add, force)
1800+
.await
1801+
}
17601802
}
17611803
}
17621804

node/src/manager/commands/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub mod provider_checks;
1414
pub mod prune;
1515
pub mod query;
1616
pub mod remove;
17+
pub mod restore;
1718
pub mod rewind;
1819
pub mod run;
1920
pub mod stats;
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
use std::sync::Arc;
2+
3+
use graph::{bail, prelude::anyhow::Result};
4+
5+
use graph::prelude::SubgraphName;
6+
use graph_store_postgres::{RestoreMode, Shard, SubgraphStore, PRIMARY_SHARD};
7+
8+
pub async fn run(
9+
subgraph_store: Arc<SubgraphStore>,
10+
directory: String,
11+
shard: Option<String>,
12+
name: Option<String>,
13+
replace: bool,
14+
add: bool,
15+
force: bool,
16+
) -> Result<()> {
17+
if add && shard.is_none() {
18+
bail!("--add requires --shard");
19+
}
20+
21+
let directory = std::path::Path::new(&directory).canonicalize()?;
22+
let stat = std::fs::metadata(&directory)?;
23+
24+
if !stat.is_dir() {
25+
bail!(
26+
"The path `{}` is not a directory",
27+
directory.to_string_lossy()
28+
);
29+
}
30+
31+
let shard = match shard {
32+
Some(s) => Shard::new(s)?,
33+
None => PRIMARY_SHARD.clone(),
34+
};
35+
36+
let name = name
37+
.map(|n| SubgraphName::new(n.clone()).map_err(|_| anyhow::anyhow!("invalid name `{n}`")))
38+
.transpose()?;
39+
40+
let mode = if replace {
41+
RestoreMode::Replace
42+
} else if add {
43+
RestoreMode::Add
44+
} else if force {
45+
RestoreMode::Force
46+
} else {
47+
RestoreMode::Default
48+
};
49+
50+
subgraph_store
51+
.restore(&directory, shard, name, mode)
52+
.await?;
53+
Ok(())
54+
}

0 commit comments

Comments
 (0)