func ImportTar(r io.Reader, ds dag.DAGService) (*dag.Node, error) { rall, err := ioutil.ReadAll(r) if err != nil { return nil, err } r = bytes.NewReader(rall) tr := tar.NewReader(r) root := new(dag.Node) root.Data = []byte("ipfs/tar") e := dagutil.NewDagEditor(root, ds) for { h, err := tr.Next() if err != nil { if err == io.EOF { break } return nil, err } header := new(dag.Node) headerBytes, err := marshalHeader(h) if err != nil { return nil, err } header.Data = headerBytes if h.Size > 0 { spl := chunk.NewRabin(tr, uint64(chunk.DefaultBlockSize)) nd, err := importer.BuildDagFromReader(ds, spl) if err != nil { return nil, err } err = header.AddNodeLinkClean("data", nd) if err != nil { return nil, err } } _, err = ds.Add(header) if err != nil { return nil, err } path := escapePath(h.Name) err = e.InsertNodeAtPath(context.Background(), path, header, func() *dag.Node { return new(dag.Node) }) if err != nil { return nil, err } } return e.Finalize(ds) }
// 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 addLinkCaller(req cmds.Request, root *dag.Node) (key.Key, error) { if len(req.Arguments()) < 4 { return "", fmt.Errorf("not enough arguments for add-link") } nd, err := req.InvocContext().GetNode() if err != nil { return "", err } path := req.Arguments()[2] childk := key.B58KeyDecode(req.Arguments()[3]) create, _, err := req.Option("create").Bool() if err != nil { return "", err } var createfunc func() *dag.Node if create { createfunc = func() *dag.Node { return &dag.Node{Data: ft.FolderPBData()} } } e := dagutils.NewDagEditor(nd.DAG, root) childnd, err := nd.DAG.Get(req.Context(), childk) if err != nil { return "", err } err = e.InsertNodeAtPath(req.Context(), path, childnd, createfunc) if err != nil { return "", err } nnode := e.GetNode() return nnode.Key() }
//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 rmLinkCaller(req cmds.Request, root *dag.Node) (key.Key, error) { if len(req.Arguments()) < 3 { return "", fmt.Errorf("not enough arguments for rm-link") } nd, err := req.InvocContext().GetNode() if err != nil { return "", err } path := req.Arguments()[2] e := dagutils.NewDagEditor(nd.DAG, root) err = e.RmLink(req.Context(), path) if err != nil { return "", err } nnode := e.GetNode() return nnode.Key() }
// check if repo will exceed storage limit if added // TODO: this doesn't handle the case if the hashed file is already in blocks (deduplicated) // TODO: conditional GC is disabled due to it is somehow not possible to pass the size to the daemon //if err := corerepo.ConditionalGC(req.Context(), n, uint64(size)); err != nil { // res.SetError(err, cmds.ErrNormal) // return //} progress, _, _ := req.Option(progressOptionName).Bool() trickle, _, _ := req.Option(trickleOptionName).Bool() wrap, _, _ := req.Option(wrapOptionName).Bool() hash, _, _ := req.Option(onlyHashOptionName).Bool() hidden, _, _ := req.Option(hiddenOptionName).Bool() chunker, _, _ := req.Option(chunkerOptionName).String() e := dagutils.NewDagEditor(NewMemoryDagService(), newDirNode()) if hash { nilnode, err := core.NewNode(n.Context(), &core.BuildCfg{ //TODO: need this to be true or all files // hashed will be stored in memory! NilRepo: true, }) if err != nil { res.SetError(err, cmds.ErrNormal) return } n = nilnode } outChan := make(chan interface{}, 8) res.SetOutput((<-chan interface{})(outChan))
func (i *gatewayHandler) putHandler(w http.ResponseWriter, r *http.Request) { // TODO(cryptix): move me to ServeHTTP and pass into all handlers ctx, cancel := context.WithCancel(i.node.Context()) defer cancel() rootPath, err := path.ParsePath(r.URL.Path) if err != nil { webError(w, "putHandler: ipfs path not valid", err, http.StatusBadRequest) return } rsegs := rootPath.Segments() if rsegs[0] == ipnsPathPrefix { webError(w, "putHandler: updating named entries not supported", errors.New("WritableGateway: ipns put not supported"), http.StatusBadRequest) return } var newnode *dag.Node if rsegs[len(rsegs)-1] == "QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn" { newnode = uio.NewEmptyDirectory() } else { putNode, err := i.newDagFromReader(r.Body) if err != nil { webError(w, "putHandler: Could not create DAG from request", err, http.StatusInternalServerError) return } newnode = putNode } var newPath string if len(rsegs) > 1 { newPath = path.Join(rsegs[2:]) } var newkey key.Key rnode, err := core.Resolve(ctx, i.node, rootPath) switch ev := err.(type) { case path.ErrNoLink: // ev.Node < node where resolve failed // ev.Name < new link // but we need to patch from the root rnode, err := i.node.DAG.Get(ctx, key.B58KeyDecode(rsegs[1])) if err != nil { webError(w, "putHandler: Could not create DAG from request", err, http.StatusInternalServerError) return } e := dagutils.NewDagEditor(rnode, i.node.DAG) err = e.InsertNodeAtPath(ctx, newPath, newnode, uio.NewEmptyDirectory) if err != nil { webError(w, "putHandler: InsertNodeAtPath failed", err, http.StatusInternalServerError) return } nnode, err := e.Finalize(i.node.DAG) if err != nil { webError(w, "putHandler: could not get node", err, http.StatusInternalServerError) return } newkey, err = nnode.Key() if err != nil { webError(w, "putHandler: could not get key of edited node", err, http.StatusInternalServerError) return } case nil: // object set-data case rnode.Data = newnode.Data newkey, err = i.node.DAG.Add(rnode) if err != nil { nnk, _ := newnode.Key() rk, _ := rnode.Key() webError(w, fmt.Sprintf("putHandler: Could not add newnode(%q) to root(%q)", nnk.B58String(), rk.B58String()), err, http.StatusInternalServerError) return } default: log.Warningf("putHandler: unhandled resolve error %T", ev) webError(w, "could not resolve root DAG", ev, http.StatusInternalServerError) return } i.addUserHeaders(w) // ok, _now_ write user's headers. w.Header().Set("IPFS-Hash", newkey.String()) http.Redirect(w, r, gopath.Join(ipfsPathPrefix, newkey.String(), newPath), http.StatusCreated) }
rootp, err := path.ParsePath(req.Arguments()[0]) if err != nil { res.SetError(err, cmds.ErrNormal) return } root, err := core.Resolve(req.Context(), nd, rootp) if err != nil { res.SetError(err, cmds.ErrNormal) return } path := req.Arguments()[1] e := dagutils.NewDagEditor(root, nd.DAG) err = e.RmLink(req.Context(), path) if err != nil { res.SetError(err, cmds.ErrNormal) return } nnode, err := e.Finalize(nd.DAG) if err != nil { res.SetError(err, cmds.ErrNormal) return } nk, err := nnode.Key() if err != nil {
root, err := core.Resolve(req.Context(), nd.Namesys, nd.Resolver, rootp) if err != nil { res.SetError(err, cmds.ErrNormal) return } rtpb, ok := root.(*dag.ProtoNode) if !ok { res.SetError(dag.ErrNotProtobuf, cmds.ErrNormal) return } path := req.Arguments()[1] e := dagutils.NewDagEditor(rtpb, nd.DAG) err = e.RmLink(req.Context(), path) if err != nil { res.SetError(err, cmds.ErrNormal) return } nnode, err := e.Finalize(nd.DAG) if err != nil { res.SetError(err, cmds.ErrNormal) return } nc := nnode.Cid()
NilRepo: false, }) if err != nil { res.SetError(err, cmds.ErrNormal) return } n = nilnode } outChan := make(chan interface{}, 8) res.SetOutput((<-chan interface{})(outChan)) fileAdder := adder{ ctx: req.Context(), node: n, editor: dagutils.NewDagEditor(n.DAG, newDirNode()), out: outChan, chunker: chunker, progress: progress, hidden: hidden, trickle: trickle, wrap: wrap, } // addAllFiles loops over a convenience slice file to // add each file individually. e.g. 'ipfs add a b c' addAllFiles := func(sliceFile files.File) error { for { file, err := sliceFile.NextFile() if err != nil && err != io.EOF { return err