package main import ( "fmt" "os" "github.com/dennwc/btrfs" "github.com/spf13/cobra" ) func init() { RootCmd.AddCommand( SubvolumeCmd, SendCmd, ReceiveCmd, ) SubvolumeCmd.AddCommand( SubvolumeCreateCmd, SubvolumeDeleteCmd, SubvolumeListCmd, ) SendCmd.Flags().StringP("parent", "p", "", "Send an incremental stream from to .") } var RootCmd = &cobra.Command{ Use: "btrfs [--help] [--version] [...] []", Short: "Use --help as an argument for information on a specific group or command.", } var SubvolumeCmd = &cobra.Command{ Use: "subvolume ", Aliases: []string{"subvol", "sub", "sv"}, } var SubvolumeCreateCmd = &cobra.Command{ Use: "create [-i ] [/]", Short: "Create a subvolume", Long: `Create a subvolume in . If is not given subvolume will be created in the current directory.`, RunE: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { return fmt.Errorf("subvolume not specified") } else if len(args) > 1 { return fmt.Errorf("only one subvolume name is allowed") } return btrfs.CreateSubVolume(args[0]) }, } var SubvolumeDeleteCmd = &cobra.Command{ Use: "delete [options] [...]", Short: "Delete subvolume(s)", Long: `Delete subvolumes from the filesystem. The corresponding directory is removed instantly but the data blocks are removed later. The deletion does not involve full commit by default due to performance reasons (as a consequence, the subvolume may appear again after a crash). Use one of the --commit options to wait until the operation is safely stored on the media.`, RunE: func(cmd *cobra.Command, args []string) error { for _, arg := range args { if err := btrfs.DeleteSubVolume(arg); err != nil { return err } } return nil }, } var SubvolumeListCmd = &cobra.Command{ Use: "list ", Short: "List subvolumes", Aliases: []string{"ls"}, RunE: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { return fmt.Errorf("expected one destination argument") } fs, err := btrfs.Open(args[0], true) if err != nil { return err } defer fs.Close() list, err := fs.ListSubvolumes(nil) if err == nil { for _, v := range list { fmt.Printf("%+v\n", v) } } return err }, } var SendCmd = &cobra.Command{ Use: "send [-v] [-p ] [-c ] [-f ] [...]", Short: "Send the subvolume(s) to stdout.", Long: `Sends the subvolume(s) specified by to stdout. should be read-only here.`, RunE: func(cmd *cobra.Command, args []string) error { parent, _ := cmd.Flags().GetString("parent") return btrfs.Send(os.Stdout, parent, args...) }, } var ReceiveCmd = &cobra.Command{ Use: "receive [-v] [-f ] [--max-errors ] ", Short: "Receive subvolumes from stdin.", Long: `Receives one or more subvolumes that were previously sent with btrfs send. The received subvolumes are stored into .`, RunE: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { return fmt.Errorf("expected one destination argument") } return btrfs.Receive(os.Stdin, args[0]) }, } func main() { if err := RootCmd.Execute(); err != nil { fmt.Println(err) os.Exit(-1) } }