提交 abefd93f 作者: Juan Batiz-Benet

edited bootstrap cmd

- safer parsing
- multiple inputs
- add: dup detection
- common cfg writing
上级 091f6f85
package main package main
import ( import (
"fmt" "errors"
"strings"
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag" "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander" "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr" ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
config "github.com/jbenet/go-ipfs/config" config "github.com/jbenet/go-ipfs/config"
"strings" peer "github.com/jbenet/go-ipfs/peer"
u "github.com/jbenet/go-ipfs/util"
) )
var cmdIpfsBootstrap = &commander.Command{ var cmdIpfsBootstrap = &commander.Command{
...@@ -14,13 +19,6 @@ var cmdIpfsBootstrap = &commander.Command{ ...@@ -14,13 +19,6 @@ var cmdIpfsBootstrap = &commander.Command{
Short: "Show a list of bootstrapped addresses.", Short: "Show a list of bootstrapped addresses.",
Long: `ipfs bootstrap - show, or manipulate bootstrap node addresses Long: `ipfs bootstrap - show, or manipulate bootstrap node addresses
SECURITY WARNING:
The bootstrap command manipulates the "bootstrap list", which contains
the addresses of bootstrap nodes. These are the *trusted peers* from
which to learn about other peers in the network. Only edit this list
if you understand the risks of adding or removing nodes from this list.
Running 'ipfs bootstrap' with no arguments will run 'ipfs bootstrap list'. Running 'ipfs bootstrap' with no arguments will run 'ipfs bootstrap list'.
Commands: Commands:
...@@ -29,150 +27,228 @@ Commands: ...@@ -29,150 +27,228 @@ Commands:
add <address> Add a node's address to the bootstrap list. add <address> Add a node's address to the bootstrap list.
remove <address> Remove an address from the bootstrap list. remove <address> Remove an address from the bootstrap list.
`, ` + bootstrapSecurityWarning,
Run: bootstrapCmd, Run: bootstrapListCmd,
Subcommands: []*commander.Command{ Subcommands: []*commander.Command{
cmdIpfsBootstrapRemove, cmdIpfsBootstrapRemove,
cmdIpfsBootstrapAdd, cmdIpfsBootstrapAdd,
cmdIpfsBootstrapList,
}, },
Flag: *flag.NewFlagSet("ipfs-bootstrap", flag.ExitOnError), Flag: *flag.NewFlagSet("ipfs-bootstrap", flag.ExitOnError),
} }
var cmdIpfsBootstrapRemove = &commander.Command{ var cmdIpfsBootstrapRemove = &commander.Command{
UsageLine: "remove", UsageLine: "remove <address | peerid>",
Run: IpfsBootstrapRemoveCmd, Short: "Remove addresses from the bootstrap list.",
Long: `ipfs bootstrap remove - remove addresses from the bootstrap list
` + bootstrapSecurityWarning,
Run: bootstrapRemoveCmd,
Flag: *flag.NewFlagSet("ipfs-bootstrap-remove", flag.ExitOnError), Flag: *flag.NewFlagSet("ipfs-bootstrap-remove", flag.ExitOnError),
} }
var cmdIpfsBootstrapAdd = &commander.Command{ var cmdIpfsBootstrapAdd = &commander.Command{
UsageLine: "add", UsageLine: "add <address | peerid>",
Run: IpfsBootstrapAddCmd, Short: "Add addresses to the bootstrap list.",
Long: `ipfs bootstrap add - add addresses to the bootstrap list
` + bootstrapSecurityWarning,
Run: bootstrapAddCmd,
Flag: *flag.NewFlagSet("ipfs-bootstrap-add", flag.ExitOnError), Flag: *flag.NewFlagSet("ipfs-bootstrap-add", flag.ExitOnError),
} }
func IpfsBootstrapRemoveCmd(c *commander.Command, inp []string) error { var cmdIpfsBootstrapList = &commander.Command{
UsageLine: "list",
Short: "Show addresses in the bootstrap list.",
Run: bootstrapListCmd,
Flag: *flag.NewFlagSet("ipfs-bootstrap-list", flag.ExitOnError),
}
func bootstrapRemoveCmd(c *commander.Command, inp []string) error {
if len(inp) == 0 { if len(inp) == 0 {
fmt.Println("No peer specified.") return errors.New("remove: no address or peerid specified")
return nil
} }
if strings.Contains(inp[0], "/") { toRemove, err := bootstrapInputToPeers(inp)
if err != nil {
return err
}
var pID = inp[0][len(inp[0])-46:] cfg, err := getConfig(c)
var ip = strings.TrimSuffix(inp[0], pID)
maddr, err := ma.NewMultiaddr(strings.TrimSuffix(ip, "/"))
var address, _ = maddr.String()
if err != nil { if err != nil {
return err return err
} }
peer := config.BootstrapPeer{ keep := []*config.BootstrapPeer{}
Address: address, remove := []*config.BootstrapPeer{}
PeerID: pID,
// function to filer what to keep
shouldKeep := func(bp *config.BootstrapPeer) bool {
for _, skipBP := range toRemove {
// IDs must match to skip.
if bp.PeerID != skipBP.PeerID {
continue
} }
configpath, _ := config.Filename("~/.go-ipfs/config") // if Addresses match, or skipBP has no addr (wildcard)
var cfg config.Config if skipBP.Address == bp.Address || skipBP.Address == "" {
readErr := config.ReadConfigFile(configpath, &cfg) return false
if readErr != nil { }
return readErr }
return true
} }
i := 0 // filter all the existing peers
for _, v := range cfg.Bootstrap { for _, currBP := range cfg.Bootstrap {
if v.PeerID == peer.PeerID && v.Address == peer.Address { if shouldKeep(currBP) {
continue keep = append(keep, currBP)
} else {
remove = append(remove, currBP)
} }
cfg.Bootstrap[i] = v
i++
} }
cfg.Bootstrap = cfg.Bootstrap[:i]
writeErr := config.WriteConfigFile(configpath, cfg) // if didn't remove anyone, bail.
if writeErr != nil { if len(keep) == len(cfg.Bootstrap) {
return writeErr return errors.New("remove: peer given did not match any in list")
} }
// write new config
cfg.Bootstrap = keep
if err := writeConfig(c, cfg); err != nil {
return err
} }
if !strings.Contains(inp[0], "/") { for _, bp := range remove {
u.POut("removed %s\n", bp)
}
return nil
}
var peerID = inp[0] func bootstrapAddCmd(c *commander.Command, inp []string) error {
configpath, _ := config.Filename("~/.go-ipfs/config") if len(inp) == 0 {
var cfg config.Config return errors.New("add: no address specified")
readErr := config.ReadConfigFile(configpath, &cfg)
if readErr != nil {
return readErr
} }
i := 0 toAdd, err := bootstrapInputToPeers(inp)
for _, v := range cfg.Bootstrap { if err != nil {
if v.PeerID == peerID { return err
}
cfg, err := getConfig(c)
if err != nil {
return err
}
// function to check whether a peer is already in the list.
combine := func(lists ...[]*config.BootstrapPeer) []*config.BootstrapPeer {
set := map[string]struct{}{}
final := []*config.BootstrapPeer{}
for _, list := range lists {
for _, peer := range list {
// if already in the set, continue
_, found := set[peer.String()]
if found {
continue continue
} }
cfg.Bootstrap[i] = v
i++ set[peer.String()] = struct{}{}
final = append(final, peer)
}
}
return final
} }
cfg.Bootstrap = cfg.Bootstrap[:i]
writeErr := config.WriteConfigFile(configpath, cfg) // combine both lists, removing dups.
if writeErr != nil { cfg.Bootstrap = combine(cfg.Bootstrap, toAdd)
return writeErr if err := writeConfig(c, cfg); err != nil {
return err
} }
for _, bp := range toAdd {
u.POut("added %s\n", bp)
} }
return nil return nil
} }
func IpfsBootstrapAddCmd(c *commander.Command, inp []string) error { func bootstrapListCmd(c *commander.Command, inp []string) error {
if len(inp) == 0 { cfg, err := getConfig(c)
fmt.Println("No peer specified.") if err != nil {
return nil return err
}
for _, bp := range cfg.Bootstrap {
u.POut("%s\n", bp)
} }
var pID = inp[0][len(inp[0])-46:] return nil
var ip = strings.TrimSuffix(inp[0], pID) }
maddr, err := ma.NewMultiaddr(strings.TrimSuffix(ip, "/"))
var address, _ = maddr.String() func writeConfig(c *commander.Command, cfg *config.Config) error {
confdir, err := getConfigDir(c)
if err != nil { if err != nil {
return err return err
} }
peer := config.BootstrapPeer{ filename, err := config.Filename(confdir)
Address: address, if err != nil {
PeerID: pID, return err
} }
configpath, _ := config.Filename("~/.go-ipfs/config") return config.WriteConfigFile(filename, cfg)
var cfg config.Config }
readErr := config.ReadConfigFile(configpath, &cfg)
if readErr != nil { func bootstrapInputToPeers(input []string) ([]*config.BootstrapPeer, error) {
return readErr split := func(addr string) (string, string) {
idx := strings.LastIndex(addr, "/")
if idx == -1 {
return "", addr
}
return addr[:idx], addr[idx+1:]
} }
addedPeer := append(cfg.Bootstrap, &peer) peers := []*config.BootstrapPeer{}
cfg.Bootstrap = addedPeer for _, addr := range input {
addrS, peeridS := split(addr)
writeErr := config.WriteConfigFile(configpath, cfg) // make sure addrS parses as a multiaddr.
if writeErr != nil { if len(addrS) > 0 {
return writeErr maddr, err := ma.NewMultiaddr(addrS)
if err != nil {
return nil, err
} }
return nil
return nil
}
func bootstrapCmd(c *commander.Command, inp []string) error {
configpath, _ := config.Filename("~/.go-ipfs/config")
var cfg config.Config
config.ReadConfigFile(configpath, &cfg)
for i := range cfg.Bootstrap { addrS, err = maddr.String()
s := []string{cfg.Bootstrap[i].Address, "/", cfg.Bootstrap[i].PeerID, "\n"} if err != nil {
fmt.Printf(strings.Join(s, "")) return nil, err
}
} }
return nil // make sure idS parses as a peer.ID
peerid, err := mh.FromB58String(peeridS)
if err != nil {
return nil, err
}
// construct config entry
peers = append(peers, &config.BootstrapPeer{
Address: addrS,
PeerID: peer.ID(peerid).Pretty(),
})
}
return peers, nil
} }
const bootstrapSecurityWarning = `
SECURITY WARNING:
The bootstrap command manipulates the "bootstrap list", which contains
the addresses of bootstrap nodes. These are the *trusted peers* from
which to learn about other peers in the network. Only edit this list
if you understand the risks of adding or removing nodes from this list.
`
...@@ -35,6 +35,10 @@ type BootstrapPeer struct { ...@@ -35,6 +35,10 @@ type BootstrapPeer struct {
PeerID string // until multiaddr supports ipfs, use another field. PeerID string // until multiaddr supports ipfs, use another field.
} }
func (bp *BootstrapPeer) String() string {
return bp.Address + "/" + bp.PeerID
}
// Config is used to load IPFS config files. // Config is used to load IPFS config files.
type Config struct { type Config struct {
Identity Identity // local node's peer identity Identity Identity // local node's peer identity
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论