You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
5.3KB

  1. #!/bin/bash
  2. # Make sure we react to these signals by running stop() when we see them - for clean shutdown
  3. # And then exiting
  4. trap "stop; exit 0;" SIGTERM SIGINT
  5. stop()
  6. {
  7. # We're here because we've seen SIGTERM, likely via a Docker stop command or similar
  8. # Let's shutdown cleanly
  9. echo "SIGTERM caught, terminating NFS process(es)..."
  10. /usr/sbin/exportfs -uav
  11. /usr/sbin/rpc.nfsd 0
  12. pid1=`pidof rpc.nfsd`
  13. pid2=`pidof rpc.mountd`
  14. # For IPv6 bug:
  15. pid3=`pidof rpcbind`
  16. kill -TERM $pid1 $pid2 $pid3 > /dev/null 2>&1
  17. echo "Terminated."
  18. exit
  19. }
  20. # Check if the SHARED_DIRECTORY variable is empty
  21. if [ -z "${SHARED_DIRECTORY}" ]; then
  22. echo "The SHARED_DIRECTORY environment variable is unset or null, exiting..."
  23. exit 1
  24. else
  25. echo "Writing SHARED_DIRECTORY to /etc/exports file"
  26. /bin/sed -i "[email protected]{{SHARED_DIRECTORY}}@${SHARED_DIRECTORY}@g" /etc/exports
  27. fi
  28. # This is here to demonsrate how multiple directories can be shared. You
  29. # would need a block like this for each extra share.
  30. # Any additional shares MUST be subdirectories of the root directory specified
  31. # by SHARED_DIRECTORY.
  32. # Check if the SHARED_DIRECTORY_2 variable is empty
  33. if [ ! -z "${SHARED_DIRECTORY_2}" ]; then
  34. echo "Writing SHARED_DIRECTORY_2 to /etc/exports file"
  35. echo "{{SHARED_DIRECTORY_2}} {{PERMITTED}}({{READ_ONLY}},{{SYNC}},no_subtree_check,no_auth_nlm,insecure,no_root_squash)" >> /etc/exports
  36. /bin/sed -i "[email protected]{{SHARED_DIRECTORY_2}}@${SHARED_DIRECTORY_2}@g" /etc/exports
  37. fi
  38. # Check if the PERMITTED variable is empty
  39. if [ -z "${PERMITTED}" ]; then
  40. echo "The PERMITTED environment variable is unset or null, defaulting to '*'."
  41. echo "This means any client can mount."
  42. /bin/sed -i "s/{{PERMITTED}}/*/g" /etc/exports
  43. else
  44. echo "The PERMITTED environment variable is set."
  45. echo "The permitted clients are: ${PERMITTED}."
  46. /bin/sed -i "s/{{PERMITTED}}/"${PERMITTED}"/g" /etc/exports
  47. fi
  48. # Check if the READ_ONLY variable is set (rather than a null string) using parameter expansion
  49. if [ -z ${READ_ONLY+y} ]; then
  50. echo "The READ_ONLY environment variable is unset or null, defaulting to 'rw'."
  51. echo "Clients have read/write access."
  52. /bin/sed -i "s/{{READ_ONLY}}/rw/g" /etc/exports
  53. else
  54. echo "The READ_ONLY environment variable is set."
  55. echo "Clients will have read-only access."
  56. /bin/sed -i "s/{{READ_ONLY}}/ro/g" /etc/exports
  57. fi
  58. # Check if the SYNC variable is set (rather than a null string) using parameter expansion
  59. if [ -z "${SYNC+y}" ]; then
  60. echo "The SYNC environment variable is unset or null, defaulting to 'async' mode".
  61. echo "Writes will not be immediately written to disk."
  62. /bin/sed -i "s/{{SYNC}}/async/g" /etc/exports
  63. else
  64. echo "The SYNC environment variable is set, using 'sync' mode".
  65. echo "Writes will be immediately written to disk."
  66. /bin/sed -i "s/{{SYNC}}/sync/g" /etc/exports
  67. fi
  68. # Partially set 'unofficial Bash Strict Mode' as described here: http://redsymbol.net/articles/unofficial-bash-strict-mode/
  69. # We don't set -e because the pidof command returns an exit code of 1 when the specified process is not found
  70. # We expect this at times and don't want the script to be terminated when it occurs
  71. set -uo pipefail
  72. IFS=$'\n\t'
  73. # This loop runs till until we've started up successfully
  74. while true; do
  75. # Check if NFS is running by recording it's PID (if it's not running $pid will be null):
  76. pid=`pidof rpc.mountd`
  77. # If $pid is null, do this to start or restart NFS:
  78. while [ -z "$pid" ]; do
  79. echo "Displaying /etc/exports contents:"
  80. cat /etc/exports
  81. echo ""
  82. # Normally only required if v3 will be used
  83. # But currently enabled to overcome an NFS bug around opening an IPv6 socket
  84. echo "Starting rpcbind..."
  85. /sbin/rpcbind -w
  86. echo "Displaying rpcbind status..."
  87. /sbin/rpcinfo
  88. # Only required if v3 will be used
  89. # /usr/sbin/rpc.idmapd
  90. # /usr/sbin/rpc.gssd -v
  91. # /usr/sbin/rpc.statd
  92. echo "Starting NFS in the background..."
  93. /usr/sbin/rpc.nfsd --debug 8 --no-udp --no-nfs-version 2 --no-nfs-version 3
  94. echo "Exporting File System..."
  95. if /usr/sbin/exportfs -rv; then
  96. /usr/sbin/exportfs
  97. else
  98. echo "Export validation failed, exiting..."
  99. exit 1
  100. fi
  101. echo "Starting Mountd in the background..."These
  102. /usr/sbin/rpc.mountd --debug all --no-udp --no-nfs-version 2 --no-nfs-version 3
  103. # --exports-file /etc/exports
  104. # Check if NFS is now running by recording it's PID (if it's not running $pid will be null):
  105. pid=`pidof rpc.mountd`
  106. # If $pid is null, startup failed; log the fact and sleep for 2s
  107. # We'll then automatically loop through and try again
  108. if [ -z "$pid" ]; then
  109. echo "Startup of NFS failed, sleeping for 2s, then retrying..."
  110. sleep 2
  111. fi
  112. done
  113. # Break this outer loop once we've started up successfully
  114. # Otherwise, we'll silently restart and Docker won't know
  115. echo "Startup successful."
  116. break
  117. done
  118. while true; do
  119. # Check if NFS is STILL running by recording it's PID (if it's not running $pid will be null):
  120. pid=`pidof rpc.mountd`
  121. # If it is not, lets kill our PID1 process (this script) by breaking out of this while loop:
  122. # This ensures Docker observes the failure and handles it as necessary
  123. if [ -z "$pid" ]; then
  124. echo "NFS has failed, exiting, so Docker can restart the container..."
  125. break
  126. fi
  127. # If it is, give the CPU a rest
  128. sleep 1
  129. done
  130. sleep 1
  131. exit 1