init.go 3.06 KB
Newer Older
1 2 3 4 5 6 7
package main

import (
	"encoding/base64"
	"errors"
	"os"

8 9
	"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
	"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
10
	config "github.com/jbenet/go-ipfs/config"
11
	ci "github.com/jbenet/go-ipfs/crypto"
12
	spipe "github.com/jbenet/go-ipfs/crypto/spipe"
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
	u "github.com/jbenet/go-ipfs/util"
)

var cmdIpfsInit = &commander.Command{
	UsageLine: "init",
	Short:     "Initialize ipfs local configuration",
	Long: `ipfs init

	Initializes ipfs configuration files and generates a
	new keypair.
`,
	Run:  initCmd,
	Flag: *flag.NewFlagSet("ipfs-init", flag.ExitOnError),
}

func init() {
	cmdIpfsInit.Flag.Int("b", 4096, "number of bits for keypair")
	cmdIpfsInit.Flag.String("p", "", "passphrase for encrypting keys")
	cmdIpfsInit.Flag.Bool("f", false, "force overwrite of existing config")
}

func initCmd(c *commander.Command, inp []string) error {
35 36 37 38 39 40 41 42 43 44 45
	configpath, err := getConfigDir(c.Parent)
	if err != nil {
		return err
	}
	if configpath == "" {
		configpath, err = u.TildeExpansion("~/.go-ipfs")
		if err != nil {
			return err
		}
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
46
	u.POut("initializing ipfs node at %s\n", configpath)
47
	filename, err := config.Filename(configpath + "/config")
48 49 50
	if err != nil {
		return errors.New("Couldn't get home directory path")
	}
51

52
	fi, err := os.Lstat(filename)
53 54 55 56
	force, ok := c.Flag.Lookup("f").Value.Get().(bool)
	if !ok {
		return errors.New("failed to parse force flag")
	}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
57 58 59 60
	if fi != nil || (err != nil && !os.IsNotExist(err)) {
		if !force {
			return errors.New("ipfs configuration file already exists!\nReinitializing would overwrite your keys.\n(use -f to force overwrite)")
		}
61 62 63
	}
	cfg := new(config.Config)

Brian Tiger Chow's avatar
Brian Tiger Chow committed
64
	cfg.Datastore = config.Datastore{}
65 66 67 68 69 70 71 72 73
	dspath, err := u.TildeExpansion("~/.go-ipfs/datastore")
	if err != nil {
		return err
	}
	cfg.Datastore.Path = dspath
	cfg.Datastore.Type = "leveldb"

	cfg.Identity = new(config.Identity)
	// This needs thought
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
74 75 76 77
	cfg.Identity.Address = "/ip4/127.0.0.1/tcp/5001"

	// local RPC endpoint
	cfg.RPCAddress = "/ip4/127.0.0.1/tcp/4001"
78

79 80 81 82
	nbits, ok := c.Flag.Lookup("b").Value.Get().(int)
	if !ok {
		return errors.New("failed to get bits flag")
	}
83 84 85
	if nbits < 1024 {
		return errors.New("Bitsize less than 1024 is considered unsafe.")
	}
86

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
87
	u.POut("generating key pair\n")
88
	sk, pk, err := ci.GenerateKeyPair(ci.RSA, nbits)
89 90 91 92
	if err != nil {
		return err
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
93 94
	// currently storing key unencrypted. in the future we need to encrypt it.
	// TODO(security)
95 96 97 98 99
	skbytes, err := sk.Bytes()
	if err != nil {
		return err
	}
	cfg.Identity.PrivKey = base64.StdEncoding.EncodeToString(skbytes)
100

101
	id, err := spipe.IDFromPubKey(pk)
102 103 104 105 106
	if err != nil {
		return err
	}
	cfg.Identity.PeerID = id.Pretty()

107 108 109 110 111 112 113 114 115
	// Use these hardcoded bootstrap peers for now.
	cfg.Peers = []*config.SavedPeer{
		&config.SavedPeer{
			// mars.i.ipfs.io
			PeerID:  "QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
			Address: "/ip4/104.131.131.82/tcp/4001",
		},
	}

116 117 118 119
	path, err := u.TildeExpansion(config.DefaultConfigFilePath)
	if err != nil {
		return err
	}
120

121 122 123 124 125 126
	err = config.WriteConfigFile(path, cfg)
	if err != nil {
		return err
	}
	return nil
}