github.com/zignig/go-ipfs@v0.0.0-20141111235910-c9e5fdf55a52/cmd/ipfs/bootstrap.go (about) 1 package main 2 3 import ( 4 "errors" 5 "strings" 6 7 "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag" 8 "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander" 9 ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr" 10 mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash" 11 12 config "github.com/jbenet/go-ipfs/config" 13 peer "github.com/jbenet/go-ipfs/peer" 14 u "github.com/jbenet/go-ipfs/util" 15 ) 16 17 var cmdIpfsBootstrap = &commander.Command{ 18 UsageLine: "bootstrap", 19 Short: "Show a list of bootstrapped addresses.", 20 Long: `ipfs bootstrap - show, or manipulate bootstrap node addresses 21 22 Running 'ipfs bootstrap' with no arguments will run 'ipfs bootstrap list'. 23 24 Commands: 25 26 list Show the boostrap list. 27 add <address> Add a node's address to the bootstrap list. 28 remove <address> Remove an address from the bootstrap list. 29 30 ` + bootstrapSecurityWarning, 31 Run: bootstrapListCmd, 32 Subcommands: []*commander.Command{ 33 cmdIpfsBootstrapRemove, 34 cmdIpfsBootstrapAdd, 35 cmdIpfsBootstrapList, 36 }, 37 Flag: *flag.NewFlagSet("ipfs-bootstrap", flag.ExitOnError), 38 } 39 40 var cmdIpfsBootstrapRemove = &commander.Command{ 41 UsageLine: "remove <address | peerid>", 42 Short: "Remove addresses from the bootstrap list.", 43 Long: `ipfs bootstrap remove - remove addresses from the bootstrap list 44 ` + bootstrapSecurityWarning, 45 Run: bootstrapRemoveCmd, 46 Flag: *flag.NewFlagSet("ipfs-bootstrap-remove", flag.ExitOnError), 47 } 48 49 var cmdIpfsBootstrapAdd = &commander.Command{ 50 UsageLine: "add <address | peerid>", 51 Short: "Add addresses to the bootstrap list.", 52 Long: `ipfs bootstrap add - add addresses to the bootstrap list 53 ` + bootstrapSecurityWarning, 54 Run: bootstrapAddCmd, 55 Flag: *flag.NewFlagSet("ipfs-bootstrap-add", flag.ExitOnError), 56 } 57 58 var cmdIpfsBootstrapList = &commander.Command{ 59 UsageLine: "list", 60 Short: "Show addresses in the bootstrap list.", 61 Run: bootstrapListCmd, 62 Flag: *flag.NewFlagSet("ipfs-bootstrap-list", flag.ExitOnError), 63 } 64 65 func bootstrapRemoveCmd(c *commander.Command, inp []string) error { 66 67 if len(inp) == 0 { 68 return errors.New("remove: no address or peerid specified") 69 } 70 71 toRemove, err := bootstrapInputToPeers(inp) 72 if err != nil { 73 return err 74 } 75 76 cfg, err := getConfig(c) 77 if err != nil { 78 return err 79 } 80 81 keep := []*config.BootstrapPeer{} 82 remove := []*config.BootstrapPeer{} 83 84 // function to filer what to keep 85 shouldKeep := func(bp *config.BootstrapPeer) bool { 86 for _, skipBP := range toRemove { 87 88 // IDs must match to skip. 89 if bp.PeerID != skipBP.PeerID { 90 continue 91 } 92 93 // if Addresses match, or skipBP has no addr (wildcard) 94 if skipBP.Address == bp.Address || skipBP.Address == "" { 95 return false 96 } 97 } 98 return true 99 } 100 101 // filter all the existing peers 102 for _, currBP := range cfg.Bootstrap { 103 if shouldKeep(currBP) { 104 keep = append(keep, currBP) 105 } else { 106 remove = append(remove, currBP) 107 } 108 } 109 110 // if didn't remove anyone, bail. 111 if len(keep) == len(cfg.Bootstrap) { 112 return errors.New("remove: peer given did not match any in list") 113 } 114 115 // write new config 116 cfg.Bootstrap = keep 117 if err := writeConfig(c, cfg); err != nil { 118 return err 119 } 120 121 for _, bp := range remove { 122 u.POut("removed %s\n", bp) 123 } 124 return nil 125 } 126 127 func bootstrapAddCmd(c *commander.Command, inp []string) error { 128 129 if len(inp) == 0 { 130 return errors.New("add: no address specified") 131 } 132 133 toAdd, err := bootstrapInputToPeers(inp) 134 if err != nil { 135 return err 136 } 137 138 cfg, err := getConfig(c) 139 if err != nil { 140 return err 141 } 142 143 // function to check whether a peer is already in the list. 144 combine := func(lists ...[]*config.BootstrapPeer) []*config.BootstrapPeer { 145 146 set := map[string]struct{}{} 147 final := []*config.BootstrapPeer{} 148 149 for _, list := range lists { 150 for _, peer := range list { 151 // if already in the set, continue 152 _, found := set[peer.String()] 153 if found { 154 continue 155 } 156 157 set[peer.String()] = struct{}{} 158 final = append(final, peer) 159 } 160 } 161 return final 162 } 163 164 // combine both lists, removing dups. 165 cfg.Bootstrap = combine(cfg.Bootstrap, toAdd) 166 if err := writeConfig(c, cfg); err != nil { 167 return err 168 } 169 170 for _, bp := range toAdd { 171 u.POut("added %s\n", bp) 172 } 173 return nil 174 } 175 176 func bootstrapListCmd(c *commander.Command, inp []string) error { 177 178 cfg, err := getConfig(c) 179 if err != nil { 180 return err 181 } 182 183 for _, bp := range cfg.Bootstrap { 184 u.POut("%s\n", bp) 185 } 186 187 return nil 188 } 189 190 func bootstrapInputToPeers(input []string) ([]*config.BootstrapPeer, error) { 191 split := func(addr string) (string, string) { 192 idx := strings.LastIndex(addr, "/") 193 if idx == -1 { 194 return "", addr 195 } 196 return addr[:idx], addr[idx+1:] 197 } 198 199 peers := []*config.BootstrapPeer{} 200 for _, addr := range input { 201 addrS, peeridS := split(addr) 202 203 // make sure addrS parses as a multiaddr. 204 if len(addrS) > 0 { 205 maddr, err := ma.NewMultiaddr(addrS) 206 if err != nil { 207 return nil, err 208 } 209 210 addrS = maddr.String() 211 } 212 213 // make sure idS parses as a peer.ID 214 peerid, err := mh.FromB58String(peeridS) 215 if err != nil { 216 return nil, err 217 } 218 219 // construct config entry 220 peers = append(peers, &config.BootstrapPeer{ 221 Address: addrS, 222 PeerID: peer.ID(peerid).Pretty(), 223 }) 224 } 225 return peers, nil 226 } 227 228 const bootstrapSecurityWarning = ` 229 SECURITY WARNING: 230 231 The bootstrap command manipulates the "bootstrap list", which contains 232 the addresses of bootstrap nodes. These are the *trusted peers* from 233 which to learn about other peers in the network. Only edit this list 234 if you understand the risks of adding or removing nodes from this list. 235 236 `