Commit 828dee6d authored by ale's avatar ale
Browse files

Small refactor of internal restic cache access API

parent 00724aff
Pipeline #24127 passed with stages
in 2 minutes and 55 seconds
......@@ -19,6 +19,28 @@ import (
"github.com/hashicorp/go-version"
)
// We need to check that we're running at least restic 0.9, or the
// restore functionality won't work as expected.
var (
resticVersionRx = regexp.MustCompile(`^restic ([0-9.]+)`)
resticMinGoodVersion = version.Must(version.NewVersion("0.9"))
resticRepositoryFileVersion = version.Must(version.NewVersion("0.11"))
resticFixedIssue3104Version = version.Must(version.NewVersion("0.12"))
)
func getResticVersion(bin string) (*version.Version, error) {
output, err := exec.Command(bin, "version").Output() // #nosec
if err != nil {
return nil, err
}
m := resticVersionRx.FindStringSubmatch(string(output))
if len(m) < 2 {
return nil, errors.New("could not parse restic version")
}
return version.NewVersion(m[1])
}
type resticRepository struct {
bin string
version *version.Version
......@@ -62,28 +84,6 @@ func (r *resticRepository) excludeArgs() string {
return strings.Join(args, " ")
}
// We need to check that we're running at least restic 0.9, or the
// restore functionality won't work as expected.
var (
resticVersionRx = regexp.MustCompile(`^restic ([0-9.]+)`)
resticMinGoodVersion = version.Must(version.NewVersion("0.9"))
resticRepositoryFileVersion = version.Must(version.NewVersion("0.11"))
resticFixedIssue3104Version = version.Must(version.NewVersion("0.12"))
)
func getResticVersion(bin string) (*version.Version, error) {
output, err := exec.Command(bin, "version").Output() // #nosec
if err != nil {
return nil, err
}
m := resticVersionRx.FindStringSubmatch(string(output))
if len(m) < 2 {
return nil, errors.New("could not parse restic version")
}
return version.NewVersion(m[1])
}
// newResticRepository returns a restic repository.
func newResticRepository(params Params) (Repository, error) {
uri := params.Get("uri")
......@@ -291,71 +291,65 @@ func (r *resticRepository) restoreStreamCmd(ctx context.Context, cc cache, shell
), nil
}
func (r *resticRepository) RunBackup(ctx context.Context, shell *Shell, backup *Backup, ds *Dataset, inputFile string, exclude []string) error {
cc, err := r.cacheMgr.Acquire()
func withCache(mgr cacheManager, fn func(cache) error) error {
cc, err := mgr.Acquire()
if err != nil {
return err
}
defer r.cacheMgr.Release(cc)
defer mgr.Release(cc)
cmd := r.backupCmd(cc, backup, ds, inputFile, exclude)
return r.runBackupCmd(ctx, shell, backup, ds, cmd)
return fn(cc)
}
func (r *resticRepository) RunStreamBackup(ctx context.Context, shell *Shell, backup *Backup, ds *Dataset, backupCmd, compressCmd string) error {
cc, err := r.cacheMgr.Acquire()
if err != nil {
return err
}
defer r.cacheMgr.Release(cc)
func (r *resticRepository) RunBackup(ctx context.Context, shell *Shell, backup *Backup, ds *Dataset, inputFile string, exclude []string) error {
return withCache(r.cacheMgr, func(cc cache) error {
cmd := r.backupCmd(cc, backup, ds, inputFile, exclude)
return r.runBackupCmd(ctx, shell, backup, ds, cmd)
})
}
// Concatenate the backupCmd with restic (and an optional
// compression command) to build a shell pipeline.
pipe := []string{
fmt.Sprintf("(%s)", expandVars(backupCmd, backup, ds)),
}
if compressCmd != "" {
pipe = append(pipe, compressCmd)
}
pipe = append(pipe, r.backupStreamCmd(cc, backup, ds))
func (r *resticRepository) RunStreamBackup(ctx context.Context, shell *Shell, backup *Backup, ds *Dataset, backupCmd, compressCmd string) error {
return withCache(r.cacheMgr, func(cc cache) error {
// Concatenate the backupCmd with restic (and an optional
// compression command) to build a shell pipeline.
pipe := []string{
fmt.Sprintf("(%s)", expandVars(backupCmd, backup, ds)),
}
if compressCmd != "" {
pipe = append(pipe, compressCmd)
}
pipe = append(pipe, r.backupStreamCmd(cc, backup, ds))
cmd := strings.Join(pipe, " | ")
return r.runBackupCmd(ctx, shell, backup, ds, cmd)
cmd := strings.Join(pipe, " | ")
return r.runBackupCmd(ctx, shell, backup, ds, cmd)
})
}
func (r *resticRepository) RunRestore(ctx context.Context, shell *Shell, backup *Backup, ds *Dataset, paths []string, target string) error {
cc, err := r.cacheMgr.Acquire()
if err != nil {
return err
}
defer r.cacheMgr.Release(cc)
cmd, err := r.restoreCmd(ctx, cc, shell, backup, ds, paths, target)
if err != nil {
return err
}
return shell.Run(ctx, cmd)
return withCache(r.cacheMgr, func(cc cache) error {
cmd, err := r.restoreCmd(ctx, cc, shell, backup, ds, paths, target)
if err != nil {
return err
}
return shell.Run(ctx, cmd)
})
}
func (r *resticRepository) RunStreamRestore(ctx context.Context, shell *Shell, backup *Backup, ds *Dataset, restoreCmd, decompressCmd string) error {
cc, err := r.cacheMgr.Acquire()
if err != nil {
return err
}
defer r.cacheMgr.Release(cc)
resticCmd, err := r.restoreStreamCmd(ctx, cc, shell, backup, ds, getWorkDir(ctx))
if err != nil {
return err
}
return withCache(r.cacheMgr, func(cc cache) error {
resticCmd, err := r.restoreStreamCmd(ctx, cc, shell, backup, ds, getWorkDir(ctx))
if err != nil {
return err
}
pipe := []string{resticCmd}
if decompressCmd != "" {
pipe = append(pipe, decompressCmd)
}
pipe = append(pipe, fmt.Sprintf("(%s)", expandVars(restoreCmd, backup, ds)))
cmd := strings.Join(pipe, " | ")
return shell.Run(ctx, cmd)
pipe := []string{resticCmd}
if decompressCmd != "" {
pipe = append(pipe, decompressCmd)
}
pipe = append(pipe, fmt.Sprintf("(%s)", expandVars(restoreCmd, backup, ds)))
cmd := strings.Join(pipe, " | ")
return shell.Run(ctx, cmd)
})
}
// Global map that keeps track of the currently running restic
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment