Compare commits
3 commits
afccf9d7bb
...
af89f1412a
Author | SHA1 | Date | |
---|---|---|---|
af89f1412a | |||
ec1b70d399 | |||
085755eebc |
52
src/main.rs
52
src/main.rs
|
@ -1,19 +1,15 @@
|
|||
use aws_config::Region;
|
||||
use aws_sdk_s3 as s3;
|
||||
use eyre::{OptionExt, WrapErr};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryFrom;
|
||||
use std::time::{Duration, SystemTime};
|
||||
use std::fmt;
|
||||
use std::time::{Duration, SystemTime};
|
||||
|
||||
const RESTIC_ALARM_BUCKET: &str = "restic-alarm-state";
|
||||
const RESTIC_ALARM_STATE_FILE: &str = "state.toml";
|
||||
const RESTIC_ALARM_WATCH_DIR: &str = "watch/";
|
||||
|
||||
const S3_REGION: &str = "infracoll";
|
||||
const S3_ENDPOINT: &str = "http://garage.isomorphis.me:3900";
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
struct State {
|
||||
last_alert: HashMap<String, u64>,
|
||||
|
@ -60,19 +56,19 @@ struct AlertStatus {
|
|||
|
||||
impl fmt::Display for AlertStatus {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let days = |d: Duration| {
|
||||
d.as_secs() / (3600 * 24)
|
||||
};
|
||||
let hours = |d: Duration| {
|
||||
(d.as_secs() / 3600) % 24
|
||||
};
|
||||
write!(f, "{}: inactivity: {} days, {} hours, last_alert: {}",
|
||||
(if self.alert { "ALERT" } else { "no alert" }),
|
||||
days(self.inactivity), hours(self.inactivity),
|
||||
match self.last_alert {
|
||||
None => "none".to_owned(),
|
||||
Some(d) => format!("{} days, {} hours", days(d), hours(d))
|
||||
})
|
||||
let days = |d: Duration| d.as_secs() / (3600 * 24);
|
||||
let hours = |d: Duration| (d.as_secs() / 3600) % 24;
|
||||
write!(
|
||||
f,
|
||||
"{}: inactivity: {} days, {} hours, last_alert: {}",
|
||||
(if self.alert { "ALERT" } else { "no alert" }),
|
||||
days(self.inactivity),
|
||||
hours(self.inactivity),
|
||||
match self.last_alert {
|
||||
None => "none".to_owned(),
|
||||
Some(d) => format!("{} days, {} hours", days(d), hours(d)),
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,7 +221,11 @@ async fn repo_last_snapshot(client: &s3::Client, repo: &str) -> eyre::Result<Opt
|
|||
// (e.g. if it fails to parse).
|
||||
// So the error must not be propagated to the toplevel, which would abort the
|
||||
// alert for remaining repositories; it should instead just be reported/logged.
|
||||
async fn check_repo(client: &s3::Client, state: &mut State, repo: &str) -> eyre::Result<Option<AlertStatus>> {
|
||||
async fn check_repo(
|
||||
client: &s3::Client,
|
||||
state: &mut State,
|
||||
repo: &str,
|
||||
) -> eyre::Result<Option<AlertStatus>> {
|
||||
let config = read_repo_config(client, repo).await?;
|
||||
if let Some(inactivity) = repo_last_snapshot(client, repo).await? {
|
||||
let last_alert = state.last_alert(repo);
|
||||
|
@ -236,7 +236,11 @@ async fn check_repo(client: &s3::Client, state: &mut State, repo: &str) -> eyre:
|
|||
state.update_last_alert(repo);
|
||||
write_state(client, state).await?;
|
||||
}
|
||||
Ok(Some(AlertStatus { alert, inactivity, last_alert }))
|
||||
Ok(Some(AlertStatus {
|
||||
alert,
|
||||
inactivity,
|
||||
last_alert,
|
||||
}))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
|
@ -246,8 +250,6 @@ async fn check_repo(client: &s3::Client, state: &mut State, repo: &str) -> eyre:
|
|||
async fn main() -> eyre::Result<()> {
|
||||
let sdk_config = aws_config::load_from_env().await;
|
||||
let config = aws_sdk_s3::config::Builder::from(&sdk_config)
|
||||
.region(Region::new(S3_REGION))
|
||||
.endpoint_url(S3_ENDPOINT)
|
||||
.force_path_style(true)
|
||||
.build();
|
||||
let client = aws_sdk_s3::Client::from_conf(config);
|
||||
|
@ -257,17 +259,17 @@ async fn main() -> eyre::Result<()> {
|
|||
for r in repos.iter() {
|
||||
println!("- {}", r);
|
||||
}
|
||||
|
||||
let mut state = read_state(&client).await?;
|
||||
println!("Current state: {:?}", &state);
|
||||
|
||||
for repo in repos {
|
||||
match check_repo(&client, &mut state, &repo).await {
|
||||
Ok(None) => {
|
||||
println!("{}: no snapshot, skipping", &repo)
|
||||
},
|
||||
}
|
||||
Ok(Some(status)) => {
|
||||
println!("{}: {}", &repo, status);
|
||||
},
|
||||
}
|
||||
Err(err) => {
|
||||
// is this the best way to log the error?
|
||||
println!("Error ({}): {:?}", &repo, err)
|
||||
|
|
Loading…
Reference in a new issue