v0.4.6: MariaDB validation fix + dashboard deployed-only + protected stack restart

- Fix ValidateDump() to scan first 10 lines for header (MariaDB 11.4+ sandbox comment)
- Dashboard shows only deployed/protected stacks, heading "Telepített alkalmazások"
- Protected stacks show restart button when operational (both dashboard + stacks page)
- API blocks all actions except restart on protected stacks
- docker-setup.sh creates .felhom.yml for FileBrowser (subdomain: files)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-16 08:44:34 +01:00
parent 24a2150520
commit fd627f3d55
6 changed files with 72 additions and 11 deletions
+6
View File
@@ -207,6 +207,12 @@ func (r *Router) deployStack(w http.ResponseWriter, req *http.Request, name stri
func (r *Router) actionStack(w http.ResponseWriter, action, name string) {
r.logger.Printf("[API] %s requested for stack: %s", action, name)
// Protected stacks only allow restart — block all other actions
if r.cfg.IsProtectedStack(name) && action != "restart" {
writeJSON(w, http.StatusForbidden, apiResponse{OK: false, Error: fmt.Sprintf("cannot %s protected stack %s", action, name)})
return
}
var err error
switch action {
case "start":
+29 -9
View File
@@ -264,18 +264,38 @@ func ValidateDump(filePath string, dbType DBType) DumpValidation {
}
v.TableCount = tableCount
// Basic header check
switch dbType {
case DBTypePostgres:
if !strings.HasPrefix(content, "--") {
v.Error = "PostgreSQL dump missing comment header"
return v
// Header check — scan first 10 lines for expected dump header
// MariaDB 11.4+ prepends a sandbox comment before the header line
headerFound := false
lines := strings.SplitN(content, "\n", 11) // at most 11 parts = 10 lines
for i, line := range lines {
if i >= 10 {
break
}
case DBTypeMariaDB:
if !strings.HasPrefix(content, "-- ") {
switch dbType {
case DBTypeMariaDB:
if strings.HasPrefix(line, "-- MariaDB dump") ||
strings.HasPrefix(line, "-- MySQL dump") ||
strings.HasPrefix(line, "-- mysqldump") {
headerFound = true
}
case DBTypePostgres:
if strings.HasPrefix(line, "-- PostgreSQL database dump") {
headerFound = true
}
}
if headerFound {
break
}
}
if !headerFound {
switch dbType {
case DBTypeMariaDB:
v.Error = "MariaDB dump missing comment header"
return v
case DBTypePostgres:
v.Error = "PostgreSQL dump missing comment header"
}
return v
}
if tableCount == 0 {
+9 -1
View File
@@ -36,10 +36,18 @@ func (s *Server) dashboardHandler(w http.ResponseWriter, _ *http.Request) {
}
}
// Filter to deployed + protected stacks only for dashboard display
var deployedStacks []stacks.Stack
for _, st := range stackList {
if st.Deployed || st.Protected {
deployedStacks = append(deployedStacks, st)
}
}
sysInfo := system.GetInfo(s.cfg.Paths.HDDPath, s.cpuCollector)
data := s.baseData("dashboard", "Vezérlőpult")
data["Stacks"] = stackList
data["Stacks"] = deployedStacks
data["RunningCount"] = running
data["StoppedCount"] = stopped
data["TotalCount"] = len(stackList)
@@ -120,7 +120,7 @@
</div>
{{end}}
<h3>Alkalmazások állapota</h3>
<h3>Telepített alkalmazások</h3>
<div class="stack-list">
{{range .Stacks}}
@@ -139,6 +139,9 @@
{{if .Protected}}
<span class="badge badge-protected">Védett</span>
{{if isOperational .State}}
<button class="btn btn-sm btn-warning" onclick="stackAction('{{.Name}}', 'restart')"></button>
{{end}}
{{else if not .Deployed}}
<a href="/stacks/{{.Name}}/deploy" class="btn btn-sm btn-primary" onclick="return checkBeforeDeploy(event, '{{.Name}}')">Telepítés</a>
{{else}}
@@ -59,6 +59,9 @@
<div class="stack-detail-actions">
{{if .Protected}}
<span class="badge badge-protected">Védett rendszerkomponens</span>
{{if isOperational .State}}
<button class="btn btn-warning" onclick="stackAction('{{.Name}}', 'restart')">Újraindítás</button>
{{end}}
{{else if not .Deployed}}
<a href="/stacks/{{.Name}}/deploy" class="btn btn-primary" onclick="return checkBeforeDeploy(event, '{{.Name}}')">Telepítés</a>
<a href="{{appPageURL .Meta.Slug}}" class="btn btn-outline">Részletek</a>
+21
View File
@@ -1323,6 +1323,27 @@ networks:
external: true
EOF
# Create .felhom.yml metadata
cat > "${FILEBROWSER_DIR}/.felhom.yml" << 'METAEOF'
display_name: Filebrowser
slug: filebrowser
description: Fájlkezelő a külső merevlemezhez
subdomain: files
category: storage
app_info:
tagline: Web-alapú fájlkezelő a külső merevlemezhez
use_cases:
- Fájlok böngészése és letöltése a külső HDD-ről
- Médiafájlok megosztása családtagokkal
- Dokumentumok feltöltése és kezelése
first_steps:
- Nyisd meg a files.DOMAIN címet a böngészőben
- Jelentkezz be az admin fiókkal
- Tallózd a /srv mappákat
prerequisites:
- Külső HDD csatlakoztatva és felcsatolva
METAEOF
# Create .env file
cat > "${FILEBROWSER_DIR}/.env" << ENVEOF
# FileBrowser environment — generated by docker-setup.sh