From ab805f33827fef4fcbe130fec3aadb6823dbe9fc Mon Sep 17 00:00:00 2001 From: Jeromy Date: Tue, 4 Nov 2014 10:55:51 -0800 Subject: [PATCH 1/4] add in a default file hash and cleaned up init functiona bit --- cmd/ipfs/init.go | 137 ++++++++++++++++++++++++++++++++--------------- pin/pin.go | 5 ++ 2 files changed, 100 insertions(+), 42 deletions(-) diff --git a/cmd/ipfs/init.go b/cmd/ipfs/init.go index 6c1293d888f..f7540517018 100644 --- a/cmd/ipfs/init.go +++ b/cmd/ipfs/init.go @@ -1,16 +1,22 @@ package main import ( + "bytes" "encoding/base64" "errors" + "fmt" "os" "path/filepath" "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag" "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander" config "github.com/jbenet/go-ipfs/config" + core "github.com/jbenet/go-ipfs/core" ci "github.com/jbenet/go-ipfs/crypto" + imp "github.com/jbenet/go-ipfs/importer" + chunk "github.com/jbenet/go-ipfs/importer/chunk" peer "github.com/jbenet/go-ipfs/peer" + updates "github.com/jbenet/go-ipfs/updates" u "github.com/jbenet/go-ipfs/util" ) @@ -33,6 +39,66 @@ func init() { cmdIpfsInit.Flag.String("d", "", "Change default datastore location") } +var defaultPeers = []*config.BootstrapPeer{ + &config.BootstrapPeer{ + // mars.i.ipfs.io + PeerID: "QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", + Address: "/ip4/104.131.131.82/tcp/4001", + }, +} + +func datastoreConfig(dspath string) (config.Datastore, error) { + ds := config.Datastore{} + if len(dspath) == 0 { + var err error + dspath, err = config.DataStorePath("") + if err != nil { + return ds, err + } + } + ds.Path = dspath + ds.Type = "leveldb" + + // Construct the data store if missing + if err := os.MkdirAll(dspath, os.ModePerm); err != nil { + return ds, err + } + + // Check the directory is writeable + if f, err := os.Create(filepath.Join(dspath, "._check_writeable")); err == nil { + os.Remove(f.Name()) + } else { + return ds, errors.New("Datastore '" + dspath + "' is not writeable") + } + + return ds, nil +} + +func identityConfig(nbits int) (config.Identity, error) { + ident := config.Identity{} + fmt.Println("generating key pair...") + sk, pk, err := ci.GenerateKeyPair(ci.RSA, nbits) + if err != nil { + return ident, err + } + + // currently storing key unencrypted. in the future we need to encrypt it. + // TODO(security) + skbytes, err := sk.Bytes() + if err != nil { + return ident, err + } + ident.PrivKey = base64.StdEncoding.EncodeToString(skbytes) + + id, err := peer.IDFromPubKey(pk) + if err != nil { + return ident, err + } + ident.PeerID = id.Pretty() + + return ident, nil +} + func initCmd(c *commander.Command, inp []string) error { configpath, err := getConfigDir(c.Parent) if err != nil { @@ -62,30 +128,12 @@ func initCmd(c *commander.Command, inp []string) error { } cfg := new(config.Config) - cfg.Datastore = config.Datastore{} - if len(dspath) == 0 { - dspath, err = config.DataStorePath("") - if err != nil { - return err - } - } - cfg.Datastore.Path = dspath - cfg.Datastore.Type = "leveldb" - - // Construct the data store if missing - if err := os.MkdirAll(dspath, os.ModePerm); err != nil { + // setup the datastore + cfg.Datastore, err = datastoreConfig(dspath) + if err != nil { return err } - // Check the directory is writeable - if f, err := os.Create(filepath.Join(dspath, "._check_writeable")); err == nil { - os.Remove(f.Name()) - } else { - return errors.New("Datastore '" + dspath + "' is not writeable") - } - - cfg.Identity = config.Identity{} - // setup the node addresses. cfg.Addresses = config.Addresses{ Swarm: "/ip4/0.0.0.0/tcp/4001", @@ -106,42 +154,47 @@ func initCmd(c *commander.Command, inp []string) error { return errors.New("Bitsize less than 1024 is considered unsafe.") } - u.POut("generating key pair\n") - sk, pk, err := ci.GenerateKeyPair(ci.RSA, nbits) + cfg.Identity, err = identityConfig(nbits) if err != nil { return err } - // currently storing key unencrypted. in the future we need to encrypt it. - // TODO(security) - skbytes, err := sk.Bytes() - if err != nil { - return err + // Use these hardcoded bootstrap peers for now. + cfg.Bootstrap = defaultPeers + + // tracking ipfs version used to generate the init folder + // and adding update checker default setting. + cfg.Version = config.Version{ + Check: "error", + Current: updates.Version, } - cfg.Identity.PrivKey = base64.StdEncoding.EncodeToString(skbytes) - id, err := peer.IDFromPubKey(pk) + err = config.WriteConfigFile(filename, cfg) if err != nil { return err } - cfg.Identity.PeerID = id.Pretty() - u.POut("peer identity: %s\n", id.Pretty()) - // Use these hardcoded bootstrap peers for now. - cfg.Bootstrap = []*config.BootstrapPeer{ - &config.BootstrapPeer{ - // mars.i.ipfs.io - PeerID: "QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", - Address: "/ip4/104.131.131.82/tcp/4001", - }, + nd, err := core.NewIpfsNode(cfg, false) + if err != nil { + return err } + defer nd.Close() - // tracking ipfs version used to generate the init folder and adding update checker default setting. - cfg.Version = config.VersionDefaultValue() + // Set up default file + msg := `Hello and Welcome to IPFS! +If you're seeing this, that means that you have successfully +installed ipfs and are now interfacing with the wonderful +world of DAGs and hashes! +` + reader := bytes.NewBufferString(msg) - err = config.WriteConfigFile(filename, cfg) + defnd, err := imp.BuildDagFromReader(reader, nd.DAG, nd.Pinning.GetManual(), chunk.DefaultSplitter) if err != nil { return err } + + k, _ := defnd.Key() + fmt.Printf("Default file key: %s\n", k) + return nil } diff --git a/pin/pin.go b/pin/pin.go index c59574edad2..60828b597ab 100644 --- a/pin/pin.go +++ b/pin/pin.go @@ -32,6 +32,7 @@ type Pinner interface { Pin(*mdag.Node, bool) error Unpin(util.Key, bool) error Flush() error + GetManual() ManualPinner } // ManualPinner is for manually editing the pin structure @@ -263,3 +264,7 @@ func (p *pinner) PinWithMode(k util.Key, mode PinMode) { p.indirPin.Increment(k) } } + +func (p *pinner) GetManual() ManualPinner { + return p +} From e857a5bc9fd66f94da045f9c69e0aa7e82b87e56 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Sat, 15 Nov 2014 18:28:54 -0800 Subject: [PATCH 2/4] move default hash into ipfs2, committed on freemont troll --- cmd/ipfs2/init.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/cmd/ipfs2/init.go b/cmd/ipfs2/init.go index 6b04a4418d8..22091c9abb9 100644 --- a/cmd/ipfs2/init.go +++ b/cmd/ipfs2/init.go @@ -1,6 +1,7 @@ package main import ( + "bytes" "encoding/base64" "errors" "fmt" @@ -9,7 +10,10 @@ import ( cmds "github.com/jbenet/go-ipfs/commands" config "github.com/jbenet/go-ipfs/config" + core "github.com/jbenet/go-ipfs/core" ci "github.com/jbenet/go-ipfs/crypto" + imp "github.com/jbenet/go-ipfs/importer" + chunk "github.com/jbenet/go-ipfs/importer/chunk" peer "github.com/jbenet/go-ipfs/peer" u "github.com/jbenet/go-ipfs/util" ) @@ -114,6 +118,29 @@ func doInit(configRoot string, dspathOverride string, force bool, nBitsForKeypai if err != nil { return err } + + nd, err := core.NewIpfsNode(&conf, false) + if err != nil { + return err + } + defer nd.Close() + + // Set up default file + msg := `Hello and Welcome to IPFS! +If you're seeing this, that means that you have successfully +installed ipfs and are now interfacing with the wonderful +world of DAGs and hashes! +` + reader := bytes.NewBufferString(msg) + + defnd, err := imp.BuildDagFromReader(reader, nd.DAG, nd.Pinning.GetManual(), chunk.DefaultSplitter) + if err != nil { + return err + } + + k, _ := defnd.Key() + fmt.Printf("Default file key: %s\n", k) + return nil } From 7596bcce2d221d8f9eed1c47ca117c745f9a5ffc Mon Sep 17 00:00:00 2001 From: Juan Batiz-Benet Date: Sat, 15 Nov 2014 22:50:42 -0800 Subject: [PATCH 3/4] cleaned up ipfs init --- cmd/ipfs2/init.go | 142 ++++++++++++++++++++++++++-------------------- 1 file changed, 82 insertions(+), 60 deletions(-) diff --git a/cmd/ipfs2/init.go b/cmd/ipfs2/init.go index 22091c9abb9..495c3c401af 100644 --- a/cmd/ipfs2/init.go +++ b/cmd/ipfs2/init.go @@ -50,98 +50,71 @@ var initCmd = &cmds.Command{ nBitsForKeypair = 4096 } - return nil, doInit(req.Context().ConfigRoot, dspathOverride, force, nBitsForKeypair) + return doInit(req.Context().ConfigRoot, dspathOverride, force, nBitsForKeypair) }, } +var errCannotInitConfigExists = errors.New(`ipfs configuration file already exists! +Reinitializing would overwrite your keys. +(use -f to force overwrite) +`) + +var welcomeMsg = `Hello and Welcome to IPFS! + +██╗██████╗ ███████╗███████╗ +██║██╔══██╗██╔════╝██╔════╝ +██║██████╔╝█████╗ ███████╗ +██║██╔═══╝ ██╔══╝ ╚════██║ +██║██║ ██║ ███████║ +╚═╝╚═╝ ╚═╝ ╚══════╝ + +If you're seeing this, you have successfully installed +IPFS and are now interfacing with the ipfs merkledag! + +For a short demo of what you can do, enter 'ipfs tour' +` + // TODO add default welcome hash: eaa68bedae247ed1e5bd0eb4385a3c0959b976e4 // NB: if dspath is not provided, it will be retrieved from the config -func doInit(configRoot string, dspathOverride string, force bool, nBitsForKeypair int) error { +func doInit(configRoot string, dspathOverride string, force bool, nBitsForKeypair int) (interface{}, error) { u.POut("initializing ipfs node at %s\n", configRoot) configFilename, err := config.Filename(configRoot) if err != nil { - return errors.New("Couldn't get home directory path") + return nil, errors.New("Couldn't get home directory path") } fi, err := os.Lstat(configFilename) if fi != nil || (err != nil && !os.IsNotExist(err)) { if !force { // TODO multi-line string - return errors.New("ipfs configuration file already exists!\nReinitializing would overwrite your keys.\n(use -f to force overwrite)") + return nil, errCannotInitConfigExists } } - ds, err := datastoreConfig(dspathOverride) - if err != nil { - return err - } - - identity, err := identityConfig(nBitsForKeypair) - if err != nil { - return err - } - - conf := config.Config{ - - // setup the node addresses. - Addresses: config.Addresses{ - Swarm: "/ip4/0.0.0.0/tcp/4001", - API: "/ip4/127.0.0.1/tcp/5001", - }, - - Bootstrap: []*config.BootstrapPeer{ - &config.BootstrapPeer{ // Use these hardcoded bootstrap peers for now. - // mars.i.ipfs.io - PeerID: "QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", - Address: "/ip4/104.131.131.82/tcp/4001", - }, - }, - - Datastore: ds, - - Identity: identity, - - // setup the node mount points. - Mounts: config.Mounts{ - IPFS: "/ipfs", - IPNS: "/ipns", - }, - - // tracking ipfs version used to generate the init folder and adding - // update checker default setting. - Version: config.VersionDefaultValue(), - } - - err = config.WriteConfigFile(configFilename, conf) + conf, err := initConfig(configFilename, dspathOverride, nBitsForKeypair) if err != nil { - return err + return nil, err } - nd, err := core.NewIpfsNode(&conf, false) + nd, err := core.NewIpfsNode(conf, false) if err != nil { - return err + return nil, err } defer nd.Close() // Set up default file - msg := `Hello and Welcome to IPFS! -If you're seeing this, that means that you have successfully -installed ipfs and are now interfacing with the wonderful -world of DAGs and hashes! -` - reader := bytes.NewBufferString(msg) + reader := bytes.NewBufferString(welcomeMsg) defnd, err := imp.BuildDagFromReader(reader, nd.DAG, nd.Pinning.GetManual(), chunk.DefaultSplitter) if err != nil { - return err + return nil, err } k, _ := defnd.Key() - fmt.Printf("Default file key: %s\n", k) - - return nil + fmt.Printf("done.\nto test, enter: ipfs cat %s\n", k) + return nil, nil } func datastoreConfig(dspath string) (config.Datastore, error) { @@ -171,6 +144,55 @@ func datastoreConfig(dspath string) (config.Datastore, error) { return ds, nil } +func initConfig(configFilename string, dspathOverride string, nBitsForKeypair int) (*config.Config, error) { + ds, err := datastoreConfig(dspathOverride) + if err != nil { + return nil, err + } + + identity, err := identityConfig(nBitsForKeypair) + if err != nil { + return nil, err + } + + conf := &config.Config{ + + // setup the node addresses. + Addresses: config.Addresses{ + Swarm: "/ip4/0.0.0.0/tcp/4001", + API: "/ip4/127.0.0.1/tcp/5001", + }, + + Bootstrap: []*config.BootstrapPeer{ + &config.BootstrapPeer{ // Use these hardcoded bootstrap peers for now. + // mars.i.ipfs.io + PeerID: "QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", + Address: "/ip4/104.131.131.82/tcp/4001", + }, + }, + + Datastore: ds, + + Identity: identity, + + // setup the node mount points. + Mounts: config.Mounts{ + IPFS: "/ipfs", + IPNS: "/ipns", + }, + + // tracking ipfs version used to generate the init folder and adding + // update checker default setting. + Version: config.VersionDefaultValue(), + } + + if err := config.WriteConfigFile(configFilename, conf); err != nil { + return nil, err + } + + return conf, nil +} + func identityConfig(nbits int) (config.Identity, error) { // TODO guard higher up ident := config.Identity{} @@ -178,7 +200,7 @@ func identityConfig(nbits int) (config.Identity, error) { return ident, errors.New("Bitsize less than 1024 is considered unsafe.") } - fmt.Println("generating key pair...") + fmt.Printf("generating key pair...") sk, pk, err := ci.GenerateKeyPair(ci.RSA, nbits) if err != nil { return ident, err From ab09c3649c070d7ab5a497a16df6fbc42c21a853 Mon Sep 17 00:00:00 2001 From: Juan Batiz-Benet Date: Sat, 15 Nov 2014 22:55:56 -0800 Subject: [PATCH 4/4] defaulthash: let's not ignore errors @maybebtc fixed it. cc @whyrusleeping --- cmd/ipfs2/init.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/ipfs2/init.go b/cmd/ipfs2/init.go index 495c3c401af..b0b945716a5 100644 --- a/cmd/ipfs2/init.go +++ b/cmd/ipfs2/init.go @@ -74,7 +74,6 @@ IPFS and are now interfacing with the ipfs merkledag! For a short demo of what you can do, enter 'ipfs tour' ` -// TODO add default welcome hash: eaa68bedae247ed1e5bd0eb4385a3c0959b976e4 // NB: if dspath is not provided, it will be retrieved from the config func doInit(configRoot string, dspathOverride string, force bool, nBitsForKeypair int) (interface{}, error) { @@ -112,7 +111,10 @@ func doInit(configRoot string, dspathOverride string, force bool, nBitsForKeypai return nil, err } - k, _ := defnd.Key() + k, err := defnd.Key() + if err != nil { + return nil, fmt.Errorf("failed to write test file: %s", err) + } fmt.Printf("done.\nto test, enter: ipfs cat %s\n", k) return nil, nil }