Can download a copy of storage
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
@ -4,6 +4,7 @@ use actix_web::HttpResponse;
|
||||
use std::error::Error;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::io::ErrorKind;
|
||||
use zip::result::ZipError;
|
||||
|
||||
/// Custom error to ease controller writing
|
||||
#[derive(Debug)]
|
||||
@ -109,6 +110,18 @@ impl From<openssl::error::ErrorStack> for HttpErr {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ZipError> for HttpErr {
|
||||
fn from(value: ZipError) -> Self {
|
||||
HttpErr::Err(std::io::Error::new(ErrorKind::Other, value.to_string()).into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<walkdir::Error> for HttpErr {
|
||||
fn from(value: walkdir::Error) -> Self {
|
||||
HttpErr::Err(std::io::Error::new(ErrorKind::Other, value.to_string()).into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<HttpResponse> for HttpErr {
|
||||
fn from(value: HttpResponse) -> Self {
|
||||
HttpErr::HTTPResponse(value)
|
||||
|
@ -243,6 +243,11 @@ pub async fn secure_server(energy_actor: EnergyActorAddr) -> anyhow::Result<()>
|
||||
"/web_api/relay/{id}/status",
|
||||
web::get().to(relays_controller::status_single),
|
||||
)
|
||||
// Management API
|
||||
.route(
|
||||
"/web_api/management/download_storage",
|
||||
web::get().to(management_controller::download_storage),
|
||||
)
|
||||
// Devices API
|
||||
.route(
|
||||
"/devices_api/utils/time",
|
||||
|
66
central_backend/src/server/web_api/management_controller.rs
Normal file
66
central_backend/src/server/web_api/management_controller.rs
Normal file
@ -0,0 +1,66 @@
|
||||
use crate::app_config::AppConfig;
|
||||
use crate::server::custom_error::HttpResult;
|
||||
use crate::utils::time_utils::current_day;
|
||||
use actix_web::HttpResponse;
|
||||
use anyhow::Context;
|
||||
use std::fs::File;
|
||||
use std::io::{Cursor, Read, Write};
|
||||
use walkdir::WalkDir;
|
||||
use zip::write::SimpleFileOptions;
|
||||
|
||||
/// Download a full copy of the storage data
|
||||
pub async fn download_storage() -> HttpResult {
|
||||
let mut zip_buff = Cursor::new(Vec::new());
|
||||
let mut zip = zip::ZipWriter::new(&mut zip_buff);
|
||||
|
||||
let options = SimpleFileOptions::default()
|
||||
.compression_method(zip::CompressionMethod::Bzip2)
|
||||
.unix_permissions(0o700);
|
||||
|
||||
let storage = AppConfig::get().storage_path();
|
||||
|
||||
let mut file_buff = Vec::new();
|
||||
for entry in WalkDir::new(&storage) {
|
||||
let entry = entry?;
|
||||
|
||||
let path = entry.path();
|
||||
let name = path.strip_prefix(&storage).unwrap();
|
||||
let path_as_string = name
|
||||
.to_str()
|
||||
.map(str::to_owned)
|
||||
.with_context(|| format!("{name:?} Is a Non UTF-8 Path"))?;
|
||||
|
||||
// Write file or directory explicitly
|
||||
// Some unzip tools unzip files with directory paths correctly, some do not!
|
||||
if path.is_file() {
|
||||
log::debug!("adding file {path:?} as {name:?} ...");
|
||||
zip.start_file(path_as_string, options)?;
|
||||
let mut f = File::open(path)?;
|
||||
|
||||
f.read_to_end(&mut file_buff)?;
|
||||
zip.write_all(&file_buff)?;
|
||||
file_buff.clear();
|
||||
} else if !name.as_os_str().is_empty() {
|
||||
// Only if not root! Avoids path spec / warning
|
||||
// and mapname conversion failed error on unzip
|
||||
log::debug!("adding dir {path_as_string:?} as {name:?} ...");
|
||||
zip.add_directory(path_as_string, options)?;
|
||||
}
|
||||
}
|
||||
|
||||
// Inject runtime configuration
|
||||
zip.start_file("/app_config.json", options)?;
|
||||
zip.write_all(&serde_json::to_vec_pretty(&AppConfig::get())?)?;
|
||||
|
||||
zip.finish()?;
|
||||
|
||||
let filename = format!("storage-{}.zip", current_day());
|
||||
|
||||
Ok(HttpResponse::Ok()
|
||||
.content_type("application/zip")
|
||||
.insert_header((
|
||||
"content-disposition",
|
||||
format!("attachment; filename=\"{filename}\""),
|
||||
))
|
||||
.body(zip_buff.into_inner()))
|
||||
}
|
@ -2,6 +2,7 @@ pub mod auth_controller;
|
||||
pub mod devices_controller;
|
||||
pub mod energy_controller;
|
||||
pub mod logging_controller;
|
||||
pub mod management_controller;
|
||||
pub mod ota_controller;
|
||||
pub mod relays_controller;
|
||||
pub mod server_controller;
|
||||
|
Reference in New Issue
Block a user