#!/bin/sh
# cloonixsbininit - pid 1 of every cloonix container.
CLOONIX_INIT_LOG=/tmp/cloonix_sbin_init.log
if [ -d /cloonixmnt/tmp ]; then
  CLOONIX_INIT_LOG=/cloonixmnt/tmp/cloonix_sbin_init.log
fi
# POSIX redirection, not "&>".
exec > "${CLOONIX_INIT_LOG}" 2>&1
echo "STARTING cloonixsbininit"
echo "log is ${CLOONIX_INIT_LOG}"
# A /var that comes empty (the tmpfs of a self_rootfs container) gets the
# skeleton of a normal system before anything runs: /var/run, /var/log...
if [ -z "$(ls -A /var 2>/dev/null)" ]; then
  mkdir -p /var/log /var/lib /var/cache /var/spool /var/tmp /var/opt \
           /var/local /var/mail /var/backups /run/lock
  chmod 1777 /var/tmp
  ln -s ../run /var/run
  ln -s ../run/lock /var/lock
  echo "empty /var: skeleton made"
fi
/cloonixmnt/cnf_fs/cloonix-agent
echo "/cloonixmnt/cnf_fs/cloonix-agent"
/cloonixmnt/cnf_fs/cloonix-cxp-srv
echo "/cloonixmnt/cnf_fs/cloonix-cxp-srv"

# Keep the two agents alive on every path, systemd or not: backgrounded, it
# survives the exec of init; a container has no other relaunch.
cloonix_keep_agents_alive() {
  while true; do
    sleep 5
    for a in cloonix-agent cloonix-cxp-srv; do
      found=0
      for pp in /proc/[0-9]*; do
        if [ "$(cat $pp/comm 2>/dev/null)" = "$a" ]; then
          found=1
          break
        fi
      done
      if [ $found = 0 ]; then
        echo "RESTARTING $a"
        /cloonixmnt/cnf_fs/$a
      fi
    done
  done
}
cloonix_keep_agents_alive &
CLOONIX_KEEP_PID=$!
if [ -e "/cloonixmnt/cnf_fs/startup_nb_eth" ]; then
  NB_ETH=$(cat /cloonixmnt/cnf_fs/startup_nb_eth)
  echo "startup_nb_eth = ${NB_ETH}"
  NB_ETH=$((NB_ETH-1))
  for i in $(seq 0 $NB_ETH); do
    LIST="${LIST} eth$i"
  done
  for eth in $LIST; do
    while [ $(ip link show | egrep -c ": ${eth}") = 0 ]; do
      sleep 1
    done
  done
fi
sleep 1
echo $$ > /run/cloonix_startup.pid
echo "startup pid $$"
STARTUP_ENV=""
if [ -e "/cloonixmnt/cnf_fs/startup_env" ]; then
  STARTUP_ENV=$(cat /cloonixmnt/cnf_fs/startup_env)
fi
WANT_SYSTEMD=0
case "${STARTUP_ENV}" in
  *CLOONIX_WITH_SYSTEMD=1*) WANT_SYSTEMD=1 ;;
esac
echo "startup_env = '${STARTUP_ENV}', systemd wanted = ${WANT_SYSTEMD}"
# systemd as pid 1 needs cgroups of its own: a toy without them comes up
# without systemd, saying why.
if [ "${WANT_SYSTEMD}" = "1" ]; then
  if mkdir /sys/fs/cgroup/cloonix_probe 2>/dev/null; then
    rmdir /sys/fs/cgroup/cloonix_probe
  else
    WANT_SYSTEMD=0
    WHY="CLOONIX_WITH_SYSTEMD=1 asked, but /sys/fs/cgroup is not writable here: systemd cannot run, started without it"
    echo "${WHY}"
    echo "${WHY}" > /run/cloonix_no_systemd
  fi
fi
if [ "${WANT_SYSTEMD}" = "0" ]; then
  echo "no systemd (the default); the syslog daemon is started directly"
  # rsyslogd on every distribution that packages it, syslog-ng where it is not
  # packaged.
  for i in /usr/sbin/rsyslogd /sbin/rsyslogd \
           /usr/sbin/syslog-ng /sbin/syslog-ng /usr/bin/syslog-ng; do
    if [ -x $i ]; then
      # pid 1 and the agents are protected from the oom killer, not this.
      /bin/sh -c "echo 0 > /proc/self/oom_score_adj; exec $i"
      echo "LAUNCHING $i"
      break
    fi
  done
  # The keep-alive is already running in the background from the top of this
  # script; on the no-systemd path there is no init to hand over to, so wait
  # on it here rather than exiting pid 1.
  echo "LAUNCHING the keep-alive wait"
  # Wait on the supervisor specifically: a bare "wait" returns as soon as any
  # child exits (rsyslogd may daemonize and do just that), which would drop
  # pid 1 and take the container down. Loop in case wait is interrupted.
  while kill -0 ${CLOONIX_KEEP_PID} 2>/dev/null; do
    wait ${CLOONIX_KEEP_PID}
  done
fi
# Say what the inotify budget looks like BEFORE handing over.
for f in /proc/sys/fs/inotify/max_user_instances \
         /proc/sys/fs/inotify/max_user_watches; do
  if [ -r $f ]; then
    echo "$f = $(cat $f)"
  fi
done
echo "inotify instances already held by uid $(id -u): $(ls -l /proc/*/fd/ 2>/dev/null | grep -c inotify)"
# An init that does not know it is protected from the oom killer would hand
# that to everything it starts: under a ram cap nothing could be killed.
echo 0 > /proc/self/oom_score_adj
if [ -x /sbin/init ]; then
  echo "/sbin/init will be launched"
  exec /sbin/init
fi
if [ -x /lib/systemd/systemd ]; then
  echo "/lib/systemd/systemd will be launched"
  exec /lib/systemd/systemd
fi
echo "No init found in the image, staying up anyway"
# A loop, not "sleep infinity".
while true; do
  sleep 3600
done
