aboutsummaryrefslogtreecommitdiff
path: root/snap/fs.go
diff options
context:
space:
mode:
Diffstat (limited to 'snap/fs.go')
-rw-r--r--snap/fs.go82
1 files changed, 67 insertions, 15 deletions
diff --git a/snap/fs.go b/snap/fs.go
index d0dc83d..b1cf513 100644
--- a/snap/fs.go
+++ b/snap/fs.go
@@ -5,6 +5,7 @@ import (
"path/filepath"
"os"
"sort"
+ "io"
)
type Snapshot struct {
@@ -36,6 +37,19 @@ func getZFSRoot(reference string) string {
return cursor
}
+func (snap * Snapshot) tryReference(reference string) {
+ if _, err := os.Stat(reference); err != nil {
+
+ if !os.IsNotExist(err) {
+ die.Fatalf("Error encountered while attempting to read reference file in snapshot:\n%v", err)
+ }
+
+ snap.Reference = ""
+ } else {
+ snap.Reference = reference
+ }
+}
+
func getSnapshots(reference string) []*Snapshot {
zfsRoot := getZFSRoot(reference)
@@ -43,15 +57,16 @@ func getSnapshots(reference string) []*Snapshot {
files, err := os.ReadDir(snapshotDir)
if err != nil {
- die.Fatalf("Could not find the snapshots directory inside %s", snapshotDir);
+ die.Fatalf("Could not find the snapshots directory inside \"%s\"", snapshotDir);
}
relPath, err := filepath.Rel(zfsRoot, reference)
if err != nil {
- die.Fatal("Could not find relative path to reference file: %v", err)
+ die.Fatalf("Could not find relative path to reference file: %v", err)
}
- snaps := make([]*Snapshot, len(files))
+ n_snaps := len(files) + 1
+ snaps := make([]*Snapshot, n_snaps)
for i, file := range files {
@@ -68,16 +83,17 @@ func getSnapshots(reference string) []*Snapshot {
pathInSnap := filepath.Join(snapshotDir, name, relPath)
- if _, err := os.Stat(pathInSnap); err != nil {
- if !os.IsNotExist(err) {
- die.Fatalf("Error encountered while attempting to read reference file in snapshot:\n%v", err)
- }
- } else {
- snaps[i].Reference = pathInSnap
- }
+ snaps[i].tryReference(pathInSnap)
+ }
+
+ snaps[n_snaps - 1] = &Snapshot {
+ ModTime: time.Now(),
+ Name: "@",
}
+ snaps[n_snaps - 1].tryReference(reference)
+
return snaps
}
@@ -97,6 +113,18 @@ func GetTimeseries(reference string) []*Snapshot {
return snaps
}
+func referenceMap(snapTs []*Snapshot) []int {
+ var trimmed []int
+
+ for i, snap := range snapTs {
+ if snap.Reference != "" {
+ trimmed = append(trimmed, i)
+ }
+ }
+
+ return trimmed
+}
+
func buildNameMap(snapTs []*Snapshot) map[string] int {
namemap := make(map[string] int)
@@ -123,15 +151,25 @@ func GetOracle(reference string) *SnapshotOracle {
}
}
-func (oracle *SnapshotOracle) ResolveRelative(ref *Relative) string {
+func (oracle *SnapshotOracle) PathTo(ref *Relative) string {
n_ts := len(oracle.timeseries)
- wanted := n_ts - 1
+ nthRef := referenceMap(oracle.timeseries)
- if ref.snapshot != "" {
+ if len(nthRef) == 0 {
+ die.Fatalf("The reference file is not contained in any snapshot.")
+ }
+
+ var wanted int
+ switch (ref.snapshot) {
+ case "@":
+ wanted = nthRef[len(nthRef) - 1]
+ case "%":
+ wanted = nthRef[0]
+ default:
id, ok := oracle.namemap[ref.snapshot]
if !ok {
- die.Fatal("Could not find the snapshot %s", ref.snapshot)
+ die.Fatalf("Could not find the snapshot \"%s\"", ref.snapshot)
}
wanted = id
@@ -144,4 +182,18 @@ func (oracle *SnapshotOracle) ResolveRelative(ref *Relative) string {
}
return oracle.timeseries[wanted].Reference
-} \ No newline at end of file
+}
+
+func (oracle *SnapshotOracle) ReadAll(ref *Relative) string {
+ path := oracle.PathTo(ref)
+
+ file, err := os.Open(path)
+
+ data, err := io.ReadAll(file)
+
+ if err != nil {
+ die.Fatalf("Can't read snapshot.\n%v", err)
+ }
+
+ return string(data)
+}