summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2020-11-09 10:47:05 +0200
committerLars Wirzenius <liw@liw.fi>2020-11-09 10:47:05 +0200
commit4d5b5c26f7c4b45434448d9ff8eb5d02c5737665 (patch)
tree84f7678e2fc2bb98239aafeaf75d2efb7ea3d77b /src
parent0809fb0ff525774b90c2a0d33b4b42752bc60b41 (diff)
downloadobnam2-4d5b5c26f7c4b45434448d9ff8eb5d02c5737665.tar.gz
fetch gen sqlite file when restoring
Diffstat (limited to 'src')
-rw-r--r--src/bin/obnam-restore.rs90
-rw-r--r--src/client.rs36
2 files changed, 51 insertions, 75 deletions
diff --git a/src/bin/obnam-restore.rs b/src/bin/obnam-restore.rs
index 2014ef8..21cc096 100644
--- a/src/bin/obnam-restore.rs
+++ b/src/bin/obnam-restore.rs
@@ -1,23 +1,12 @@
-// Fetch a backup generation's chunks, write to stdout.
-
-use log::{debug, info, trace};
-use obnam::chunk::{DataChunk, GenerationChunk};
-use obnam::chunkid::ChunkId;
+use log::{debug, info};
+use obnam::client::BackupClient;
//use obnam::chunkmeta::ChunkMeta;
use serde::Deserialize;
-use std::io::{stdout, Write};
+use std::fs::File;
+use std::io::prelude::*;
use std::path::{Path, PathBuf};
use structopt::StructOpt;
-#[derive(Debug, thiserror::Error)]
-enum ClientError {
- #[error("Server does not have generation {0}")]
- GenerationNotFound(String),
-
- #[error("Server does not have chunk {0}")]
- ChunkNotFound(String),
-}
-
#[derive(Debug, StructOpt)]
#[structopt(name = "obnam-backup", about = "Simplistic backup client")]
struct Opt {
@@ -26,6 +15,9 @@ struct Opt {
#[structopt()]
gen_id: String,
+
+ #[structopt(parse(from_os_str))]
+ dbname: PathBuf,
}
fn main() -> anyhow::Result<()> {
@@ -38,17 +30,15 @@ fn main() -> anyhow::Result<()> {
info!("opt: {:?}", opt);
info!("config: {:?}", config);
- let client = reqwest::blocking::Client::builder()
- .danger_accept_invalid_certs(true)
- .build()?;
- let mut stdout = stdout();
-
- let gen = fetch_generation(&client, &config, &opt.gen_id)?;
+ let client = BackupClient::new(&config.server_name, config.server_port)?;
+ let gen = client.fetch_generation(&opt.gen_id)?;
debug!("gen: {:?}", gen);
- for id in gen.chunk_ids() {
- let chunk = fetch_chunk(&client, &config, id)?;
- debug!("got chunk: {}", id);
- stdout.write_all(chunk.data())?;
+ {
+ let mut dbfile = File::create(&opt.dbname)?;
+ for id in gen.chunk_ids() {
+ let chunk = client.fetch_chunk(id)?;
+ dbfile.write_all(chunk.data())?;
+ }
}
Ok(())
@@ -67,53 +57,3 @@ impl Config {
Ok(config)
}
}
-
-fn fetch_generation(
- client: &reqwest::blocking::Client,
- config: &Config,
- gen_id: &str,
-) -> anyhow::Result<GenerationChunk> {
- let url = format!(
- "http://{}:{}/chunks/{}",
- config.server_name, config.server_port, gen_id,
- );
-
- trace!("fetch_generation: url={:?}", url);
- let req = client.get(&url).build()?;
-
- let res = client.execute(req)?;
- debug!("fetch_generation: status={}", res.status());
- if res.status() != 200 {
- debug!("fetch_generation: error from server");
- return Err(ClientError::GenerationNotFound(gen_id.to_string()).into());
- }
-
- let text = res.text()?;
- debug!("fetch_generation: text={:?}", text);
- let gen = serde_json::from_str(&text)?;
- Ok(gen)
-}
-
-fn fetch_chunk(
- client: &reqwest::blocking::Client,
- config: &Config,
- chunk_id: &ChunkId,
-) -> anyhow::Result<DataChunk> {
- let url = format!(
- "http://{}:{}/chunks/{}",
- config.server_name, config.server_port, chunk_id,
- );
-
- trace!("fetch_chunk: url={:?}", url);
- let req = client.get(&url).build()?;
-
- let res = client.execute(req)?;
- debug!("fetch_chunk: status={}", res.status());
- if res.status() != 200 {
- debug!("fetch_chunk: error from server");
- return Err(ClientError::ChunkNotFound(chunk_id.to_string()).into());
- }
-
- let body = res.bytes()?;
- Ok(DataChunk::new(body.to_vec()))
-}
diff --git a/src/client.rs b/src/client.rs
index 24d961a..ecfc42c 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -32,6 +32,12 @@ impl ClientConfig {
pub enum ClientError {
#[error("Server successful response to creating chunk lacked chunk id")]
NoCreatedChunkId,
+
+ #[error("Server does not have chunk {0}")]
+ ChunkNotFound(String),
+
+ #[error("Server does not have generation {0}")]
+ GenerationNotFound(String),
}
pub struct BackupClient {
@@ -178,4 +184,34 @@ impl BackupClient {
debug!("list_generations: map={:?}", map);
Ok(map.keys().into_iter().map(|key| key.into()).collect())
}
+
+ pub fn fetch_chunk(&self, chunk_id: &ChunkId) -> anyhow::Result<DataChunk> {
+ let url = format!("{}/{}", self.base_url(), chunk_id);
+ trace!("fetch_chunk: url={:?}", url);
+ let req = self.client.get(&url).build()?;
+ let res = self.client.execute(req)?;
+ debug!("fetch_chunk: status={}", res.status());
+ if res.status() != 200 {
+ return Err(ClientError::ChunkNotFound(chunk_id.to_string()).into());
+ }
+
+ let body = res.bytes()?;
+ Ok(DataChunk::new(body.to_vec()))
+ }
+
+ pub fn fetch_generation(&self, gen_id: &str) -> anyhow::Result<GenerationChunk> {
+ let url = format!("{}/{}", self.base_url(), gen_id);
+ trace!("fetch_generation: url={:?}", url);
+ let req = self.client.get(&url).build()?;
+ let res = self.client.execute(req)?;
+ debug!("fetch_generation: status={}", res.status());
+ if res.status() != 200 {
+ return Err(ClientError::GenerationNotFound(gen_id.to_string()).into());
+ }
+
+ let text = res.text()?;
+ debug!("fetch_generation: text={:?}", text);
+ let gen = serde_json::from_str(&text)?;
+ Ok(gen)
+ }
}