ipfs/kubo

Strange error trying to run the daemon through supervisord

darkstar opened this issue · 15 comments

When I try to run the daemon through supervisord, I keep getting the following error in the log file (stdout/stderr):

Use 'ipfs daemon --help' for information about this command
Error: Expected 0 arguments, got 1

which is strange as the config file I'm using to launch the daemon contains just the word "daemon" as argument:

[program:ipfs]
command=/var/lib/go/bin/ipfs daemon
user=darkstar
redirect_stderr=true
stdout_logfile=/var/log/ipfs-daemon.log

I tried tracing the launch with strace and it also shows that only 1 argument is given:

darkstar@flonne:/etc/supervisor$ cat /tmp/strace.log |grep daemon
open("/var/log/ipfs-daemon.log", O_WRONLY|O_CREAT|O_APPEND|O_LARGEFILE, 0666) = 9
[pid  9015] execve("/var/lib/go/bin/ipfs", ["/var/lib/go/bin/ipfs", "daemon"], [/* 28 vars */]) = 0
[pid  9015] write(2, "Use 'ipfs daemon --help' for inf"..., 60 <unfinished ...>
[pid  9012] read(7, "Use 'ipfs daemon --help' for inf"..., 131072) = 60
[pid  9012] write(9, "Use 'ipfs daemon --help' for inf"..., 60) = 60

Then I modified the file github.com/jbenet/go-ipfs/commands/cli/parse.go to print the arguments:

darkstar@flonne:/var/lib/go/src/github.com/jbenet/go-ipfs$ git diff commands/cli/parse.go
diff --git a/commands/cli/parse.go b/commands/cli/parse.go
index 4981747..7590174 100644
--- a/commands/cli/parse.go
+++ b/commands/cli/parse.go
@@ -171,7 +171,7 @@ func parseArgs(inputs []string, stdin *os.File, argDefs []cmds.Argument, recursi
        // and the last arg definition is not variadic (or there are no definitions), return an error
        notVariadic := len(argDefs) == 0 || !argDefs[len(argDefs)-1].Variadic
        if notVariadic && numInputs > len(argDefs) {
-               return nil, nil, fmt.Errorf("Expected %v arguments, got %v", len(argDefs), numInputs)
+               return nil, nil, fmt.Errorf("Expected %v arguments, got %v: %v", len(argDefs), numInputs, inputs)
        }

        stringArgs := make([]string, 0, numInputs)

and recompiled via go get github.com/jbenet/go-ipfs/cmd/ipfs (note that I don't know any go language, so I don't know if there's a different/better way to just recompile that binary, but this seemed to work) and I got the following in the log file:

Use 'ipfs daemon --help' for information about this command
Error: Expected 0 arguments, got 1: []

At this point I'm out of ideas what goes wrong where. I know that supervisord launches the binary correctly (as shown by the strace output), however, ipfs seems to insist that there's an extra argument being given.

Any ideas?

Oh by the way this is on xubuntu 14.10 with go 1.4.1 from ppa:evarlast/golang1.4 and supervisord 3.0

also, running the daemon from the shell via /var/lib/go/bin/ipfs daemon works just fine:

darkstar@flonne:~$ /var/lib/go/bin/ipfs daemon
Initializing daemon...
Gateway (readonly) server listening on /ip4/127.0.0.1/tcp/8080
API server listening on /ip4/127.0.0.1/tcp/5001

@darkstar thanks for reporting this! It looks like an empty string is somehow being passed in as an argument to the command... weird

Might be stdin-- our commands lib is overly aggressive on that, and I think treats it as an arg. I'll look at it closer when I'm back to comp.


Sent from Mailbox

On Thu, Mar 5, 2015 at 4:48 PM, Jeromy Johnson notifications@github.com
wrote:

@darkstar thanks for reporting this! It looks like an empty string is somehow being passed in as an argument to the command... weird

Reply to this email directly or view it on GitHub:
#861 (comment)

@darkstar could you try changing the command to /var/lib/go/bin/ipfs daemon < /dev/null ?

@whyrusleeping

Now it is:

Error: Expected 0 arguments, got 3

Use 'ipfs daemon --help' for information about this command

Could reproduce it too.

If I delete this chunk, the problem becomes reproducible on terminal as well.

very interesting... @mappum I'll buy you coffee if you know whats going on here!

By the way, this ugly hack:

[program:ipfs]
command=/bin/bash -c "/var/lib/go/bin/ipfs daemon < /dev/null"

gives you:

Initializing daemon...
Error: ipfs not initialized, please run 'ipfs init'

That's because we use @mitchellh's go-homedir to resolve ~/.go-ipfs/ to an absolute path.

Here it assumes that sh -c 'eval echo ~$USER' returns the home directory. But if HOME and USER are unset (our case), bash will return an empty string and dash gives you a ~. In Ubuntu sh is symlinked to dash by default.

So we get ~/.go-ipfs/ when we try to resolve ~/.go-ipfs/.

@kkoroviev Wow! Good analysis. Thanks for the info

@kkoroviev I'm happy to augment the library to return more accurate results! Please let me know a more resilient test.

@mitchellh

A better way is to parse /etc/passwd directly. Not sure about Mac, but on Linux it will definitely work.

Does Go have a function to find out the UID of the current user?

Okay, so this here is now a combined workaround which actually works:

[program:ipfs]
command=/bin/bash -c "/var/lib/go/bin/ipfs daemon < /dev/null"
environment=HOME="/home/darkstar",USER="darkstar"
user=darkstar
redirect_stderr=true
stdout_logfile=/var/log/ipfs-daemon.log

I think this issue might have been fixed by merging PR #1263 or PR #1238.
At least on my Linux machine @kkoroviev 's test now passes.
We might want to monitor if it is passing on CI machines too and then turn the test_expect_failure into test_expect_success.

@chriscool: The stdin test now passes on my box too.

I pushed a PR that switches them back to success and also improves error detection in t0060. ( #1297 )

Ok, great! I am closing this issue then.