Files
URBM/internal/model/model.go
T
2026-06-14 23:12:39 +02:00

198 lines
6.7 KiB
Go

package model
import "time"
const SchemaVersion = 1
type JobType string
const (
JobShare JobType = "share"
JobAppdata JobType = "appdata"
JobDocker JobType = "docker"
JobVM JobType = "vm"
JobFlash JobType = "flash"
)
type RepositoryType string
const (
RepositoryLocal RepositoryType = "local"
RepositorySMB RepositoryType = "smb"
RepositoryNFS RepositoryType = "nfs"
RepositorySFTP RepositoryType = "sftp"
)
type Config struct {
SchemaVersion int `json:"schemaVersion"`
Jobs []Job `json:"jobs"`
Repositories []Repository `json:"repositories"`
Notifications []NotificationTarget `json:"notifications"`
Settings Settings `json:"settings"`
}
type Settings struct {
ResticPath string `json:"resticPath"`
RestoreRoot string `json:"restoreRoot"`
PersistentLogDir string `json:"persistentLogDir,omitempty"`
ShowLiveLog bool `json:"showLiveLog"`
CatchUpWindowHrs int `json:"catchUpWindowHours"`
CheckCron string `json:"checkCron"`
PruneCron string `json:"pruneCron"`
}
type Job struct {
SchemaVersion int `json:"schemaVersion"`
ID string `json:"id"`
Name string `json:"name"`
Type JobType `json:"type"`
Enabled bool `json:"enabled"`
RepositoryID string `json:"repositoryId"`
Sources []Source `json:"sources"`
Schedule Schedule `json:"schedule"`
Consistency Consistency `json:"consistency"`
Compression string `json:"compression"`
Excludes []string `json:"excludes,omitempty"`
Tags []string `json:"tags,omitempty"`
Retention Retention `json:"retention"`
NotifyOn []string `json:"notifyOn,omitempty"`
ShutdownSecs int `json:"shutdownTimeoutSeconds"`
}
type Source struct {
Path string `json:"path,omitempty"`
WorkloadID string `json:"workloadId,omitempty"`
Metadata map[string]string `json:"metadata,omitempty"`
}
type Schedule struct {
Cron string `json:"cron"`
Timezone string `json:"timezone,omitempty"`
}
type Consistency struct {
Mode string `json:"mode"`
}
type Retention struct {
KeepWithinDays int `json:"keepWithinDays,omitempty"`
Daily int `json:"daily"`
Weekly int `json:"weekly"`
Monthly int `json:"monthly"`
}
type Repository struct {
SchemaVersion int `json:"schemaVersion"`
ID string `json:"id"`
Name string `json:"name"`
Type RepositoryType `json:"type"`
Location string `json:"location"`
PasswordRef string `json:"passwordRef"`
CredentialRef string `json:"credentialRef,omitempty"`
Mount *MountConfig `json:"mount,omitempty"`
Options map[string]string `json:"options,omitempty"`
}
type MountConfig struct {
Managed bool `json:"managed"`
Remote string `json:"remote,omitempty"`
MountPoint string `json:"mountPoint,omitempty"`
ReadOnly bool `json:"readOnly,omitempty"`
}
type NotificationTarget struct {
SchemaVersion int `json:"schemaVersion"`
ID string `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
Enabled bool `json:"enabled"`
URL string `json:"url,omitempty"`
Topic string `json:"topic,omitempty"`
TokenRef string `json:"tokenRef,omitempty"`
Events []string `json:"events,omitempty"`
}
type Run struct {
SchemaVersion int `json:"schemaVersion"`
ID string `json:"id"`
JobID string `json:"jobId,omitempty"`
TaskType string `json:"taskType"`
Status string `json:"status"`
Priority int `json:"priority"`
CreatedAt time.Time `json:"createdAt"`
StartedAt *time.Time `json:"startedAt,omitempty"`
FinishedAt *time.Time `json:"finishedAt,omitempty"`
SnapshotID string `json:"snapshotId,omitempty"`
Message string `json:"message,omitempty"`
ErrorCode string `json:"errorCode,omitempty"`
BytesAdded int64 `json:"bytesAdded,omitempty"`
FilesNew int64 `json:"filesNew,omitempty"`
FilesChanged int64 `json:"filesChanged,omitempty"`
BytesProcessed int64 `json:"bytesProcessed,omitempty"`
FilesProcessed int64 `json:"filesProcessed,omitempty"`
ProgressPercent float64 `json:"progressPercent,omitempty"`
ProgressBytes int64 `json:"progressBytes,omitempty"`
ProgressTotal int64 `json:"progressTotal,omitempty"`
ProgressFiles int64 `json:"progressFiles,omitempty"`
ProgressFileTotal int64 `json:"progressFileTotal,omitempty"`
BytesPerSecond float64 `json:"bytesPerSecond,omitempty"`
SecondsRemaining int64 `json:"secondsRemaining,omitempty"`
CurrentFile string `json:"currentFile,omitempty"`
LiveLog []string `json:"liveLog,omitempty"`
}
type RestoreTask struct {
SchemaVersion int `json:"schemaVersion"`
ID string `json:"id"`
RepositoryID string `json:"repositoryId"`
SnapshotID string `json:"snapshotId"`
Includes []string `json:"includes"`
Target string `json:"target"`
InPlace bool `json:"inPlace"`
Confirmed bool `json:"confirmed"`
}
type Snapshot struct {
ID string `json:"id"`
ShortID string `json:"short_id"`
Time time.Time `json:"time"`
Hostname string `json:"hostname"`
Paths []string `json:"paths"`
Tags []string `json:"tags"`
}
func DefaultConfig() Config {
return Config{
SchemaVersion: SchemaVersion,
Jobs: []Job{},
Repositories: []Repository{},
Notifications: []NotificationTarget{{SchemaVersion: SchemaVersion, ID: "unraid", Name: "Unraid", Type: "unraid", Enabled: true, Events: []string{"success", "warning", "failed"}}},
Settings: Settings{
ResticPath: "/usr/local/libexec/urbm/restic",
RestoreRoot: "/mnt/user/urbm-restores",
CatchUpWindowHrs: 24,
CheckCron: "0 3 1 * *",
PruneCron: "0 4 * * 0",
},
}
}
func NormalizeConfig(c Config) Config {
notifications := make([]NotificationTarget, 0, len(c.Notifications)+1)
hasUnraid := false
for _, target := range c.Notifications {
if target.Type == "ntfy" {
continue
}
if target.Type == "unraid" {
hasUnraid = true
}
notifications = append(notifications, target)
}
if !hasUnraid {
notifications = append(notifications, NotificationTarget{SchemaVersion: SchemaVersion, ID: "unraid", Name: "Unraid", Type: "unraid", Enabled: true, Events: []string{"success", "warning", "failed"}})
}
c.Notifications = notifications
return c
}