mirror of
https://github.com/ipfs/kubo.git
synced 2025-06-28 17:03:58 +08:00
coreapi unixfs: pin/local/hash-only options
License: MIT Signed-off-by: Łukasz Magiera <magik6k@gmail.com>
This commit is contained in:
@ -21,6 +21,10 @@ type UnixfsAddSettings struct {
|
|||||||
|
|
||||||
Chunker string
|
Chunker string
|
||||||
Layout Layout
|
Layout Layout
|
||||||
|
|
||||||
|
Pin bool
|
||||||
|
OnlyHash bool
|
||||||
|
Local bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type UnixfsAddOption func(*UnixfsAddSettings) error
|
type UnixfsAddOption func(*UnixfsAddSettings) error
|
||||||
@ -36,6 +40,10 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, error) {
|
|||||||
|
|
||||||
Chunker: "size-262144",
|
Chunker: "size-262144",
|
||||||
Layout: BalancedLayout,
|
Layout: BalancedLayout,
|
||||||
|
|
||||||
|
Pin: false,
|
||||||
|
OnlyHash: false,
|
||||||
|
Local: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
@ -94,3 +102,24 @@ func (unixfsOpts) Layout(layout Layout) UnixfsAddOption {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (unixfsOpts) Pin(pin bool) UnixfsAddOption {
|
||||||
|
return func(settings *UnixfsAddSettings) error {
|
||||||
|
settings.Pin = pin
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (unixfsOpts) HashOnly(hashOnly bool) UnixfsAddOption {
|
||||||
|
return func(settings *UnixfsAddSettings) error {
|
||||||
|
settings.OnlyHash = hashOnly
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (unixfsOpts) Local(local bool) UnixfsAddOption {
|
||||||
|
return func(settings *UnixfsAddSettings) error {
|
||||||
|
settings.Local = local
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -4,18 +4,25 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/ipfs/go-ipfs/core"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
|
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
|
||||||
"github.com/ipfs/go-ipfs/core/coreapi/interface/options"
|
"github.com/ipfs/go-ipfs/core/coreapi/interface/options"
|
||||||
"github.com/ipfs/go-ipfs/core/coreunix"
|
"github.com/ipfs/go-ipfs/core/coreunix"
|
||||||
|
|
||||||
uio "gx/ipfs/QmPL8bYtbACcSFFiSr4s2du7Na382NxRADR8hC7D9FkEA2/go-unixfs/io"
|
|
||||||
mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash"
|
mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash"
|
||||||
cidutil "gx/ipfs/QmQJSeE3CX4zos9qeaG8EhecEK9zvrTEfTG84J8C5NVRwt/go-cidutil"
|
cidutil "gx/ipfs/QmQJSeE3CX4zos9qeaG8EhecEK9zvrTEfTG84J8C5NVRwt/go-cidutil"
|
||||||
|
offline "gx/ipfs/QmR5miWuikPxWyUrzMYJVmFUcD44pGdtc98h9Qsbp4YcJw/go-ipfs-exchange-offline"
|
||||||
"gx/ipfs/QmSP88ryZkHSRn1fnngAaV2Vcn63WUJzAavnRM9CVdU1Ky/go-ipfs-cmdkit/files"
|
"gx/ipfs/QmSP88ryZkHSRn1fnngAaV2Vcn63WUJzAavnRM9CVdU1Ky/go-ipfs-cmdkit/files"
|
||||||
|
ft "gx/ipfs/QmU4x3742bvgfxJsByEDpBnifJqjJdV6x528co4hwKCn46/go-unixfs"
|
||||||
|
uio "gx/ipfs/QmU4x3742bvgfxJsByEDpBnifJqjJdV6x528co4hwKCn46/go-unixfs/io"
|
||||||
|
mfs "gx/ipfs/QmahrY1adY4wvtYEtoGjpZ2GUohTyukrkMkwUR9ytRjTG2/go-mfs"
|
||||||
dag "gx/ipfs/QmcBoNcAP6qDjgRBew7yjvCqHq7p5jMstE44jPUBWBxzsV/go-merkledag"
|
dag "gx/ipfs/QmcBoNcAP6qDjgRBew7yjvCqHq7p5jMstE44jPUBWBxzsV/go-merkledag"
|
||||||
|
dagtest "gx/ipfs/QmcBoNcAP6qDjgRBew7yjvCqHq7p5jMstE44jPUBWBxzsV/go-merkledag/test"
|
||||||
|
blockservice "gx/ipfs/QmcRecCZWM2NZfCQrCe97Ch3Givv8KKEP82tGUDntzdLFe/go-blockservice"
|
||||||
ipld "gx/ipfs/QmdDXJs4axxefSPgK6Y1QhpJWKuDPnGJiqgq4uncb4rFHL/go-ipld-format"
|
ipld "gx/ipfs/QmdDXJs4axxefSPgK6Y1QhpJWKuDPnGJiqgq4uncb4rFHL/go-ipld-format"
|
||||||
|
bstore "gx/ipfs/QmdriVJgKx4JADRgh3cYPXqXmsa1A45SvFki1nDWHhQNtC/go-ipfs-blockstore"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UnixfsAPI CoreAPI
|
type UnixfsAPI CoreAPI
|
||||||
@ -59,7 +66,33 @@ func (api *UnixfsAPI) Add(ctx context.Context, r io.ReadCloser, opts ...options.
|
|||||||
prefix.MhType = settings.MhType
|
prefix.MhType = settings.MhType
|
||||||
prefix.MhLength = -1
|
prefix.MhLength = -1
|
||||||
|
|
||||||
fileAdder, err := coreunix.NewAdder(ctx, api.node.Pinning, api.node.Blockstore, api.node.DAG)
|
n := api.node
|
||||||
|
if settings.OnlyHash {
|
||||||
|
nilnode, err := core.NewNode(ctx, &core.BuildCfg{
|
||||||
|
//TODO: need this to be true or all files
|
||||||
|
// hashed will be stored in memory!
|
||||||
|
NilRepo: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
n = nilnode
|
||||||
|
}
|
||||||
|
|
||||||
|
addblockstore := n.Blockstore
|
||||||
|
//if !(fscache || nocopy) {
|
||||||
|
addblockstore = bstore.NewGCBlockstore(n.BaseBlocks, n.GCLocker)
|
||||||
|
//}
|
||||||
|
|
||||||
|
exch := n.Exchange
|
||||||
|
if settings.Local {
|
||||||
|
exch = offline.Exchange(addblockstore)
|
||||||
|
}
|
||||||
|
|
||||||
|
bserv := blockservice.New(addblockstore, exch) // hash security 001
|
||||||
|
dserv := dag.NewDAGService(bserv)
|
||||||
|
|
||||||
|
fileAdder, err := coreunix.NewAdder(ctx, n.Pinning, n.Blockstore, dserv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -68,7 +101,7 @@ func (api *UnixfsAPI) Add(ctx context.Context, r io.ReadCloser, opts ...options.
|
|||||||
//fileAdder.Progress = progress
|
//fileAdder.Progress = progress
|
||||||
//fileAdder.Hidden = hidden
|
//fileAdder.Hidden = hidden
|
||||||
//fileAdder.Wrap = wrap
|
//fileAdder.Wrap = wrap
|
||||||
//fileAdder.Pin = dopin
|
fileAdder.Pin = settings.Pin
|
||||||
fileAdder.Silent = true
|
fileAdder.Silent = true
|
||||||
fileAdder.RawLeaves = settings.RawLeaves
|
fileAdder.RawLeaves = settings.RawLeaves
|
||||||
//fileAdder.NoCopy = nocopy
|
//fileAdder.NoCopy = nocopy
|
||||||
@ -91,6 +124,19 @@ func (api *UnixfsAPI) Add(ctx context.Context, r io.ReadCloser, opts ...options.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if settings.OnlyHash {
|
||||||
|
md := dagtest.Mock()
|
||||||
|
emptyDirNode := ft.EmptyDirNode()
|
||||||
|
// Use the same prefix for the "empty" MFS root as for the file adder.
|
||||||
|
emptyDirNode.SetCidBuilder(fileAdder.CidBuilder)
|
||||||
|
mr, err := mfs.NewRoot(ctx, md, emptyDirNode, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
fileAdder.SetMfsRoot(mr)
|
||||||
|
}
|
||||||
|
|
||||||
err = fileAdder.AddFile(files.NewReaderFile("", "", r, nil))
|
err = fileAdder.AddFile(files.NewReaderFile("", "", r, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -101,8 +147,11 @@ func (api *UnixfsAPI) Add(ctx context.Context, r io.ReadCloser, opts ...options.
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return coreiface.IpfsPath(nd.Cid()), err
|
if settings.Pin {
|
||||||
|
err = fileAdder.PinRoot()
|
||||||
|
}
|
||||||
|
|
||||||
|
return coreiface.IpfsPath(nd.Cid()), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cat returns the data contained by an IPFS or IPNS object(s) at path `p`.
|
// Cat returns the data contained by an IPFS or IPNS object(s) at path `p`.
|
||||||
|
@ -204,6 +204,13 @@ func TestAdd(t *testing.T) {
|
|||||||
path: "/ipfs/QmNNhDGttafX3M1wKWixGre6PrLFGjnoPEDXjBYpTv93HP",
|
path: "/ipfs/QmNNhDGttafX3M1wKWixGre6PrLFGjnoPEDXjBYpTv93HP",
|
||||||
opts: []options.UnixfsAddOption{options.Unixfs.Chunker("size-4"), options.Unixfs.Layout(options.TrickleLeyout)},
|
opts: []options.UnixfsAddOption{options.Unixfs.Chunker("size-4"), options.Unixfs.Layout(options.TrickleLeyout)},
|
||||||
},
|
},
|
||||||
|
// Local
|
||||||
|
{
|
||||||
|
name: "addLocal", // better cases in sharness
|
||||||
|
data: helloStr,
|
||||||
|
path: hello,
|
||||||
|
opts: []options.UnixfsAddOption{options.Unixfs.Local(true)},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, testCase := range cases {
|
for _, testCase := range cases {
|
||||||
@ -244,6 +251,55 @@ func TestAdd(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAddPinned(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
_, api, err := makeAPI(ctx)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
str := strings.NewReader(helloStr)
|
||||||
|
_, err = api.Unixfs().Add(ctx, ioutil.NopCloser(str), options.Unixfs.Pin(true))
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pins, err := api.Pin().Ls(ctx)
|
||||||
|
if len(pins) != 1 {
|
||||||
|
t.Fatalf("expected 1 pin, got %d", len(pins))
|
||||||
|
}
|
||||||
|
|
||||||
|
if pins[0].Path().String() != "/ipld/QmQy2Dw4Wk7rdJKjThjYXzfFJNaRKRHhHP5gHHXroJMYxk" {
|
||||||
|
t.Fatalf("got unexpected pin: %s", pins[0].Path().String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddHashOnly(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
_, api, err := makeAPI(ctx)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
str := strings.NewReader(helloStr)
|
||||||
|
p, err := api.Unixfs().Add(ctx, ioutil.NopCloser(str), options.Unixfs.HashOnly(true))
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.String() != hello {
|
||||||
|
t.Errorf("unxepected path: %s", p.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = api.Block().Get(ctx, p)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("expected an error")
|
||||||
|
}
|
||||||
|
if err.Error() != "blockservice: key not found" {
|
||||||
|
t.Errorf("unxepected error: %s", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestCatEmptyFile(t *testing.T) {
|
func TestCatEmptyFile(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
node, api, err := makeAPI(ctx)
|
node, api, err := makeAPI(ctx)
|
||||||
|
Reference in New Issue
Block a user