internal/backup/backup_service.go
Rama main · réplica de lectura del repositorio original.
package backup
import (
"archive/tar"
"compress/gzip"
"errors"
"io"
"os"
"path/filepath"
"time"
)
type BackupService struct{}
func (backupService BackupService) CreateSnapshotBundle(bundlePath string, includedPaths []string) (SnapshotBundle, error) {
if len(includedPaths) == 0 {
return SnapshotBundle{}, errors.New("included paths are required")
}
bundleFile, errorValue := os.Create(bundlePath)
if errorValue != nil {
return SnapshotBundle{}, errorValue
}
defer bundleFile.Close()
gzipWriter := gzip.NewWriter(bundleFile)
defer gzipWriter.Close()
tarWriter := tar.NewWriter(gzipWriter)
defer tarWriter.Close()
for _, includedPath := range includedPaths {
errorValue = addPathToTar(tarWriter, includedPath)
if errorValue != nil {
return SnapshotBundle{}, errorValue
}
}
return SnapshotBundle{
BundlePath: bundlePath,
IncludedPaths: includedPaths,
CreatedAt: time.Now(),
}, nil
}
func (backupService BackupService) VerifySnapshotBundle(bundlePath string) error {
bundleFile, errorValue := os.Open(bundlePath)
if errorValue != nil {
return errorValue
}
defer bundleFile.Close()
gzipReader, errorValue := gzip.NewReader(bundleFile)
if errorValue != nil {
return errorValue
}
defer gzipReader.Close()
tarReader := tar.NewReader(gzipReader)
_, errorValue = tarReader.Next()
return errorValue
}
func addPathToTar(tarWriter *tar.Writer, includedPath string) error {
fileInfo, errorValue := os.Stat(includedPath)
if errorValue != nil {
return errorValue
}
if fileInfo.IsDir() {
return filepath.Walk(includedPath, func(path string, information os.FileInfo, walkError error) error {
if walkError != nil || information.IsDir() {
return walkError
}
return addFileToTar(tarWriter, includedPath, path, information)
})
}
return addFileToTar(tarWriter, filepath.Dir(includedPath), includedPath, fileInfo)
}
func addFileToTar(tarWriter *tar.Writer, rootPath string, filePath string, fileInfo os.FileInfo) error {
file, errorValue := os.Open(filePath)
if errorValue != nil {
return errorValue
}
defer file.Close()
header, errorValue := tar.FileInfoHeader(fileInfo, "")
if errorValue != nil {
return errorValue
}
relativePath, errorValue := filepath.Rel(rootPath, filePath)
if errorValue != nil {
return errorValue
}
header.Name = filepath.ToSlash(relativePath)
errorValue = tarWriter.WriteHeader(header)
if errorValue != nil {
return errorValue
}
_, errorValue = io.Copy(tarWriter, file)
return errorValue
}