提交 6080944a 作者: Jeromy 提交者: Juan Batiz-Benet

writing files inside ipns works now! also implemented resolve cli command

上级 006b68b5
...@@ -53,6 +53,7 @@ Use "ipfs help <command>" for more information about a command. ...@@ -53,6 +53,7 @@ Use "ipfs help <command>" for more information about a command.
cmdIpfsServe, cmdIpfsServe,
cmdIpfsRun, cmdIpfsRun,
cmdIpfsPub, cmdIpfsPub,
cmdIpfsResolve,
}, },
Flag: *flag.NewFlagSet("ipfs", flag.ExitOnError), Flag: *flag.NewFlagSet("ipfs", flag.ExitOnError),
} }
......
package main
import (
"fmt"
"os"
"time"
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
"github.com/jbenet/go-ipfs/core/commands"
"github.com/jbenet/go-ipfs/daemon"
u "github.com/jbenet/go-ipfs/util"
)
var cmdIpfsResolve = &commander.Command{
UsageLine: "resolve",
Short: "resolve an ipns link to a hash",
Long: `ipfs resolve <hash>... - Resolve hash.
`,
Run: resolveCmd,
Flag: *flag.NewFlagSet("ipfs-resolve", flag.ExitOnError),
}
func resolveCmd(c *commander.Command, inp []string) error {
u.Debug = true
if len(inp) < 1 {
u.POut(c.Long)
return nil
}
conf, err := getConfigDir(c.Parent)
if err != nil {
return err
}
cmd := daemon.NewCommand()
cmd.Command = "resolve"
cmd.Args = inp
err = daemon.SendCommand(cmd, conf)
if err != nil {
now := time.Now()
// Resolve requires working DHT
n, err := localNode(conf, true)
if err != nil {
return err
}
took := time.Now().Sub(now)
fmt.Printf("localNode creation took %s\n", took.String())
return commands.Resolve(n, cmd.Args, cmd.Opts, os.Stdout)
}
return nil
}
...@@ -21,10 +21,9 @@ func Publish(n *core.IpfsNode, args []string, opts map[string]interface{}, out i ...@@ -21,10 +21,9 @@ func Publish(n *core.IpfsNode, args []string, opts map[string]interface{}, out i
} }
k := n.Identity.PrivKey k := n.Identity.PrivKey
val := u.Key(args[0])
pub := nsys.NewPublisher(n.DAG, n.Routing) pub := nsys.NewPublisher(n.DAG, n.Routing)
err := pub.Publish(k, val) err := pub.Publish(k, args[0])
if err != nil { if err != nil {
return err return err
} }
...@@ -33,7 +32,7 @@ func Publish(n *core.IpfsNode, args []string, opts map[string]interface{}, out i ...@@ -33,7 +32,7 @@ func Publish(n *core.IpfsNode, args []string, opts map[string]interface{}, out i
if err != nil { if err != nil {
return err return err
} }
fmt.Fprintf(out, "Published %s to %s\n", val, u.Key(hash).Pretty()) fmt.Fprintf(out, "Published %s to %s\n", args[0], u.Key(hash).Pretty())
return nil return nil
} }
package commands
import (
"fmt"
"io"
"github.com/jbenet/go-ipfs/core"
)
func Resolve(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
res, err := n.Namesys.Resolve(args[0])
if err != nil {
return err
}
fmt.Fprintf(out, "%s -> %s\n", args[0], res)
return nil
}
...@@ -133,6 +133,8 @@ func (dl *DaemonListener) handleConnection(conn net.Conn) { ...@@ -133,6 +133,8 @@ func (dl *DaemonListener) handleConnection(conn net.Conn) {
err = commands.Pin(dl.node, command.Args, command.Opts, conn) err = commands.Pin(dl.node, command.Args, command.Opts, conn)
case "publish": case "publish":
err = commands.Publish(dl.node, command.Args, command.Opts, conn) err = commands.Publish(dl.node, command.Args, command.Opts, conn)
case "resolve":
err = commands.Resolve(dl.node, command.Args, command.Opts, conn)
default: default:
err = fmt.Errorf("Invalid Command: '%s'", command.Command) err = fmt.Errorf("Invalid Command: '%s'", command.Command)
} }
......
...@@ -2,6 +2,7 @@ package ipns ...@@ -2,6 +2,7 @@ package ipns
import ( import (
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"os" "os"
"os/exec" "os/exec"
...@@ -83,6 +84,11 @@ func CreateRoot(n *core.IpfsNode, keys []ci.PrivKey, ipfsroot string) (*Root, er ...@@ -83,6 +84,11 @@ func CreateRoot(n *core.IpfsNode, keys []ci.PrivKey, ipfsroot string) (*Root, er
continue continue
} }
if !u.IsValidHash(pointsTo) {
log.Critical("Got back bad data from namesys resolve! [%s]", pointsTo)
return nil, nil
}
node, err := n.Resolver.ResolvePath(pointsTo) node, err := n.Resolver.ResolvePath(pointsTo)
if err != nil { if err != nil {
log.Warning("Failed to resolve value from ipns entry in ipfs") log.Warning("Failed to resolve value from ipns entry in ipfs")
...@@ -120,7 +126,7 @@ func (*Root) Attr() fuse.Attr { ...@@ -120,7 +126,7 @@ func (*Root) Attr() fuse.Attr {
// Lookup performs a lookup under this node. // Lookup performs a lookup under this node.
func (s *Root) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) { func (s *Root) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) {
log.Debug("ipns: Root Lookup: '%s'", name) log.Debug("ipns: Root Lookup: '%s' [intr = %s]", name, intr.String())
switch name { switch name {
case "mach_kernel", ".hidden", "._.": case "mach_kernel", ".hidden", "._.":
// Just quiet some log noise on OS X. // Just quiet some log noise on OS X.
...@@ -139,14 +145,14 @@ func (s *Root) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) { ...@@ -139,14 +145,14 @@ func (s *Root) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) {
return nd, nil return nd, nil
} }
log.Debug("ipns: Falling back to resolution.") log.Debug("ipns: Falling back to resolution for [%s].", name)
resolved, err := s.Ipfs.Namesys.Resolve(name) resolved, err := s.Ipfs.Namesys.Resolve(name)
if err != nil { if err != nil {
log.Error("ipns: namesys resolve error: %s", err) log.Error("ipns: namesys resolve error: %s", err)
return nil, fuse.ENOENT return nil, fuse.ENOENT
} }
return &Link{s.IpfsRoot + "/" + resolved}, nil return &Link{s.IpfsRoot + "/" + u.Key(resolved).Pretty()}, nil
} }
// ReadDir reads a particular directory. Disallowed for root. // ReadDir reads a particular directory. Disallowed for root.
...@@ -221,7 +227,7 @@ func (s *Node) Attr() fuse.Attr { ...@@ -221,7 +227,7 @@ func (s *Node) Attr() fuse.Attr {
// Lookup performs a lookup under this node. // Lookup performs a lookup under this node.
func (s *Node) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) { func (s *Node) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) {
log.Debug("ipns node Lookup '%s'", name) log.Debug("ipns: node Lookup '%s'", name)
nd, err := s.Ipfs.Resolver.ResolveLinks(s.Nd, []string{name}) nd, err := s.Ipfs.Resolver.ResolveLinks(s.Nd, []string{name})
if err != nil { if err != nil {
// todo: make this error more versatile. // todo: make this error more versatile.
...@@ -276,7 +282,7 @@ func (n *Node) Write(req *fuse.WriteRequest, resp *fuse.WriteResponse, intr fs.I ...@@ -276,7 +282,7 @@ func (n *Node) Write(req *fuse.WriteRequest, resp *fuse.WriteResponse, intr fs.I
if n.dataBuf == nil { if n.dataBuf == nil {
n.dataBuf = new(bytes.Buffer) n.dataBuf = new(bytes.Buffer)
} }
log.Debug("ipns Node Write: flags = %s, offset = %d, size = %d", req.Flags.String(), req.Offset, len(req.Data)) log.Debug("ipns: Node Write: flags = %s, offset = %d, size = %d", req.Flags.String(), req.Offset, len(req.Data))
if req.Offset == 0 { if req.Offset == 0 {
n.dataBuf.Reset() n.dataBuf.Reset()
n.dataBuf.Write(req.Data) n.dataBuf.Write(req.Data)
...@@ -298,11 +304,18 @@ func (n *Node) Flush(req *fuse.FlushRequest, intr fs.Intr) fuse.Error { ...@@ -298,11 +304,18 @@ func (n *Node) Flush(req *fuse.FlushRequest, intr fs.Intr) fuse.Error {
// but for now, since the buf is all in memory anyways... // but for now, since the buf is all in memory anyways...
err := imp.NewDagInNode(n.dataBuf, n.Nd) err := imp.NewDagInNode(n.dataBuf, n.Nd)
if err != nil { if err != nil {
log.Error("ipns Flush error: %s", err) log.Error("ipns: Flush error: %s", err)
// return fuse.EVERYBAD // return fuse.EVERYBAD
return fuse.ENODATA return fuse.ENODATA
} }
read, err := mdag.NewDagReader(n.Nd, n.Ipfs.DAG)
if err != nil {
panic(err)
}
io.Copy(os.Stdout, read)
var root *Node var root *Node
if n.nsRoot != nil { if n.nsRoot != nil {
root = n.nsRoot root = n.nsRoot
...@@ -312,13 +325,13 @@ func (n *Node) Flush(req *fuse.FlushRequest, intr fs.Intr) fuse.Error { ...@@ -312,13 +325,13 @@ func (n *Node) Flush(req *fuse.FlushRequest, intr fs.Intr) fuse.Error {
err = root.Nd.Update() err = root.Nd.Update()
if err != nil { if err != nil {
log.Error("ipns dag tree update failed: %s", err) log.Error("ipns: dag tree update failed: %s", err)
return fuse.ENODATA return fuse.ENODATA
} }
err = n.Ipfs.DAG.AddRecursive(root.Nd) err = n.Ipfs.DAG.AddRecursive(root.Nd)
if err != nil { if err != nil {
log.Critical("ipns Dag Add Error: %s", err) log.Critical("ipns: Dag Add Error: %s", err)
} }
n.changed = false n.changed = false
...@@ -332,9 +345,9 @@ func (n *Node) Flush(req *fuse.FlushRequest, intr fs.Intr) fuse.Error { ...@@ -332,9 +345,9 @@ func (n *Node) Flush(req *fuse.FlushRequest, intr fs.Intr) fuse.Error {
} }
log.Debug("Publishing changes!") log.Debug("Publishing changes!")
err = n.Ipfs.Publisher.Publish(root.key, ndkey) err = n.Ipfs.Publisher.Publish(root.key, ndkey.Pretty())
if err != nil { if err != nil {
log.Error("ipns Publish Failed: %s", err) log.Error("ipns: Publish Failed: %s", err)
} }
} }
return nil return nil
...@@ -433,5 +446,6 @@ func (l *Link) Attr() fuse.Attr { ...@@ -433,5 +446,6 @@ func (l *Link) Attr() fuse.Attr {
} }
func (l *Link) Readlink(req *fuse.ReadlinkRequest, intr fs.Intr) (string, fuse.Error) { func (l *Link) Readlink(req *fuse.ReadlinkRequest, intr fs.Intr) (string, fuse.Error) {
log.Debug("ReadLink: %s", l.Target)
return l.Target, nil return l.Target, nil
} }
...@@ -67,7 +67,7 @@ func NewDagInNode(r io.Reader, n *dag.Node) error { ...@@ -67,7 +67,7 @@ func NewDagInNode(r io.Reader, n *dag.Node) error {
blkChan := DefaultSplitter.Split(r) blkChan := DefaultSplitter.Split(r)
first := <-blkChan first := <-blkChan
n.Data = first n.Data = dag.FilePBData(first)
for blk := range blkChan { for blk := range blkChan {
child := &dag.Node{Data: dag.WrapData(blk)} child := &dag.Node{Data: dag.WrapData(blk)}
......
package namesys package namesys
type Resolver interface { type Resolver interface {
// Resolve returns a base58 encoded string
Resolve(string) (string, error) Resolve(string) (string, error)
Matches(string) bool Matches(string) bool
} }
...@@ -25,8 +25,8 @@ func NewPublisher(dag *mdag.DAGService, route routing.IpfsRouting) *IpnsPublishe ...@@ -25,8 +25,8 @@ func NewPublisher(dag *mdag.DAGService, route routing.IpfsRouting) *IpnsPublishe
} }
// Publish accepts a keypair and a value, // Publish accepts a keypair and a value,
func (p *IpnsPublisher) Publish(k ci.PrivKey, value u.Key) error { func (p *IpnsPublisher) Publish(k ci.PrivKey, value string) error {
log.Debug("namesys: Publish %s", value.Pretty()) log.Debug("namesys: Publish %s", value)
ctx := context.TODO() ctx := context.TODO()
data, err := CreateEntryData(k, value) data, err := CreateEntryData(k, value)
if err != nil { if err != nil {
...@@ -66,7 +66,7 @@ func (p *IpnsPublisher) Publish(k ci.PrivKey, value u.Key) error { ...@@ -66,7 +66,7 @@ func (p *IpnsPublisher) Publish(k ci.PrivKey, value u.Key) error {
return nil return nil
} }
func CreateEntryData(pk ci.PrivKey, val u.Key) ([]byte, error) { func CreateEntryData(pk ci.PrivKey, val string) ([]byte, error) {
entry := new(IpnsEntry) entry := new(IpnsEntry)
sig, err := pk.Sign([]byte(val)) sig, err := pk.Sign([]byte(val))
if err != nil { if err != nil {
......
...@@ -7,9 +7,8 @@ import ( ...@@ -7,9 +7,8 @@ import (
bs "github.com/jbenet/go-ipfs/blockservice" bs "github.com/jbenet/go-ipfs/blockservice"
ci "github.com/jbenet/go-ipfs/crypto" ci "github.com/jbenet/go-ipfs/crypto"
mdag "github.com/jbenet/go-ipfs/merkledag" mdag "github.com/jbenet/go-ipfs/merkledag"
"github.com/jbenet/go-ipfs/net/swarm"
"github.com/jbenet/go-ipfs/peer" "github.com/jbenet/go-ipfs/peer"
"github.com/jbenet/go-ipfs/routing/dht" mock "github.com/jbenet/go-ipfs/routing/mock"
u "github.com/jbenet/go-ipfs/util" u "github.com/jbenet/go-ipfs/util"
) )
...@@ -17,9 +16,8 @@ func TestRoutingResolve(t *testing.T) { ...@@ -17,9 +16,8 @@ func TestRoutingResolve(t *testing.T) {
local := &peer.Peer{ local := &peer.Peer{
ID: []byte("testID"), ID: []byte("testID"),
} }
net := swarm.NewSwarm(local)
lds := ds.NewMapDatastore() lds := ds.NewMapDatastore()
d := dht.NewDHT(local, net, lds) d := mock.NewMockRouter(local, lds)
bserv, err := bs.NewBlockService(lds, nil) bserv, err := bs.NewBlockService(lds, nil)
if err != nil { if err != nil {
...@@ -40,7 +38,7 @@ func TestRoutingResolve(t *testing.T) { ...@@ -40,7 +38,7 @@ func TestRoutingResolve(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
err = pub.Publish(privk, u.Key("Hello")) err = pub.Publish(privk, "Hello")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
......
...@@ -35,6 +35,7 @@ func (r *RoutingResolver) Matches(name string) bool { ...@@ -35,6 +35,7 @@ func (r *RoutingResolver) Matches(name string) bool {
} }
func (r *RoutingResolver) Resolve(name string) (string, error) { func (r *RoutingResolver) Resolve(name string) (string, error) {
log.Debug("RoutingResolve: '%s'", name)
ctx := context.TODO() ctx := context.TODO()
hash, err := mh.FromB58String(name) hash, err := mh.FromB58String(name)
if err != nil { if err != nil {
......
...@@ -8,8 +8,11 @@ import ( ...@@ -8,8 +8,11 @@ import (
mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash" mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
merkledag "github.com/jbenet/go-ipfs/merkledag" merkledag "github.com/jbenet/go-ipfs/merkledag"
u "github.com/jbenet/go-ipfs/util" u "github.com/jbenet/go-ipfs/util"
"github.com/op/go-logging"
) )
var log = logging.MustGetLogger("path")
// Resolver provides path resolution to IPFS // Resolver provides path resolution to IPFS
// It has a pointer to a DAGService, which is uses to resolve nodes. // It has a pointer to a DAGService, which is uses to resolve nodes.
type Resolver struct { type Resolver struct {
...@@ -20,7 +23,7 @@ type Resolver struct { ...@@ -20,7 +23,7 @@ type Resolver struct {
// path component as a hash (key) of the first node, then resolves // path component as a hash (key) of the first node, then resolves
// all other components walking the links, with ResolveLinks. // all other components walking the links, with ResolveLinks.
func (s *Resolver) ResolvePath(fpath string) (*merkledag.Node, error) { func (s *Resolver) ResolvePath(fpath string) (*merkledag.Node, error) {
u.DOut("Resolve: '%s'\n", fpath) log.Debug("Resolve: '%s'", fpath)
fpath = path.Clean(fpath) fpath = path.Clean(fpath)
parts := strings.Split(fpath, "/") parts := strings.Split(fpath, "/")
...@@ -66,10 +69,12 @@ func (s *Resolver) ResolveLinks(ndd *merkledag.Node, names []string) ( ...@@ -66,10 +69,12 @@ func (s *Resolver) ResolveLinks(ndd *merkledag.Node, names []string) (
for _, name := range names { for _, name := range names {
var next u.Key var next u.Key
var nlink *merkledag.Link
// for each of the links in nd, the current object // for each of the links in nd, the current object
for _, link := range nd.Links { for _, link := range nd.Links {
if link.Name == name { if link.Name == name {
next = u.Key(link.Hash) next = u.Key(link.Hash)
nlink = link
break break
} }
} }
...@@ -80,10 +85,15 @@ func (s *Resolver) ResolveLinks(ndd *merkledag.Node, names []string) ( ...@@ -80,10 +85,15 @@ func (s *Resolver) ResolveLinks(ndd *merkledag.Node, names []string) (
return nil, fmt.Errorf("no link named %q under %s", name, h2) return nil, fmt.Errorf("no link named %q under %s", name, h2)
} }
// fetch object for link and assign to nd if nlink.Node == nil {
nd, err = s.DAG.Get(next) // fetch object for link and assign to nd
if err != nil { nd, err = s.DAG.Get(next)
return nd, err if err != nil {
return nd, err
}
nlink.Node = nd
} else {
nd = nlink.Node
} }
} }
return return
......
...@@ -18,7 +18,7 @@ import ( ...@@ -18,7 +18,7 @@ import (
// PutValue adds value corresponding to given Key. // PutValue adds value corresponding to given Key.
// This is the top level "Store" operation of the DHT // This is the top level "Store" operation of the DHT
func (dht *IpfsDHT) PutValue(ctx context.Context, key u.Key, value []byte) error { func (dht *IpfsDHT) PutValue(ctx context.Context, key u.Key, value []byte) error {
log.Debug("[%s] PutValue %v %v", dht.self.ID.Pretty(), key.Pretty(), value) log.Debug("PutValue %s %v", key.Pretty(), value)
err := dht.putLocal(key, value) err := dht.putLocal(key, value)
if err != nil { if err != nil {
return err return err
......
...@@ -11,8 +11,17 @@ import ( ...@@ -11,8 +11,17 @@ import (
ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go" ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/datastore.go"
b58 "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-base58" b58 "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-base58"
mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash" mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
"github.com/op/go-logging"
) )
var format = "%{color}%{time} %{shortfile} %{level}: %{color:reset}%{message}"
func init() {
backend := logging.NewLogBackend(os.Stderr, "", 0)
logging.SetBackend(backend)
logging.SetFormatter(logging.MustStringFormatter(format))
}
// Debug is a global flag for debugging. // Debug is a global flag for debugging.
var Debug bool var Debug bool
...@@ -42,6 +51,14 @@ func Hash(data []byte) (mh.Multihash, error) { ...@@ -42,6 +51,14 @@ func Hash(data []byte) (mh.Multihash, error) {
return mh.Sum(data, mh.SHA2_256, -1) return mh.Sum(data, mh.SHA2_256, -1)
} }
func IsValidHash(s string) bool {
out := b58.Decode(s)
if out == nil || len(out) == 0 {
return false
}
return true
}
// TildeExpansion expands a filename, which may begin with a tilde. // TildeExpansion expands a filename, which may begin with a tilde.
func TildeExpansion(filename string) (string, error) { func TildeExpansion(filename string) (string, error) {
if strings.HasPrefix(filename, "~/") { if strings.HasPrefix(filename, "~/") {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论