Skip to content

Commit

Permalink
feat(ipfs): use tcp shell on simulator
Browse files Browse the repository at this point in the history
  • Loading branch information
gfanton authored and aeddi committed Dec 1, 2019
1 parent 106c14e commit 3e4f7ef
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 115 deletions.
27 changes: 16 additions & 11 deletions go/bind/ipfs/bind_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,40 @@ import (
// ipfs_log "github.com/ipfs/go-log"
)

type Node interface {
// Close ipfs node
Close() error
type Node struct {
*mobile_node.IpfsMobile
}

func (n *Node) Close() error {
return n.IpfsMobile.Close()
}

// GetApiAddrs return current api listeners (separate with a comma)
GetApiAddrs() string
func (n *Node) ServeUnixSocketAPI(sockpath string) error {
return n.IpfsMobile.Serve("/unix/" + sockpath)
}

// Serve api on the given unix socket path
ServeOnUDS(sockpath string) error
func (n *Node) ServeTCPAPI(port string) error {
return n.IpfsMobile.Serve("/ip4/127.0.0.1/tcp/" + port)
}

func NewNode(r *Repo) (Node, error) {
func NewNode(r *Repo) (*Node, error) {
ctx := context.Background()

if _, err := loadPlugins(r.path); err != nil {
return nil, err
}

repo := &mobile_node.MobileRepo{r.irepo, r.path}
node, err := mobile_node.NewNode(ctx, repo, &mobile_host.MobileConfig{})
mnode, err := mobile_node.NewNode(ctx, repo, &mobile_host.MobileConfig{})
if err != nil {
return nil, err
}

if err := node.IpfsNode.Bootstrap(ipfs_bs.DefaultBootstrapConfig); err != nil {
if err := mnode.IpfsNode.Bootstrap(ipfs_bs.DefaultBootstrapConfig); err != nil {
log.Printf("failed to bootstrap node: `%s`", err)
}

return node, nil
return &Node{mnode}, nil
}

func init() {
Expand Down
39 changes: 15 additions & 24 deletions go/pkg/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import (
"context"
"fmt"
"log"
"strings"
"sync"

host "github.com/berty/gomobile-ipfs/go/pkg/host"
"github.com/pkg/errors"

ipfs_core "github.com/ipfs/go-ipfs/core"

Expand All @@ -29,31 +29,14 @@ func (im *IpfsMobile) Close() error {
_ = l.Close()
}

// unlockRepo(im.repoPath)

return err
}

// GetApiAddrs return current api listeners (separate with a comma)
func (im *IpfsMobile) GetApiAddrs() string {
var addrs []string
for _, l := range im.listeners {
a, err := manet.FromNetAddr(l.Addr())
if err != nil {
log.Printf("unable to get multiaddr from `%s`: %s", l.Addr().String(), err)
continue
}

addrs = append(addrs, a.String())
}

return strings.Join(addrs, ",")
}

func NewNode(ctx context.Context, repo *MobileRepo, mcfg *host.MobileConfig) (*IpfsMobile, error) {
// if err := lockRepo(repoPath); err != nil {
// return nil, fmt.Errorf("failed to init ipfs node: %s", err)
// }
cfg, err := repo.Config()
if err != nil {
return nil, errors.Wrap(err, "cant get config")
}

// build config
buildcfg := &ipfs_core.BuildCfg{
Expand All @@ -72,9 +55,17 @@ func NewNode(ctx context.Context, repo *MobileRepo, mcfg *host.MobileConfig) (*I
return nil, fmt.Errorf("failed to init ipfs node: %s", err)
}

return &IpfsMobile{
node := &IpfsMobile{
listeners: make([]manet.Listener, 0),
IpfsNode: inode,
Repo: repo,
}, nil
}

if len(cfg.Addresses.API) > 0 {
if err = node.Serve(cfg.Addresses.API...); err != nil {
log.Printf("unable to serve config API")
}
}

return node, nil
}
92 changes: 19 additions & 73 deletions go/pkg/node/node_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,80 +14,9 @@ import (
manet "github.com/multiformats/go-multiaddr-net"
)

func (im *IpfsMobile) ServeOnUDS(sockpath string) error {
var cfg *ipfs_config.Config
func (im *IpfsMobile) Serve(maddrs ...string) error {
var err error

cfg, err = im.Repo.Config()
if err != nil {
return fmt.Errorf("config error: %s", err)
}

im.muListeners.Lock()
defer im.muListeners.Unlock()

// closes previous listeners if any
for _, l := range im.listeners {
_ = l.Close()
}

addrs := append(cfg.Addresses.API, "/unix/"+sockpath)

// Configure API if needed
listeners := make([]manet.Listener, len(addrs))
for i, addr := range addrs {
var listener manet.Listener
var maddr ma.Multiaddr

maddr, err = ma.NewMultiaddr(addr)
if err != nil {
return fmt.Errorf("failed to parse ma: %s, %s", addr, err)
}

listener, err = manet.Listen(maddr)
// ma.ForEach(maddr, func(c ma.Component) bool {
// switch c.Protocol().Code {
// case ma.P_IP4, ma.P_IP6:
// listener, err = manet.Listen(maddr)
// case ma.P_UNIX:
// // sockpath := c.Value()
// // if !strings.HasPrefix(sockpath, "//") {
// // sockpath = filepath.Join(im.Repo.Path, sockpath)
// // if maddr, err = ma.NewMultiaddr("/unix/" + sockpath); err != nil {
// // return true
// // }
// // }

// // // @HOTFIX: if api sock already exists, delete it before listening.
// // // This will happen everytime the app is killed and
// // // the node isn't properly closed on the ios/android side.
// // if _, serr := os.Stat(sockpath); serr == nil {
// // if serr := os.Remove(sockpath); serr != nil {
// // log.Printf("unable to delete old sock: %s", serr)
// // }
// // }

// listener, err = manet.Listen(maddr)
// default:
// return false
// }

// return true
// })

if err != nil {
return fmt.Errorf("Listen on `%s` failed: %s", maddr.String(), err)
}

if listener == nil {
return fmt.Errorf("`%s` is not supported", maddr.String())
}

listeners[i] = listener
}

im.listeners = listeners

// @TODO: no sure about how to init this, must be another way
cctx := ipfs_oldcmds.Context{
ConfigRoot: im.Repo.Path,
Expand All @@ -111,14 +40,31 @@ func (im *IpfsMobile) ServeOnUDS(sockpath string) error {
ipfs_corehttp.CommandsOption(cctx),
}

for _, ml := range im.listeners {
im.muListeners.Lock()
defer im.muListeners.Unlock()

for _, addr := range maddrs {
var ml manet.Listener
var maddr ma.Multiaddr

maddr, err = ma.NewMultiaddr(addr)
if err != nil {
return fmt.Errorf("failed to parse ma: %s, %s", addr, err)
}

ml, err = manet.Listen(maddr)
if err != nil {
return fmt.Errorf("Listen on `%s` failed: %s", maddr.String(), err)
}

l := manet.NetListener(ml)
go func(l net.Listener) {
if err := ipfs_corehttp.Serve(im.IpfsNode, l, opts...); err != nil {
log.Printf("serve error: %s", err)
}
}(l)

im.listeners = append(im.listeners, ml)
}

return nil
Expand Down
20 changes: 16 additions & 4 deletions ios/GomobileIPFS/Classes/IPFS.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ extension FileManager {
}
}


public enum IpfsError: LocalizedError {
case nodeAlreadyStarted
case nodeNotStarted
Expand Down Expand Up @@ -66,12 +65,16 @@ public class IPFS: NSObject {
self.absRepoURL = absUserUrl.appendingPathComponent(repoPath, isDirectory: true)

// init sockmanager singleton if needed
self.absSockPath = ""
#if !targetEnvironment(simulator)
if IPFS.sockManager == nil {
let absTmpURL = FileManager.default.compatTemporaryDirectory
IPFS.sockManager = try SockManager(absTmpURL)
}

self.absSockPath = try IPFS.sockManager!.newSockPath()
#endif


// init repo if needed
if !(try Repo.isInitialized(url: absRepoURL)) {
Expand All @@ -95,23 +98,32 @@ public class IPFS: NSObject {
throw IpfsError.nodeAlreadyStarted
}

var err: NSError?

// open repo
let repo = try Repo(self.absRepoURL)

// init node
let node = try Node(repo)

// serve api
try node.serveOnUDS(sockpath: self.absSockPath)
var err: NSError?

#if targetEnvironment(simulator) // fallback on tcp on simulator
try node.serve(onTCPPort: "4555")
// init shell
if let shell = IpfsNewTCPShell("4555", &err) {
self.shell = shell
} else {
throw IpfsError.runtimeError("unable to get shell")
}
#else
try node.serve(onUDS: self.absSockPath)
// init shell
if let shell = IpfsNewUDSShell(self.absSockPath, &err) {
self.shell = shell
} else {
throw IpfsError.runtimeError("unable to get shell")
}
#endif

if let err = err {
throw IpfsError.runtime(err, "unable to start shell")
Expand Down
10 changes: 7 additions & 3 deletions ios/GomobileIPFS/Classes/Node.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public enum NodeError: Error {
}

public class Node {
let node: IpfsNodeProtocol
let node: IpfsNode

public init(_ repo: Repo) throws {
var err: NSError?
Expand All @@ -32,7 +32,11 @@ public class Node {
try self.node.close()
}

public func serveOnUDS(sockpath: String) throws {
try self.node.serve(onUDS: sockpath)
public func serve(onUDS: String) throws {
try self.node.serveUnixSocketAPI(onUDS)
}

public func serve(onTCPPort: String) throws {
try self.node.serveTCPAPI(onTCPPort)
}
}

0 comments on commit 3e4f7ef

Please sign in to comment.