use dg_edge_updater::{BIN_PATH, TMP_PATH};
use dg_edge_updater::{
download_file, fetch_manifest, get_binary_version, get_download_url, run_systemctl,
set_executable_bit, swap_binaries, try_start_with_rollback,
};
use dg_logger::{DruidGardenLogger, TimestampFormat};
use log::{Level, error, info};
use reqwest::Client;
use semver::Version;
use std::io::{Error, ErrorKind};
#[tokio::main]
async fn main() -> Result<(), Error> {
let _ = DruidGardenLogger::build()
.use_colors(true)
.current_level(Level::Info)
.timestamp_format(TimestampFormat::Local)
.with_target_level("zbus", Level::Warn)
.with_target_level("tracing", Level::Warn)
.init()
.map_err(|e| Error::new(ErrorKind::Other, format!("{e:?}")))?;
let client = Client::new();
let manifest = fetch_manifest(&client).await?;
let remote_version =
Version::parse(&manifest.version).map_err(|e| Error::new(ErrorKind::Other, e))?;
info!("Found Remote version: {}", remote_version);
let local_version = get_binary_version(BIN_PATH)
.await
.unwrap_or_else(|| Version::new(0, 0, 0));
info!("Found Local version: {}", local_version);
if remote_version <= local_version {
info!("Up to date! nothing to do.");
return Ok(());
}
let download_url = get_download_url(manifest.version.as_str())?;
download_file(&client, TMP_PATH, &download_url).await?;
set_executable_bit(TMP_PATH).await?;
let downloaded_version = get_binary_version(TMP_PATH).await.ok_or(Error::new(
ErrorKind::Other,
"Failed to read downloaded binary version",
))?;
if downloaded_version != remote_version {
return Err(Error::new(
ErrorKind::Other,
"Downloaded binary version mismatch",
));
}
run_systemctl("stop").await?;
swap_binaries().await?;
if try_start_with_rollback().await? {
info!("Update successful!");
} else {
error!("CRITICAL UPDATE FAILURE - PLEASE REBOOT DEVICE");
}
Ok(())
}