forked from tuna/tunasync
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/dev'
- Loading branch information
Showing
4 changed files
with
158 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package worker | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/dennwc/btrfs" | ||
) | ||
|
||
type btrfsSnapshotHook struct { | ||
provider mirrorProvider | ||
mirrorSnapshotPath string | ||
} | ||
|
||
// the user who runs the jobs (typically `tunasync`) should be granted the permission to run btrfs commands | ||
// TODO: check if the filesystem is Btrfs | ||
func newBtrfsSnapshotHook(provider mirrorProvider, snapshotPath string, mirror mirrorConfig) *btrfsSnapshotHook { | ||
mirrorSnapshotPath := mirror.SnapshotPath | ||
if mirrorSnapshotPath == "" { | ||
mirrorSnapshotPath = filepath.Join(snapshotPath, provider.Name()) | ||
} | ||
return &btrfsSnapshotHook{ | ||
provider: provider, | ||
mirrorSnapshotPath: mirrorSnapshotPath, | ||
} | ||
} | ||
|
||
// check if path `snapshotPath/providerName` exists | ||
// Case 1: Not exists => create a new subvolume | ||
// Case 2: Exists as a subvolume => nothing to do | ||
// Case 3: Exists as a directory => error detected | ||
func (h *btrfsSnapshotHook) preJob() error { | ||
path := h.provider.WorkingDir() | ||
if _, err := os.Stat(path); os.IsNotExist(err) { | ||
// create subvolume | ||
err := btrfs.CreateSubVolume(path) | ||
if err != nil { | ||
logger.Errorf("failed to create Btrfs subvolume %s: %s", path, err.Error()) | ||
return err | ||
} | ||
logger.Noticef("created new Btrfs subvolume %s", path) | ||
} else { | ||
if is, err := btrfs.IsSubVolume(path); err != nil { | ||
return err | ||
} else if !is { | ||
return fmt.Errorf("path %s exists but isn't a Btrfs subvolume", path) | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func (h *btrfsSnapshotHook) preExec() error { | ||
return nil | ||
} | ||
|
||
func (h *btrfsSnapshotHook) postExec() error { | ||
return nil | ||
} | ||
|
||
// delete old snapshot if exists, then create a new snapshot | ||
func (h *btrfsSnapshotHook) postSuccess() error { | ||
if _, err := os.Stat(h.mirrorSnapshotPath); !os.IsNotExist(err) { | ||
isSubVol, err := btrfs.IsSubVolume(h.mirrorSnapshotPath) | ||
if err != nil { | ||
return err | ||
} else if !isSubVol { | ||
return fmt.Errorf("path %s exists and isn't a Btrfs snapshot", h.mirrorSnapshotPath) | ||
} | ||
// is old snapshot => delete it | ||
if err := btrfs.DeleteSubVolume(h.mirrorSnapshotPath); err != nil { | ||
logger.Errorf("failed to delete old Btrfs snapshot %s", h.mirrorSnapshotPath) | ||
return err | ||
} | ||
logger.Noticef("deleted old snapshot %s", h.mirrorSnapshotPath) | ||
} | ||
// create a new writable snapshot | ||
// (the snapshot is writable so that it can be deleted easily) | ||
if err := btrfs.SnapshotSubVolume(h.provider.WorkingDir(), h.mirrorSnapshotPath, false); err != nil { | ||
logger.Errorf("failed to create new Btrfs snapshot %s", h.mirrorSnapshotPath) | ||
return err | ||
} | ||
logger.Noticef("created new Btrfs snapshot %s", h.mirrorSnapshotPath) | ||
return nil | ||
} | ||
|
||
// keep the old snapshot => nothing to do | ||
func (h *btrfsSnapshotHook) postFail() error { | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters