Added 'keep hosting settings' option for db import

This commit is contained in:
CasVT
2024-03-03 13:06:49 +01:00
parent a65676ffb7
commit f7decf4b4e
6 changed files with 76 additions and 17 deletions

View File

@@ -425,16 +425,21 @@ def revert_db_import(
return
def import_db(new_db_file: str) -> None:
def import_db(
new_db_file: str,
copy_hosting_settings: bool
) -> None:
"""Replace the current database with a new one.
Args:
new_db_file (str): The path to the new database file.
copy_hosting_settings (bool): Keep the hosting settings from the current
database.
Raises:
InvalidDatabaseFile: The new database file is invalid or unsupported.
"""
logging.info(f'Importing new database')
logging.info(f'Importing new database; {copy_hosting_settings=}')
try:
cursor = Connection(new_db_file, timeout=20.0).cursor()
@@ -446,15 +451,13 @@ def import_db(new_db_file: str) -> None:
except (OperationalError, InvalidDatabaseFile):
logging.error('Uploaded database is not a MIND database file')
cursor.connection.close()
revert_db_import(
swap=False,
imported_db_file=new_db_file
)
raise InvalidDatabaseFile
finally:
cursor.connection.close()
if database_version > __DATABASE_VERSION__:
logging.error('Uploaded database is higher version than this MIND installation can support')
revert_db_import(
@@ -463,6 +466,28 @@ def import_db(new_db_file: str) -> None:
)
raise InvalidDatabaseFile
if copy_hosting_settings:
hosting_settings = get_db().execute("""
SELECT key, value, value
FROM config
WHERE key = 'host'
OR key = 'port'
OR key = 'url_prefix'
LIMIT 3;
"""
)
cursor.executemany("""
INSERT INTO config(key, value)
VALUES (?, ?)
ON CONFLICT(key) DO
UPDATE
SET value = ?;
""",
hosting_settings
)
cursor.connection.commit()
cursor.connection.close()
move(
DBConnection.file,
join(dirname(DBConnection.file), __DATEBASE_NAME_ORIGINAL__)

View File

@@ -29,7 +29,7 @@ from backend.server import SERVER
from backend.settings import (backup_hosting_settings, get_admin_settings,
get_setting, set_setting)
from backend.users import Users
from frontend.input_validation import (AllowNewAccountsVariable, ColorVariable,
from frontend.input_validation import (AllowNewAccountsVariable, ColorVariable, CopyHostingSettingsVariable,
DatabaseFileVariable,
EditNotificationServicesVariable,
EditTimeVariable, EditTitleVariable,
@@ -792,7 +792,7 @@ def api_admin_user(inputs: Dict[str, Any], u_id: int):
description="Download the database file"
),
post=Method(
vars=[DatabaseFileVariable],
vars=[DatabaseFileVariable, CopyHostingSettingsVariable],
description="Upload and apply a database file"
)
),
@@ -822,5 +822,5 @@ def api_admin_database(inputs: Dict[str, Any]):
), 200
elif request.method == "POST":
import_db(inputs['file'])
import_db(inputs['file'], inputs['copy_hosting_settings'])
return return_api({})

View File

@@ -426,6 +426,19 @@ class DatabaseFileVariable(BaseInputVariable):
return False
class CopyHostingSettingsVariable(BaseInputVariable):
name = 'copy_hosting_settings'
description = 'Copy the hosting settings from the current database'
source = DataSource.VALUES
def validate(self) -> bool:
if not self.value in ('true', 'false'):
return False
self.value = self.value == 'true'
return True
def input_validation() -> Union[None, Dict[str, Any]]:
"""Checks, extracts and transforms inputs

View File

@@ -234,8 +234,15 @@ h2 {
padding: .25rem;
}
#upload-database-form {
display: flex;
flex-direction: column;
align-items: center;
gap: 1rem;
}
#hosting-form > p,
#upload-database-form p {
#upload-database-form > p {
max-width: 50rem;
margin-inline: auto;
text-align: center;

View File

@@ -19,6 +19,7 @@ const user_inputs = {
const import_inputs = {
file: document.querySelector('#database-file-input'),
copy_hosting: document.querySelector('#copy-hosting-input'),
button: document.querySelector('#upload-db-button')
};
@@ -226,9 +227,10 @@ function loadUsers() {
function upload_database() {
import_inputs.button.innerText = 'Importing';
const copy_hosting = import_inputs.copy_hosting.checked ? 'true' : 'false';
const formData = new FormData();
formData.append('file', import_inputs.file.files[0]);
fetch(`${url_prefix}/api/admin/database?api_key=${api_key}`, {
fetch(`${url_prefix}/api/admin/database?api_key=${api_key}&copy_hosting_settings=${copy_hosting}`, {
method: 'POST',
body: formData
})

View File

@@ -83,14 +83,14 @@
<td><label for="host-input">Host</label></td>
<td>
<input type="text" id="host-input" required>
<p>Valid IPv4 address (default is '0.0.0.0' for all available interfaces)</p>
<p>Valid IPv4 address (default is '0.0.0.0' for all available interfaces).</p>
</td>
</tr>
<tr>
<td><label for="port-input">Port</label></td>
<td>
<input type="number" id="port-input" min="1" max="65535" required>
<p>The port used to access the web UI (default is '8080')</p>
<p>The port used to access the web UI (default is '8080').</p>
</td>
</tr>
<tr>
@@ -156,14 +156,26 @@
<button id="download-db-button">Download Database</button>
</div>
<form id="upload-database-form">
<div class="database-container">
<input type="file" id="database-file-input" required>
<button type="submit" id="upload-db-button">Import Database</button>
<div class="settings-table-container">
<table class="settings-table">
<tbody>
<tr>
<td><label for="database-file-input">Database File</label></td>
<td><input type="file" id="database-file-input" required></td>
</tr>
<tr>
<td><label for="copy-hosting-input">Keep Hosting Settings</label></td>
<td>
<input type="checkbox" id="copy-hosting-input">
<p>Keep the current hosting settings instead of using the settings in the uploaded database.</p>
</td>
</tr>
</tbody>
</table>
</div>
<button type="submit" id="upload-db-button">Import Database</button>
<p>Restore a backup.</p>
<br>
<p>Note: The uploaded file can be denied if it is not a valid database file, is too old or is for a newer version than this MIND instance.</p>
<br>
<p>IMPORTANT: After uploading the backup, it is required to log into the admin panel within 1 minute (60 seconds) in order to keep the new database file. Otherwise, MIND will revert the upload and go back to the old database.</p>
</form>
<h2>Power</h2>