提交 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.
cmdIpfsServe,
cmdIpfsRun,
cmdIpfsPub,
cmdIpfsResolve,
},
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
}
k := n.Identity.PrivKey
val := u.Key(args[0])
pub := nsys.NewPublisher(n.DAG, n.Routing)
err := pub.Publish(k, val)
err := pub.Publish(k, args[0])
if err != nil {
return err
}
......@@ -33,7 +32,7 @@ func Publish(n *core.IpfsNode, args []string, opts map[string]interface{}, out i
if err != nil {
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
}
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) {
err = commands.Pin(dl.node, command.Args, command.Opts, conn)
case "publish":
err = commands.Publish(dl.node, command.Args, command.Opts, conn)
case "resolve":
err = commands.Resolve(dl.node, command.Args, command.Opts, conn)
default:
err = fmt.Errorf("Invalid Command: '%s'", command.Command)
}
......
......@@ -2,6 +2,7 @@ package ipns
import (
"fmt"
"io"
"io/ioutil"
"os"
"os/exec"
......@@ -83,6 +84,11 @@ func CreateRoot(n *core.IpfsNode, keys []ci.PrivKey, ipfsroot string) (*Root, er
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)
if err != nil {
log.Warning("Failed to resolve value from ipns entry in ipfs")
......@@ -120,7 +126,7 @@ func (*Root) Attr() fuse.Attr {
// Lookup performs a lookup under this node.
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 {
case "mach_kernel", ".hidden", "._.":
// 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) {
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)
if err != nil {
log.Error("ipns: namesys resolve error: %s", err)
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.
......@@ -221,7 +227,7 @@ func (s *Node) Attr() fuse.Attr {
// Lookup performs a lookup under this node.
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})
if err != nil {
// todo: make this error more versatile.
......@@ -276,7 +282,7 @@ func (n *Node) Write(req *fuse.WriteRequest, resp *fuse.WriteResponse, intr fs.I
if n.dataBuf == nil {
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 {
n.dataBuf.Reset()
n.dataBuf.Write(req.Data)
......@@ -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...
err := imp.NewDagInNode(n.dataBuf, n.Nd)
if err != nil {
log.Error("ipns Flush error: %s", err)
log.Error("ipns: Flush error: %s", err)
// return fuse.EVERYBAD
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
if n.nsRoot != nil {
root = n.nsRoot
......@@ -312,13 +325,13 @@ func (n *Node) Flush(req *fuse.FlushRequest, intr fs.Intr) fuse.Error {
err = root.Nd.Update()
if err != nil {
log.Error("ipns dag tree update failed: %s", err)
log.Error("ipns: dag tree update failed: %s", err)
return fuse.ENODATA
}
err = n.Ipfs.DAG.AddRecursive(root.Nd)
if err != nil {
log.Critical("ipns Dag Add Error: %s", err)
log.Critical("ipns: Dag Add Error: %s", err)
}
n.changed = false
......@@ -332,9 +345,9 @@ func (n *Node) Flush(req *fuse.FlushRequest, intr fs.Intr) fuse.Error {
}
log.Debug("Publishing changes!")
err = n.Ipfs.Publisher.Publish(root.key, ndkey)
err = n.Ipfs.Publisher.Publish(root.key, ndkey.Pretty())
if err != nil {
log.Error("ipns Publish Failed: %s", err)
log.Error("ipns: Publish Failed: %s", err)
}
}
return nil
......@@ -433,5 +446,6 @@ func (l *Link) Attr() fuse.Attr {
}
func (l *Link) Readlink(req *fuse.ReadlinkRequest, intr fs.Intr) (string, fuse.Error) {
log.Debug("ReadLink: %s", l.Target)
return l.Target, nil
}
......@@ -67,7 +67,7 @@ func NewDagInNode(r io.Reader, n *dag.Node) error {
blkChan := DefaultSplitter.Split(r)
first := <-blkChan
n.Data = first
n.Data = dag.FilePBData(first)
for blk := range blkChan {
child := &dag.Node{Data: dag.WrapData(blk)}
......
package namesys
type Resolver interface {
// Resolve returns a base58 encoded string
Resolve(string) (string, error)
Matches(string) bool
}
......@@ -25,8 +25,8 @@ func NewPublisher(dag *mdag.DAGService, route routing.IpfsRouting) *IpnsPublishe
}
// Publish accepts a keypair and a value,
func (p *IpnsPublisher) Publish(k ci.PrivKey, value u.Key) error {
log.Debug("namesys: Publish %s", value.Pretty())
func (p *IpnsPublisher) Publish(k ci.PrivKey, value string) error {
log.Debug("namesys: Publish %s", value)
ctx := context.TODO()
data, err := CreateEntryData(k, value)
if err != nil {
......@@ -66,7 +66,7 @@ func (p *IpnsPublisher) Publish(k ci.PrivKey, value u.Key) error {
return nil
}
func CreateEntryData(pk ci.PrivKey, val u.Key) ([]byte, error) {
func CreateEntryData(pk ci.PrivKey, val string) ([]byte, error) {
entry := new(IpnsEntry)
sig, err := pk.Sign([]byte(val))
if err != nil {
......
......@@ -7,9 +7,8 @@ import (
bs "github.com/jbenet/go-ipfs/blockservice"
ci "github.com/jbenet/go-ipfs/crypto"
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/routing/dht"
mock "github.com/jbenet/go-ipfs/routing/mock"
u "github.com/jbenet/go-ipfs/util"
)
......@@ -17,9 +16,8 @@ func TestRoutingResolve(t *testing.T) {
local := &peer.Peer{
ID: []byte("testID"),
}
net := swarm.NewSwarm(local)
lds := ds.NewMapDatastore()
d := dht.NewDHT(local, net, lds)
d := mock.NewMockRouter(local, lds)
bserv, err := bs.NewBlockService(lds, nil)
if err != nil {
......@@ -40,7 +38,7 @@ func TestRoutingResolve(t *testing.T) {
t.Fatal(err)
}
err = pub.Publish(privk, u.Key("Hello"))
err = pub.Publish(privk, "Hello")
if err != nil {
t.Fatal(err)
}
......
......@@ -35,6 +35,7 @@ func (r *RoutingResolver) Matches(name string) bool {
}
func (r *RoutingResolver) Resolve(name string) (string, error) {
log.Debug("RoutingResolve: '%s'", name)
ctx := context.TODO()
hash, err := mh.FromB58String(name)
if err != nil {
......
......@@ -8,8 +8,11 @@ import (
mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
merkledag "github.com/jbenet/go-ipfs/merkledag"
u "github.com/jbenet/go-ipfs/util"
"github.com/op/go-logging"
)
var log = logging.MustGetLogger("path")
// Resolver provides path resolution to IPFS
// It has a pointer to a DAGService, which is uses to resolve nodes.
type Resolver struct {
......@@ -20,7 +23,7 @@ type Resolver struct {
// path component as a hash (key) of the first node, then resolves
// all other components walking the links, with ResolveLinks.
func (s *Resolver) ResolvePath(fpath string) (*merkledag.Node, error) {
u.DOut("Resolve: '%s'\n", fpath)
log.Debug("Resolve: '%s'", fpath)
fpath = path.Clean(fpath)
parts := strings.Split(fpath, "/")
......@@ -66,10 +69,12 @@ func (s *Resolver) ResolveLinks(ndd *merkledag.Node, names []string) (
for _, name := range names {
var next u.Key
var nlink *merkledag.Link
// for each of the links in nd, the current object
for _, link := range nd.Links {
if link.Name == name {
next = u.Key(link.Hash)
nlink = link
break
}
}
......@@ -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)
}
// fetch object for link and assign to nd
nd, err = s.DAG.Get(next)
if err != nil {
return nd, err
if nlink.Node == nil {
// fetch object for link and assign to nd
nd, err = s.DAG.Get(next)
if err != nil {
return nd, err
}
nlink.Node = nd
} else {
nd = nlink.Node
}
}
return
......
......@@ -18,7 +18,7 @@ import (
// PutValue adds value corresponding to given Key.
// This is the top level "Store" operation of the DHT
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)
if err != nil {
return err
......
......@@ -11,8 +11,17 @@ import (
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"
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.
var Debug bool
......@@ -42,6 +51,14 @@ func Hash(data []byte) (mh.Multihash, error) {
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.
func TildeExpansion(filename string) (string, error) {
if strings.HasPrefix(filename, "~/") {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论