Compare commits
5 Commits
feature/ba
...
9eb0e0fcbf
| Author | SHA1 | Date | |
|---|---|---|---|
| 9eb0e0fcbf | |||
| 90a4264691 | |||
| a94ba0d8a0 | |||
| 7253c64c78 | |||
| b074b8fe47 |
@@ -6,8 +6,9 @@ services:
|
|||||||
- "8080:8080"
|
- "8080:8080"
|
||||||
volumes:
|
volumes:
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
- upaas-data:/var/lib/upaas
|
- ${HOST_DATA_DIR:-./data}:/var/lib/upaas
|
||||||
# environment:
|
environment:
|
||||||
|
- UPAAS_HOST_DATA_DIR=${HOST_DATA_DIR:-./data}
|
||||||
# Optional: uncomment to enable debug logging
|
# Optional: uncomment to enable debug logging
|
||||||
# - DEBUG=true
|
# - DEBUG=true
|
||||||
# Optional: Sentry error reporting
|
# Optional: Sentry error reporting
|
||||||
@@ -15,6 +16,3 @@ services:
|
|||||||
# Optional: Prometheus metrics auth
|
# Optional: Prometheus metrics auth
|
||||||
# - METRICS_USERNAME=prometheus
|
# - METRICS_USERNAME=prometheus
|
||||||
# - METRICS_PASSWORD=secret
|
# - METRICS_PASSWORD=secret
|
||||||
|
|
||||||
volumes:
|
|
||||||
upaas-data:
|
|
||||||
|
|||||||
@@ -113,9 +113,9 @@ func (d *Database) applyMigration(ctx context.Context, filename string) error {
|
|||||||
return fmt.Errorf("failed to record migration: %w", err)
|
return fmt.Errorf("failed to record migration: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
commitErr := transaction.Commit()
|
err = transaction.Commit()
|
||||||
if commitErr != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to commit migration: %w", commitErr)
|
return fmt.Errorf("failed to commit migration: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ func (h *Handlers) HandleAppCreate() http.HandlerFunc { //nolint:funlen // valid
|
|||||||
nameErr := validateAppName(name)
|
nameErr := validateAppName(name)
|
||||||
if nameErr != nil {
|
if nameErr != nil {
|
||||||
data["Error"] = "Invalid app name: " + nameErr.Error()
|
data["Error"] = "Invalid app name: " + nameErr.Error()
|
||||||
_ = tmpl.ExecuteTemplate(writer, "app_new.html", data)
|
h.renderTemplate(writer, tmpl, "app_new.html", data)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -228,7 +228,7 @@ func (h *Handlers) HandleAppUpdate() http.HandlerFunc { //nolint:funlen // valid
|
|||||||
"App": application,
|
"App": application,
|
||||||
"Error": "Invalid app name: " + nameErr.Error(),
|
"Error": "Invalid app name: " + nameErr.Error(),
|
||||||
}, request)
|
}, request)
|
||||||
_ = tmpl.ExecuteTemplate(writer, "app_edit.html", data)
|
h.renderTemplate(writer, tmpl, "app_edit.html", data)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -239,7 +239,7 @@ func (h *Handlers) HandleAppUpdate() http.HandlerFunc { //nolint:funlen // valid
|
|||||||
"App": application,
|
"App": application,
|
||||||
"Error": "Invalid repository URL: " + repoURLErr.Error(),
|
"Error": "Invalid repository URL: " + repoURLErr.Error(),
|
||||||
}, request)
|
}, request)
|
||||||
_ = tmpl.ExecuteTemplate(writer, "app_edit.html", data)
|
h.renderTemplate(writer, tmpl, "app_edit.html", data)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.eeqj.de/sneak/upaas/internal/database"
|
"git.eeqj.de/sneak/upaas/internal/database"
|
||||||
@@ -76,7 +77,11 @@ func (d *Deployment) Reload(ctx context.Context) error {
|
|||||||
return d.scan(row)
|
return d.scan(row)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// maxLogSize is the maximum size of deployment logs stored in the database (1MB).
|
||||||
|
const maxLogSize = 1 << 20
|
||||||
|
|
||||||
// AppendLog appends a log line to the deployment logs.
|
// AppendLog appends a log line to the deployment logs.
|
||||||
|
// If the total log size exceeds maxLogSize, the oldest lines are truncated.
|
||||||
func (d *Deployment) AppendLog(ctx context.Context, line string) error {
|
func (d *Deployment) AppendLog(ctx context.Context, line string) error {
|
||||||
var currentLogs string
|
var currentLogs string
|
||||||
|
|
||||||
@@ -84,7 +89,22 @@ func (d *Deployment) AppendLog(ctx context.Context, line string) error {
|
|||||||
currentLogs = d.Logs.String
|
currentLogs = d.Logs.String
|
||||||
}
|
}
|
||||||
|
|
||||||
d.Logs = sql.NullString{String: currentLogs + line + "\n", Valid: true}
|
newLogs := currentLogs + line + "\n"
|
||||||
|
|
||||||
|
if len(newLogs) > maxLogSize {
|
||||||
|
// Keep the most recent logs that fit within the limit.
|
||||||
|
// Find a newline after the truncation point to avoid partial lines.
|
||||||
|
truncateAt := len(newLogs) - maxLogSize
|
||||||
|
idx := strings.Index(newLogs[truncateAt:], "\n")
|
||||||
|
|
||||||
|
if idx >= 0 {
|
||||||
|
newLogs = "[earlier logs truncated]\n" + newLogs[truncateAt+idx+1:]
|
||||||
|
} else {
|
||||||
|
newLogs = "[earlier logs truncated]\n" + newLogs[truncateAt:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Logs = sql.NullString{String: newLogs, Valid: true}
|
||||||
|
|
||||||
return d.Save(ctx)
|
return d.Save(ctx)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -251,8 +251,8 @@ func New(lc fx.Lifecycle, params ServiceParams) (*Service, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetBuildDir returns the build directory path for an app.
|
// GetBuildDir returns the build directory path for an app.
|
||||||
func (svc *Service) GetBuildDir(appID string) string {
|
func (svc *Service) GetBuildDir(appName string) string {
|
||||||
return filepath.Join(svc.config.DataDir, "builds", appID)
|
return filepath.Join(svc.config.DataDir, "builds", appName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLogFilePath returns the path to the log file for a deployment.
|
// GetLogFilePath returns the path to the log file for a deployment.
|
||||||
|
|||||||
Reference in New Issue
Block a user