YNIT is init
process supports sysv-like format scripts. I aims to handle PID 1 problems in docker.
See phusion's awesome blog post for detail.
Because golang is cool!
YNIT script is just a shell script accepts only one parameter: start
or stop
. You can set dependencies by adding some properties in special format, which is roughly like the scripts in /etc/init.d/
.
A typical YNIT script will be like:
#!/bin/bash
### BEGIN INIT INFO
# Provides: myprog mytest-prog
# Required-Start: another-script
# Required-Stop:
# X-Start-Before:
# X-Stop-After:
# Non-Stop:
### END INIT INFO
PIDFILE=/tmp/myprog.pid
case "$1" in
start)
start-stop-daemon --start --pidfile $PIDFILE --exec /usr/bin/myprog -- --daemon
;;
stop)
start-stop-daemon --stop --oknodo --pidfile $PIDFILE
;;
*)
echo "Usage: $0 start|stop" >&2
exit 1
;;
esac
or
#!/usr/bin/env php
<?php
/*
### BEGIN INIT INFO
# Provides: myprog mytest-prog
# Required-Start: another-script
# Required-Stop:
# X-Start-Before:
# X-Stop-After:
# Non-Stop:
### END INIT INFO
*/
// here are codes to handle command line arguments and start/stop your program
As you can see, it is almost compatible with the scripts in /etc/init.d/
. In fact, you can just make a symlink to YNIT directory instead of writing your own script.
You can also run a program without forking it to background. This can be done easily by setting Non-Stop
property to yes
or `true.
#!/bin/bash
### BEGIN INIT INFO
# Provides: log-redirector
# Required-Start: service1 service2 and all services
# Required-Stop: service1 service2 and all services
# X-Start-Before:
# X-Stop-After:
# Non-Stop:
### END INIT INFO
tail -f /log/of/service1 /log/of/other/services
This example is an useful trick to forward service logs to docker.
- Property lines MUST begin with
#
, no other characters allowed. - Property block is case-sensitive.
- The
### BEGIN INIT INFO
and### END INIT INFO
lines are required, and must begin with###
. - Only first property block is parsed.
- No variable subsitution.
YNIT reads all scripts in /etc/ynit/
, parse for properties (if exist), and executes them asynchronously. To be compatible with scripts in /etc/init.d/
, dependency will be ignored if not exists.
It will create separated runner in goroutines for each script. The runner waits for dependencies to finish if there are some, and broadcasts its name to other runners when itself finished.
After services are started, YNIT sleeps in background, waiting for SIGTERM
or SIGINT
to stop services.
Since YNIT is mainly build for running in docker container, you will need a running docker environment to test it.
- Build ynit binary with
go build
. - Build test image with
docker build -t ynit .
- Run a container with
docker run --rm --name ynit
. - Exec' into the container with
docker exec -it ynit ps ax
, see if ssh, nginx and php-fpm services are all up. - Stop the container with
docker stop ynit
- Extract log files from container and examine if they were gracefully exited.
GNU General Public License