add zip file support
This commit is contained in:
@@ -3,6 +3,7 @@ use std::{
|
|||||||
path::Path,
|
path::Path,
|
||||||
};
|
};
|
||||||
use rust_util::{
|
use rust_util::{
|
||||||
|
iff,
|
||||||
XResult,
|
XResult,
|
||||||
new_box_ioerror,
|
new_box_ioerror,
|
||||||
util_msg::*,
|
util_msg::*,
|
||||||
@@ -211,11 +212,7 @@ fn parse_oss_backupd_config_item(item: &json::JsonValue, root_oss_config_object:
|
|||||||
|
|
||||||
fn parse_sub_oss_config(json: &json::JsonValue) -> Option<OSSConfig> {
|
fn parse_sub_oss_config(json: &json::JsonValue) -> Option<OSSConfig> {
|
||||||
let root_oss_config = &json["oss_config"];
|
let root_oss_config = &json["oss_config"];
|
||||||
let root_oss_config_object: Option<OSSConfig> = match root_oss_config.is_null() {
|
iff!(root_oss_config.is_null(), None, Some(parse_oss_config(root_oss_config)))
|
||||||
true => None,
|
|
||||||
false => Some(parse_oss_config(root_oss_config)),
|
|
||||||
};
|
|
||||||
root_oss_config_object
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_oss_config(oss_config: &json::JsonValue) -> OSSConfig {
|
fn parse_oss_config(oss_config: &json::JsonValue) -> OSSConfig {
|
||||||
@@ -230,10 +227,7 @@ fn parse_oss_config(oss_config: &json::JsonValue) -> OSSConfig {
|
|||||||
|
|
||||||
fn get_string_value(json: &json::JsonValue, key: &str) -> Option<String> {
|
fn get_string_value(json: &json::JsonValue, key: &str) -> Option<String> {
|
||||||
let value = &json[key];
|
let value = &json[key];
|
||||||
match value.is_string() {
|
value.as_str().map(|s| s.to_owned())
|
||||||
true => Some(value.as_str().unwrap().to_string()),
|
|
||||||
false => None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_u32_value(json: &json::JsonValue, key: &str) -> Option<u32> {
|
fn get_u32_value(json: &json::JsonValue, key: &str) -> Option<u32> {
|
||||||
|
|||||||
11
src/main.rs
11
src/main.rs
@@ -80,13 +80,12 @@ fn process_config_item(options: &Options, config_item: &OSSBackupdConfigItem,
|
|||||||
if options.verbose {
|
if options.verbose {
|
||||||
print_message(MessageType::DEBUG, &format!("Endpoint: {}", endpoint));
|
print_message(MessageType::DEBUG, &format!("Endpoint: {}", endpoint));
|
||||||
}
|
}
|
||||||
|
|
||||||
let access_key_id = oss_config.access_key_id.as_ref().ok_or("oss_config#access_key_id".to_owned())?;
|
let access_key_id = oss_config.access_key_id.as_ref().ok_or("oss_config#access_key_id".to_owned())?;
|
||||||
if options.verbose {
|
if options.verbose {
|
||||||
print_message(MessageType::DEBUG, &format!("Access key id: {}", access_key_id));
|
print_message(MessageType::DEBUG, &format!("Access key id: {}", access_key_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
let access_key_secret = oss_config.access_key_secret.as_ref().ok_or("oss_config#access_key_secret".to_owned())?;
|
let access_key_secret = oss_config.access_key_secret.as_ref().ok_or("oss_config#access_key_secret".to_owned())?;
|
||||||
|
|
||||||
let bucket = &oss_config.bucket.as_ref().ok_or("oss_config#bucket".to_owned())?;
|
let bucket = &oss_config.bucket.as_ref().ok_or("oss_config#bucket".to_owned())?;
|
||||||
if options.verbose {
|
if options.verbose {
|
||||||
print_message(MessageType::DEBUG, &format!("Bucket: {}", bucket));
|
print_message(MessageType::DEBUG, &format!("Bucket: {}", bucket));
|
||||||
@@ -173,12 +172,8 @@ fn process_config_item(options: &Options, config_item: &OSSBackupdConfigItem,
|
|||||||
print_message(MessageType::DEBUG, &format!("Processing meta file: {}", meta_file_name));
|
print_message(MessageType::DEBUG, &format!("Processing meta file: {}", meta_file_name));
|
||||||
}
|
}
|
||||||
match process_oss_files(&options, &oss_client, bucket, path, meta_file_name, &new_file, backup_count) {
|
match process_oss_files(&options, &oss_client, bucket, path, meta_file_name, &new_file, backup_count) {
|
||||||
Err(e) => {
|
Err(e) => print_message(MessageType::ERROR, &format!("Error: {}, at item index: {}", e, item_index)),
|
||||||
print_message(MessageType::ERROR, &format!("Error: {}, at item index: {}", e, item_index));
|
Ok(_) => print_message(MessageType::OK, &format!("Success, at item index: {}", item_index)),
|
||||||
},
|
|
||||||
Ok(_) => {
|
|
||||||
print_message(MessageType::OK, &format!("Success, at item index: {}", item_index));
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
remove_temp_files();
|
remove_temp_files();
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ use argparse::{ArgumentParser, StoreTrue, Store};
|
|||||||
// pub static ref IS_DEBUG: bool = rust_util::util_env::is_env_on("DEBUG");
|
// pub static ref IS_DEBUG: bool = rust_util::util_env::is_env_on("DEBUG");
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
const EMPTY: &str = "";
|
||||||
|
|
||||||
pub struct Options {
|
pub struct Options {
|
||||||
pub version: bool,
|
pub version: bool,
|
||||||
pub verbose: bool,
|
pub verbose: bool,
|
||||||
@@ -18,7 +20,7 @@ impl Options {
|
|||||||
Options {
|
Options {
|
||||||
version: false,
|
version: false,
|
||||||
verbose: false,
|
verbose: false,
|
||||||
config: "".to_owned(),
|
config: EMPTY.to_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,18 +22,18 @@ pub const OSS_VERB_PUT: &str = "PUT";
|
|||||||
pub const OSS_VERB_DELETE: &str = "DELETE";
|
pub const OSS_VERB_DELETE: &str = "DELETE";
|
||||||
|
|
||||||
// https://help.aliyun.com/document_detail/31952.html
|
// https://help.aliyun.com/document_detail/31952.html
|
||||||
pub struct OSSClient<'a> {
|
pub struct OSSClient {
|
||||||
pub endpoint: &'a str,
|
pub endpoint: String,
|
||||||
pub access_key_id: &'a str,
|
pub access_key_id: String,
|
||||||
pub access_key_secret: &'a str,
|
pub access_key_secret: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> OSSClient<'a> {
|
impl OSSClient {
|
||||||
pub fn new(endpoint: &'a str, access_key_id: &'a str, access_key_secret: &'a str) -> OSSClient<'a> {
|
pub fn new(endpoint: &str, access_key_id: &str, access_key_secret: &str) -> OSSClient {
|
||||||
OSSClient {
|
OSSClient {
|
||||||
endpoint: endpoint,
|
endpoint: endpoint.to_owned(),
|
||||||
access_key_id: access_key_id,
|
access_key_id: access_key_id.to_owned(),
|
||||||
access_key_secret: access_key_secret,
|
access_key_secret: access_key_secret.to_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,9 +78,9 @@ impl<'a> OSSClient<'a> {
|
|||||||
|
|
||||||
pub fn generate_signed_url(&self, verb: &str, bucket_name: &str, key: &str, expire_in_seconds: u64, is_https: bool) -> String {
|
pub fn generate_signed_url(&self, verb: &str, bucket_name: &str, key: &str, expire_in_seconds: u64, is_https: bool) -> String {
|
||||||
let mut signed_url = String::with_capacity(1024);
|
let mut signed_url = String::with_capacity(1024);
|
||||||
signed_url.push_str(if is_https { "https://" } else { "http://" });
|
signed_url.push_str(iff!(is_https, "https://", "http://"));
|
||||||
|
|
||||||
let endpoint = &remove_endpoint_http_or_s(self.endpoint);
|
let endpoint = &remove_endpoint_http_or_s(&self.endpoint);
|
||||||
signed_url.push_str(&format!("{}.{}/{}", bucket_name, endpoint, key));
|
signed_url.push_str(&format!("{}.{}/{}", bucket_name, endpoint, key));
|
||||||
|
|
||||||
let current_secs = get_current_secs();
|
let current_secs = get_current_secs();
|
||||||
@@ -89,7 +89,7 @@ impl<'a> OSSClient<'a> {
|
|||||||
signed_url.push_str("?Expires=");
|
signed_url.push_str("?Expires=");
|
||||||
signed_url.push_str(expire_secs.to_string().as_str());
|
signed_url.push_str(expire_secs.to_string().as_str());
|
||||||
signed_url.push_str("&OSSAccessKeyId=");
|
signed_url.push_str("&OSSAccessKeyId=");
|
||||||
signed_url.push_str(&urlencoding::encode(self.access_key_id));
|
signed_url.push_str(&urlencoding::encode(&self.access_key_id));
|
||||||
signed_url.push_str("&Signature=");
|
signed_url.push_str("&Signature=");
|
||||||
|
|
||||||
let to_be_signed = get_to_be_signed(verb, expire_secs, bucket_name, key);
|
let to_be_signed = get_to_be_signed(verb, expire_secs, bucket_name, key);
|
||||||
|
|||||||
@@ -45,16 +45,22 @@ pub fn zip_file(target: &str, zip_file: &str) -> XResult<()> {
|
|||||||
copy_io_with_head(&mut File::open(target_path)?, &mut zip, -1, "Compressing")?;
|
copy_io_with_head(&mut File::open(target_path)?, &mut zip, -1, "Compressing")?;
|
||||||
|
|
||||||
zip.finish()?;
|
zip.finish()?;
|
||||||
} else { // TODO when target is PATH!
|
} else {
|
||||||
let mut_zip = RefCell::new(zip);
|
let mut_zip = RefCell::new(zip);
|
||||||
walk_dir(&target_path, &|p, e| {
|
walk_dir(&target_path, &|p, e| {
|
||||||
print_message(MessageType::WARN, &format!("Compress {} failed: {}", &p.display(), &e));
|
print_message(MessageType::WARN, &format!("Compress {} failed: {}", &p.display(), &e));
|
||||||
}, &|f| {
|
}, &|f| {
|
||||||
let options = FileOptions::default().compression_method(CompressionMethod::Stored);
|
let options = FileOptions::default().compression_method(CompressionMethod::Stored);
|
||||||
let mut m_zip = mut_zip.borrow_mut();
|
let mut m_zip = mut_zip.borrow_mut();
|
||||||
match m_zip.start_file("", options) { // TODO filename
|
let file_name = get_file_name(&f);
|
||||||
Ok(_) => (),
|
match m_zip.start_file(&file_name, options) {
|
||||||
Err(e) => print_message(MessageType::WARN, &format!("Compress {} failed: {}", &f.display(), &e)),
|
Ok(_) => match File::open(f) {
|
||||||
|
Err(e) => print_message(MessageType::WARN, &format!("Compress {} failed: {}", &f.display(), e)),
|
||||||
|
Ok(mut ff) => if let Err(e) = copy_io_with_head(&mut ff, &mut *m_zip, -1, &format!("Compressing {}", &file_name)) {
|
||||||
|
print_message(MessageType::WARN, &format!("Compress {} failed: {}", &f.display(), e))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => print_message(MessageType::WARN, &format!("Compress {} failed: {}", &f.display(), e)),
|
||||||
};
|
};
|
||||||
}, &|_| { true })?;
|
}, &|_| { true })?;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user