-
Notifications
You must be signed in to change notification settings - Fork 0
/
snaps.go
127 lines (110 loc) · 2.84 KB
/
snaps.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package main
import (
"context"
"flag"
"fmt"
"os"
"strconv"
"time"
"github.com/peterbourgon/ff/v3/ffcli"
"github.com/jtolio/jam/manifest"
"github.com/jtolio/jam/session"
)
var (
snapsFlags = flag.NewFlagSet("", flag.ExitOnError)
snapsFlagsBrief = snapsFlags.Bool("b", false, "if set, just list snap timestamps only (brief)")
cmdSnaps = &ffcli.Command{
Name: "snaps",
ShortHelp: "lists snapshots",
ShortUsage: fmt.Sprintf("%s [opts] snaps", os.Args[0]),
FlagSet: snapsFlags,
Exec: Snaps,
}
cmdUnsnap = &ffcli.Command{
Name: "unsnap",
ShortHelp: "unsnap removes an old snap",
ShortUsage: fmt.Sprintf("%s [opts] unsnap <snapid>", os.Args[0]),
Exec: Unsnap,
}
cmdRevertTo = &ffcli.Command{
Name: "revert-to",
ShortHelp: "revert-to makes a new snapshot that matches an older one",
ShortUsage: fmt.Sprintf("%s [opts] revert-to <snapid>", os.Args[0]),
Exec: RevertTo,
}
)
func Snaps(ctx context.Context, args []string) error {
if len(args) != 0 {
return flag.ErrHelp
}
mgr, _, _, mgrClose, err := getManager(ctx)
if err != nil {
return err
}
defer mgrClose()
return mgr.ListSnapshots(ctx, func(ctx context.Context, timestamp time.Time) error {
if *snapsFlagsBrief {
fmt.Printf("%v: %v\n", timestamp.UnixNano(), timestamp.Local().Format("2006-01-02 03:04:05 pm"))
return nil
}
snapshot, err := mgr.OpenSnapshot(ctx, timestamp)
if err != nil {
return err
}
defer snapshot.Close()
var fileCount int64
var byteCount int64
err = snapshot.List(ctx, "", true, func(ctx context.Context, entry *session.ListEntry) error {
fileCount++
if entry.Prefix || entry.Meta.Type != manifest.Metadata_FILE {
return nil
}
s, err := entry.Stream(ctx)
if err != nil {
return err
}
byteCount += s.Length()
return s.Close()
})
if err != nil {
return err
}
fmt.Printf("%v: %v (%d files, %s)\n", timestamp.UnixNano(), timestamp.Local().Format("2006-01-02 03:04:05 pm"), fileCount, byteFmt(byteCount))
return nil
})
}
func Unsnap(ctx context.Context, args []string) error {
if len(args) != 1 {
return flag.ErrHelp
}
mgr, _, _, mgrClose, err := getManager(ctx)
if err != nil {
return err
}
defer mgrClose()
nano, err := strconv.ParseInt(args[0], 10, 64)
if err != nil {
return fmt.Errorf("invalid snapshot value: %q", args[0])
}
return mgr.DeleteSnapshot(ctx, time.Unix(0, nano))
}
func RevertTo(ctx context.Context, args []string) error {
if len(args) != 1 {
return flag.ErrHelp
}
mgr, _, _, mgrClose, err := getManager(ctx)
if err != nil {
return err
}
defer mgrClose()
nano, err := strconv.ParseInt(args[0], 10, 64)
if err != nil {
return fmt.Errorf("invalid snapshot value: %q", args[0])
}
sess, err := mgr.RevertTo(ctx, time.Unix(0, nano))
if err != nil {
return err
}
defer sess.Close()
return sess.Commit(ctx)
}