Skip to content

Commit

Permalink
Upload overhaul (#400)
Browse files Browse the repository at this point in the history
* overhaul filebrowser upload

* uploaded file rows

* remove external filebrowser

* move log retention var to Config

* cleanup

* increase chunk size

* progress bar

* luanti image

* fix corrupt zip download

* fix mtui database restore

* update latest engine image version

* nav fix

* add backup/restore page stub

* backup/restore wip

* replace maintenance page with backup

---------

Co-authored-by: BuckarooBanzay <[email protected]>
  • Loading branch information
BuckarooBanzay and BuckarooBanzay authored Dec 18, 2024
1 parent 3fa60d8 commit 9698e8f
Show file tree
Hide file tree
Showing 17 changed files with 222 additions and 253 deletions.
12 changes: 11 additions & 1 deletion app/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,17 @@ func (a *App) DetachDatabase() error {
a.ModManager = nil
a.Mail = nil
a.Repos = nil
err := a.DB.Close()
gdb, err := a.G.DB()
if err != nil {
return fmt.Errorf("could not get gorm database: %v", err)
}

err = gdb.Close()
if err != nil {
return fmt.Errorf("could not close gorm database: %v", err)
}

err = a.DB.Close()
if err != nil {
return fmt.Errorf("could not close database: %v", err)
}
Expand Down
14 changes: 0 additions & 14 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ services:
SERVER_NAME: "dev-server"
DEFAULT_THEME: "darkly"
ENABLE_FEATURES: "shell,luashell,minetest_config,docker,modmanagement,signup,chat,minetest_web"
FILEBROWSER_URL: "http://filebrowser/"
INSTALL_MTUI_MOD: "true"
MINETEST_CONFIG: "/world/minetest.conf"
GEOIP_API: "https://hosting.minetest.ch/api/geoip"
Expand All @@ -40,21 +39,8 @@ services:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
working_dir: /app
command: ["go", "run", "."]

filebrowser:
image: filebrowser/filebrowser:v2.31.2
ports:
- 8081:80
environment:
FB_DATABASE: /database/filebrowser.db
FB_BASEURL: /filebrowser
FB_NOAUTH: "true"
volumes:
- world_dir:/srv
- filebrowser_db:/database

volumes:
go_cache: {}
go_dir: {}
world_dir: {}
filebrowser_db: {}
8 changes: 3 additions & 5 deletions jobs/log_cleanup.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,16 @@ package jobs
import (
"fmt"
"mtui/app"
"os"
"time"
)

func logCleanup(a *app.App) {
log_retention_str := os.Getenv("LOG_RETENTION")
log_retention := time.Hour * 24 * 7 // 7 days default log retention
if log_retention_str != "" {
if a.Config.LogRetention != "" {
var err error
log_retention, err = time.ParseDuration(log_retention_str)
log_retention, err = time.ParseDuration(a.Config.LogRetention)
if err != nil {
fmt.Printf("Log retention parsing of '%s' failed: %v, defaulting to 7 days\n", log_retention_str, err)
fmt.Printf("Log retention parsing of '%s' failed: %v, defaulting to 7 days\n", a.Config.LogRetention, err)
log_retention = time.Hour * 24 * 7
}
}
Expand Down
6 changes: 3 additions & 3 deletions public/js/components/NavBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,14 +169,14 @@ export default {
<i class="fa fa-photo-film"></i> Mediaserver
</router-link>
</li>
<li>
<li v-if="!maintenance">
<router-link to="/restart-conditions" class="dropdown-item">
<i class="fa fa-refresh"></i> Restart conditions
</router-link>
</li>
<li>
<router-link to="/maintenance" class="dropdown-item">
<i class="fa fa-wrench"></i> Maintenance
<router-link to="/backup" class="dropdown-item">
<i class="fa fa-upload"></i> Backup/Restore
</router-link>
</li>
</nav-dropdown>
Expand Down
127 changes: 127 additions & 0 deletions public/js/components/pages/administration/BackupRestore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import { get_maintenance, get_stats } from "../../../service/stats.js";
import { enable_maintenance, disable_maintenance } from "../../../api/maintenance.js";
import { engine } from "../../../service/service.js";
import { upload_chunked } from "../../../service/uploader.js";
import { unzip, remove } from "../../../api/filebrowser.js";

import DefaultLayout from "../../layouts/DefaultLayout.js";
import { START } from "../../Breadcrumb.js";

export default {
components: {
"default-layout": DefaultLayout
},
data: function() {
return {
breadcrumb: [START, {
name: "Backup/Restore",
icon: "upload",
link: "/backup"
}],
restore_active: false,
restore_message: "",
restore_progress: 0
};
},
computed: {
maintenance: get_maintenance,
is_engine_running: () => engine.is_running()
},
methods: {
enable_maintenance: async function() {
await enable_maintenance();
get_stats();
},
disable_maintenance: async function() {
await disable_maintenance();
window.location.reload();
},
restore: async function() {
const file = this.$refs.input_upload.files[0];
if (!file) {
return;
}

this.restore_message = "Starting to upload archive";
this.restore_active = true;

await upload_chunked("/", "restore.zip", file, progress => {
this.restore_progress = progress;
this.restore_message = `Uploading: ${Math.floor(progress*100)}% done`;
});

this.restore_message = "Unzipping archive...";
await unzip("/restore.zip");

this.restore_message = "Removing temporary archive";
await remove("/restore.zip");

this.restore_active = false;

await this.disable_maintenance();
}
},
template: /*html*/`
<default-layout title="Backup/Restore" icon="upload" :breadcrumb="breadcrumb">
<div class="row">
<div class="col-md-6">
<div class="card">
<div class="card-header">
Download backup <i class="fa fa-download"></i>
</div>
<div class="card-body">
<a class="btn btn-primary" href="api/filebrowser/zip?dir=/">
<i class="fa fa-file-zipper"></i>
Download world-backup as zip-file
</a>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">
Restore from backup <i class="fa fa-upload"></i>
</div>
<div class="card-body">
<div class="alert alert-info" v-if="!maintenance">
<i class="fa-solid fa-info"></i>
The maintenance mode must be enabled and all the services stopped to restore from a backup
</div>
<div class="alert alert-warning" v-if="is_engine_running && !maintenance">
<i class="fa-solid fa-triangle-exclamation"></i>
The <router-link to="/services/engine">minetest engine</router-link> is still running, please stop it to enable the maintenance mode
</div>
<div class="alert alert-warning" v-if="!is_engine_running && maintenance">
<i class="fa-solid fa-triangle-exclamation"></i>
<b>Warning:</b> All existing world-data will be overwritten by a backup-restore!
</div>
<div class="input-group" v-if="!restore_active">
<button class="btn btn-warning" v-if="!maintenance" v-on:click="enable_maintenance" :disabled="is_engine_running">
<i class="fa-solid fa-triangle-exclamation"></i>
Enable maintenance mode
</button>
<button class="btn btn-success" v-if="maintenance" v-on:click="disable_maintenance">
Disable maintenance mode
</button>
<input ref="input_upload" type="file" class="form-control" :disabled="!maintenance" accept=".zip"/>
<button class="btn btn-danger" v-on:click="restore" :disabled="!maintenance">
<i class="fa fa-file-zipper"></i>
Restore from zipfile backup
</button>
</div>
<div class="progress" v-if="restore_active">
<div class="progress-bar overflow-visible progress-bar-striped progress-bar-animated" v-bind:style="{ width: (restore_progress*100)+'%' }">
{{restore_message}}
</div>
</div>
</div>
</div>
</div>
</div>
</default-layout>
`
};
70 changes: 0 additions & 70 deletions public/js/components/pages/administration/Maintenance.js

This file was deleted.

44 changes: 24 additions & 20 deletions public/js/components/pages/administration/UISettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,26 +37,30 @@ export default {
template: /*html*/`
<default-layout icon="list-check" title="UI Settings" :breadcrumb="breadcrumb">
<table class="table table-striped" v-if="themes">
<tr>
<th>Setting</th>
<th>Value</th>
<th>Action</th>
</tr>
<tr>
<td>
Theme
</td>
<td>
<select class="form-control" v-model="current_theme">
<option v-for="theme in themes" :value="theme">{{theme}}</option>
</select>
</td>
<td>
<a class="btn btn-success w-100" v-on:click="set_config('theme', current_theme, true)">
<i class="fa fa-save"></i> Save
</a>
</td>
</tr>
<thead>
<tr>
<th>Setting</th>
<th>Value</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>
Theme
</td>
<td>
<select class="form-control" v-model="current_theme">
<option v-for="theme in themes" :value="theme">{{theme}}</option>
</select>
</td>
<td>
<a class="btn btn-success w-100" v-on:click="set_config('theme', current_theme, true)">
<i class="fa fa-save"></i> Save
</a>
</td>
</tr>
</tbody>
</table>
</default-layout>
`
Expand Down
Loading

0 comments on commit 9698e8f

Please sign in to comment.