-
-
Notifications
You must be signed in to change notification settings - Fork 318
(Optionally) run ncp apps in tmux #796
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 11 commits
c9768d2
0dbc586
d91a5f5
a3c2edf
88ed633
33f44f8
d707807
8bf2d85
8d62991
5664109
4fd441d
bff0bc1
2a4ee28
cd8451d
6c8e95c
467dc01
59fe7ce
a357f2c
a0b9b28
aaa4202
e2edadf
5da8938
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,3 +10,4 @@ ncp-web/wizard.cfg | |
| ncp-web/ncp-web.cfg | ||
| docker-armhf/qemu-arm-static | ||
| .vagrant/ | ||
| .vscode/ | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -10,6 +10,7 @@ | |||||
|
|
||||||
| CFGDIR=/usr/local/etc/ncp-config.d | ||||||
| BINDIR=/usr/local/bin/ncp | ||||||
| LOCK_FILE=/usr/local/etc/ncp.lock | ||||||
|
|
||||||
| function configure_app() | ||||||
| { | ||||||
|
|
@@ -22,14 +23,16 @@ function configure_app() | |||||
| type dialog &>/dev/null || { echo "please, install dialog for interactive configuration"; return 1; } | ||||||
| [[ -f "$cfg_file" ]] || return 0; | ||||||
|
|
||||||
| local cfg="$( cat "$cfg_file" )" | ||||||
| local len="$(jq '.params | length' <<<"$cfg")" | ||||||
| local cfg len | ||||||
| cfg="$( cat "$cfg_file" )" | ||||||
| len="$(jq '.params | length' <<<"$cfg")" | ||||||
| [[ $len -eq 0 ]] && return | ||||||
|
|
||||||
| # read cfg parameters | ||||||
| for (( i = 0 ; i < len ; i++ )); do | ||||||
| local var="$(jq -r ".params[$i].id" <<<"$cfg")" | ||||||
| local val="$(jq -r ".params[$i].value" <<<"$cfg")" | ||||||
| local var val | ||||||
| var="$(jq -r ".params[$i].id" <<<"$cfg")" | ||||||
| val="$(jq -r ".params[$i].value" <<<"$cfg")" | ||||||
| local vars+=("$var") | ||||||
| local vals+=("$val") | ||||||
| local idx=$((i+1)) | ||||||
|
|
@@ -91,8 +94,9 @@ function configure_app() | |||||
|
|
||||||
| function run_app() | ||||||
| { | ||||||
| local ncp_app=$1 | ||||||
| local script="$(find "$BINDIR" -name $ncp_app.sh)" | ||||||
| local script ncp_app | ||||||
| ncp_app=$1 | ||||||
| script="$(find "$BINDIR" -name "$ncp_app.sh")" | ||||||
|
|
||||||
| [[ -f "$script" ]] || { echo "file $script not found"; return 1; } | ||||||
|
|
||||||
|
|
@@ -102,10 +106,11 @@ function run_app() | |||||
| # receives a script file, no security checks | ||||||
| function run_app_unsafe() | ||||||
| { | ||||||
| local script=$1 | ||||||
| local ncp_app="$(basename "$script" .sh)" | ||||||
| local script ncp_app | ||||||
| script=$1 | ||||||
| ncp_app="$(basename "$script" .sh)" | ||||||
| local cfg_file="$CFGDIR/$ncp_app.cfg" | ||||||
| local log=/var/log/ncp.log | ||||||
| local log=/var/log/ncp/ncp.log | ||||||
|
|
||||||
| [[ -f "$script" ]] || { echo "file $script not found"; return 1; } | ||||||
|
|
||||||
|
|
@@ -114,51 +119,151 @@ function run_app_unsafe() | |||||
| chown root:www-data $log | ||||||
|
|
||||||
| echo "Running $ncp_app" | ||||||
| echo "[ $ncp_app ]" >> $log | ||||||
|
|
||||||
| # read script | ||||||
| unset configure | ||||||
| source "$script" | ||||||
|
|
||||||
| # read cfg parameters | ||||||
| [[ -f "$cfg_file" ]] && { | ||||||
| local cfg="$( cat "$cfg_file" )" | ||||||
| local len="$(jq '.params | length' <<<"$cfg")" | ||||||
| for (( i = 0 ; i < len ; i++ )); do | ||||||
| local var="$(jq -r ".params[$i].id" <<<"$cfg")" | ||||||
| local val="$(jq -r ".params[$i].value" <<<"$cfg")" | ||||||
| eval "$var=$val" | ||||||
| done | ||||||
| # Check if app is already running in tmux | ||||||
| running_app=$( [[ -f "$LOCK_FILE" ]] && cat "$LOCK_FILE" || echo "" ) | ||||||
|
theCalcaholic marked this conversation as resolved.
Outdated
|
||||||
| [[ ! -z $running_app ]] && which tmux > /dev/null && tmux has-session -t="$running_app" > /dev/null 2>&1 && { | ||||||
|
theCalcaholic marked this conversation as resolved.
Outdated
|
||||||
| #echo "Already running. Attaching to output..." | tee -a $log | ||||||
|
theCalcaholic marked this conversation as resolved.
Outdated
|
||||||
|
|
||||||
| local choice | ||||||
|
theCalcaholic marked this conversation as resolved.
Outdated
|
||||||
| [[ $ATTACH_TO_RUNNING == "1" ]] && choice="y" | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My IDE tells me, that it's not required to quote variables inside double brackets? |
||||||
| [[ $ATTACH_TO_RUNNING == "0" ]] && choice="n" | ||||||
| question="An app ($running_app) is already running. Do you want to attach to it's output? <y/n>" | ||||||
| if [[ $choice == "y" ]] || [[ $choice == "n" ]] | ||||||
| then | ||||||
| echo "$question" | ||||||
| echo "Choice: <y>" | ||||||
|
theCalcaholic marked this conversation as resolved.
Outdated
|
||||||
| else | ||||||
| read -rp "$question" choice | ||||||
| while [[ "$choice" != "y" ]] && [[ "$choice" != "n" ]] | ||||||
| do | ||||||
| echo "choice was '$choice'" | ||||||
| read -rp "Invalid choice. y or n expected." choice | ||||||
| done | ||||||
| fi | ||||||
|
|
||||||
| if [[ "$choice" == "y" ]] | ||||||
| then | ||||||
| attach_to_app "$running_app" | ||||||
| fi | ||||||
| return $? | ||||||
| } | ||||||
|
|
||||||
| # run | ||||||
| configure 2>&1 | tee -a $log | ||||||
| local ret="${PIPESTATUS[0]}" | ||||||
|
|
||||||
| unset configure | ||||||
| ( | ||||||
| # read cfg parameters | ||||||
| [[ -f "$cfg_file" ]] && { | ||||||
| local len cfg | ||||||
| cfg="$( cat "$cfg_file" )" | ||||||
| jq -e '.tmux' <<<"$cfg" > /dev/null 2>&1 | ||||||
|
theCalcaholic marked this conversation as resolved.
Outdated
|
||||||
| use_tmux="$?" | ||||||
|
theCalcaholic marked this conversation as resolved.
Outdated
|
||||||
| len="$(jq '.params | length' <<<"$cfg")" | ||||||
| for (( i = 0 ; i < len ; i++ )); do | ||||||
| local var val | ||||||
| var="$(jq -r ".params[$i].id" <<<"$cfg")" | ||||||
| val="$(jq -r ".params[$i].value" <<<"$cfg")" | ||||||
| eval "export $var=$val" | ||||||
| done | ||||||
| } | ||||||
|
|
||||||
| echo "$ncp_app" > "$LOCK_FILE" | ||||||
| if which tmux > /dev/null && [[ $use_tmux == 0 ]] | ||||||
| then | ||||||
| echo "Running $ncp_app in tmux..." | tee -a $log | ||||||
|
theCalcaholic marked this conversation as resolved.
Outdated
|
||||||
| # Run app in tmux | ||||||
| local tmux_log_file tmux_status_file LIBPATH | ||||||
| tmux_log_file="/var/log/ncp/tmux.${ncp_app}.log" | ||||||
| tmux_status_file="/var/log/ncp/tmux.${ncp_app}.status" | ||||||
| LIBPATH="$(dirname $CFGDIR)/library.sh" | ||||||
|
theCalcaholic marked this conversation as resolved.
Outdated
|
||||||
|
|
||||||
| # Reset tmux output | ||||||
| echo "[ $ncp_app ]" | tee -a $log | ||||||
|
theCalcaholic marked this conversation as resolved.
Outdated
|
||||||
| echo "[ $ncp_app ]" > "$tmux_log_file" | ||||||
| echo "" > "$tmux_status_file" | ||||||
|
nachoparker marked this conversation as resolved.
Outdated
|
||||||
| chmod 640 "$tmux_log_file" "$tmux_status_file" | ||||||
| chown root:www-data "$tmux_log_file" "$tmux_status_file" | ||||||
|
|
||||||
| tmux new-session -d -s "$ncp_app" "bash -c '( | ||||||
| trap \"echo \\\$? > $tmux_status_file && rm $LOCK_FILE\" 1 2 3 4 6 9 11 15 19 29 | ||||||
| source \"$LIBPATH\" | ||||||
| source \"$script\" | ||||||
| configure 2>&1 | tee -a $log | ||||||
| echo \"\${PIPESTATUS[0]}\" > $tmux_status_file | ||||||
| rm $LOCK_FILE | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe you could add
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought about this. In the trap I write |
||||||
| )' 2>&1 | tee -a $tmux_log_file" | ||||||
|
|
||||||
| attach_to_app "$ncp_app" | ||||||
| exit | ||||||
|
|
||||||
| else | ||||||
| trap "rm '$LOCK_FILE'" 0 1 2 3 4 6 11 15 19 29 | ||||||
| echo "[ $ncp_app ]" | tee -a $log | ||||||
| echo "Running $ncp_app directly..." | tee -a $log | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm... Maybe I should include a note that the user shouldn't disconnect instead? And the contrary when running in tmux?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reworked in 5da8938 |
||||||
| # read script | ||||||
| # shellcheck source=/dev/null | ||||||
| source "$script" | ||||||
| # run | ||||||
| configure 2>&1 | tee -a $log | ||||||
| local ret="${PIPESTATUS[0]}" | ||||||
| exit "$ret" | ||||||
| fi | ||||||
| ) | ||||||
| ret="$?" | ||||||
| echo "" >> $log | ||||||
|
|
||||||
| return "$ret" | ||||||
| } | ||||||
|
|
||||||
| function attach_to_app() | ||||||
| { | ||||||
| local tmux_log_file tmux_status_file | ||||||
| tmux_log_file="/var/log/ncp/tmux.${ncp_app}.log" | ||||||
| tmux_status_file="/var/log/ncp/tmux.${ncp_app}.status" | ||||||
|
|
||||||
| if [[ "$ATTACH_NO_FOLLOW" == "1" ]] | ||||||
| then | ||||||
| cat "$tmux_log_file" | ||||||
| return 0 | ||||||
| else | ||||||
| (while tmux has-session -t="$ncp_app" > /dev/null 2>&1 | ||||||
| do | ||||||
| sleep 1 | ||||||
| done) & | ||||||
|
|
||||||
| # Follow log file until tmux session has terminated | ||||||
| tail --lines=+0 -f "$tmux_log_file" --pid="$!" | ||||||
| fi | ||||||
|
|
||||||
| # Read return value from tmux log file | ||||||
| ret="$(tail -n 1 "$tmux_status_file")" | ||||||
| #rm "$tmux_log_file" | ||||||
|
theCalcaholic marked this conversation as resolved.
Outdated
|
||||||
| #rm "$tmux_status_file" | ||||||
|
|
||||||
| [[ $ret =~ ^[0-9]+$ ]] && return $ret | ||||||
| return 1 | ||||||
| } | ||||||
|
|
||||||
| function is_active_app() | ||||||
| { | ||||||
| local ncp_app=$1 | ||||||
| local bin_dir=${2:-.} | ||||||
| local script="$bin_dir/$ncp_app.sh" | ||||||
| local cfg_file="$CFGDIR/$ncp_app.cfg" | ||||||
|
|
||||||
| [[ -f "$script" ]] || local script="$(find "$BINDIR" -name $ncp_app.sh)" | ||||||
| [[ -f "$script" ]] || script="$(find "$BINDIR" -name $ncp_app.sh)" | ||||||
| [[ -f "$script" ]] || { echo "file $script not found"; return 1; } | ||||||
|
|
||||||
| # function | ||||||
| unset is_active | ||||||
| # shellcheck source=/dev/null | ||||||
|
nachoparker marked this conversation as resolved.
|
||||||
| source "$script" | ||||||
| [[ $( type -t is_active ) == function ]] && { is_active; return $?; } | ||||||
|
|
||||||
| # config | ||||||
| [[ -f "$cfg_file" ]] || return 1 | ||||||
|
|
||||||
| local cfg="$( cat "$cfg_file" )" | ||||||
| local cfg | ||||||
| cfg="$( cat "$cfg_file" )" | ||||||
| [[ "$(jq -r ".params[0].id" <<<"$cfg")" == "ACTIVE" ]] && \ | ||||||
| [[ "$(jq -r ".params[0].value" <<<"$cfg")" == "yes" ]] && \ | ||||||
| return 0 | ||||||
|
|
@@ -170,9 +275,10 @@ function info_app() | |||||
| local ncp_app=$1 | ||||||
| local cfg_file="$CFGDIR/$ncp_app.cfg" | ||||||
|
|
||||||
| local cfg="$( cat "$cfg_file" 2>/dev/null )" | ||||||
| local info=$( jq -r .info <<<"$cfg" ) | ||||||
| local infotitle=$( jq -r .infotitle <<<"$cfg" ) | ||||||
| local cfg info infotitle | ||||||
| cfg="$( cat "$cfg_file" 2>/dev/null )" | ||||||
| info=$( jq -r .info <<<"$cfg" ) | ||||||
| infotitle=$( jq -r .infotitle <<<"$cfg" ) | ||||||
|
|
||||||
| [[ "$info" == "" ]] || [[ "$info" == "null" ]] && return 0 | ||||||
| [[ "$infotitle" == "" ]] || [[ "$infotitle" == "null" ]] && infotitle="Info" | ||||||
|
|
@@ -187,18 +293,20 @@ function info_app() | |||||
|
|
||||||
| function install_app() | ||||||
| { | ||||||
| local script | ||||||
| local ncp_app=$1 | ||||||
|
|
||||||
| # $1 can be either an installed app name or an app script | ||||||
| if [[ -f "$ncp_app" ]]; then | ||||||
| local script="$ncp_app" | ||||||
| local ncp_app="$(basename "$script" .sh)" | ||||||
| script="$ncp_app" | ||||||
| ncp_app="$(basename "$script" .sh)" | ||||||
| else | ||||||
| local script="$(find "$BINDIR" -name $ncp_app.sh)" | ||||||
| script="$(find "$BINDIR" -name $ncp_app.sh)" | ||||||
| fi | ||||||
|
|
||||||
| # do it | ||||||
| unset install | ||||||
| # shellcheck source=/dev/null | ||||||
| source "$script" | ||||||
| echo "Installing $ncp_app" | ||||||
| (install) | ||||||
|
|
@@ -208,6 +316,7 @@ function cleanup_script() | |||||
| { | ||||||
| local script=$1 | ||||||
| unset cleanup | ||||||
| # shellcheck source=/dev/null | ||||||
| source "$script" | ||||||
| if [[ $( type -t cleanup ) == function ]]; then | ||||||
| cleanup | ||||||
|
|
||||||
Uh oh!
There was an error while loading. Please reload this page.