github.com/zignig/go-ipfs@v0.0.0-20141111235910-c9e5fdf55a52/cmd/ipfs2/init.go (about) 1 package main 2 3 import ( 4 "encoding/base64" 5 "errors" 6 "fmt" 7 "os" 8 "path/filepath" 9 10 cmds "github.com/jbenet/go-ipfs/commands" 11 config "github.com/jbenet/go-ipfs/config" 12 ci "github.com/jbenet/go-ipfs/crypto" 13 peer "github.com/jbenet/go-ipfs/peer" 14 u "github.com/jbenet/go-ipfs/util" 15 ) 16 17 var initCmd = &cmds.Command{ 18 Description: "Initializes IPFS config file", 19 Help: `Initializes IPFS configuration files and generates a new keypair. 20 `, 21 22 Options: []cmds.Option{ 23 cmds.IntOption("bits", "b", "Number of bits to use in the generated RSA private key (defaults to 4096)"), 24 cmds.StringOption("passphrase", "p", "Passphrase for encrypting the private key"), 25 cmds.BoolOption("force", "f", "Overwrite existing config (if it exists)"), 26 cmds.StringOption("datastore", "d", "Location for the IPFS data store"), 27 }, 28 Run: func(req cmds.Request) (interface{}, error) { 29 30 dspath, err := req.Option("d").String() 31 if err != nil { 32 return nil, err 33 } 34 35 force, err := req.Option("f").Bool() 36 if err != nil { 37 return nil, err 38 } 39 40 nBitsForKeypair, err := req.Option("b").Int() 41 if err != nil { 42 return nil, err 43 } 44 if !req.Option("b").Found() { 45 nBitsForKeypair = 4096 46 } 47 48 return nil, doInit(req.Context().ConfigRoot, dspath, force, nBitsForKeypair) 49 }, 50 } 51 52 // TODO add default welcome hash: eaa68bedae247ed1e5bd0eb4385a3c0959b976e4 53 func doInit(configRoot string, dspath string, force bool, nBitsForKeypair int) error { 54 55 u.POut("initializing ipfs node at %s\n", configRoot) 56 57 configFilename, err := config.Filename(configRoot) 58 if err != nil { 59 return errors.New("Couldn't get home directory path") 60 } 61 62 fi, err := os.Lstat(configFilename) 63 if fi != nil || (err != nil && !os.IsNotExist(err)) { 64 if !force { 65 // TODO multi-line string 66 return errors.New("ipfs configuration file already exists!\nReinitializing would overwrite your keys.\n(use -f to force overwrite)") 67 } 68 } 69 70 ds, err := datastoreConfig(dspath) 71 if err != nil { 72 return err 73 } 74 75 identity, err := identityConfig(nBitsForKeypair) 76 if err != nil { 77 return err 78 } 79 80 conf := config.Config{ 81 82 // setup the node addresses. 83 Addresses: config.Addresses{ 84 Swarm: "/ip4/0.0.0.0/tcp/4001", 85 API: "/ip4/127.0.0.1/tcp/5001", 86 }, 87 88 Bootstrap: []*config.BootstrapPeer{ 89 &config.BootstrapPeer{ // Use these hardcoded bootstrap peers for now. 90 // mars.i.ipfs.io 91 PeerID: "QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", 92 Address: "/ip4/104.131.131.82/tcp/4001", 93 }, 94 }, 95 96 Datastore: ds, 97 98 Identity: identity, 99 100 // setup the node mount points. 101 Mounts: config.Mounts{ 102 IPFS: "/ipfs", 103 IPNS: "/ipns", 104 }, 105 106 // tracking ipfs version used to generate the init folder and adding 107 // update checker default setting. 108 Version: config.VersionDefaultValue(), 109 } 110 111 err = config.WriteConfigFile(configFilename, conf) 112 if err != nil { 113 return err 114 } 115 return nil 116 } 117 118 func datastoreConfig(dspath string) (config.Datastore, error) { 119 ds := config.Datastore{} 120 if len(dspath) == 0 { 121 var err error 122 dspath, err = config.DataStorePath("") 123 if err != nil { 124 return ds, err 125 } 126 } 127 ds.Path = dspath 128 ds.Type = "leveldb" 129 130 // Construct the data store if missing 131 if err := os.MkdirAll(dspath, os.ModePerm); err != nil { 132 return ds, err 133 } 134 135 // Check the directory is writeable 136 if f, err := os.Create(filepath.Join(dspath, "._check_writeable")); err == nil { 137 os.Remove(f.Name()) 138 } else { 139 return ds, errors.New("Datastore '" + dspath + "' is not writeable") 140 } 141 142 return ds, nil 143 } 144 145 func identityConfig(nbits int) (config.Identity, error) { 146 // TODO guard higher up 147 ident := config.Identity{} 148 if nbits < 1024 { 149 return ident, errors.New("Bitsize less than 1024 is considered unsafe.") 150 } 151 152 fmt.Println("generating key pair...") 153 sk, pk, err := ci.GenerateKeyPair(ci.RSA, nbits) 154 if err != nil { 155 return ident, err 156 } 157 158 // currently storing key unencrypted. in the future we need to encrypt it. 159 // TODO(security) 160 skbytes, err := sk.Bytes() 161 if err != nil { 162 return ident, err 163 } 164 ident.PrivKey = base64.StdEncoding.EncodeToString(skbytes) 165 166 id, err := peer.IDFromPubKey(pk) 167 if err != nil { 168 return ident, err 169 } 170 ident.PeerID = id.Pretty() 171 172 return ident, nil 173 }