Implement initial 'wdcli backup_instance' command

This commit performs an initial implementation of the 'backup_instance'
command.
This commit is contained in:
Tom Wiesing 2022-09-05 14:43:50 +02:00
parent a64c02cd78
commit 2a14d93d3c
No known key found for this signature in database
17 changed files with 437 additions and 135 deletions

View file

@ -4,6 +4,7 @@ import (
"errors"
"io"
"os"
"path/filepath"
)
var ErrCopySameFile = errors.New("src and dst must be different files")
@ -39,3 +40,70 @@ func CopyFile(dst, src string) error {
_, err = io.Copy(dstFile, srcFile)
return err
}
var ErrCopyNoDirectory = errors.New("dst is not a directory")
// CopyDirectory copies the directory src to dst recursively.
// The destination directory must exist, or an error is returned.
//
// onCopy, when not nil, is called for each file or directory being copied.
func CopyDirectory(dst, src string, onCopy func(dst, src string)) error {
// TODO: Allow copying in parallel? Maybe with a mutex?
// sanity checks
if src == dst {
return ErrCopySameFile
}
if !IsDirectory(dst) {
return ErrCopyNoDirectory
}
// call onCopy for this directory!
if onCopy != nil {
onCopy(dst, src)
}
// iterate over the entries or bail out
entries, err := os.ReadDir(src)
if err != nil {
return err
}
for _, entry := range entries {
name := entry.Name()
eDest := filepath.Join(dst, name)
eSrc := filepath.Join(src, name)
// it is not a directory => Use CopyFile
if !entry.IsDir() {
if onCopy != nil {
onCopy(eDest, eSrc)
}
// do the copy!
if err := CopyFile(eDest, eSrc); err != nil {
return err
}
continue
}
// find out the mode of the entry
eInfo, err := entry.Info()
if err != nil {
return err
}
// make the target directory
if err := os.Mkdir(eDest, eInfo.Mode()); err != nil {
return err
}
// do the copy!
if err := CopyDirectory(eDest, eSrc, onCopy); err != nil {
return err
}
}
return nil
}