Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to tell if succeede to start ipfs daemon ? #5983

Closed
mitra42 opened this issue Feb 11, 2019 · 10 comments
Closed

How to tell if succeede to start ipfs daemon ? #5983

mitra42 opened this issue Feb 11, 2019 · 10 comments

Comments

@mitra42
Copy link

mitra42 commented Feb 11, 2019

Version information:

go-ipfs version: 0.4.18-
Repo version: 7
System version: amd64/darwin
Golang version: go1.11.1

Type:

enhancement

Description:

I'm trying to ensure that the IPFS daemon is running when starting a server that will use it, so something like what you'd logically think from .... :

ipfs daemon &
if [ $? -ne 0 ]; then echo "IPFS failed to start"; fi
mirrorHttp &

There are two problems with this ... firstly that running ipfs daemon & is always going to return 0, and secondly ipfs daemon fails in either the case that ipfs doesnt exist OR that its already running.

And ipfs --version returns a version whether the daemon is running or not so I can't use that.

What I'd like to figure out is how to do two things - either at the same time, or in two steps.
1: Start ipfs if its not already running.
2: Tell (in a shell script) whether IPFS daemon started.

Am I missing this in the docs and in ipfs daemon --help, or is this an enhancement request ?

@schomatis
Copy link
Contributor

The standard way is to check the daemon api file (normally found in .ipfs/api). That is the way the ipfs CLI knows whether to execute the command on its own or forward it to the running daemon.

Keep in mind that this isn't a 100% safe method as the file may remain there after, say, a crash (see #5784).

I'm going to close this issue for tracking purposes since it seems like it's something that should be discussed in our forum https://discuss.ipfs.io (although this could actually be reformatted as a documentation issue, since this api file is something that's not at all clear for new -or experienced- users, and seems pretty much be part of our public API from the moment we can't guarantee its correct clean-up and may request the user to do it for us).

@mitra42
Copy link
Author

mitra42 commented Feb 11, 2019

Thanks @schomatis - though as you say, it probably should be documented since its so different from how IPFS does everything else.

Also ... I guess its a bug that if you run ipfs daemon and then Ctrl-C Ctrl C out of it, that it fails to delete that api file ? (Though it deletes it on a 'kill')

If I've got this right the process is something like this .... which is pretty counterintuitive so at very least probably needs documenting somewhere.

if [ ! -e ${HOME}/.ipfs/api ]
then 
    ipfs daemon &
else
   echo "IPFS already started"
fi
while [ ! -e ${HOME}/.ipfs/api ]
do 
   echo "Waiting for IPFS to start";
   sleep 1
done
start_server_that_uses_IPFS

@schomatis
Copy link
Contributor

Also ... I guess its a bug that if you run ipfs daemon and then Ctrl-C Ctrl C out of it, that it fails to delete that api file ? (Though it deletes it on a 'kill')

That's the issue I was pointing you to, see #5784. Using Ctrl-C twice is the way you tell ipfs to send a SIGKILL:

Received interrupt signal, shutting down...
(Hit ctrl-c again to force-shutdown the daemon.)

and in that case the process doesn't get the chance to do anything else (like cleaning the api file), so that is expected (as with any service the advice would be to let it finish if possible to keep a consistent state), but that case is not considered a bug.

If I've got this right the process is something like this

As a secondary measure you can also check if the daemon API port is open (to which the commands connect to), it's the one reported in the initial log as,

Initializing daemon...
[...]
API server listening on /ip4/127.0.0.1/tcp/47153

It is set to a random port by default (in that case you'd need to parse this output) but you can just set it to a fixed value in .ipfs/config ("API": "/ip4/127.0.0.1/tcp/0").

Also, we can just offload this to any command that needs the daemon to run, e.g.,

ipfs swarm addrs

This command works only with a daemon running and I think it will fail otherwise (check this please), that is, we have an --offline flag that instructs the CLI to run the command on its own without caring if the daemon is running, but as far as I know there's no --online counterpart that would force the command to be run only in the daemon (and hence check that it is actually running). Libp2p commands like the ipfs swarm family can be used for that purpose I think.

Duplicate of #862.


which is pretty counterintuitive so at very least probably needs documenting somewhere

Documentation PRs are always welcomed 😄

@mitra42
Copy link
Author

mitra42 commented Feb 11, 2019

Understood re Ctrl-C; Ctlr-C, my mistake - I misread it as one of those messages that was really asking "Are you sure", rather than "I've started the process, another ctrl-c will hurry it up!".

Correct ipfs swarm addrs returns 1 if the daemon isn't running.

A "Documentation PR" requires
a) actually finding the docs which is often hard with IPFS as they are spread all over the place (and the links are often broken (and a documentation PR links requires knowing the new location they should point to))
b) knowing if the doc is wrong, or my understanding is wrong, which is hard for anyone except one of the team.

By the way ....I'll use that shell sequence for now, but I think a supported command whose behavior was .

  • start the daemon if not already started - wait for it to start
  • report 0 or 1 based on failure/success in starting
    would be useful.

Or maybe ipfs daemon --wait could be a supported flag ?

Just a suggestion - I don't know golang so can't really be of use there.

@Stebalien
Copy link
Member

So... the most correct way to do this is to wait for the string "Daemon is ready" on stdout. But yeah, some kind of ipfs daemon --wait or ipfs daemon --fork would be useful.

@jamiehewitt15
Copy link

Is anyone able to share a code example of how to wait until the IPFS daemon is running? I have tried to write a script based on waiting until ipfs swarm addrs doesn't return 1 but I have been running into problems with it.

@godcong
Copy link
Contributor

godcong commented Sep 30, 2020

Or you can try whether the id interface has the correct return value or exception
I used to do that

curl -X POST "http://127.0.0.1:5001/api/v0/id"

@mvdan
Copy link
Contributor

mvdan commented Feb 2, 2021

I've further developed the idea from #5983 (comment) in a new issue, if anyone here wants to follow it.

@SomajitDey
Copy link
Contributor

SomajitDey commented Aug 20, 2021

For the time-being, I am using this one-liner to start the daemon in background and wait until it's ready.

ipfs daemon 2>/dev/null | grep -i -o -m1 'Daemon is ready' & tail -f --pid=$! /dev/null

Outputs something when Daemon is ready, nothing otherwise.

To reflect daemon launch success in exit code, simply modify it as:

[ "$(ipfs daemon 2>/dev/null | grep -i -o -m1 'Daemon is ready' & tail -f --pid=$! /dev/null)" ]

@thedmdim
Copy link

it will launch your command only after daemon is ready:

ipfs daemon 2>&1 | grep -i -o -m1 "Daemon is ready" | xargs -i <your_any_command>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants