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  }