'wdcli backup': Move to separate package
This commit is contained in:
parent
5cd5ae9be2
commit
822c70cd69
11 changed files with 493 additions and 380 deletions
43
internal/component/backup.go
Normal file
43
internal/component/backup.go
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
package component
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/tkw1536/goprogram/stream"
|
||||
)
|
||||
|
||||
// Backupable represents a component with a Backup method
|
||||
type Backupable interface {
|
||||
Component
|
||||
|
||||
// BackupName returns a new name to be used as an argument for path.
|
||||
BackupName() string
|
||||
|
||||
// Backup backs up this component into the destination path path
|
||||
Backup(context BackupContext) error
|
||||
}
|
||||
|
||||
// BackupContext is the context for backups
|
||||
type BackupContext interface {
|
||||
// IO returns the input output stream belonging to this backup file
|
||||
IO() stream.IOStream
|
||||
|
||||
// Name creates a new directory inside the destination.
|
||||
// Passing the empty path creates the destination as a directory.
|
||||
//
|
||||
// It then allows op to fill the file.
|
||||
AddDirectory(path string, op func() error) error
|
||||
|
||||
// CopyFile copies a file from source to dst.
|
||||
CopyFile(dest, src string) error
|
||||
|
||||
// AddFile creates a new file at the provided path inside the destination.
|
||||
// Passing the empty path creates the destination as a file.
|
||||
//
|
||||
// It then allows op to write to the file.
|
||||
//
|
||||
// The op function must not retain file.
|
||||
// The underlying file does not need to be closed.
|
||||
// AddFile will not return before op has returned.
|
||||
AddFile(path string, op func(file io.Writer) error) error
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@ package component
|
|||
|
||||
import (
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/config"
|
||||
"github.com/tkw1536/goprogram/stream"
|
||||
)
|
||||
|
||||
// Component represents a logical subsystem of the distillery.
|
||||
|
|
@ -46,20 +45,6 @@ type Installable interface {
|
|||
Context(parent InstallationContext) InstallationContext
|
||||
}
|
||||
|
||||
// Backupable represents a component with a Backup method
|
||||
type Backupable interface {
|
||||
Component
|
||||
|
||||
// BackupName returns a new name to be used as an argument for path.
|
||||
BackupName() string
|
||||
|
||||
// Backup backs up this component into the destination path path.
|
||||
//
|
||||
// The destination path may be a folder or directory, depending on the component.
|
||||
// The destination path does not need to exist.
|
||||
Backup(io stream.IOStream, path string) error
|
||||
}
|
||||
|
||||
// ComponentBase implements base functionality for a component
|
||||
type ComponentBase struct {
|
||||
Dir string // Dir is the directory this component lives in
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
package control
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/pkg/fsx"
|
||||
"github.com/tkw1536/goprogram/stream"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component"
|
||||
)
|
||||
|
||||
func (*Control) BackupName() string {
|
||||
|
|
@ -14,27 +11,18 @@ func (*Control) BackupName() string {
|
|||
}
|
||||
|
||||
// Backup backups all control plane configuration files into dest
|
||||
func (control *Control) Backup(io stream.IOStream, dest string) error {
|
||||
// create the destination directory, TODO: outsource this
|
||||
if err := os.Mkdir(dest, fs.ModeDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
func (control *Control) Backup(context component.BackupContext) error {
|
||||
files := control.backupFiles()
|
||||
for _, src := range files {
|
||||
dst := filepath.Join(dest, filepath.Base(src)) // destination path
|
||||
|
||||
// if the src file does not exist, don't copy it!
|
||||
if !fsx.IsFile(src) { // TODO: log this somewhere
|
||||
continue
|
||||
return context.AddDirectory("", func() error {
|
||||
for _, src := range files {
|
||||
name := filepath.Base(src)
|
||||
if err := context.CopyFile(name, src); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := fsx.CopyFile(dst, src); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// backupfiles lists the files to be backed up.
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ package sql
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"io"
|
||||
|
||||
"github.com/tkw1536/goprogram/stream"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component"
|
||||
)
|
||||
|
||||
var errSQLBackup = errors.New("SQLBackup: Mysqldump returned non-zero exit code")
|
||||
|
|
@ -14,22 +14,17 @@ func (*SQL) BackupName() string {
|
|||
}
|
||||
|
||||
// Backup makes a backup of all SQL databases into the path dest.
|
||||
func (sql *SQL) Backup(io stream.IOStream, dest string) error {
|
||||
// open the file, TODO: Outsource this to context
|
||||
writer, err := os.Create(dest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer writer.Close()
|
||||
func (sql *SQL) Backup(context component.BackupContext) error {
|
||||
return context.AddFile("", func(file io.Writer) error {
|
||||
io := context.IO().Streams(file, nil, nil, 0).NonInteractive()
|
||||
code, err := sql.Stack().Exec(io, "sql", "mysqldump", "--all-databases")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if code != 0 {
|
||||
return errSQLBackup
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
// run sqldump
|
||||
io = io.Streams(writer, nil, nil, 0).NonInteractive()
|
||||
code, err := sql.Stack().Exec(io, "sql", "mysqldump", "--all-databases")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if code != 0 {
|
||||
return errSQLBackup
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,48 +2,34 @@ package triplestore
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"io"
|
||||
|
||||
"github.com/tkw1536/goprogram/stream"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/component"
|
||||
)
|
||||
|
||||
func (ts *Triplestore) BackupName() string { return "triplestore" }
|
||||
|
||||
// Backup makes a backup of all Triplestore repositories databases into the path dest.
|
||||
func (ts *Triplestore) Backup(io stream.IOStream, dest string) error {
|
||||
func (ts *Triplestore) Backup(context component.BackupContext) error {
|
||||
|
||||
// list all the repositories
|
||||
// list all the directories
|
||||
repos, err := ts.listRepositories()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// create the base directory, todo: outsource this
|
||||
if err := os.Mkdir(dest, fs.ModeDir); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// iterate over all the repositories
|
||||
for _, repo := range repos {
|
||||
if rErr := (func(repo Repository) error {
|
||||
name := filepath.Join(dest, repo.ID+".nq")
|
||||
|
||||
// todo: outsource this
|
||||
dest, err := os.Create(name)
|
||||
if err != nil {
|
||||
// then backup each file separatly
|
||||
return context.AddDirectory("", func() error {
|
||||
for _, repo := range repos {
|
||||
if err := context.AddFile(repo.ID+".nq", func(file io.Writer) error {
|
||||
_, err := ts.Snapshot(file, repo.ID)
|
||||
return err
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
defer dest.Close()
|
||||
|
||||
_, err = ts.Snapshot(dest, repo.ID)
|
||||
return err
|
||||
}(repo)); err == nil && rErr != nil {
|
||||
err = rErr
|
||||
}
|
||||
}
|
||||
return err
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (ts Triplestore) listRepositories() (repos []Repository, err error) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue