Skip to content

Commit

Permalink
feat(cmd.Init): brand new initialization process
Browse files Browse the repository at this point in the history
lotsa fixes to the initialization process. I'd do a proper writeup
but alas no time.
  • Loading branch information
b5 committed Dec 14, 2017
1 parent a3530c1 commit 79371c0
Show file tree
Hide file tree
Showing 6 changed files with 236 additions and 56 deletions.
3 changes: 3 additions & 0 deletions api/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"

"github.com/qri-io/qri/logging"
"github.com/qri-io/qri/p2p"
)

// server modes
Expand Down Expand Up @@ -65,6 +66,8 @@ type Config struct {
Online bool
// list of addresses to bootsrap qri peers on
BoostrapAddrs []string
// PostP2POnlineHook is a chance to call a function after starting P2P services
PostP2POnlineHook func(*p2p.QriNode)
}

// Validate returns nil if this configuration is valid,
Expand Down
8 changes: 7 additions & 1 deletion api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,13 @@ func New(r repo.Repo, options ...func(*Config)) (s *Server, err error) {
s.log.Info("running qri in offline mode, no peer-2-peer connections")
}

s.qriNode.StartOnlineServices()
err = s.qriNode.StartOnlineServices()
if err != nil {
return nil, fmt.Errorf("error starting P2P service: %s", err.Error())
}
if cfg.PostP2POnlineHook != nil {
cfg.PostP2POnlineHook(s.qriNode)
}
// p2p.PrintSwarmAddrs(qriNode)
return s, nil
}
Expand Down
37 changes: 19 additions & 18 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,19 @@ import (
"os"
"path/filepath"

"github.com/qri-io/qri/core"
"github.com/qri-io/qri/p2p"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"gopkg.in/yaml.v2"
)

// Config configures the behaviour of qri
// Config configures the behavior of qri
type Config struct {
// Initialized is a flag for when this repo has been properly initialized at least once.
// used to check weather default datasets should be added or not
Initialized bool
// Identity Configuration details
Identity IdentityCfg
// Identity IdentityCfg
// List of nodes to boostrap to
Bootstrap []string
// Datastore configuration details
Expand All @@ -28,14 +27,14 @@ type Config struct {
}

// IdentityCfg holds details about user identity & configuration
type IdentityCfg struct {
// ID to feed to IPFS node, and for profile identification
PeerID string
// PrivateKey for
PrivateKey string
// Profile
Profile *core.Profile
}
// type IdentityCfg struct {
// // ID to feed to IPFS node, and for profile identification
// PeerID string
// // PrivateKey for
// PrivateKey string
// // Profile
// Profile *core.Profile
// }

// DatastoreCfg configures the underlying IPFS datastore. WIP.
// type DatastoreCfg struct {
Expand Down Expand Up @@ -92,13 +91,15 @@ func configFilepath() string {
return path
}

// func EnsureConfigFile() (bool, error) {
// if _, err := os.Stat(configFilepath()); os.IsNotExist(err) {
// fmt.Println("writing config file")
// return true, WriteConfigFile(defaultCfg)
// }
// return false, nil
// }
func ReadConfigFile() (*Config, error) {
data, err := ioutil.ReadFile(configFilepath())
if err != nil {
return nil, err
}
cfg := Config{}
err = yaml.Unmarshal(data, &cfg)
return &cfg, err
}

func WriteConfigFile(cfg *Config) error {
data, err := yaml.Marshal(cfg)
Expand Down
179 changes: 172 additions & 7 deletions cmd/init.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package cmd

import (
"encoding/json"
"fmt"
"github.com/qri-io/qri/core"
"io/ioutil"
"os"
"path/filepath"
Expand All @@ -10,12 +12,16 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/viper"
"gopkg.in/yaml.v2"

config "gx/ipfs/QmViBzgruNUoLNBnXcx8YWbDNwV8MNGEGKkLo6JGetygdw/go-ipfs/repo/config"
)

var (
initOverwrite bool
initIPFS bool
initIPFSConfigFile string
initIdentityData string
initProfileData string
)

// initCmd represents the init command
Expand All @@ -27,7 +33,8 @@ var initCmd = &cobra.Command{
var cfgData []byte

if QRIRepoInitialized() && !initOverwrite {
ErrExit(fmt.Errorf("repo already initialized. use --overwrite to overwrite this repo, erasing all data"))
// use --overwrite to overwrite this repo, erasing all data and deleting your account for good
ErrExit(fmt.Errorf("repo already initialized."))
}

// if cfgFile is specified, override
Expand All @@ -53,13 +60,57 @@ var initCmd = &cobra.Command{
err = viper.ReadInConfig()
ExitIfErr(err)

if initIdentityData != "" {
err = readAtFile(&initIdentityData)
ExitIfErr(err)

id := config.Identity{}
err = json.Unmarshal([]byte(initIdentityData), &id)
ExitIfErr(err)

path := filepath.Join(os.TempDir(), "config")
data, err := json.Marshal(DefaaultIPFSConfig(id))
ExitIfErr(err)

err = ioutil.WriteFile(path, data, os.ModePerm)
ExitIfErr(err)

initIPFSConfigFile = path
defer os.Remove(path)
}

if initIPFS {
err := ipfs.InitRepo(IpfsFsPath, initIPFSConfigFile)
err = ipfs.InitRepo(IpfsFsPath, initIPFSConfigFile)
ExitIfErr(err)
}

if initProfileData != "" {
err = readAtFile(&initProfileData)
ExitIfErr(err)

p := &core.Profile{}
err = json.Unmarshal([]byte(initProfileData), p)
ExitIfErr(err)

pr, err := ProfileRequests(false)
ExitIfErr(err)

res := &core.Profile{}
err = pr.SaveProfile(p, res)
ExitIfErr(err)
}
},
}

func init() {
RootCmd.AddCommand(initCmd)
initCmd.Flags().BoolVarP(&initOverwrite, "overwrite", "", false, "overwrite repo if one exists")
initCmd.Flags().BoolVarP(&initIPFS, "init-ipfs", "", true, "initialize an IPFS repo if one isn't present")
// initCmd.Flags().StringVarP(&initIPFSConfigFile, "ipfs-config", "", "", "config file for initialization")
initCmd.Flags().StringVarP(&initIdentityData, "id", "", "", "json-encoded identity data, specify a filepath with '@' prefix")
initCmd.Flags().StringVarP(&initProfileData, "profile", "", "", "json-encoded user profile data, specify a filepath with '@' prefix")
}

// QRIRepoInitialized checks to see if a repository has been initialized at $QRI_PATH
func QRIRepoInitialized() bool {
// for now this just checks for an existing config file
Expand All @@ -81,9 +132,123 @@ func initRepoIfEmpty(repoPath, configPath string) error {
return nil
}

func init() {
RootCmd.AddCommand(initCmd)
initCmd.Flags().BoolVarP(&initOverwrite, "overwrite", "", false, "overwrite repo if one exists")
initCmd.Flags().BoolVarP(&initIPFS, "init-ipfs", "", true, "initialize an IPFS repo if one isn't present")
initCmd.Flags().StringVarP(&initIPFSConfigFile, "ipfs-config", "", "", "config file for initialization")
// readAtFile is a unix curl inspired method. any data input that begins with "@"
// is assumed to instead be a filepath that should be read & replaced with the contents
// of the specified path
func readAtFile(data *string) error {
d := *data
if len(d) > 0 && d[0] == '@' {
fileData, err := ioutil.ReadFile(d[1:])
if err != nil {
return err
}
*data = string(fileData)
}
return nil
}

// TODO - this is a bit of a hack for the moment, will be removed later
func DefaaultIPFSConfig(identity config.Identity) *config.Config {
return &config.Config{
Identity: identity,
Datastore: config.Datastore{
StorageMax: "10GB",
StorageGCWatermark: 90,
GCPeriod: "1h",
Spec: map[string]interface{}{
"mounts": []map[string]interface{}{
{
"child": map[string]interface{}{
"path": "blocks",
"shardFunc": "/repo/flatfs/shard/v1/next-to-last/2",
"sync": true,
"type": "flatfs",
},
"mountpoint": "/blocks",
"prefix": "flatfs.datastore",
"type": "measure",
},
{
"child": map[string]interface{}{
"compression": "none",
"path": "datastore",
"type": "levelds",
},
"mountpoint": "/",
"prefix": "leveldb.datastore",
"type": "measure",
},
},
"type": "mount",
},
HashOnRead: false,
BloomFilterSize: 0,
},
Bootstrap: []string{
"/dnsaddr/bootstrap.libp2p.io/ipfs/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
"/dnsaddr/bootstrap.libp2p.io/ipfs/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa",
"/dnsaddr/bootstrap.libp2p.io/ipfs/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb",
"/dnsaddr/bootstrap.libp2p.io/ipfs/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt",
"/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
"/ip4/104.236.179.241/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM",
"/ip4/128.199.219.111/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu",
"/ip4/104.236.76.40/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64",
"/ip4/178.62.158.247/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd",
"/ip6/2604:a880:1:20::203:d001/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM",
"/ip6/2400:6180:0:d0::151:6001/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu",
"/ip6/2604:a880:800:10::4a:5001/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64",
"/ip6/2a03:b0c0:0:1010::23:1001/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd",
},
// setup the node's default addresses.
// NOTE: two swarm listen addrs, one tcp, one utp.
Addresses: config.Addresses{
Swarm: []string{
"/ip4/0.0.0.0/tcp/4001",
// "/ip4/0.0.0.0/udp/4002/utp", // disabled for now.
"/ip6/::/tcp/4001",
},
Announce: []string{},
NoAnnounce: []string{},
API: "/ip4/127.0.0.1/tcp/5001",
Gateway: "/ip4/127.0.0.1/tcp/8080",
},

Discovery: config.Discovery{config.MDNS{
Enabled: true,
Interval: 10,
}},

// setup the node mount points.
Mounts: config.Mounts{
IPFS: "/ipfs",
IPNS: "/ipns",
},

Ipns: config.Ipns{
ResolveCacheSize: 128,
},

Gateway: config.Gateway{
RootRedirect: "",
Writable: false,
PathPrefixes: []string{},
HTTPHeaders: map[string][]string{
"Access-Control-Allow-Origin": []string{"*"},
"Access-Control-Allow-Methods": []string{"GET"},
"Access-Control-Allow-Headers": []string{"X-Requested-With", "Range"},
},
},
Reprovider: config.Reprovider{
Interval: "12h",
Strategy: "all",
},
Swarm: config.SwarmConfig{
ConnMgr: config.ConnMgr{
LowWater: config.DefaultConnMgrLowWater,
HighWater: config.DefaultConnMgrHighWater,
GracePeriod: config.DefaultConnMgrGracePeriod.String(),
Type: "basic",
},
},
}
}
5 changes: 2 additions & 3 deletions cmd/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/qri-io/qri/core"
"github.com/qri-io/qri/repo"
"github.com/qri-io/qri/repo/fs"
"github.com/spf13/viper"
)

var r repo.Repo
Expand Down Expand Up @@ -79,15 +78,15 @@ func SearchRequests(online bool) (*core.SearchRequests, error) {
// RepoOrClient returns either a
func RepoOrClient(online bool) (repo.Repo, *rpc.Client, error) {
if fs, err := ipfs.NewFilestore(func(cfg *ipfs.StoreCfg) {
cfg.FsRepoPath = viper.GetString(IpfsFsPath)
cfg.FsRepoPath = IpfsFsPath
cfg.Online = online
}); err == nil {
id := ""
if fs.Node().PeerHost != nil {
id = fs.Node().PeerHost.ID().Pretty()
}

r, err := fs_repo.NewRepo(fs, viper.GetString(QriRepoPath), id)
r, err := fs_repo.NewRepo(fs, QriRepoPath, id)
return r, nil, err

} else if strings.Contains(err.Error(), "lock") {
Expand Down
Loading

0 comments on commit 79371c0

Please sign in to comment.