#!/bin/execlineb -S0

# This file is executed (not as process 1!) as soon as s6-svscan
# starts, with the original stdin/out/err, but NOT the original
# environment.
# Purpose of this file: to perform all the one-time initialization tasks.

# Merge environments from our custom stage into current context
s6-envdir -I /var/run/s6/env-stage2

# This env decides what to do if stage2 fails
backtick -D 0 -n S6_BEHAVIOUR_IF_STAGE2_FAILS { printcontenv S6_BEHAVIOUR_IF_STAGE2_FAILS }
importas -u S6_BEHAVIOUR_IF_STAGE2_FAILS S6_BEHAVIOUR_IF_STAGE2_FAILS

# This env determines whether user provided files in /etc should be linked 
# or copied into /var/run/s6
backtick -D 0 -n S6_READ_ONLY_ROOT { printcontenv S6_READ_ONLY_ROOT }
importas -u S6_READ_ONLY_ROOT S6_READ_ONLY_ROOT

foreground
{
  if
  {
    /etc/s6/init/init-stage2-redirfd
    foreground
    {
      ##
      ## copy user provided files to /var/run/s6/etc, depending on S6_RUNTIME_PROFILE env,
      ## /etc (if not defined) or /etc/cont-profile.d/${S6_RUNTIME_PROFILE} will be used
      ## as copying source.
      ##

      if
      {
        if { s6-echo -n -- "[s6-init] making user provided files available at /var/run/s6/etc..." }
        foreground
        {
          backtick -n S6_RUNTIME_PROFILE { printcontenv S6_RUNTIME_PROFILE }
          importas -u S6_RUNTIME_PROFILE S6_RUNTIME_PROFILE
          backtick -n S6_RUNTIME_PROFILE_SRC {
            ifte { s6-echo "/etc/cont-profile.d/${S6_RUNTIME_PROFILE}" } { s6-echo "/etc" }
            s6-test -n ${S6_RUNTIME_PROFILE}
          }
          importas -u S6_RUNTIME_PROFILE_SRC S6_RUNTIME_PROFILE_SRC
          if { s6-rmrf /var/run/s6/etc }
          if { s6-mkdir -pm 0755 /var/run/s6/etc }
          forx i { "fix-attrs.d" "cont-init.d" "cont-finish.d" "services.d" }
          importas -u i i
          if { s6-test -d ${S6_RUNTIME_PROFILE_SRC}/${i} }
          # although s6-hiercopy is prefered, and until it doesn't support 'follow symlinks'
          # option, there is no clean way to allow symlinks between user provided runcoms.
          ifelse { s6-test ${S6_READ_ONLY_ROOT} -eq 0 } { 
            s6-ln -s ${S6_RUNTIME_PROFILE_SRC}/${i} /var/run/s6/etc/${i} 
          }
          if { s6-hiercopy ${S6_RUNTIME_PROFILE_SRC}/${i} /var/run/s6/etc/${i} }
        }
        importas -u ? ?
        if { s6-echo -- "exited ${?}." }
        ifelse { s6-test ${S6_BEHAVIOUR_IF_STAGE2_FAILS} -eq 0 } { exit 0 }
        exit ${?}
      }


      ##
      ## fix-attrs: ensure user-provided files have correct ownership & perms
      ##
      
      if
      {
        if { s6-echo -n -- "[s6-init] ensuring user provided files have correct perms..." }
        foreground { redirfd -r 0 /etc/s6/init/init-stage2-fixattrs.txt fix-attrs }
        importas -u ? ?
        if { s6-echo -- "exited ${?}." }
        ifelse { s6-test ${S6_BEHAVIOUR_IF_STAGE2_FAILS} -eq 0 } { exit 0 }
        exit ${?}
      }
      

      ##
      ## fix-attrs.d: apply user-provided ownership & permission fixes
      ##

      if
      {
        if -t { s6-test -d /var/run/s6/etc/fix-attrs.d }
        if { s6-echo "[fix-attrs.d] applying ownership & permissions fixes..." }
        if
        {
          pipeline { s6-ls -0 -- /var/run/s6/etc/fix-attrs.d }
          pipeline { s6-sort -0 -- }
          forstdin -0 -- i
          importas -u i i
          if { s6-echo -- "[fix-attrs.d] ${i}: applying... " }
          foreground { redirfd -r 0 /var/run/s6/etc/fix-attrs.d/${i} fix-attrs }
          importas -u ? ?
          if { s6-echo -- "[fix-attrs.d] ${i}: exited ${?}." }
          ifelse { s6-test ${S6_BEHAVIOUR_IF_STAGE2_FAILS} -eq 0 } { exit 0 }
          exit ${?}
        }
        if { s6-echo -- "[fix-attrs.d] done." }
      }

      ##
      ## cont-init.d: one-time init scripts
      ##

      if
      {
        if -t { s6-test -d /var/run/s6/etc/cont-init.d }
        if { s6-echo "[cont-init.d] executing container initialization scripts..." }
        if
        {
          pipeline { s6-ls -0 -- /var/run/s6/etc/cont-init.d }
          pipeline { s6-sort -0 -- }
          forstdin -o 0 -0 -- i
          importas -u i i
          if { s6-echo -- "[cont-init.d] ${i}: executing... " }
          foreground { /var/run/s6/etc/cont-init.d/${i} }
          importas -u ? ?
          if { s6-echo -- "[cont-init.d] ${i}: exited ${?}." }
          ifelse { s6-test ${S6_BEHAVIOUR_IF_STAGE2_FAILS} -eq 0 } { exit 0 }
          exit ${?}
        }
        if { s6-echo -- "[cont-init.d] done." }
      }

      ##
      ## services.d: long-lived processes to be supervised
      ##

      if
      {
        if -t { s6-test -d /var/run/s6/etc/services.d }
        if { s6-echo "[services.d] starting services" }
        if
        {
          pipeline { s6-ls -0 -- /var/run/s6/etc/services.d }
          forstdin -0 -p -- i
          importas -u i i
          if { s6-test -d /var/run/s6/etc/services.d/${i} }
          s6-hiercopy /var/run/s6/etc/services.d/${i} /var/run/s6/services/${i}
        }
        if { s6-svscanctl -a /var/run/s6/services }
        if
        {
          # This envs decide if CMD should wait until services are up
          backtick -D 0 -n S6_CMD_WAIT_FOR_SERVICES { printcontenv S6_CMD_WAIT_FOR_SERVICES }
          importas -u S6_CMD_WAIT_FOR_SERVICES S6_CMD_WAIT_FOR_SERVICES
          backtick -D 5000 -n S6_CMD_WAIT_FOR_SERVICES_MAXTIME { printcontenv S6_CMD_WAIT_FOR_SERVICES_MAXTIME }
          importas -u S6_CMD_WAIT_FOR_SERVICES_MAXTIME S6_CMD_WAIT_FOR_SERVICES_MAXTIME

          if -t { if { s6-test ${S6_CMD_WAIT_FOR_SERVICES} -ne 0 } s6-test $# -ne 0 }
          s6-maximumtime -t ${S6_CMD_WAIT_FOR_SERVICES_MAXTIME}
          pipeline { s6-ls -0 -- /var/run/s6/etc/services.d }
          forstdin -0 -o 0 -- i
          importas -u i i
          ifelse { s6-test -f /var/run/s6/services/${i}/down } { exit 0 }
          ifelse { s6-test -f /var/run/s6/services/${i}/notification-fd }
          {
            s6-svwait -t ${S6_CMD_WAIT_FOR_SERVICES_MAXTIME} -U /var/run/s6/services/${i}
          }
          s6-svwait -t ${S6_CMD_WAIT_FOR_SERVICES_MAXTIME} -u /var/run/s6/services/${i}
        }
        if { s6-echo -- "[services.d] done." }
      }
    }
    importas -u ? ?
    ifelse { s6-test ${S6_BEHAVIOUR_IF_STAGE2_FAILS} -eq 0 } { exit 0 }

    # Make stage2 exit code available in stage3
    foreground { redirfd -w 1 /var/run/s6/env-stage3/S6_STAGE2_EXITED s6-echo -n -- "${?}" }
    exit ${?}
  }


  ##
  ## The init is complete, If the user has a given CMD, run it now, then
  ## kill everything when it exits.
  ##

  if -t { s6-test $# -ne 0 }

  foreground {
      s6-setsid -gq -- with-contenv
      backtick -D 0 -n S6_LOGGING { printcontenv S6_LOGGING }
      importas S6_LOGGING S6_LOGGING
      ifelse { s6-test ${S6_LOGGING} -eq 2 }
      {
          redirfd -w 1 /var/run/s6/uncaught-logs-fifo
          fdmove -c 2 1
          $@
      }
      $@
  }

  importas -u ? ?

  foreground {
      /etc/s6/init/init-stage2-redirfd
      s6-echo -- "[cmd] ${1} exited ${?}"
  }

  # Make CMD exit code available in stage3
  foreground { redirfd -w 1 /var/run/s6/env-stage3/S6_STAGE2_EXITED s6-echo -n -- "${?}" }

  # Stop supervision tree
  foreground { s6-svscanctl -t /var/run/s6/services }

  # Wait to be nuked
  s6-pause -th

}
importas -u ? ?
if { s6-test ${?} -ne 0 }
if { s6-test ${S6_BEHAVIOUR_IF_STAGE2_FAILS} -ne 0 }
ifelse { s6-test ${S6_BEHAVIOUR_IF_STAGE2_FAILS} -ne 1 }
{
  s6-svscanctl -t /var/run/s6/services
}
s6-echo -- "\n!!!!!\n init-stage2 failed.\n!!!!!"
