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