fix: allow daemon to start correctly if the API is null (#10062)
(cherry picked from commit 8c4bdd8556e0c8b1a4ea3a6d703402bd6cfe1229)
Jorropo committed
Dec 11, 2023 at 11:45 UTC
f93a3869849ca1e5e07ae5ae05fb615ae477a1bd
3 files changed
+44
-5
cmd/ipfs/daemon.go
+5
-2
@@ -727,8 +727,11 @@ func serveHTTPApi(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, error
727
return nil, fmt.Errorf("serveHTTPApi: ConstructNode() failed: %s", err)
728
}
729
730
- if err := node.Repo.SetAPIAddr(rewriteMaddrToUseLocalhostIfItsAny(listeners[0].Multiaddr())); err != nil {
731
- return nil, fmt.Errorf("serveHTTPApi: SetAPIAddr() failed: %w", err)
730
+ if len(listeners) > 0 {
731
+ // Only add an api file if the API is running.
732
+ if err := node.Repo.SetAPIAddr(rewriteMaddrToUseLocalhostIfItsAny(listeners[0].Multiaddr())); err != nil {
733
+ return nil, fmt.Errorf("serveHTTPApi: SetAPIAddr() failed: %w", err)
734
+ }
735
}
736
737
errc := make(chan error)
test/cli/daemon_test.go
new
+25
@@ -0,0 +1,25 @@
1
+package cli
2
+
3
+import (
4
+ "os/exec"
5
+ "testing"
6
+
7
+ "github.com/ipfs/kubo/test/cli/harness"
8
+)
9
+
10
+func TestDaemon(t *testing.T) {
11
+ t.Parallel()
12
+
13
+ t.Run("daemon starts if api is set to null", func(t *testing.T) {
14
+ t.Parallel()
15
+ node := harness.NewT(t).NewNode().Init()
16
+ node.SetIPFSConfig("Addresses.API", nil)
17
+ node.Runner.MustRun(harness.RunRequest{
18
+ Path: node.IPFSBin,
19
+ Args: []string{"daemon"},
20
+ RunFunc: (*exec.Cmd).Start, // Start without waiting for completion.
21
+ })
22
+
23
+ node.StopDaemon()
24
+ })
25
+}
test/cli/harness/ipfs.go
+14
-3
@@ -38,9 +38,20 @@ func (n *Node) SetIPFSConfig(key string, val interface{}, flags ...string) {
38
n.IPFS(args...)
39
40
// validate the config was set correctly
41
- var newVal string
42
- n.GetIPFSConfig(key, &newVal)
43
- if val != newVal {
41
+
42
+ // Create a new value which is a pointer to the same type as the source.
43
+ var newVal any
44
+ if val != nil {
45
+ // If it is not nil grab the type with reflect.
46
+ newVal = reflect.New(reflect.TypeOf(val)).Interface()
47
+ } else {
48
+ // else just set a pointer to an any.
49
+ var anything any
50
+ newVal = &anything
51
+ }
52
+ n.GetIPFSConfig(key, newVal)
53
+ // dereference newVal using reflect to load the resulting value
54
+ if !reflect.DeepEqual(val, reflect.ValueOf(newVal).Elem().Interface()) {
55
log.Panicf("key '%s' did not retain value '%s' after it was set, got '%s'", key, val, newVal)
56
}
57
}