package cli import ( "archive/tar" "bufio" "bytes" "compress/gzip" "context" "errors" "fmt" "io" "os" "os/exec" "os/user" "path/filepath" "strconv" "strings" "time" agecrypt "filippo.io/age" "filippo.io/age/agessh" "github.com/spf13/cobra" "gitea.mynodes.xyz/ilker/llmgw/internal/config" "gitea.mynodes.xyz/ilker/llmgw/internal/store" "gitea.mynodes.xyz/ilker/llmgw/internal/version" ) // restore is `llmgw server restore`: an archive `server backup` wrote, put // back on this machine. type restore struct { archive string identities []string etcDir string storeAddr string // overrides the restored server.yaml's dryRun bool force bool // service is the unit stopped before and started after; "" touches no // service, for tests and machines without systemd. service string out io.Writer now func() time.Time } func newRestoreCmd() *cobra.Command { rs := restore{etcDir: "/etc/llmgw", service: "llmgw-server", now: time.Now} c := &cobra.Command{ Use: "restore ARCHIVE", Short: "Put a backup back: /etc/llmgw and the store, on this machine", Long: "Reads an archive `llmgw server backup` wrote — opening an encrypted one\n" + "with --identity, an age identity file or an SSH private key — and checks\n" + "it before anything is touched: that it is whole, that this llmgw is not\n" + "older than the one that wrote it, and where the store goes. --dry-run\n" + "stops there and says what it would do.\n\n" + "Then: the server is stopped, /etc/llmgw is moved aside to\n" + "/etc/llmgw.before-restore-