{backup,snapshot}: Rename common code to export

This commit is contained in:
Tom Wiesing 2022-10-07 22:12:14 +02:00
parent b3a827e042
commit bf57c0d5a6
No known key found for this signature in database
14 changed files with 145 additions and 133 deletions

View file

@ -4,6 +4,7 @@ import (
"io"
"path/filepath"
"github.com/FAU-CDI/wisski-distillery/internal/component/instances"
"github.com/FAU-CDI/wisski-distillery/internal/models"
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
"github.com/FAU-CDI/wisski-distillery/pkg/logging"
@ -12,43 +13,66 @@ import (
"github.com/tkw1536/goprogram/stream"
)
type SnapshotFlags struct {
Dest string
Slug string
Title string // "Backup" or "Snapshot"
// ExportTask describes a task that makes either a [Backup] or a [Snapshot].
// See [Manager.MakeExport]
type ExportTask struct {
// Dest is the destination path to write the backup to.
// When empty, this is created automatically in the staging or archive directory.
Dest string
// By default, a .tar.gz file is generated.
// To generated an unpacked directory, set [StagingOnly] to true.
StagingOnly bool
Do func(dest string) SnapshotLike
// Instance is the instance to generate a snapshot of.
// To generate a backup, leave this to be nil.
Instance *instances.WissKI
// BackupDescriptions and SnapshotDescriptions further specitfy options for the export.
// The Dest parameter is ignored, and updated automatically.
BackupDescription BackupDescription
SnapshotDescription SnapshotDescription
}
type SnapshotLike interface {
LogEntry() models.Snapshot
// export is implemented by [Backup] and [Snapshot]
type export interface {
LogEntry() models.Export
Report(w io.Writer) (int, error)
}
func (manager *Manager) HandleSnapshotLike(context stream.IOStream, flags SnapshotFlags) (err error) {
// MakeExport performs an export task as described by flags.
// Output is directed to the provided io.
func (manager *Manager) MakeExport(io stream.IOStream, task ExportTask) (err error) {
// extract parameters
Title := "Backup"
Slug := ""
if task.Instance != nil {
Title = "Snapshot"
Slug = task.Instance.Slug
}
// determine target paths
logging.LogMessage(context, "Determining target paths")
logging.LogMessage(io, "Determining target paths")
var stagingDir, archivePath string
if flags.StagingOnly {
stagingDir = flags.Dest
if task.StagingOnly {
stagingDir = task.Dest
} else {
archivePath = flags.Dest
archivePath = task.Dest
}
if stagingDir == "" {
stagingDir, err = manager.NewStagingDir(flags.Slug)
stagingDir, err = manager.NewStagingDir(Slug)
if err != nil {
return err
}
}
if !flags.StagingOnly && archivePath == "" {
archivePath = manager.NewArchivePath(flags.Slug)
if !task.StagingOnly && archivePath == "" {
archivePath = manager.NewArchivePath(Slug)
}
context.Printf("Staging Directory: %s\n", stagingDir)
context.Printf("Archive Path: %s\n", archivePath)
io.Printf("Staging Directory: %s\n", stagingDir)
io.Printf("Archive Path: %s\n", archivePath)
// create the staging directory
logging.LogMessage(context, "Creating staging directory")
logging.LogMessage(io, "Creating staging directory")
err = manager.Environment.Mkdir(stagingDir, environment.DefaultDirPerm)
if !environment.IsExist(err) && err != nil {
return err
@ -56,9 +80,9 @@ func (manager *Manager) HandleSnapshotLike(context stream.IOStream, flags Snapsh
// if it was requested to not do staging only
// we need the staging directory to be deleted at the end
if !flags.StagingOnly {
if !task.StagingOnly {
defer func() {
logging.LogMessage(context, "Removing staging directory")
logging.LogMessage(io, "Removing staging directory")
manager.Environment.RemoveAll(stagingDir)
}()
}
@ -66,17 +90,25 @@ func (manager *Manager) HandleSnapshotLike(context stream.IOStream, flags Snapsh
// create the actual snapshot or backup
// write out the report
// and retain a log entry
var entry models.Snapshot
var entry models.Export
logging.LogOperation(func() error {
// do the snapshot!
sl := flags.Do(stagingDir)
var sl export
if task.Instance == nil {
task.BackupDescription.Dest = stagingDir
backup := manager.NewBackup(io, task.BackupDescription)
sl = &backup
} else {
task.SnapshotDescription.Dest = stagingDir
snapshot := manager.NewSnapshot(*task.Instance, io, task.SnapshotDescription)
sl = &snapshot
}
// create a log entry
entry = sl.LogEntry()
// find the report path
reportPath := filepath.Join(stagingDir, "report.txt")
context.Println(reportPath)
io.Println(reportPath)
// create the path
report, err := manager.Environment.Create(reportPath, environment.DefaultFilePerm)
@ -89,28 +121,28 @@ func (manager *Manager) HandleSnapshotLike(context stream.IOStream, flags Snapsh
_, err := sl.Report(report)
return err
}
}, context, "Generating %s", flags.Title)
}, io, "Generating %s", Title)
// if we only requested staging
// all that is left is to write the log entry
if flags.StagingOnly {
logging.LogMessage(context, "Writing Log Entry")
if task.StagingOnly {
logging.LogMessage(io, "Writing Log Entry")
// write out the log entry
entry.Path = stagingDir
entry.Packed = false
manager.Instances.AddSnapshotLog(entry)
manager.Instances.AddToExportLog(entry)
context.Printf("Wrote %s\n", stagingDir)
io.Printf("Wrote %s\n", stagingDir)
return nil
}
// package everything up as an archive!
if err := logging.LogOperation(func() error {
var count int64
defer func() { context.Printf("Wrote %d byte(s) to %s\n", count, archivePath) }()
defer func() { io.Printf("Wrote %d byte(s) to %s\n", count, archivePath) }()
st := status.NewWithCompat(context.Stdout, 1)
st := status.NewWithCompat(io.Stdout, 1)
st.Start()
defer st.Stop()
@ -119,15 +151,15 @@ func (manager *Manager) HandleSnapshotLike(context stream.IOStream, flags Snapsh
})
return err
}, context, "Writing archive"); err != nil {
}, io, "Writing archive"); err != nil {
return err
}
// write out the log entry
logging.LogMessage(context, "Writing Log Entry")
logging.LogMessage(io, "Writing Log Entry")
entry.Path = archivePath
entry.Packed = true
manager.Instances.AddSnapshotLog(entry)
manager.Instances.AddToExportLog(entry)
// and we're done!
return nil