// TODO: extract all this logic from the core/commands/object.go to avoid dupe code func (s *Shell) Patch(root, action string, args ...string) (string, error) { p, err := path.ParsePath(root) if err != nil { return "", err } rootnd, err := core.Resolve(s.ctx, s.node, p) if err != nil { return "", err } insertpath := args[0] childhash := args[1] childpath, err := path.ParsePath(childhash) if err != nil { return "", err } nnode, err := core.Resolve(s.ctx, s.node, childpath) if err != nil { return "", err } e := dagutils.NewDagEditor(rootnd, s.node.DAG) switch action { case "add-link": err := e.InsertNodeAtPath(s.ctx, insertpath, nnode, nil) if err != nil { return "", err } _, err = e.Finalize(s.node.DAG) if err != nil { return "", err } final, err := e.GetNode().Key() if err != nil { return "", err } return final.B58String(), nil default: return "", fmt.Errorf("unsupported action (impl not complete)") } }
func Pin(n *core.IpfsNode, ctx context.Context, paths []string, recursive bool) ([]*cid.Cid, error) { dagnodes := make([]node.Node, 0) for _, fpath := range paths { p, err := path.ParsePath(fpath) if err != nil { return nil, err } dagnode, err := core.Resolve(ctx, n.Namesys, n.Resolver, p) if err != nil { return nil, fmt.Errorf("pin: %s", err) } dagnodes = append(dagnodes, dagnode) } var out []*cid.Cid for _, dagnode := range dagnodes { c := dagnode.Cid() ctx, cancel := context.WithCancel(ctx) defer cancel() err := n.Pinning.Pin(ctx, dagnode, recursive) if err != nil { return nil, fmt.Errorf("pin: %s", err) } out = append(out, c) } err := n.Pinning.Flush() if err != nil { return nil, err } return out, nil }
func Unpin(n *core.IpfsNode, paths []string, recursive bool) ([]key.Key, error) { // TODO(cryptix): do we want a ctx as first param for (Un)Pin() as well, just like core.Resolve? ctx := n.Context() dagnodes := make([]*merkledag.Node, 0) for _, fpath := range paths { dagnode, err := core.Resolve(ctx, n, path.Path(fpath)) if err != nil { return nil, err } dagnodes = append(dagnodes, dagnode) } var unpinned []key.Key for _, dagnode := range dagnodes { k, _ := dagnode.Key() ctx, cancel := context.WithTimeout(ctx, time.Minute) defer cancel() err := n.Pinning.Unpin(ctx, k, recursive) if err != nil { return nil, err } unpinned = append(unpinned, k) } err := n.Pinning.Flush() if err != nil { return nil, err } return unpinned, nil }
func publish(ctx context.Context, n *core.IpfsNode, k crypto.PrivKey, ref path.Path, opts *publishOpts) (*IpnsEntry, error) { if opts.verifyExists { // verify the path exists _, err := core.Resolve(ctx, n.Namesys, n.Resolver, ref) if err != nil { return nil, err } } eol := time.Now().Add(opts.pubValidTime) err := n.Namesys.PublishWithEOL(ctx, k, ref, eol) if err != nil { return nil, err } pid, err := peer.IDFromPrivateKey(k) if err != nil { return nil, err } return &IpnsEntry{ Name: pid.Pretty(), Value: ref.String(), }, nil }
func Unpin(n *core.IpfsNode, ctx context.Context, paths []string, recursive bool) ([]key.Key, error) { dagnodes := make([]*merkledag.Node, 0) for _, fpath := range paths { dagnode, err := core.Resolve(ctx, n, path.Path(fpath)) if err != nil { return nil, err } dagnodes = append(dagnodes, dagnode) } var unpinned []key.Key for _, dagnode := range dagnodes { k, _ := dagnode.Key() ctx, cancel := context.WithTimeout(ctx, time.Minute) defer cancel() err := n.Pinning.Unpin(ctx, k, recursive) if err != nil { return nil, err } unpinned = append(unpinned, k) } err := n.Pinning.Flush() if err != nil { return nil, err } return unpinned, nil }
func getNodeFromPath(ctx context.Context, node *core.IpfsNode, p string) (node.Node, error) { switch { case strings.HasPrefix(p, "/ipfs/"): np, err := path.ParsePath(p) if err != nil { return nil, err } resolver := &path.Resolver{ DAG: node.DAG, ResolveOnce: uio.ResolveUnixfsOnce, } nd, err := core.Resolve(ctx, node.Namesys, resolver, np) if err != nil { return nil, err } pbnd, ok := nd.(*dag.ProtoNode) if !ok { return nil, dag.ErrNotProtobuf } return pbnd, nil default: fsn, err := mfs.Lookup(node.FilesRoot, p) if err != nil { return nil, err } return fsn.GetNode() } }
func loadRoot(ctx context.Context, rt *keyRoot, ipfs *core.IpfsNode, name string) (fs.Node, error) { p, err := path.ParsePath("/ipns/" + name) if err != nil { log.Errorf("mkpath %s: %s", name, err) return nil, err } node, err := core.Resolve(ctx, ipfs, p) if err != nil { log.Errorf("looking up %s: %s", p, err) return nil, err } root, err := mfs.NewRoot(ctx, ipfs.DAG, node, ipnsPubFunc(ipfs, rt.k)) if err != nil { return nil, err } rt.root = root switch val := root.GetValue().(type) { case *mfs.Directory: return &Directory{dir: val}, nil case *mfs.File: return &FileNode{fi: val}, nil default: return nil, errors.New("unrecognized type") } panic("not reached") }
func publish(ctx context.Context, n *core.IpfsNode, k crypto.PrivKey, ref path.Path, opts *publishOpts) (*IpnsEntry, error) { if opts.verifyExists { // verify the path exists _, err := core.Resolve(ctx, n, ref) if err != nil { return nil, err } } eol := time.Now().Add(opts.pubValidTime) err := n.Namesys.PublishWithEOL(ctx, k, ref, eol) if err != nil { return nil, err } hash, err := k.GetPublic().Hash() if err != nil { return nil, err } return &IpnsEntry{ Name: key.Key(hash).String(), Value: ref.String(), }, nil }
func Cat(ctx context.Context, n *core.IpfsNode, pstr string) (*uio.DagReader, error) { dagNode, err := core.Resolve(ctx, n, path.Path(pstr)) if err != nil { return nil, err } return uio.NewDagReader(ctx, dagNode, n.DAG) }
// getZip is equivalent to `ipfs getdag $hash | gzip` func getZip(ctx context.Context, node *core.IpfsNode, p path.Path, compression int) (io.Reader, error) { dagnode, err := core.Resolve(ctx, node, p) if err != nil { return nil, err } reader, err := uio.NewDagReader(ctx, dagnode, node.DAG) if err != nil { return nil, err } pr, pw := io.Pipe() gw, err := gzip.NewWriterLevel(pw, compression) if err != nil { return nil, err } bufin := bufio.NewReader(reader) go func() { _, err := bufin.WriteTo(gw) if err != nil { log.Error("Fail to compress the stream") } gw.Close() pw.Close() }() return pr, nil }
func Pin(n *core.IpfsNode, ctx context.Context, paths []string, recursive bool) ([]key.Key, error) { dagnodes := make([]*merkledag.Node, 0) for _, fpath := range paths { dagnode, err := core.Resolve(ctx, n, path.Path(fpath)) if err != nil { return nil, fmt.Errorf("pin: %s", err) } dagnodes = append(dagnodes, dagnode) } var out []key.Key for _, dagnode := range dagnodes { k, err := dagnode.Key() if err != nil { return nil, err } ctx, cancel := context.WithTimeout(ctx, time.Minute) defer cancel() err = n.Pinning.Pin(ctx, dagnode, recursive) if err != nil { return nil, fmt.Errorf("pin: %s", err) } out = append(out, k) } err := n.Pinning.Flush() if err != nil { return nil, err } return out, nil }
func get(ctx context.Context, node *core.IpfsNode, p path.Path, compression int) (io.Reader, error) { dagnode, err := core.Resolve(ctx, node, p) if err != nil { return nil, err } return utar.NewReader(ctx, p, node.DAG, dagnode, compression) }
func TestResolveNoComponents(t *testing.T) { n, err := coremock.NewMockNode() if n == nil || err != nil { t.Fatal("Should have constructed a mock node", err) } _, err = core.Resolve(n.Context(), n, path.Path("/ipns/")) if err != path.ErrNoComponents { t.Fatal("Should error with no components (/ipns/).", err) } _, err = core.Resolve(n.Context(), n, path.Path("/ipfs/")) if err != path.ErrNoComponents { t.Fatal("Should error with no components (/ipfs/).", err) } }
func get(ctx context.Context, node *core.IpfsNode, p string, compression int) (io.Reader, error) { pathToResolve := path.Path(p) dagnode, err := core.Resolve(ctx, node, pathToResolve) if err != nil { return nil, err } return utar.NewReader(pathToResolve, node.DAG, dagnode, compression) }
func objectsForPaths(ctx context.Context, n *core.IpfsNode, paths []string) ([]*dag.Node, error) { objects := make([]*dag.Node, len(paths)) for i, p := range paths { o, err := core.Resolve(ctx, n, path.Path(p)) if err != nil { return nil, err } objects[i] = o } return objects, nil }
//TODO: hrm, maybe this interface could be better func (s *Shell) PatchLink(root, npath, childhash string, create bool) (string, error) { p, err := path.ParsePath(root) if err != nil { return "", err } rootnd, err := core.Resolve(s.ctx, s.node, p) if err != nil { return "", err } childpath, err := path.ParsePath(childhash) if err != nil { return "", err } nnode, err := core.Resolve(s.ctx, s.node, childpath) if err != nil { return "", err } e := dagutils.NewDagEditor(rootnd, s.node.DAG) err = e.InsertNodeAtPath(s.ctx, npath, nnode, func() *dag.Node { return &dag.Node{Data: ft.FolderPBData()} }) if err != nil { return "", err } _, err = e.Finalize(s.node.DAG) if err != nil { return "", err } final, err := e.GetNode().Key() if err != nil { return "", err } return final.B58String(), nil }
func (s *Shell) ResolvePath(ipath string) (string, error) { p, err := path.ParsePath(ipath) if err != nil { return "", err } nd, err := core.Resolve(s.ctx, s.node, p) if err != nil { return "", err } return nd.Key().B58String(), nil }
func cat(ctx context.Context, node *core.IpfsNode, fpath string) (io.Reader, uint64, error) { dagnode, err := core.Resolve(ctx, node, path.Path(fpath)) if err != nil { return nil, 0, err } reader, err := uio.NewDagReader(ctx, dagnode, node.DAG) if err != nil { return nil, 0, err } length := uint64(reader.Size()) return reader, length, nil }
func resolve(ctx context.Context, n *core.IpfsNode, p string) (ipld.Node, error) { pp, err := path.ParsePath(p) if err != nil { return nil, err } dagnode, err := core.Resolve(ctx, n.Namesys, n.Resolver, pp) if err == core.ErrNoNamesys { return nil, coreiface.ErrOffline } else if err != nil { return nil, err } return dagnode, nil }
// Cat resolves the ipfs path p and returns a reader for that data, if it exists and is availalbe func (s *Shell) Cat(p string) (io.ReadCloser, error) { ipfsPath, err := path.ParsePath(p) if err != nil { return nil, errgo.Notef(err, "cat: could not parse %q", p) } nd, err := core.Resolve(s.ctx, s.node, ipfsPath) if err != nil { return nil, errgo.Notef(err, "cat: could not resolve %s", ipfsPath) } dr, err := unixfsio.NewDagReader(s.ctx, nd, s.node.DAG) if err != nil { return nil, errgo.Notef(err, "cat: failed to construct DAG reader") } return dr, nil }
func objectsForPaths(ctx context.Context, n *core.IpfsNode, paths []string) ([]node.Node, error) { objects := make([]node.Node, len(paths)) for i, sp := range paths { p, err := path.ParsePath(sp) if err != nil { return nil, err } o, err := core.Resolve(ctx, n.Namesys, n.Resolver, p) if err != nil { return nil, err } objects[i] = o } return objects, nil }
func getNodeFromPath(ctx context.Context, node *core.IpfsNode, p string) (*dag.Node, error) { switch { case strings.HasPrefix(p, "/ipfs/"): np, err := path.ParsePath(p) if err != nil { return nil, err } return core.Resolve(ctx, node, np) default: fsn, err := mfs.Lookup(node.FilesRoot, p) if err != nil { return nil, err } return fsn.GetNode() } }
func cat(ctx context.Context, node *core.IpfsNode, paths []string) ([]io.Reader, uint64, error) { readers := make([]io.Reader, 0, len(paths)) length := uint64(0) for _, fpath := range paths { dagnode, err := core.Resolve(ctx, node, path.Path(fpath)) if err != nil { return nil, 0, err } read, err := uio.NewDagReader(ctx, dagnode, node.DAG) if err != nil { return nil, 0, err } readers = append(readers, read) length += uint64(read.Size()) } return readers, length, nil }
func pinLsKeys(args []string, typeStr string, ctx context.Context, n *core.IpfsNode) (map[string]RefKeyObject, error) { keys := make(map[string]RefKeyObject) for _, p := range args { pth, err := path.ParsePath(p) if err != nil { return nil, err } dagNode, err := core.Resolve(ctx, n.Namesys, n.Resolver, pth) if err != nil { return nil, err } mode, ok := pin.StringToPinMode(typeStr) if !ok { return nil, fmt.Errorf("Invalid pin mode '%s'", typeStr) } c := dagNode.Cid() pinType, pinned, err := n.Pinning.IsPinnedWithType(c, mode) if err != nil { return nil, err } if !pinned { return nil, fmt.Errorf("Path '%s' is not pinned", p) } switch pinType { case "direct", "indirect", "recursive", "internal": default: pinType = "indirect through " + pinType } keys[c.String()] = RefKeyObject{ Type: pinType, } } return keys, nil }
// Cat resolves the ipfs path p and returns a reader for that data, if it exists and is availalbe func (s *Shell) Get(ref, outdir string) error { ipfsPath, err := path.ParsePath(ref) if err != nil { return errgo.Notef(err, "get: could not parse %q", ref) } nd, err := core.Resolve(s.ctx, s.node, ipfsPath) if err != nil { return errgo.Notef(err, "get: could not resolve %s", ipfsPath) } r, err := uarchive.DagArchive(s.ctx, nd, outdir, s.node.DAG, false, 0) if err != nil { return err } ext := tar.Extractor{outdir} return ext.Extract(r) }
func (s *Shell) List(ipath string) ([]*sh.LsLink, error) { p, err := path.ParsePath(ipath) if err != nil { return nil, err } nd, err := core.Resolve(s.ctx, s.node, p) if err != nil { return nil, err } var out []*sh.LsLink for _, l := range nd.Links { out = append(out, &sh.LsLink{ Hash: l.Hash.B58String(), Name: l.Name, Size: l.Size, }) } return out, nil }
func publish(ctx context.Context, n *core.IpfsNode, k crypto.PrivKey, ref path.Path) (*IpnsEntry, error) { // First, verify the path exists _, err := core.Resolve(ctx, n, ref) if err != nil { return nil, err } err = n.Namesys.Publish(ctx, k, ref) if err != nil { return nil, err } hash, err := k.GetPublic().Hash() if err != nil { return nil, err } return &IpnsEntry{ Name: key.Key(hash).String(), Value: ref.String(), }, nil }
func pinLsKeys(args []string, typeStr string, ctx context.Context, n *core.IpfsNode) (map[string]RefKeyObject, error) { keys := make(map[string]RefKeyObject) for _, p := range args { dagNode, err := core.Resolve(ctx, n, path.Path(p)) if err != nil { return nil, err } k, err := dagNode.Key() if err != nil { return nil, err } pinType, pinned, err := n.Pinning.IsPinnedWithType(k, typeStr) if err != nil { return nil, err } if !pinned { return nil, fmt.Errorf("Path '%s' is not pinned", p) } switch pinType { case "direct", "indirect", "recursive", "internal": default: pinType = "indirect through " + pinType } keys[k.B58String()] = RefKeyObject{ Type: pinType, } } return keys, nil }
is the raw data of the object. `, }, Arguments: []cmds.Argument{ cmds.StringArg("key", true, false, "Key of the object to retrieve, in base58-encoded multihash format.").EnableStdin(), }, Run: func(req cmds.Request, res cmds.Response) { n, err := req.InvocContext().GetNode() if err != nil { res.SetError(err, cmds.ErrNormal) return } fpath := path.Path(req.Arguments()[0]) node, err := core.Resolve(req.Context(), n, fpath) if err != nil { res.SetError(err, cmds.ErrNormal) return } res.SetOutput(bytes.NewReader(node.Data())) }, } var ObjectLinksCmd = &cmds.Command{ Helptext: cmds.HelpText{ Tagline: "Outputs the links pointed to by the specified object.", ShortDescription: ` 'ipfs object links' is a plumbing command for retrieving the links from a DAG node. It outputs to stdout, and <key> is a base58 encoded multihash.
pa, err := path.ParsePath(a) if err != nil { res.SetError(err, cmds.ErrNormal) return } pb, err := path.ParsePath(b) if err != nil { res.SetError(err, cmds.ErrNormal) return } ctx := req.Context() obj_a, err := core.Resolve(ctx, node, pa) if err != nil { res.SetError(err, cmds.ErrNormal) return } obj_b, err := core.Resolve(ctx, node, pb) if err != nil { res.SetError(err, cmds.ErrNormal) return } changes, err := dagutils.Diff(ctx, node.DAG, obj_a, obj_b) if err != nil { res.SetError(err, cmds.ErrNormal) return