troglobit / finit

Fast init for Linux. Cookies included
https://troglobit.com/projects/finit/
MIT License
621 stars 61 forks source link

initctl: add JSON status output support #273

Closed hongkongkiwi closed 1 year ago

hongkongkiwi commented 2 years ago

I would like a way to know if a task is in ready state.

Right now initctl -q will show errorcode for failure and 0 for anything else.

I propose that it should show 0 only for done and a different error code depending on if it's ready or failed.

# initctl status test
     Status : ready (code=exited, status=0/SUCCESS)
   Identity : test
Description : test
     Origin : /configs/finit.d/test.conf
Environment :
Condition(s): <-usr/test>
    Command : /tmp/test > /tmp/test2
   PID file : none
        PID : 0
       User : root
      Group : root
     Uptime : N/A
   Restarts : 0 (0/10)
  Runlevels : [S123456789]

May 17 12:53:24 finit[1]: Starting test[4026]
# initctl -q status test; echo $?
0
troglobit commented 2 years ago

Hmm yeah there would be definite value in that, this is clear. Just a clarification, it returns 0 if the run/task/sysv has started and executed successfully in the current runlevel.

I'll see what I can come up with, this in combination with manual:yes for run/task/sysv would be a great combination.

troglobit commented 2 years ago

Carrying over from #276, and with a cup of fresh coffee in hand. In systemd land they have systemctl is-failed ... and systemctl is-active ... to the state. I'm leaning towards adding a new command, maybe: initctl [-q] state foo, which would only return the internal state, running and done(success) would result in an exit code of zero. Then we can let initctl -q status foo be the exit code of foo.

troglobit commented 2 years ago

Back on this now. Turns out the exit code from initctl status foo was added in e1c59a25 by another user of Finit, so we cannot change the behavior of that command the way I said previously.

So I'm leaning towards your original proposal, @hongkongkiwi, with the following "twist" to initctl status foo to not break the use-case for Atlas Copco (ping @liuming50 for information).

  1. If a run/task has been run once (started and completed), the exit code of initctl is 0
  2. If a service is active and running, the exit code of initctl is 0
  3. For all other cases the exit code of initctl is non-zero, the Finit state of the run/task/service (exact exit code values to be determined later)

I believe this should meet your requirements, @hongkongkiwi, please let me know otherwise.

troglobit commented 1 year ago

Not much feedback in this thread, so after some deliberation with my colleague @wkz, we decided the best course of action for this (and #276) is to instead add JSON output support to initctl. JSON is easy to generate and can be used to not only solve this issue but also used in web interfaces and similar.

(With jq this could become very powerful when scripting.)

troglobit commented 1 year ago

Here's an example of how to query the exit code of a service. (If it died because of a signal the output is slightly different.)

root@anarchy:~# initctl status -j mdevd
{
  "identity": "mdevd",
  "description": "MDEVD Extended Hotplug Daemon",
  "status": "crashed",
  "exit": { "code": 100 },
  "origin": "built-in",
  "command": "/bin/mdevd -C -O 4",
  "restarts": 10,
  "pidfile": "/run/mdevd.pid",
  "pid": 0,
  "user": "root",
  "group": "root",
  "uptime": 0,
  "runlevels": [ "S", 1, 2, 3, 4, 5, 7, 8, 9 ]
}
root@anarchy:~# initctl status -j mdevd |jq .exit
{
  "code": 100
}
root@anarchy:~# initctl status -j mdevd |jq .exit.code
100