github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/cmd/swarm/fs.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:33</date>
    10  //</624450070913224704>
    11  
    12  
    13  package main
    14  
    15  import (
    16  	"context"
    17  	"fmt"
    18  	"path/filepath"
    19  	"strings"
    20  	"time"
    21  
    22  	"github.com/ethereum/go-ethereum/cmd/utils"
    23  	"github.com/ethereum/go-ethereum/log"
    24  	"github.com/ethereum/go-ethereum/rpc"
    25  	"github.com/ethereum/go-ethereum/swarm/fuse"
    26  	"gopkg.in/urfave/cli.v1"
    27  )
    28  
    29  var fsCommand = cli.Command{
    30  	Name:               "fs",
    31  	CustomHelpTemplate: helpTemplate,
    32  	Usage:              "perform FUSE operations",
    33  	ArgsUsage:          "fs COMMAND",
    34  	Description:        "Performs FUSE operations by mounting/unmounting/listing mount points. This assumes you already have a Swarm node running locally. For all operation you must reference the correct path to bzzd.ipc in order to communicate with the node",
    35  	Subcommands: []cli.Command{
    36  		{
    37  			Action:             mount,
    38  			CustomHelpTemplate: helpTemplate,
    39  			Name:               "mount",
    40  			Usage:              "mount a swarm hash to a mount point",
    41  			ArgsUsage:          "swarm fs mount <manifest hash> <mount point>",
    42  			Description:        "Mounts a Swarm manifest hash to a given mount point. This assumes you already have a Swarm node running locally. You must reference the correct path to your bzzd.ipc file",
    43  		},
    44  		{
    45  			Action:             unmount,
    46  			CustomHelpTemplate: helpTemplate,
    47  			Name:               "unmount",
    48  			Usage:              "unmount a swarmfs mount",
    49  			ArgsUsage:          "swarm fs unmount <mount point>",
    50  			Description:        "Unmounts a swarmfs mount residing at <mount point>. This assumes you already have a Swarm node running locally. You must reference the correct path to your bzzd.ipc file",
    51  		},
    52  		{
    53  			Action:             listMounts,
    54  			CustomHelpTemplate: helpTemplate,
    55  			Name:               "list",
    56  			Usage:              "list swarmfs mounts",
    57  			ArgsUsage:          "swarm fs list",
    58  			Description:        "Lists all mounted swarmfs volumes. This assumes you already have a Swarm node running locally. You must reference the correct path to your bzzd.ipc file",
    59  		},
    60  	},
    61  }
    62  
    63  func mount(cliContext *cli.Context) {
    64  	args := cliContext.Args()
    65  	if len(args) < 2 {
    66  		utils.Fatalf("Usage: swarm fs mount <manifestHash> <file name>")
    67  	}
    68  
    69  	client, err := dialRPC(cliContext)
    70  	if err != nil {
    71  		utils.Fatalf("had an error dailing to RPC endpoint: %v", err)
    72  	}
    73  	defer client.Close()
    74  
    75  	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    76  	defer cancel()
    77  
    78  	mf := &fuse.MountInfo{}
    79  	mountPoint, err := filepath.Abs(filepath.Clean(args[1]))
    80  	if err != nil {
    81  		utils.Fatalf("error expanding path for mount point: %v", err)
    82  	}
    83  	err = client.CallContext(ctx, mf, "swarmfs_mount", args[0], mountPoint)
    84  	if err != nil {
    85  		utils.Fatalf("had an error calling the RPC endpoint while mounting: %v", err)
    86  	}
    87  }
    88  
    89  func unmount(cliContext *cli.Context) {
    90  	args := cliContext.Args()
    91  
    92  	if len(args) < 1 {
    93  		utils.Fatalf("Usage: swarm fs unmount <mount path>")
    94  	}
    95  	client, err := dialRPC(cliContext)
    96  	if err != nil {
    97  		utils.Fatalf("had an error dailing to RPC endpoint: %v", err)
    98  	}
    99  	defer client.Close()
   100  
   101  	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
   102  	defer cancel()
   103  
   104  	mf := fuse.MountInfo{}
   105  	err = client.CallContext(ctx, &mf, "swarmfs_unmount", args[0])
   106  	if err != nil {
   107  		utils.Fatalf("encountered an error calling the RPC endpoint while unmounting: %v", err)
   108  	}
   109  fmt.Printf("%s\n", mf.LatestManifest) //
   110  }
   111  
   112  func listMounts(cliContext *cli.Context) {
   113  	client, err := dialRPC(cliContext)
   114  	if err != nil {
   115  		utils.Fatalf("had an error dailing to RPC endpoint: %v", err)
   116  	}
   117  	defer client.Close()
   118  
   119  	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
   120  	defer cancel()
   121  
   122  	mf := []fuse.MountInfo{}
   123  	err = client.CallContext(ctx, &mf, "swarmfs_listmounts")
   124  	if err != nil {
   125  		utils.Fatalf("encountered an error calling the RPC endpoint while listing mounts: %v", err)
   126  	}
   127  	if len(mf) == 0 {
   128  		fmt.Print("Could not found any swarmfs mounts. Please make sure you've specified the correct RPC endpoint\n")
   129  	} else {
   130  		fmt.Printf("Found %d swarmfs mount(s):\n", len(mf))
   131  		for i, mountInfo := range mf {
   132  			fmt.Printf("%d:\n", i)
   133  			fmt.Printf("\tMount point: %s\n", mountInfo.MountPoint)
   134  			fmt.Printf("\tLatest Manifest: %s\n", mountInfo.LatestManifest)
   135  			fmt.Printf("\tStart Manifest: %s\n", mountInfo.StartManifest)
   136  		}
   137  	}
   138  }
   139  
   140  func dialRPC(ctx *cli.Context) (*rpc.Client, error) {
   141  	endpoint := getIPCEndpoint(ctx)
   142  	log.Info("IPC endpoint", "path", endpoint)
   143  	return rpc.Dial(endpoint)
   144  }
   145  
   146  func getIPCEndpoint(ctx *cli.Context) string {
   147  	cfg := defaultNodeConfig
   148  	utils.SetNodeConfig(ctx, &cfg)
   149  
   150  	endpoint := cfg.IPCEndpoint()
   151  
   152  	if strings.HasPrefix(endpoint, "rpc:") || strings.HasPrefix(endpoint, "ipc:") {
   153  //与geth的向后兼容性<1.5,这需要
   154  //这些前缀。
   155  		endpoint = endpoint[4:]
   156  	}
   157  	return endpoint
   158  }
   159