64 lines
1.9 KiB
Go
64 lines
1.9 KiB
Go
package app
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
|
|
"gitea.maximumdirect.net/eric/narratio/internal/artifacts"
|
|
"gitea.maximumdirect.net/eric/narratio/internal/fileops"
|
|
)
|
|
|
|
type restoreMarker struct {
|
|
StartedAt time.Time `json:"started_at"`
|
|
}
|
|
|
|
func writeRestoreMarker(paths artifacts.SessionPaths) error {
|
|
marker := restoreMarker{StartedAt: nowUTC()}
|
|
data, err := json.Marshal(marker)
|
|
if err != nil {
|
|
return fmt.Errorf("encode recovery marker: %w", err)
|
|
}
|
|
if err := fileops.WriteFileAtomic(paths.RestoreMarkerPath, data, fileops.WorkspaceFileMode); err != nil {
|
|
return fmt.Errorf("write recovery marker: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func clearRestoreMarker(paths artifacts.SessionPaths) error {
|
|
if strings.TrimSpace(paths.RestoreMarkerPath) == "" {
|
|
return fmt.Errorf("recovery marker path is required")
|
|
}
|
|
if err := os.Remove(paths.RestoreMarkerPath); err != nil && !os.IsNotExist(err) {
|
|
return fmt.Errorf("remove recovery marker: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func requireCompleteRestore(paths artifacts.SessionPaths) error {
|
|
if strings.TrimSpace(paths.RestoreMarkerPath) == "" {
|
|
return fmt.Errorf("restore recovery marker path is required")
|
|
}
|
|
info, err := os.Lstat(paths.RestoreMarkerPath)
|
|
if os.IsNotExist(err) {
|
|
return nil
|
|
}
|
|
if err != nil {
|
|
return fmt.Errorf("check restore recovery marker: %w", err)
|
|
}
|
|
if !info.Mode().IsRegular() {
|
|
return fmt.Errorf("restore recovery marker is not a regular file; rerun session restore")
|
|
}
|
|
data, err := os.ReadFile(paths.RestoreMarkerPath)
|
|
if err != nil {
|
|
return fmt.Errorf("read restore recovery marker: %w", err)
|
|
}
|
|
var marker restoreMarker
|
|
if err := json.Unmarshal(data, &marker); err != nil || marker.StartedAt.IsZero() {
|
|
return fmt.Errorf("restore recovery marker is invalid; rerun session restore")
|
|
}
|
|
return fmt.Errorf("restore is incomplete; rerun session restore before running pipeline stages")
|
|
}
|