243 lines
8.6 KiB
Go
243 lines
8.6 KiB
Go
package model
|
|
|
|
import (
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
const SchemaVersion = 1
|
|
|
|
type JobType string
|
|
|
|
const (
|
|
JobShare JobType = "share"
|
|
JobAppdata JobType = "appdata"
|
|
JobDocker JobType = "docker"
|
|
JobVM JobType = "vm"
|
|
JobFlash JobType = "flash"
|
|
JobRsync JobType = "rsync"
|
|
)
|
|
|
|
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"`
|
|
RsyncPath string `json:"rsyncPath"`
|
|
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"`
|
|
CPUCores int `json:"cpuCores,omitempty"`
|
|
ReadConcurrency int `json:"readConcurrency,omitempty"`
|
|
Excludes []string `json:"excludes,omitempty"`
|
|
Tags []string `json:"tags,omitempty"`
|
|
FlashImage bool `json:"flashImage,omitempty"`
|
|
Retention Retention `json:"retention"`
|
|
NotifyOn []string `json:"notifyOn,omitempty"`
|
|
ShutdownSecs int `json:"shutdownTimeoutSeconds"`
|
|
Rsync RsyncOptions `json:"rsync,omitempty"`
|
|
}
|
|
|
|
type RsyncOptions struct {
|
|
Target string `json:"target"`
|
|
Overwrite bool `json:"overwrite"`
|
|
Delete bool `json:"delete"`
|
|
PreservePermissions bool `json:"preservePermissions"`
|
|
PreserveOwner bool `json:"preserveOwner"`
|
|
PreserveGroup bool `json:"preserveGroup"`
|
|
PreserveTimes bool `json:"preserveTimes"`
|
|
PreserveLinks bool `json:"preserveLinks"`
|
|
PreserveACLs bool `json:"preserveAcls"`
|
|
PreserveXattrs bool `json:"preserveXattrs"`
|
|
Checksum bool `json:"checksum"`
|
|
DryRun bool `json:"dryRun"`
|
|
SkipSpaceCheck bool `json:"skipSpaceCheck"`
|
|
}
|
|
|
|
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"`
|
|
RetentionBefore int `json:"retentionBefore,omitempty"`
|
|
RetentionAfter int `json:"retentionAfter,omitempty"`
|
|
RetentionRemoved int `json:"retentionRemoved,omitempty"`
|
|
RepositoryBefore int64 `json:"repositoryBefore,omitempty"`
|
|
RepositoryAfter int64 `json:"repositoryAfter,omitempty"`
|
|
RepositoryFreed int64 `json:"repositoryFreed,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"`
|
|
Restore *RestoreTask `json:"restore,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"`
|
|
}
|
|
|
|
type RepositoryStats struct {
|
|
RepositoryID string `json:"repositoryId"`
|
|
RepositoryName string `json:"repositoryName"`
|
|
StoredBytes int64 `json:"storedBytes"`
|
|
FileCount int64 `json:"fileCount"`
|
|
SnapshotCount int `json:"snapshotCount"`
|
|
Error string `json:"error,omitempty"`
|
|
}
|
|
|
|
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",
|
|
RsyncPath: "/usr/bin/rsync",
|
|
RestoreRoot: "/mnt/user/urbm-restores",
|
|
CatchUpWindowHrs: 24,
|
|
CheckCron: "0 3 1 * *",
|
|
PruneCron: "0 4 * * 0",
|
|
},
|
|
}
|
|
}
|
|
|
|
func NormalizeConfig(c Config) Config {
|
|
if strings.TrimSpace(c.Settings.RsyncPath) == "" {
|
|
c.Settings.RsyncPath = "/usr/bin/rsync"
|
|
}
|
|
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
|
|
}
|