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"` 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"` BytesProcessed int64 `json:"bytesProcessed,omitempty"` FilesProcessed int64 `json:"filesProcessed,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/backupper/restic", RestoreRoot: "/mnt/user/backupper-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 }