Merge pull request #475 from TheMardy/master

Create Backup funcitonality
This commit is contained in:
Daniel García 2019-06-01 23:29:58 +02:00 committed by GitHub
commit 9ed2ba61c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 1 deletions

View File

@ -9,7 +9,7 @@ use rocket_contrib::json::Json;
use crate::api::{ApiResult, EmptyResult, JsonResult}; use crate::api::{ApiResult, EmptyResult, JsonResult};
use crate::auth::{decode_admin, encode_jwt, generate_admin_claims, ClientIp}; use crate::auth::{decode_admin, encode_jwt, generate_admin_claims, ClientIp};
use crate::config::ConfigBuilder; use crate::config::ConfigBuilder;
use crate::db::{models::*, DbConn}; use crate::db::{models::*, DbConn, backup_database};
use crate::error::Error; use crate::error::Error;
use crate::mail; use crate::mail;
use crate::CONFIG; use crate::CONFIG;
@ -30,6 +30,7 @@ pub fn routes() -> Vec<Route> {
update_revision_users, update_revision_users,
post_config, post_config,
delete_config, delete_config,
backup_db,
] ]
} }
@ -204,6 +205,11 @@ fn delete_config(_token: AdminToken) -> EmptyResult {
CONFIG.delete_user_config() CONFIG.delete_user_config()
} }
#[post("/config/backup_db")]
fn backup_db(_token: AdminToken) -> EmptyResult {
backup_database()
}
pub struct AdminToken {} pub struct AdminToken {}
impl<'a, 'r> FromRequest<'a, 'r> for AdminToken { impl<'a, 'r> FromRequest<'a, 'r> for AdminToken {

View File

@ -9,6 +9,11 @@ use rocket::http::Status;
use rocket::request::{self, FromRequest}; use rocket::request::{self, FromRequest};
use rocket::{Outcome, Request, State}; use rocket::{Outcome, Request, State};
use std::process::Command;
use chrono::prelude::*;
use crate::error::Error;
use crate::CONFIG; use crate::CONFIG;
/// An alias to the database connection used /// An alias to the database connection used
@ -34,6 +39,21 @@ pub fn get_connection() -> Result<Connection, ConnectionError> {
Connection::establish(&CONFIG.database_url()) 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 /// Attempts to retrieve a single connection from the managed database pool. If
/// no pool is currently managed, fails with an `InternalServerError` status. If /// no pool is currently managed, fails with an `InternalServerError` status. If
/// no connections are available, fails with a `ServiceUnavailable` status. /// no connections are available, fails with a `ServiceUnavailable` status.

View File

@ -154,6 +154,17 @@
{{/unless}} {{/unless}}
{{/each}} {{/each}}
{{/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>
</div> </div>
@ -268,6 +279,12 @@
return false; return false;
} }
function backupDatabase() {
_post("/admin/config/backup_db",
"Backup created successfully",
"Error creating backup");
return false;
}
function masterCheck(check_id, inputs_query) { function masterCheck(check_id, inputs_query) {
function toggleEnabled(check_id, inputs_query, enabled) { function toggleEnabled(check_id, inputs_query, enabled) {
$(inputs_query).prop("disabled", !enabled) $(inputs_query).prop("disabled", !enabled)