summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2020-12-30 13:33:57 +0200
committerLars Wirzenius <liw@liw.fi>2020-12-30 13:56:20 +0200
commitc492bc19aaf404ab4115b8d7f06eff81a6480b4e (patch)
tree99bb10c1cfc99bded3b7187f18541c9e7c676ead /src
parent48639d00710cf945cff7298cf927efc7275364e2 (diff)
downloadobnam2-c492bc19aaf404ab4115b8d7f06eff81a6480b4e.tar.gz
feat! store and show timestamp for each backup generation
This changes the output format of "obnam list".
Diffstat (limited to 'src')
-rw-r--r--src/client.rs17
-rw-r--r--src/cmd/list.rs6
-rw-r--r--src/generation.rs5
3 files changed, 21 insertions, 7 deletions
diff --git a/src/client.rs b/src/client.rs
index 3149ec5..adca373 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -5,6 +5,8 @@ use crate::chunker::Chunker;
use crate::chunkid::ChunkId;
use crate::chunkmeta::ChunkMeta;
use crate::fsentry::{FilesystemEntry, FilesystemKind};
+use crate::generation::FinishedGeneration;
+use chrono::{DateTime, Local};
use log::{debug, error, info, trace};
use reqwest::blocking::Client;
use serde::Deserialize;
@@ -73,7 +75,7 @@ impl BackupClient {
let ids = self.read_file(filename.to_path_buf(), size)?;
let gen = GenerationChunk::new(ids);
let data = gen.to_data_chunk()?;
- let meta = ChunkMeta::new_generation(&sha256(data.data()), "timestamp");
+ let meta = ChunkMeta::new_generation(&sha256(data.data()), &current_timestamp());
let gen_id = self.upload_gen_chunk(meta, gen)?;
Ok(gen_id)
}
@@ -179,7 +181,7 @@ impl BackupClient {
Ok(chunk_ids)
}
- pub fn list_generations(&self) -> anyhow::Result<Vec<ChunkId>> {
+ pub fn list_generations(&self) -> anyhow::Result<Vec<FinishedGeneration>> {
let url = format!("{}?generation=true", &self.chunks_url());
trace!("list_generations: url={:?}", url);
let req = self.client.get(&url).build()?;
@@ -189,7 +191,11 @@ impl BackupClient {
debug!("list_generationgs: body={:?}", body);
let map: HashMap<String, ChunkMeta> = serde_yaml::from_slice(&body)?;
debug!("list_generations: map={:?}", map);
- Ok(map.keys().into_iter().map(|key| key.into()).collect())
+ let finished = map
+ .iter()
+ .map(|(id, meta)| FinishedGeneration::new(id, meta.ended().map_or("", |s| s)))
+ .collect();
+ Ok(finished)
}
pub fn fetch_chunk(&self, chunk_id: &ChunkId) -> anyhow::Result<DataChunk> {
@@ -222,3 +228,8 @@ impl BackupClient {
Ok(gen)
}
}
+
+fn current_timestamp() -> String {
+ let now: DateTime<Local> = Local::now();
+ format!("{}", now.format("%Y-%m-%d %H:%M:%S %z"))
+}
diff --git a/src/cmd/list.rs b/src/cmd/list.rs
index 6c48244..70aa0a7 100644
--- a/src/cmd/list.rs
+++ b/src/cmd/list.rs
@@ -3,8 +3,10 @@ use crate::client::{BackupClient, ClientConfig};
pub fn list(config: &ClientConfig) -> anyhow::Result<()> {
let client = BackupClient::new(&config.server_url)?;
- for gen_id in client.list_generations()? {
- println!("{}", gen_id);
+ let mut generations = client.list_generations()?;
+ generations.sort_by_cached_key(|gen| gen.ended().to_string());
+ for finished in generations {
+ println!("{} {}", finished.id(), finished.ended());
}
Ok(())
diff --git a/src/generation.rs b/src/generation.rs
index fdfd7f1..dc9bf0c 100644
--- a/src/generation.rs
+++ b/src/generation.rs
@@ -164,9 +164,10 @@ pub struct FinishedGeneration {
}
impl FinishedGeneration {
- pub fn new(id: ChunkId, ended: &str) -> Self {
+ pub fn new(id: &str, ended: &str) -> Self {
+ let id = id.parse().unwrap(); // this never fails
Self {
- id: id.clone(),
+ id,
ended: ended.to_string(),
}
}