From 5921d27f1e5916dbe2b640d50bae85a080cfd2bd Mon Sep 17 00:00:00 2001 From: philippe lhardy Date: Thu, 12 Mar 2026 14:45:17 +0100 Subject: [PATCH] runit.sh update Signed-off-by: philippe lhardy --- nextcloud_devenv/README.md | 8 +- nextcloud_devenv/lib/log_functions.sh | 90 ++-- nextcloud_devenv/lib/metascript.sh | 629 +++++++++++++++++--------- nextcloud_devenv/runit.README.md | 7 + nextcloud_devenv/runit.sh | 11 + 5 files changed, 473 insertions(+), 272 deletions(-) create mode 100644 nextcloud_devenv/runit.README.md diff --git a/nextcloud_devenv/README.md b/nextcloud_devenv/README.md index ce9ec2f..94711fe 100644 --- a/nextcloud_devenv/README.md +++ b/nextcloud_devenv/README.md @@ -1,6 +1,6 @@ -# Nextcloud Dev En +# Nextcloud Dev Environment for Poll -two options +Two options one created manualy with a simple podman and a local database @@ -37,7 +37,7 @@ puis ./sync_poll.sh ``` -il reste encore a compiler avec les dependances composer et le build npm vuejs +il reste encore a compiler avec les dépendances composer et le build npm vuejs ``` ./enter_www_data.sh @@ -72,7 +72,7 @@ utiliser la base de donnee postgres et non le SQLLite ? ./migrate_db_sqlite2postgres.sh -# NEW PLAIN nextcloud dev +# Option 2 : nextcloud-docker-dev setup diff --git a/nextcloud_devenv/lib/log_functions.sh b/nextcloud_devenv/lib/log_functions.sh index 399b1ad..b0dd0cb 100644 --- a/nextcloud_devenv/lib/log_functions.sh +++ b/nextcloud_devenv/lib/log_functions.sh @@ -5,25 +5,44 @@ # [[ -f $log_functions ]] || { echo "[FATAL] Missing $log_functions" >&2 ; exit 1 ;} # source $log_functions +metalog_color_start() { + if [[ -n $metalog_color ]] + then + echo -en "${metalog_color}" + fi +} + +metalog_color_stop() { + if [[ -n $metalog_color ]] + then + echo -en "\033[0m" + fi +} + log_any() { priority=$1 shift + metalog_color_start echo "[$priority] $@" >&2 + metalog_color_stop } log_fatal() { + local metalog_color=$metalog_color_error log_any FATAL "$*" } log_error() { + local metalog_color=$metalog_color_error log_any ERROR "$*" } log_warn() { + local metalog_color=$metalog_color_warning log_any WARN "$*" } @@ -32,59 +51,36 @@ log_info() log_any INFO "$*" } +log_success() +{ + local metalog_color=$metalog_color_success + log_info "$*" +} + log_debug() { + local metalog_color=$metalog_color_info [[ -n $debug ]] && log_any DEBUG "$*" } - -deferpipe() -{ - cat - echo "# | $@" -} - -autoquoteargs() -{ - echo -n "$1" - shift - while [[ $# > 0 ]] - do - if [[ "$1" =~ [\ \$] ]] - then - echo -n " '$1'" - else - echo -n " $1" - fi - shift - done - echo -} - -echoarray() -{ - declare -a arr=("${@}") - declare -i len=${#arr[@]} - # Show passed array - for ((n = 0; n < len; n++)) - do - echo -en " \"${arr[$n]}\"" - done - echo -} - -include_source() -{ - if [[ -f $1 ]] - then - source $1 - else - log_fatal "Missing $1 script" - exit 1 - fi -} - verbose() { [[ -n $verbose ]] && log_any $verbose $@ } + +metalog_no_colors() +{ + metalog_color_info= + metalog_color_success= + metalog_color_error= + metalog_color_warning= +} + +# default colors +metalog_default_colors() +{ + metalog_color_info="\033[38;5;79m" + metalog_color_success="\033[1;32m" + metalog_color_error="\033[1;31m" + metalog_color_warning="\033[1;34m" +} diff --git a/nextcloud_devenv/lib/metascript.sh b/nextcloud_devenv/lib/metascript.sh index 632bc4a..dd8f8bd 100644 --- a/nextcloud_devenv/lib/metascript.sh +++ b/nextcloud_devenv/lib/metascript.sh @@ -9,49 +9,60 @@ # ex: # bash lib/metascript.sh header +metascript_version=v1.1.0 + # if called directly if [[ "$0" =~ ^(.*)/metascript.sh$ ]] then prefix=${BASH_REMATCH[1]} - if [[ $1 == header ]] - then + case $1 in + header) cat </dev/null toolsdir=\$(pwd) source metascript.sh popd >/dev/null +metarun=metarun +# change default to sudo if needed +# metasudo=sudo + while [[ \$# > 0 ]] do case "\$1" in - *) - parsemetaarg "\$1" - ;; + *) + parsemetaarg "\$1" + ;; esac shift done -exit 0 +usage EOF - else - echo "[WARNING] only header argument is supported. (prefix=$prefix)" >&2 - fi + ;; + version) + echo $metascript_version + ;; + *) + echo "[WARNING] only header and version arguments are supported. (prefix=$prefix), this script is intended to be included not to be directly called." >&2 + exit 1 + esac exit 0 fi if [[ "$metascript_included" == "yes" ]] then - log_warn "metascript already included ($0)" + echo "[WARNING] metascript already included ($0)" >&2 else metascript_included=yes - # at this step $(pwd) should be this of metascript.sh # while $0 is this of caller script using metascript @@ -75,7 +86,7 @@ metascript_usage() cat <&2 metascript commands : -help|usage help or usage of this {$0} tool +help|usage help or usage of this {$0} tool. stop after usage display. dryrun|show|showdoc display what should/will be done defersource= script file defining defer() non standard function @@ -84,12 +95,17 @@ toolsresourcesdir= where to pick resource default to parent of script $toolsresourcesdir mostly used with dryrun apply default : will actual do work without defer +text_format=md set text format output to markdown EOF } +md_output_init() { + md_quote='```' +} + usage() { - echo "[WARNING} no specific usage function for {$0}, to improve by developer" >&2 + log_warn "no specific usage function for {$0}, to improve by developer" echo >&2 metascript_usage } @@ -102,6 +118,68 @@ showinfo() metarun() { $defer $metasudo "$@" + return 0 +} + +metasudo_auto() +{ + if [[ $EUID -eq 0 ]] + then + log_info "already effective user id as root, don't require sudo" + else + metasudo=sudo + fi +} + +autoquoteargs() +{ + echo -n "$1" + shift + while [[ $# > 0 ]] + do + if [[ "$1" =~ [\ \$] ]] + then + echo -n " '$1'" + else + echo -n " $1" + fi + shift + done +} + +echoarray() +{ + declare -a arr=("${@}") + declare -i len=${#arr[@]} + # Show passed array + for ((n = 0; n < len; n++)) + do + echo -en " \"${arr[$n]}\"" + done + echo +} + +start_quote() { + [[ -n $md_quote ]] && echo "$md_quote" +} + +end_quote() { + [[ -n $md_quote ]] && echo "$md_quote" +} + +deferpipe() +{ + cat + echo "# | $@" +} + +include_source() +{ + local script="$1" + + enforce var script + + source "$script" } showdoc() @@ -111,10 +189,10 @@ showdoc() # assumes it handles ENV_METASCRIPT_DEFER "$@" else - echo '```' + start_quote autoquoteargs "$@" echo - echo '```' + end_quote fi } @@ -124,70 +202,147 @@ redirectto() if [[ -n $defer ]] then echo "Copy to $tofile" - echo '```' + start_quote cat - echo '```' + end_quote else cat > $tofile fi } -execredirectfrom() +redirectappendto() { tofile=$1 - shift if [[ -n $defer ]] then - echo '```' - autoquoteargs "$@" - echo ' < '"$tofile" - echo '```' + echo "Append to $tofile" + start_quote + cat + end_quote else - "$@" < $tofile + cat >> $tofile + fi +} + +execredirectfrom() +{ + fromfile="$1" + shift + enforcefile "$fromfile" exists + if [[ -n $defer ]] + then + start_quote + autoquoteargs "$@" + echo ' < '"$fromfile" + end_quote + else + "$@" < $fromfile fi } execredirectto() { - tofile=$1 + tofile="$1" shift if [[ -n $defer ]] then - echo '```' + start_quote autoquoteargs "$@" echo ' > '"$tofile" - echo '```' + end_quote else - $@ > $tofile + "$@" > $tofile fi } +defer_exec_set_var() +{ + tovar="$1" + shift + cat </dev/null' + end_quote else - "$@" | sudo tee $tofile + "$@" | sudo tee $tofile >/dev/null fi } +execredirectas_to() +{ + while [[ $# > 0 ]] + do + case $1 in + user=*) + if [[ "$1" =~ ^user=([a-z]+[-_a-z0-9]*)$ ]] + then + asuser=${BASH_REMATCH[1]} + else + log_fatal "execredirecttouser missing user= in '$@'" + [[ -n $defer ]] || exit 1 + fi + ;; + chroot=*) + aschroot=${1/chroot=} + ;; + *) + tofile=$1 + shift + break + esac + shift + done + local command=() + if [[ -n $aschroot ]] + then + command=(sudo chroot) + if [[ -n $asuser ]] + then + # no group yet + command+=(--userspec=$asuser:$asuser) + fi + command+=($aschroot) + elif [[ -n $asuser ]] + then + command=(sudo -u $asuser) + fi + command+=(tee $tofile) + if [[ -n $defer ]] + then + start_quote + autoquoteargs "$@" + echo ' | '"${command[@]}"' >/dev/null' + end_quote + else + "$@" | "${command[@]}" >/dev/null + fi +} + + pipeto() { if [[ -n $defer ]] then - echo '```' + echo "$md_quote" echo -n 'cat << EOF| ' autoquoteargs "$@" echo cat echo "EOF" - echo '```' + echo "$md_quote" else cat | "$@" fi @@ -279,129 +434,6 @@ check_missing_dest_dir() fi } -sed_substitute_expr() -{ - local from="$1" - shift - local to="$1" - shift - local s='/' - if [[ $from =~ [\\] ]] - then -# escape char \ should be doubled - from=${from//\\/\\\\} - fi - if [[ $from =~ $s ]] - then -# echo "[ERROR] character $s is prohibited due to sed usage" >&2 - from=${from//$s/\\$s} - fi - if [[ $from =~ \[ ]] - then - from=${from//\[/\\\[} - fi - if [[ $from =~ \* ]] - then - from=${from//\*/\\\*} - fi - if [[ $from =~ ^(.*)\$$ ]] - then - from=${BASH_REMATCH[1]}'\$' - fi - if [[ $from =~ ^\^(.*)$ ]] - then - from='\^'${BASH_REMATCH[1]} - fi - - if [[ $to =~ [\\] ]] - then -# escape char \ should be doubled - to=${to//\\/\\\\} - fi - if [[ $to =~ $s ]] - then -# echo "[ERROR] character $s is prohibited due to sed usage" >&2 -# echo "This is a limitation of metascript.sh script, replaced by \$s" >&2 - to=${to//$s/\\$s} - fi - if [[ $to =~ [\&] ]] - then -# echo "[ERROR] character & is prohibited due to sed usage" >&2 - to=${to//\&/\\\&} - fi - - # replace it globaly - echo "s$s$from$s$to${s}g" - -} - -sedreplacefromto() -{ - local from="$1" - local to="$2" - shift 2 - local sedexpr="$1" - execredirectto $to sed "$sedexpr" $from - shift - while [[ $# > 0 ]] - do - sedexpr="$1" - $defer sed -i "$sedexpr" $to - shift - done - -} - -replacefromto() -{ - local from="$1" - local to="$2" - shift 2 - if [[ -n $defer ]] - then - $defer "replace $@ from '$from' into '$to'" - else - local sedexpr=$(sed_substitute_expr "$1" "$2") - execredirectto $to sed "$sedexpr" $from - shift 2 - while [[ $# > 0 ]] - do - sedexpr=$(sed_substitute_expr "$1" "$2") - $defer sed -i "$sedexpr" $to - shift 2 - done - fi - -} - -sedreplacein() -{ - local file=$1 - shift - while [[ $# > 0 ]] - do - $defer sed -i "$1" $file - shift - done -} - -replacein() -{ - local infile=$1 - shift - if [[ -n $defer ]] - then - $defer "replace $@ into '$infile'" - else - while [[ $# > 0 ]] - do - sedexpr=$(sed_substitute_expr "$1" "$2") - $defer sed -i "$sedexpr" $infile - shift 2 - done - fi -} - parsemetaarg() { case $1 in @@ -417,11 +449,15 @@ parsemetaarg() dryrun|show|showdoc) defer=showdoc ;; + debug) + set -ex + ;; metasudo=*) metasudo=${1/metasudo=} ;; help|usage) usage + exit 0 ;; toolsresourcesdir=*) toolsresourcesdir=${1/toolsresourcesdir=/} @@ -429,6 +465,9 @@ parsemetaarg() scl_enable=*) scl_args=(scl enable ${1/scl_enable=/} --) ;; + text_format=md) + md_output_init + ;; *) log_error "unrecognized argument '$1'" usage @@ -445,28 +484,82 @@ enforcearg() if [[ -z $value ]] then - log_error "{0} expect '$var' to be set ex $var=$default" - usage - exit 1 + log_error "{$0} expect '$var' to be set ex $var=$default" + if [[ -n $defer ]] + then + [[ -z $default ]] && default="DEFAULT" + log_warn "in defer/dryrun force $var=$default" + eval "$var=$default" + else + usage + exit 1 + fi fi } +enforce() +{ + objecttype=$1 + shift + case $objecttype in + file|dir) + object=$1 + shift + constraint=$1 + case $constraint in + exists|does_not_exist|create_if_needed|well_named) + enforce${objecttype} "$object" "$@" + ;; + *) + log_error "enforce $objecttype '$object' $@" + log_fatal "constraint '$constraint' unsupported. currently known (exists|does_not_exist|create_if_needed) Please fix the code." + exit 1 + ;; + esac + ;; + var|arg) + enforcearg "$@" + ;; + user) + enforceuser "$@" + ;; + *) + log_error "enforce $objecttype $@" + log_fatal "objectttype $objecttype unsupported" + exit 1 + ;; + esac +} + enforcefile() { - file="$1" - constraint="$2" + local file="$1" + local constraint="$2" + + if [[ $constraint == well_named ]] + then + if [[ "$file" =~ /$ ]] + then + log_error "'$file' as a file should not end with a '/'" + [[ -n $defer ]] || exit 1 + fi + fi if [[ ! -f "$file" ]] then - if [[ $constraint = exists ]] - then - log_error "[ERROR] Missing expected $file" - [[ -n $defer ]] || exit 1 - fi + case $constraint in + exists) + log_error "Missing expected $file" + [[ -n $defer ]] || exit 1 + ;; + create_if_needed) + $metarun touch $file + ;; + esac else - if [[ $constraint = does_not_exists ]] + if [[ $constraint = does_not_exist ]] then - log_error "[ERROR] '$file' already exists. Move it away" + log_error "'$file' already exists. Move it away" [[ -n $defer ]] || exit 1 fi fi @@ -474,33 +567,53 @@ enforcefile() enforcedir() { - dir="$1" - constraint="$2" + local dir="$1" + local constraint="$2" - if [[ $constraint = does_not_exist ]] + if [[ $constraint == well_named ]] then - if [[ -e $dir ]] - then - log_error "'$dir' already exists. Move it away" - [[ -n $defer ]] || exit 1 - fi + if [[ ! "$dir" =~ /$ ]] + then + log_error "'$dir' should end with a '/'" + [[ -n $defer ]] || exit 1 + fi fi - if [[ $constraint = exists ]] + if [[ -e $dir ]] then - if [[ ! -d "$dir" ]] - then - if [[ -e "$dir" ]] - then - log_error "'$dir' already exists but is not a directory as expected" - [[ -n $defer ]] || exit 1 - fi - log_error "[ERROR] Missing expected directory '$dir'" - [[ -n $defer ]] || exit 1 - fi - + case $constraint in + does_not_exist) + if [[ -d "$dir" ]] + then + log_error "'$dir' already exists" + [[ -n $defer ]] || exit 1 + else + log_error "'$dir' already exists and is not a directory as expected" + [[ -n $defer ]] || exit 1 + fi + ;; + create_if_needed|exists) + if [[ ! -d "$dir" ]] + then + log_error "'$dir' already exists and is not a directory as expected" + [[ -n $defer ]] || exit 1 + fi + ;; + esac + else + case $constraint in + exists) + log_error "Missing expected directory $dir" + [[ -n $defer ]] || exit 1 + ;; + create_if_needed) + if [[ ! -d "$dir" ]] + then + $metarun mkdir -p "$dir" + fi + ;; + esac fi - } applymetaargs() @@ -654,7 +767,7 @@ get_resource_var() { echo "# $varname=" >>$collect_context exit 1 fi - log_warn "($0) Using default value '$varname'='$default_value' HARDCODED in script : should be fixed with proper default file .resources.var, see traces in $collect_context" + log_warn "($0) Using default value '$varname'='$default_value' HARDCODED in script : should be fixed with proper default file resources.var, see traces in $collect_context" read "$varname" <<<"$default_value" echo "$varname=$default_value" >>$collect_context fi @@ -664,29 +777,56 @@ setup_resources_var() { local resource_var="$1" enforcefile "$resource_var" exists - while read line - do - if [[ $line =~ ^([a-zA-Z0-9_]+)=(.+)$ ]] - then - varname=${BASH_REMATCH[1]} - value=${BASH_REMATCH[2]} - read "$varname" <<<"$value" - elif [[ $line =~ ^# ]] - then - echo "$line" - else - log_warn "Invalid syntax in $resource_var '$line' does not match any expected expression" - fi - done <"$resource_var" + if [[ -f $resource_var ]] + then + while read line + do + if [[ $line =~ ^([a-zA-Z0-9_]+)=(.+)$ ]] + then + varname=${BASH_REMATCH[1]} + value=${BASH_REMATCH[2]} + read "$varname" <<<"$value" + elif [[ $line =~ ^# ]] + then + if [[ -n $defer ]] + then + $defer : "$line" + fi + else + log_warn "Invalid syntax in $resource_var '$line' does not match any expected expression" + fi + done <"$resource_var" + fi } # allow to check mounted points mountpoint_get_device() { local mount_point="$1" + mount_point=$(readlink -f "$mount_point") $defer awk "{ if (\$2 == \""$mount_point"\") print \$1 ;}" /proc/mounts } +enforce_device() { + local device=$1 + local constraint=$2 + if [[ -n $defer ]] + then + $defer "mountpoint=$(device_get_mountpoints $device)" + else + mountpoint=$(device_get_mountpoints $device) + fi + if [[ -n $mountpoint ]] && [[ $constraint == "unmounted" ]] + then + log_error "$device seen as mounted on $mountpoint" + $defer exit 1 + elif [[ -z $mountpoint ]] && [[ $constraint == "mounted" ]] + then + log_error "$device not seen as mounted" + $defer exit 1 + fi +} + device_get_mountpoints() { local device="$1" @@ -695,10 +835,15 @@ device_get_mountpoints() mount_if_needed() { - local mountpoint="$1" - local mountdevice="$2" + local mountdevice="$1" + local mountpoint="$2" local param="$3" - device=$(mountpoint_get_device "$mountpoint") + if [[ -n $defer ]] + then + $defer 'device=$(mountpoint_get_device '"$mountpoint"')' + else + device=$(mountpoint_get_device "$mountpoint") + fi enforcedir "$mountpoint" exists # device is a device ... @@ -706,28 +851,70 @@ mount_if_needed() if [[ -z $device ]] then - $metarun mount $param "$mountdevice" "$device" + $metarun mount $param "$mountdevice" "$mountpoint" elif [[ "$device" == "$mountdevice" ]] then log_info "$device already mounted on $mountdevice" else - log_warn "Another device $device is mounted on $mountdevice, not $mountdevice" + log_warn "Another device $device is mounted on $mountpoint, not $mountdevice" fi } umount_if_needed() { - local mountpoint="$1" - local mountdevice="$2" + local mountdevice="$1" + local mountpoint="$2" + local param="$3" device=$(mountpoint_get_device "$mountpoint") if [[ -n "$device" ]] then - if [[ "$device" == "$mountpoint" ]] + if [[ "$device" == "$mountdevice" ]] then $metarun umount "$mountpoint" else - log_warn "Another device $device is mounted on $mountdevice, not $mountdevice" + log_warn "Another device $device is mounted on $mountpoint, not $mountdevice" + if [[ $param == '--bind' ]] + then + log_warn "Unmouning ANYWAY ( mount --bind show root device, not mounted directory )" + $metarun umount "$mountpoint" + fi fi + else + log_warn "no device found mounted for umount_if_needed $@" + fi +} + +exec_bg() +{ + if [[ -z $defer ]] + then + "$@" & + else + $defer "$@" '&' + fi +} + +notice() +{ + case "$1" in + git_commit) + log_warn "$1 should be $2" + ;; + *) + log_fatal "unrecognized notice '$1'" + exit 2 + ;; + esac +} + +enforceuser() +{ + local expecteduser="$1" + + if [[ "$USER" != "$expecteduser" ]] + then + log_error "expected user $expecteduser is not current user $USER" + exit 1 fi } @@ -739,9 +926,9 @@ if [[ -z $toolsresourcesdir ]] then # project directory - # from current $(pwd) will follow parent dir hierarchy to find .resources.var + # from current $(pwd) will follow parent dir hierarchy to find resources.var dir="$(pwd)" - while [[ -n $dir ]] && [[ -d $dir ]] && [[ ! -f $dir/.resources.var ]] + while [[ -n $dir ]] && [[ -d $dir ]] && [[ ! -f $dir/resources.var ]] do new_dir=$(dirname "$dir") if [[ $new_dir == $dir ]] @@ -751,7 +938,7 @@ then fi dir="$new_dir" done - if [[ -f $dir/.resources.var ]] + if [[ -f $dir/resources.var ]] then toolsresourcesdir=$dir else @@ -764,7 +951,7 @@ then fi fi -resources_var=$toolsresourcesdir/.resources.var +resources_var=$toolsresourcesdir/resources.var if [[ -f $resources_var ]] then setup_resources_var "$resources_var" diff --git a/nextcloud_devenv/runit.README.md b/nextcloud_devenv/runit.README.md new file mode 100644 index 0000000..c34d23c --- /dev/null +++ b/nextcloud_devenv/runit.README.md @@ -0,0 +1,7 @@ + +See README.md Option 2 + +./runit.sh dryrun up +./runit.sh dryrun down + +Please remove dryrun to actualy do it. diff --git a/nextcloud_devenv/runit.sh b/nextcloud_devenv/runit.sh index 3c1afee..e4faca1 100755 --- a/nextcloud_devenv/runit.sh +++ b/nextcloud_devenv/runit.sh @@ -8,6 +8,10 @@ toolsdir=$(pwd) source metascript.sh popd >/dev/null +usage() { + cat runit.README.md +} + while [[ $# > 0 ]] do case "$1" in @@ -21,6 +25,13 @@ do shift done +if [[ -z $action ]] +then + log_warn "Missing arguments" + + usage + exit 0 +fi metarun=metarun metasudo=sudo