mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-22 02:47:48 +08:00
* Provide according to strategy Updates boxo to a version with the changes from https://github.com/ipfs/boxo/pull/976, which decentralize the providing responsibilities (from a central providing.Exchange to blockstore, pinner, mfs). The changes consist in initializing the Pinner, MFS and the blockstore with the provider.System, which is created first. Since the provider.System is created first, the reproviding KeyChanFunc is set later when we can create it once we have the Pinner, MFS and the blockstore. Some additional work applies to the Add() workflow. Normally, blocks would get provided at the Blockstore or the Pinner, but when adding blocks AND a "pinned" strategy is used, the blockstore does not provide, and the pinner does not traverse the DAG (and thus doesn't provide either), so we need to provide directly from the Adder. This is resolved by wrapping the DAGService in a "providingDAGService" which provides every added block, when using the "pinned" strategy. `ipfs --offline add` when the ONLINE daemon is running will now announce blocks per the chosen strategy, where before it did not announce them. This is documented in the changelog. A couple of releases ago, adding with `ipfs --offline add` was faster, but this is no longer the case so we are not incurring in any penalties by sticking to the fact that the daemon is online and has a providing strategy that we follow. Co-authored-by: gammazero <11790789+gammazero@users.noreply.github.com> Co-authored-by: Marcin Rataj <lidel@lidel.org>
162 lines
4.8 KiB
Go
162 lines
4.8 KiB
Go
package harness
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"reflect"
|
|
"strings"
|
|
|
|
. "github.com/ipfs/kubo/test/cli/testutils"
|
|
)
|
|
|
|
func (n *Node) IPFSCommands() []string {
|
|
res := n.IPFS("commands").Stdout.String()
|
|
res = strings.TrimSpace(res)
|
|
split := SplitLines(res)
|
|
var cmds []string
|
|
for _, line := range split {
|
|
trimmed := strings.TrimSpace(line)
|
|
if trimmed == "ipfs" {
|
|
continue
|
|
}
|
|
cmds = append(cmds, trimmed)
|
|
}
|
|
return cmds
|
|
}
|
|
|
|
func (n *Node) SetIPFSConfig(key string, val interface{}, flags ...string) {
|
|
valBytes, err := json.Marshal(val)
|
|
if err != nil {
|
|
log.Panicf("marshling config for key '%s': %s", key, err)
|
|
}
|
|
valStr := string(valBytes)
|
|
|
|
args := []string{"config", "--json"}
|
|
args = append(args, flags...)
|
|
args = append(args, key, valStr)
|
|
n.IPFS(args...)
|
|
|
|
// validate the config was set correctly
|
|
|
|
// Create a new value which is a pointer to the same type as the source.
|
|
var newVal any
|
|
if val != nil {
|
|
// If it is not nil grab the type with reflect.
|
|
newVal = reflect.New(reflect.TypeOf(val)).Interface()
|
|
} else {
|
|
// else just set a pointer to an any.
|
|
var anything any
|
|
newVal = &anything
|
|
}
|
|
n.GetIPFSConfig(key, newVal)
|
|
// dereference newVal using reflect to load the resulting value
|
|
if !reflect.DeepEqual(val, reflect.ValueOf(newVal).Elem().Interface()) {
|
|
log.Panicf("key '%s' did not retain value '%s' after it was set, got '%s'", key, val, newVal)
|
|
}
|
|
}
|
|
|
|
func (n *Node) GetIPFSConfig(key string, val interface{}) {
|
|
res := n.IPFS("config", key)
|
|
valStr := strings.TrimSpace(res.Stdout.String())
|
|
// only when the result is a string is the result not well-formed JSON,
|
|
// so check the value type and add quotes if it's expected to be a string
|
|
reflectVal := reflect.ValueOf(val)
|
|
if reflectVal.Kind() == reflect.Ptr && reflectVal.Elem().Kind() == reflect.String {
|
|
valStr = fmt.Sprintf(`"%s"`, valStr)
|
|
}
|
|
err := json.Unmarshal([]byte(valStr), val)
|
|
if err != nil {
|
|
log.Fatalf("unmarshaling config for key '%s', value '%s': %s", key, valStr, err)
|
|
}
|
|
}
|
|
|
|
func (n *Node) IPFSAddStr(content string, args ...string) string {
|
|
log.Debugf("node %d adding content '%s' with args: %v", n.ID, PreviewStr(content), args)
|
|
return n.IPFSAdd(strings.NewReader(content), args...)
|
|
}
|
|
|
|
// IPFSAddDeterministic produces a CID of a file of a certain size, filled with deterministically generated bytes based on some seed.
|
|
// This ensures deterministic CID on the other end, that can be used in tests.
|
|
func (n *Node) IPFSAddDeterministic(size string, seed string, args ...string) string {
|
|
log.Debugf("node %d adding %s of deterministic pseudo-random data with seed %q and args: %v", n.ID, size, seed, args)
|
|
reader, err := DeterministicRandomReader(size, seed)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return n.IPFSAdd(reader, args...)
|
|
}
|
|
|
|
func (n *Node) IPFSAdd(content io.Reader, args ...string) string {
|
|
log.Debugf("node %d adding with args: %v", n.ID, args)
|
|
fullArgs := []string{"add", "-q"}
|
|
fullArgs = append(fullArgs, args...)
|
|
res := n.Runner.MustRun(RunRequest{
|
|
Path: n.IPFSBin,
|
|
Args: fullArgs,
|
|
CmdOpts: []CmdOpt{RunWithStdin(content)},
|
|
})
|
|
out := strings.TrimSpace(res.Stdout.String())
|
|
log.Debugf("add result: %q", out)
|
|
return out
|
|
}
|
|
|
|
func (n *Node) IPFSBlockPut(content io.Reader, args ...string) string {
|
|
log.Debugf("node %d block put with args: %v", n.ID, args)
|
|
fullArgs := []string{"block", "put"}
|
|
fullArgs = append(fullArgs, args...)
|
|
res := n.Runner.MustRun(RunRequest{
|
|
Path: n.IPFSBin,
|
|
Args: fullArgs,
|
|
CmdOpts: []CmdOpt{RunWithStdin(content)},
|
|
})
|
|
out := strings.TrimSpace(res.Stdout.String())
|
|
log.Debugf("block put result: %q", out)
|
|
return out
|
|
}
|
|
|
|
func (n *Node) IPFSDAGPut(content io.Reader, args ...string) string {
|
|
log.Debugf("node %d dag put with args: %v", n.ID, args)
|
|
fullArgs := []string{"dag", "put"}
|
|
fullArgs = append(fullArgs, args...)
|
|
res := n.Runner.MustRun(RunRequest{
|
|
Path: n.IPFSBin,
|
|
Args: fullArgs,
|
|
CmdOpts: []CmdOpt{RunWithStdin(content)},
|
|
})
|
|
out := strings.TrimSpace(res.Stdout.String())
|
|
log.Debugf("dag put result: %q", out)
|
|
return out
|
|
}
|
|
|
|
func (n *Node) IPFSDagImport(content io.Reader, cid string, args ...string) error {
|
|
log.Debugf("node %d dag import with args: %v", n.ID, args)
|
|
fullArgs := []string{"dag", "import", "--pin-roots=false"}
|
|
fullArgs = append(fullArgs, args...)
|
|
res := n.Runner.MustRun(RunRequest{
|
|
Path: n.IPFSBin,
|
|
Args: fullArgs,
|
|
CmdOpts: []CmdOpt{RunWithStdin(content)},
|
|
})
|
|
if res.Err != nil {
|
|
return res.Err
|
|
}
|
|
res = n.Runner.MustRun(RunRequest{
|
|
Path: n.IPFSBin,
|
|
Args: []string{"block", "stat", "--offline", cid},
|
|
})
|
|
return res.Err
|
|
}
|
|
|
|
/*
|
|
func (n *Node) IPFSDagExport(cid string, car *os.File) error {
|
|
log.Debugf("node %d dag export of %s to %q with args: %v", n.ID, cid, car.Name())
|
|
res := n.Runner.MustRun(RunRequest{
|
|
Path: n.IPFSBin,
|
|
Args: []string{"dag", "export", cid},
|
|
CmdOpts: []CmdOpt{RunWithStdout(car)},
|
|
})
|
|
return res.Err
|
|
}
|
|
*/
|