78b8f47c14
Usually we had wrap-in-directory enabled by default because otherwise we had an error when adding single, non-directory files. wrap-in-directory happens automatically when adding more than one file so that was no problem. Thigns also worked when adding a folder and Wrap was disabled. The only case was adding a single with wrap disabled (a default option). This patches the ipfsadd/add.go file to remember the last added file so that we can use it's Cid as the resulting root of the adding process without having to fetch it from our dummy dagservice. We have to pass this CID to our Finalize() functions, because it turns out that in this case (single file without wrap-in-directory), the last block added to the DAG is not the IPFS root (the ipfsadd/Adder adds the mfs root folder last always). This was the case when wrap-in-directory was enabled by default. License: MIT Signed-off-by: Hector Sanjuan <code@hector.link>
100 lines
2.2 KiB
Go
100 lines
2.2 KiB
Go
// Package local implements a ClusterDAGService that chunks and adds content
|
|
// to a local peer, before pinning it.
|
|
package local
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
adder "github.com/ipfs/ipfs-cluster/adder"
|
|
"github.com/ipfs/ipfs-cluster/api"
|
|
|
|
rpc "github.com/hsanjuan/go-libp2p-gorpc"
|
|
cid "github.com/ipfs/go-cid"
|
|
ipld "github.com/ipfs/go-ipld-format"
|
|
logging "github.com/ipfs/go-log"
|
|
peer "github.com/libp2p/go-libp2p-peer"
|
|
)
|
|
|
|
var errNotFound = errors.New("dagservice: block not found")
|
|
|
|
var logger = logging.Logger("localdags")
|
|
|
|
// DAGService is an implementation of an adder.ClusterDAGService which
|
|
// puts the added blocks directly in the peers allocated to them (without
|
|
// sharding).
|
|
type DAGService struct {
|
|
adder.BaseDAGService
|
|
|
|
rpcClient *rpc.Client
|
|
|
|
dests []peer.ID
|
|
pinOpts api.PinOptions
|
|
}
|
|
|
|
// New returns a new Adder with the given rpc Client. The client is used
|
|
// to perform calls to IPFSBlockPut and Pin content on Cluster.
|
|
func New(rpc *rpc.Client, opts api.PinOptions) *DAGService {
|
|
return &DAGService{
|
|
rpcClient: rpc,
|
|
dests: nil,
|
|
pinOpts: opts,
|
|
}
|
|
}
|
|
|
|
// Add puts the given node in the destination peers.
|
|
func (dag *DAGService) Add(ctx context.Context, node ipld.Node) error {
|
|
if dag.dests == nil {
|
|
dests, err := adder.BlockAllocate(ctx, dag.rpcClient, dag.pinOpts)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
dag.dests = dests
|
|
}
|
|
|
|
size, err := node.Size()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
nodeSerial := &api.NodeWithMeta{
|
|
Cid: node.Cid().String(),
|
|
Data: node.RawData(),
|
|
CumSize: size,
|
|
}
|
|
|
|
return adder.PutBlock(ctx, dag.rpcClient, nodeSerial, dag.dests)
|
|
}
|
|
|
|
// Finalize pins the last Cid added to this DAGService.
|
|
func (dag *DAGService) Finalize(ctx context.Context, root *cid.Cid) (*cid.Cid, error) {
|
|
// Cluster pin the result
|
|
pinS := api.PinSerial{
|
|
Cid: root.String(),
|
|
Type: int(api.DataType),
|
|
MaxDepth: -1,
|
|
PinOptions: dag.pinOpts,
|
|
}
|
|
|
|
dag.dests = nil
|
|
|
|
return root, dag.rpcClient.CallContext(
|
|
ctx,
|
|
"",
|
|
"Cluster",
|
|
"Pin",
|
|
pinS,
|
|
&struct{}{},
|
|
)
|
|
}
|
|
|
|
// AddMany calls Add for every given node.
|
|
func (dag *DAGService) AddMany(ctx context.Context, nodes []ipld.Node) error {
|
|
for _, node := range nodes {
|
|
err := dag.Add(ctx, node)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|