github.com/yasker/longhorn-engine@v0.0.0-20160621014712-6ed6cfca0729/app/snapshot.go (about) 1 package app 2 3 import ( 4 "fmt" 5 "os" 6 "strings" 7 "text/tabwriter" 8 9 "github.com/Sirupsen/logrus" 10 "github.com/codegangsta/cli" 11 "github.com/rancher/longhorn/sync" 12 "github.com/rancher/longhorn/util" 13 ) 14 15 func SnapshotCmd() cli.Command { 16 return cli.Command{ 17 Name: "snapshots", 18 ShortName: "snapshot", 19 Subcommands: []cli.Command{ 20 SnapshotCreateCmd(), 21 SnapshotRevertCmd(), 22 SnapshotLsCmd(), 23 SnapshotRmCmd(), 24 }, 25 Action: func(c *cli.Context) { 26 if err := lsSnapshot(c); err != nil { 27 logrus.Fatalf("Error running snapshot command: %v", err) 28 } 29 }, 30 } 31 } 32 33 func SnapshotCreateCmd() cli.Command { 34 return cli.Command{ 35 Name: "create", 36 Action: func(c *cli.Context) { 37 if err := createSnapshot(c); err != nil { 38 logrus.Fatalf("Error running create snapshot command: %v", err) 39 } 40 }, 41 } 42 } 43 44 func SnapshotRevertCmd() cli.Command { 45 return cli.Command{ 46 Name: "revert", 47 Action: func(c *cli.Context) { 48 if err := revertSnapshot(c); err != nil { 49 logrus.Fatalf("Error running revert snapshot command: %v", err) 50 } 51 }, 52 } 53 } 54 55 func SnapshotRmCmd() cli.Command { 56 return cli.Command{ 57 Name: "rm", 58 Action: func(c *cli.Context) { 59 if err := rmSnapshot(c); err != nil { 60 logrus.Fatalf("Error running rm snapshot command: %v", err) 61 } 62 }, 63 } 64 } 65 66 func SnapshotLsCmd() cli.Command { 67 return cli.Command{ 68 Name: "ls", 69 Action: func(c *cli.Context) { 70 if err := lsSnapshot(c); err != nil { 71 logrus.Fatalf("Error running ls snapshot command: %v", err) 72 } 73 }, 74 } 75 } 76 77 func createSnapshot(c *cli.Context) error { 78 cli := getCli(c) 79 80 var name string 81 if len(c.Args()) > 0 { 82 name = c.Args()[0] 83 } 84 id, err := cli.Snapshot(name) 85 if err != nil { 86 return err 87 } 88 89 fmt.Println(id) 90 return nil 91 } 92 93 func revertSnapshot(c *cli.Context) error { 94 cli := getCli(c) 95 96 name := c.Args()[0] 97 if name == "" { 98 return fmt.Errorf("Missing parameter for snapshot") 99 } 100 101 err := cli.RevertSnapshot(name) 102 if err != nil { 103 return err 104 } 105 106 return nil 107 } 108 109 func rmSnapshot(c *cli.Context) error { 110 var lastErr error 111 url := c.GlobalString("url") 112 task := sync.NewTask(url) 113 114 for _, name := range c.Args() { 115 if err := task.DeleteSnapshot(name); err == nil { 116 fmt.Printf("deleted %s\n", name) 117 } else { 118 lastErr = err 119 fmt.Fprintf(os.Stderr, "Failed to delete %s: %v\n", name, err) 120 } 121 } 122 123 return lastErr 124 } 125 126 func lsSnapshot(c *cli.Context) error { 127 cli := getCli(c) 128 129 replicas, err := cli.ListReplicas() 130 if err != nil { 131 return err 132 } 133 134 first := true 135 snapshots := []string{} 136 for _, r := range replicas { 137 if r.Mode == "ERR" { 138 continue 139 } 140 141 if first { 142 first = false 143 chain, err := getChain(r.Address) 144 if err != nil { 145 return err 146 } 147 snapshots = chain[1:] 148 continue 149 } 150 151 chain, err := getChain(r.Address) 152 if err != nil { 153 return err 154 } 155 156 snapshots = util.Filter(snapshots, func(i string) bool { 157 return util.Contains(chain, i) 158 }) 159 } 160 161 format := "%s\n" 162 tw := tabwriter.NewWriter(os.Stdout, 0, 20, 1, ' ', 0) 163 fmt.Fprintf(tw, format, "ID") 164 for _, s := range snapshots { 165 s = strings.TrimSuffix(strings.TrimPrefix(s, "volume-snap-"), ".img") 166 fmt.Fprintf(tw, format, s) 167 } 168 tw.Flush() 169 170 return nil 171 }