# cloud-init-blocknet
# the purpose of this job is
#  * to block networking from coming up until cloud-init-nonet has run
#  * timeout if they all do not come up in a reasonable amount of time
description "block networking until cloud-init-local"
start on (starting network-interface
          or starting network-manager
          or starting networking)
stop on stopped cloud-init-local

instance $JOB${INTERFACE:+/}${INTERFACE:-}
export INTERFACE
task

script
   set +e  # you cannot trap TERM reliably with 'set -e'
   SLEEP_CHILD=""

   static_network_up() {
      local emitted="/run/network/static-network-up-emitted"
      # /run/network/static-network-up-emitted is written by
      # upstart (via /etc/network/if-up.d/upstart). its presense would
      # indicate that static-network-up has already fired.
      [ -e "$emitted" -o -e "/var/$emitted" ]
   }
   msg() {
      local uptime="" idle="" msg=""
      if [ -r /proc/uptime ]; then
         read uptime idle < /proc/uptime
      fi
      msg="${UPSTART_INSTANCE}${uptime:+[${uptime}]}: $*"
      echo "$msg"
   }

   handle_sigterm() {
      # if we received sigterm and static networking is up then it probably
      # came from upstart as a result of 'stop on static-network-up'
      msg "got sigterm"
      if [ -n "$SLEEP_CHILD" ]; then
          if ! kill $SLEEP_CHILD 2>/dev/null; then
              [ ! -d "/proc/$SLEEP_CHILD" ] ||
                  msg "hm.. failed to kill sleep pid $SLEEP_CHILD"
          fi
      fi
      msg "stopped"
      exit 0
   }

   dowait() {
      msg "blocking $1 seconds"
      # all this 'exec -a' does is get me a nicely named process in 'ps'
      # ie, 'sleep-block-network-interface.eth1'
      if [ -x /bin/bash ]; then 
         bash -c 'exec -a sleep-block-$1 sleep $2' -- "$UPSTART_INSTANCE" "$1" &
      else
         sleep "$1" &
      fi
      SLEEP_CHILD=$!
      msg "sleepchild=$SLEEP_CHILD"
      wait $SLEEP_CHILD
      SLEEP_CHILD=""
   }

   trap handle_sigterm TERM

   if [ -n "$INTERFACE" -a "${INTERFACE#lo}" != "${INTERFACE}" ]; then
     msg "ignoring interface ${INTERFACE}";
     exit 0;
   fi

   # static_network_up already occurred
   static_network_up && { msg "static_network_up already"; exit 0; }

   # local-finished cloud-init-local success or failure
   lfin="/run/cloud-init/local-finished"
   disable="/etc/cloud/no-blocknet"
   [ -f "$lfin" ] && { msg "$lfin found"; exit 0; }
   [ -f "$disable" ] && { msg "$disable found"; exit 0; }

   dowait 120
   msg "gave up waiting for $lfin"
   exit 1
end script
