From dca5448c2d7a71c33ab7c2672866536166280c5b Mon Sep 17 00:00:00 2001 From: Eric Hough Date: Thu, 9 Nov 2017 14:39:34 -0800 Subject: [PATCH] improving /etc/exports construction from environment variables --- README.md | 14 +++++++------- entrypoint.sh | 44 +++++++++++++++++++------------------------- 2 files changed, 26 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index cc629d3..dd3f56a 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ This is the only containerized NFS server that offers **all** of the following f The container requires you to supply it with your desired [NFS exports](https://linux.die.net/man/5/exports) upon startup. You have **two choices** for doing this: -1. **Bind mount an exports file into the container at `/etc/exports`**. +1. **Bind mount a full exports file into the container at `/etc/exports`**. docker run \ -v /host/path/to/exports.txt:/etc/exports:ro \ @@ -33,15 +33,15 @@ The container requires you to supply it with your desired [NFS exports](https:// -p 2049:2049 \ erichough/nfs4-server:latest` -1. **Supply environment variable triplets to the container to allow it to construct `/etc/exports`**. +1. **Supply each line of `/etc/exports` as an environment variable**. - Each triplet should consist of `NFS_EXPORT_DIR_*`, `NFS_EXPORT_CLIENT_*`, and `NFS_EXPORT_OPTIONS_*`. You can add as many triplets as you'd like. + The container will look for environment variables that start with `NFS_EXPORT_` and end with an integer. e.g. `NFS_EXPORT_0`, `NFS_EXPORT_1`, etc. docker run \ - -e NFS_EXPORT_DIR_0=/nfs \ - -e NFS_EXPORT_CLIENT_0=192.168.1.0/24 \ - -e NFS_EXPORT_OPTIONS_0=rw,no_subtree_check,fsid=0 \ - -v /host/files:/nfs \ + -e NFS_EXPORT_0='/nfs/foo 192.168.1.0/24(ro,no_subtree_check)' \ + -e NFS_EXPORT_1='/nfs/bar 123.123.123.123/32(rw,no_subtree_check)' \ + -v /host/path/foo:/nfs/foo \ + -v /host/path/bar:/nfs/bar \ --cap-add SYS_ADMIN \ -p 2049:2049 \ erichough/nfs4-server:latest` diff --git a/entrypoint.sh b/entrypoint.sh index d6c62a3..492c4fc 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -246,8 +246,8 @@ init_trap() { trap stop SIGTERM SIGINT } -init_exports() -{ +init_exports() { + if mount | grep -Eq '^[^ ]+ on /etc/exports type '; then log '/etc/exports appears to be mounted via Docker' return @@ -255,45 +255,39 @@ init_exports() local collected=0 local exports='' - local candidateDirs + local candidateExportVariables - candidateDirs=$(compgen -A variable | grep -E 'NFS_EXPORT_DIR_[0-9]*') - exit_on_failure 'missing NFS_EXPORT_DIR_* environment variable(s)' + candidateExportVariables=$(compgen -A variable | grep -E 'NFS_EXPORT_[0-9]+' | sort) + exit_on_failure 'please bind mount /etc/exports or supply NFS_EXPORT_* environment variables' log 'building /etc/exports' - for dir in $candidateDirs; do + for exportVariable in $candidateExportVariables; do - local index=${dir##*_} - local net=NFS_EXPORT_CLIENT_$index - local opt=NFS_EXPORT_OPTIONS_$index + local line=${!exportVariable} + local lineAsArray + IFS=' ' read -r -a lineAsArray <<< "$line" + local dir="${lineAsArray[0]}" - if [[ ! -d "${!dir}" ]]; then - log "skipping $dir (${!dir}) since it is not a directory" + if [[ ! -d "$dir" ]]; then + log "skipping $line since $dir is not a directory" continue fi - if [[ -n ${!net} ]] && [[ -n ${!opt} ]]; then - - log "will export ${!dir} to ${!net} with options ${!opt}" + log "will export $line" - local line="${!dir} ${!net}(${!opt})" - - if [[ $collected -gt 0 ]]; then - exports=$exports$'\n' - fi + if [[ $collected -gt 0 ]]; then + exports=$exports$'\n' + fi - exports=$exports$line + exports=$exports$line - (( collected++ )) + (( collected++ )) - else - log "skipping $dir (${!dir}) as it is missing domain and/or options. be sure to set both $net and $opt." - fi done if [[ $collected -eq 0 ]]; then - log 'no directories to export.' + log 'no valid exports' exit 1 fi