#EOF:runphp.userconf:ne pas modifier cette ligne ################################################################################ # Ne pas modifier à partir d'ici if [ -n "$_sourced" ]; then if [ "${0#-}" != "$0" ]; then # sourcé depuis la ligne de commande MYSELF="${BASH_SOURCE[1]}" else # sourcé depuis un script MYSELF="${BASH_SOURCE[0]}" fi MYDIR="$(cd "$(dirname -- "$MYSELF")"; pwd)" MYNAME="$(basename -- "$MYSELF")" else MYDIR="$(cd "$(dirname -- "$0")"; pwd)" MYNAME="$(basename -- "$0")" fi if [ -f "$MYDIR/runphp.userconf.local" ]; then source "$MYDIR/runphp.userconf.local" fi DEFAULT_DIST=d12 if [ -n "$RUNPHP_STANDALONE" ]; then PROJDIR="$RUNPHP_PROJDIR" COMPOSERDIR=. COMPOSERPHAR= VENDORDIR=vendor BUILDENV0= BUILDENV= DIST="${RUNPHP_DIST:-$DEFAULT_DIST}" IMAGENAME=nulib/ PRIVAREG=docker.io REGISTRY="$RUNPHP_REGISTRY" else [ -n "$PROJDIR" ] || PROJDIR="$(dirname -- "$MYDIR")" [ "${PROJDIR#/}" != "$PROJDIR" ] || PROJDIR="$(cd "$MYDIR/$PROJDIR"; pwd)" [ -n "$COMPOSERDIR" ] || COMPOSERDIR=. [ -n "$COMPOSERPHAR" ] || COMPOSERPHAR=sbin/composer.phar [ -n "$VENDORDIR" ] || VENDORDIR=vendor [ -n "$BUILDENV0" ] || BUILDENV0=.build.env.dist [ -n "$BUILDENV" ] || BUILDENV=build.env [ -n "$DIST" ] || DIST="$DEFAULT_DIST" [ -n "$IMAGENAME" ] || IMAGENAME=nulib/ [ "$COMPOSERPHAR" == none ] && COMPOSERPHAR= [ "$BUILDENV0" == none ] && BUILDENV0= [ "$BUILDENV" == none ] && BUILDENV= fi function after_source_buildenv() { NDIST="${DIST#d}" } after_source_buildenv [ -n "$_sourced" ] && return 0 function eecho() { echo "$*" 1>&2; } function eerror() { eecho "ERROR: $*"; } function die() { [ $# -gt 0 ] && eerror "$*"; exit 1; } function is_defined() { [ -n "$(declare -p "$1" 2>/dev/null)" ]; } function in_path() { [ -n "$1" -a -x "$(which "$1" 2>/dev/null)" ]; } function composer() { cd "$PROJDIR/$COMPOSERDIR" || exit 1 if [ -n "$COMPOSERPHAR" -a -x "$PROJDIR/$COMPOSERPHAR" ]; then "$PROJDIR/$COMPOSERPHAR" "$@" elif in_path composer; then command composer "$@" elif [ -x /usr/bin/composer ]; then /usr/bin/composer "$@" elif [ -x /usr/local/bin/composer ]; then /usr/local/bin/composer "$@" else die "impossible de trouver composer" fi if [ -z "$RUNPHP_STANDALONE" -a -f composer.lock ]; then cp composer.lock "$PROJDIR/.composer.lock.runphp" fi } function ensure_image() { local privareg imagename if [ -z "$IMAGE" ]; then [[ "$IMAGENAME" == */ ]] && imagename=runphp || imagename="${IMAGENAME%/*}/runphp" privareg="$PRIVAREG" if [ "$imagename" == runphp ]; then [ -z "$privareg" -o "$privareg" == docker.io ] && privareg=docker.io/library else [ -z "$privareg" ] && privareg=docker.io fi IMAGE="$privareg/$imagename:$DIST" fi } function check_image() { local image="$IMAGE" for prefix in docker.io/library/ docker.io; do if [ "${image#$prefix}" != "$image" ]; then image="${image#$prefix}" break fi done [ -n "$(docker image ls --no-trunc --format '{{.Repository}}:{{.Tag}}' "$image" 2>/dev/null)" ] } ## Arguments initiaux Bootstrap= ComposerInstall= if [ "$1" == --runphp-bootstrap -o "$1" == --bs ]; then Bootstrap=1 shift elif [ "$1" == --runphp-exec ]; then Bootstrap= shift elif [ "$1" == --runphp-install -o "$1" == --ci ]; then ComposerInstall=1 shift fi ForcedBootstrap= if [ -z "$Bootstrap" -a -z "$RUNPHP_STANDALONE" ]; then # si vendor/ n'existe pas, alors on doit faire bootstrap if [ ! -f "$PROJDIR/$VENDORDIR/nulib/php/load.sh" ]; then ForcedBootstrap=1 elif [ ! -f "$PROJDIR/.composer.lock.runphp" ]; then ForcedBootstrap=1 elif ! diff -q "$PROJDIR/$COMPOSERDIR/composer.lock" "$PROJDIR/.composer.lock.runphp" >&/dev/null; then ForcedBootstrap=1 fi if [ -n "$ForcedBootstrap" ]; then [ "$RUNPHP_MODE" != docker ] && eecho "== bootstrapping runphp" Bootstrap=1 ComposerInstall=1 fi fi if [ "$RUNPHP_MODE" != docker ]; then ############################################################################ # Lancement depuis l'extérieur du container ############################################################################ ## Charger ~/.dkbuild.env APT_PROXY= APT_MIRROR= SEC_MIRROR= TIMEZONE= PRIVAREG= REGISTRY= PROFILE= HOST_MAPPINGS=() function default_profile() { PROFILE="$1" } function profile() { local profile for profile in "$@"; do [ "$profile" == "$PROFILE" ] && return 0 done return 1 } function setenv() { eval "export $1" } function default() { local command="$1"; shift local nv n v case "$command" in docker) for nv in "$@"; do [[ "$nv" == *=* ]] || continue n="${nv%%=*}" v="${nv#*=}" case "$n" in host-mappings) read -a ns <<<"$v" for v in "${ns[@]}"; do HOST_MAPPINGS+=("$v") done ;; esac done ;; esac } [ -f ~/.dkbuild.env ] && source ~/.dkbuild.env [ -n "$APT_PROXY" ] || APT_PROXY= [ -n "$APT_MIRROR" ] || APT_MIRROR=default [ -n "$SEC_MIRROR" ] || SEC_MIRROR=default [ -n "$TIMEZONE" ] || TIMEZONE=Europe/Paris [ -n "$PRIVAREG" ] || PRIVAREG= [ -n "$REGISTRY" ] || REGISTRY=pubdocker.univ-reunion.fr ## Charger la configuration # Recenser les valeur de proxy declare -A PROXY_VARS for var in {HTTPS,ALL,NO}_PROXY {http,https,all,no}_proxy; do is_defined "$var" && PROXY_VARS[${var,,}]="${!var}" done # Paramètres de montage if [ -n "$RUNPHP_NO_USE_RSLAVE" ]; then UseRslave= elif [ -n "$RUNPHP_USE_RSLAVE" ]; then UseRslave=1 elif [ -e /proc/sys/fs/binfmt_misc/WSLInterop ]; then # pas de mount propagation sous WSL UseRslave= else UseRslave=1 fi # Toujours vérifier l'existence de l'image IMAGE= if [ -z "$Bootstrap" ]; then if [ -n "$RUNPHP_FORCE_BUILDENVS" ]; then eval "Configs=($RUNPHP_FORCE_BUILDENVS)" for config in "${Configs[@]}"; do source "$config" || exit 1 done after_source_buildenv elif [ -n "$BUILDENV" -a -f "$PROJDIR/$BUILDENV" ]; then source "$PROJDIR/$BUILDENV" || exit 1 after_source_buildenv elif [ -n "$BUILDENV0" -a -f "$PROJDIR/$BUILDENV0" ]; then source "$PROJDIR/$BUILDENV0" || exit 1 after_source_buildenv fi ensure_image check_image || Bootstrap=1 fi Chdir= Verbose="$RUNPHP_VERBOSE" if [ -n "$Bootstrap" ]; then ## Mode bootstrap de l'image ########################################### # Ici, on a déterminé que l'image doit être construite BUILD_ARGS=( DIST NDIST REGISTRY APT_PROXY APT_MIRROR SEC_MIRROR TIMEZONE ) SOPTS=+d:9876543210:c:UjDx:z:r:p LOPTS=help,dist:,d19,d18,d17,d16,d15,d14,d13,d12,d11,d10,config:,ue,unless-exists,pull,nc,no-cache,po,plain-output,apt-proxy:,timezone:,privareg:,push,ci,no-use-rslave args="$(getopt -n "$MYNAME" -o "$SOPTS" -l "$LOPTS" -- "$@")" || exit 1; eval "set -- $args" Dist= if [ -n "$RUNPHP_FORCE_BUILDENVS" ]; then eval "Configs=($RUNPHP_FORCE_BUILDENVS)" elif [ -n "$BUILDENV" -a -f "$PROJDIR/$BUILDENV" ]; then Configs=("$PROJDIR/$BUILDENV") elif [ -n "$BUILDENV0" -a -f "$PROJDIR/$BUILDENV0" ]; then Configs=("$PROJDIR/$BUILDENV0") else Configs=() fi UnlessExists= Pull= NoCache= PlainOutput= while [ $# -gt 0 ]; do case "$1" in --) shift; break;; --help) eecho "\ runphp: construire l'image docker USAGE $MYNAME --bootstrap [options...] OPTIONS -c, --config build.env --unless-exists -U, --pull -j, --no-cache -D, --plain-output -x, --apt-proxy APT_PROXY -z, --timezone TIMEZONE -r, --privareg PRIVAREG -p, --push paramètres pour la consruction de l'image" exit 0 ;; -d|--dist) shift; Dist="$1";; -[0-9]) Dist="d1${1#-}";; --d*) Dist="${1#--}";; -c|--config) shift; Configs+="$1";; --ue|--unless-exists) UnlessExists=1;; -U|--pull) Pull=1;; -j|--nc|--no-cache) NoCache=1;; -D|--po|--plain-output) PlainOutput=1;; -x|--apt-proxy) shift; APT_PROXY="$1";; -z|--timezone) shift; TIMEZONE="$1";; -r|--privareg) shift; PRIVAREG="$1";; -p|--push) Push=1;; --ci) ComposerInstall=1;; --no-use-rslave) UseRslave=;; *) die "$1: option non configurée";; esac shift done for config in "${Configs[@]}"; do if [ "$config" == none ]; then Configs=() break fi done if [ ${#Configs[*]} -gt 0 ]; then for config in "${Configs[@]}"; do source "$config" || exit 1 done after_source_buildenv fi [ -n "$Dist" ] && DIST="$Dist" ensure_image check_image && exists=1 || exists= if [ -z "$UnlessExists" -o -z "$exists" ]; then eecho "== Building $IMAGE" if [ -n "$RUNPHP_STANDALONE" ]; then DFDIR="$RUNPHP_STANDALONE/runphp" else DFDIR="$MYDIR" fi dockerfiles=( "$DFDIR/Dockerfile.runphp.local" "$DFDIR/Dockerfile.runphp$BUILD_FLAVOUR" "$DFDIR/Dockerfile.runphp" ) for dockerfile in "${dockerfiles[@]}"; do [ -f "$dockerfile" ] && break done args=( -f "$dockerfile" ${Pull:+--pull} ${NoCache:+--no-cache} ${BuildPlain:+--progress plain} -t "$IMAGE" ) for arg in "${BUILD_ARGS[@]}"; do args+=(--build-arg "$arg=${!arg}") done for arg in "${!PROXY_VARS[@]}"; do args+=(--build-arg "$arg=${PROXY_VARS[$arg]}") done for host in "${HOST_MAPPINGS[@]}"; do args+=(--add-host "$host") done mkdir -p /tmp/runphp-build docker build "${args[@]}" /tmp/runphp-build || exit 1 if [ -n "$Push" -a -n "$PRIVAREG" ]; then eecho "== Pushing $IMAGE" docker push "$IMAGE" || exit 1 fi fi if [ -z "$RUNPHP_STANDALONE" -a ! -f "$PROJDIR/$VENDORDIR/nulib/php/load.sh" ]; then # Forcer l'installation des dépendances si nécessaire ComposerInstall=1 fi [ -z "$ComposerInstall" -o -n "$UnlessExists" ] && exit 0 else ## Mode exécution de commande ########################################## # Ici, on a déterminé qu'il faut lancer une commande SOPTS=+w: LOPTS=help,chdir:,no-use-rslave args="$(getopt -n "$MYNAME" -o "$SOPTS" -l "$LOPTS" -- "$@")" || exit 1; eval "set -- $args" while [ $# -gt 0 ]; do case "$1" in --) shift; break;; --help) eecho "\ runphp: lancer une commande dans un environnement PHP déterminé USAGE $MYNAME ci|cu|composer $MYNAME [options] command [args...] COMMANDES COMPOSER ci cu installer/mettre à jour les dépendances du projet avec composer composer [args...] lancer composer avec les arguments spécifiés. pour les commandes ci-dessus, l'option --chdir est ignorée: le répertoire courant est forcé au répertoire du projet composer OPTIONS -w, --chdir CHDIR aller dans le répertoire spécifié avant de lancer la commande" exit 0 ;; -w|--chdir) shift; Chdir="$1";; --no-use-rslave) UseRslave=;; *) die "$1: option non configurée";; esac shift done if [ -z "$RUNPHP_STANDALONE" -a ! -f "$PROJDIR/$VENDORDIR/nulib/php/load.sh" ]; then # Forcer l'installation des dépendances si nécessaire ComposerInstall=1 fi fi ## Lancer la commande args=( run -it --rm --name "runphp-$(basename -- "$1")-$$" -e RUNPHP_MODE=docker ) for arg in "${!PROXY_VARS[@]}"; do args+=(-e "$arg=${PROXY_VARS[$arg]}") done if [ -n "$RUNPHP_STANDALONE" ]; then args+=( -e "RUNPHP_STANDALONE=$RUNPHP_STANDALONE" -e "RUNPHP_PROJDIR=$PROJDIR" ) fi for host in "${HOST_MAPPINGS[@]}"; do args+=(--add-host "$host") done # monter le répertoire qui contient $PROJDIR mount_composer= mount_runphp=1 if [ "${PROJDIR#$HOME/}" != "$PROJDIR" -o "$PROJDIR" == "$HOME" ]; then # bind mount $HOME args+=(-v "$HOME:$HOME${UseRslave:+:rslave}") [ -n "$RUNPHP_STANDALONE" ] && [ "${RUNPHP_STANDALONE#$HOME/}" != "$RUNPHP_STANDALONE" ] && mount_runphp= else # bind mount uniquement le répertoire du projet args+=(-v "$PROJDIR:$PROJDIR${UseRslave:+:rslave}") mount_composer=1 [ "$RUNPHP_STANDALONE" == "$PROJDIR" ] && mount_runphp= fi if [ -n "$mount_composer" -a -d "$HOME/.composer" ]; then # monter la configuration de composer args+=(-v "$HOME/.composer:$HOME/.composer") fi if [ -n "$RUNPHP_STANDALONE" -a -n "$mount_runphp" ]; then args+=(-v "$RUNPHP_STANDALONE:$RUNPHP_STANDALONE") fi args+=(-w "$(pwd)") # lancer avec l'utilisateur courant if [ $(id -u) -ne 0 ]; then # si c'est un utilisateur lambda, il faut monter les informations # nécessaires. composer est déjà monté via $HOME args+=( -e DEVUSER_USERENT="$(getent passwd "$(id -un)")" -e DEVUSER_GROUPENT="$(getent group "$(id -gn)")" ) fi args+=( "$IMAGE" exec "$0" ${Chdir:+-w "$Chdir"} ) [ -n "$ComposerInstall" ] && set -- ci [ -n "$Verbose" ] && eecho "\$ docker ${args[*]} $*" exec docker "${args[@]}" "$@" else ############################################################################ # Lancement depuis l'intérieur du container ############################################################################ if [ -n "$DEVUSER_USERENT" ]; then user="${DEVUSER_USERENT%%:*}" export DEVUSER_USERENT= export DEVUSER_GROUPENT= if in_path su-exec; then exec su-exec "$user" "$0" "$@" else exec runuser -u "$user" -- "$0" "$@" fi fi SOPTS=+w: LOPTS=chdir: args="$(getopt -n "$MYNAME" -o "$SOPTS" -l "$LOPTS" -- "$@")" || exit 1; eval "set -- $args" chdir= action= while [ $# -gt 0 ]; do case "$1" in --) shift; break;; -w|--chdir) shift; chdir="$1";; *) die "$1: option non configurée";; esac shift done if [ -z "$1" ]; then die "no command specified" elif [ "$1" == ci ]; then eecho "== installing composer dependencies" composer i elif [ "$1" == cu ]; then eecho "== upgrading composer dependencies" composer u elif [ "$1" == composer ]; then "$@" else if [ -n "$chdir" ]; then cd "$chdir" || exit 1 fi exec "$@" fi fi