commit 9ed2ba61c6267b95aa936a55994554631f725538
parent 08a445e2acb911b09ed0e3b56b03f905635fe5c6
Author: Daniel GarcĂa <dani-garcia@users.noreply.github.com>
Date: Sat, 1 Jun 2019 23:29:58 +0200
Merge pull request #475 from TheMardy/master
Create Backup funcitonality
Diffstat:
3 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/src/api/admin.rs b/src/api/admin.rs
@@ -9,7 +9,7 @@ use rocket_contrib::json::Json;
use crate::api::{ApiResult, EmptyResult, JsonResult};
use crate::auth::{decode_admin, encode_jwt, generate_admin_claims, ClientIp};
use crate::config::ConfigBuilder;
-use crate::db::{models::*, DbConn};
+use crate::db::{models::*, DbConn, backup_database};
use crate::error::Error;
use crate::mail;
use crate::CONFIG;
@@ -30,6 +30,7 @@ pub fn routes() -> Vec<Route> {
update_revision_users,
post_config,
delete_config,
+ backup_db,
]
}
@@ -204,6 +205,11 @@ fn delete_config(_token: AdminToken) -> EmptyResult {
CONFIG.delete_user_config()
}
+#[post("/config/backup_db")]
+fn backup_db(_token: AdminToken) -> EmptyResult {
+ backup_database()
+}
+
pub struct AdminToken {}
impl<'a, 'r> FromRequest<'a, 'r> for AdminToken {
diff --git a/src/db/mod.rs b/src/db/mod.rs
@@ -9,6 +9,11 @@ use rocket::http::Status;
use rocket::request::{self, FromRequest};
use rocket::{Outcome, Request, State};
+use std::process::Command;
+use chrono::prelude::*;
+use crate::error::Error;
+
+
use crate::CONFIG;
/// An alias to the database connection used
@@ -34,6 +39,21 @@ pub fn get_connection() -> Result<Connection, ConnectionError> {
Connection::establish(&CONFIG.database_url())
}
+/// Creates a back-up of the database using sqlite3
+pub fn backup_database() -> Result<(), Error> {
+ let now: DateTime<Utc> = Utc::now();
+ let file_date = String::from(now.format("%Y%m%d").to_string());
+ let backup_command: String = format!("{}{}{}", ".backup 'db_", file_date, ".sqlite3'");
+
+ Command::new("sqlite3")
+ .current_dir("./data")
+ .args(&["db.sqlite3", &backup_command])
+ .output()
+ .expect("Can't open database, sqlite3 is not available, make sure it's installed and available on the PATH");
+
+ Ok(())
+}
+
/// Attempts to retrieve a single connection from the managed database pool. If
/// no pool is currently managed, fails with an `InternalServerError` status. If
/// no connections are available, fails with a `ServiceUnavailable` status.
diff --git a/src/static/templates/admin/page.hbs b/src/static/templates/admin/page.hbs
@@ -154,6 +154,17 @@
{{/unless}}
{{/each}}
{{/each}}
+
+ </div>
+ </div>
+ <div class="card bg-light mb-3">
+ <div class="card-header"><button type="button" class="btn btn-link collapsed" data-toggle="collapse"
+ data-target="#g_database">Database</button></div>
+ <div id="g_database" class="card-body collapse" data-parent="#config-form">
+ <div class="small mb-3">
+ NOTE: A local installation of sqlite3 is required for this section to work.
+ </div>
+ <button type="button" class="btn btn-primary" onclick="backupDatabase();">Backup Database</button>
</div>
</div>
@@ -268,6 +279,12 @@
return false;
}
+ function backupDatabase() {
+ _post("/admin/config/backup_db",
+ "Backup created successfully",
+ "Error creating backup");
+ return false;
+ }
function masterCheck(check_id, inputs_query) {
function toggleEnabled(check_id, inputs_query, enabled) {
$(inputs_query).prop("disabled", !enabled)