summaryrefslogtreecommitdiff
path: root/src/rpc.bash
diff options
context:
space:
mode:
Diffstat (limited to 'src/rpc.bash')
-rw-r--r--src/rpc.bash114
1 files changed, 59 insertions, 55 deletions
diff --git a/src/rpc.bash b/src/rpc.bash
index 644df95..eb41538 100644
--- a/src/rpc.bash
+++ b/src/rpc.bash
@@ -14,50 +14,8 @@ extract_words()
14 grep -o -E '\b\w+\b' | sort -u 14 grep -o -E '\b\w+\b' | sort -u
15} 15}
16 16
17read_len()
18{
19 REPLY=
20 [ "$1" -gt 0 ] && read -r -N"$1" && [ "$REPLY" ]
21}
22
23read_remote_command()
24{
25 read_len "$1"
26 shift
27 remote_command=(bash -c "${REPLY@Q}" bash "${@@Q}")
28}
29
30remote_run_shell_script_stdin()
31{
32 read_remote_command "$@"
33 ssh -- "${REMOTE_DEST}" "${remote_command[@]}"
34}
35
36remote_run_shell_script_tty()
37{
38 read_remote_command "$@"
39 ssh -t -- "${REMOTE_DEST}" "${remote_command[@]}" </dev/tty
40}
41
42remote_run_shell_script_arg1()
43{
44 script=$1
45 shift
46 set -- "${#script}" "$@"
47 if test -t 0 && test -t 1
48 then
49 printf '%s' "$script" |
50 remote_run_shell_script_tty "$@"
51 else
52 cat <(printf '%s' "$script") - |
53 remote_run_shell_script_stdin "$@"
54 fi
55}
56
57immediate_dependencies1() 17immediate_dependencies1()
58{ 18{
59 # Thanks Lri from stackoverflow.com/questions/4471364/
60 # how-do-i-list-the-functions-defined-in-my-shell/28278090
61 intersection \ 19 intersection \
62 <(compgen -A function | sort -u) \ 20 <(compgen -A function | sort -u) \
63 <(declare -f "$1" | extract_words) 21 <(declare -f "$1" | extract_words)
@@ -73,29 +31,75 @@ immediate_dependencies()
73 31
74recursive_dependencies() 32recursive_dependencies()
75{ 33{
76 resolved=() 34 seen=()
77 while [ $# -gt 0 ] 35 while [ $# -gt 0 ]
78 do 36 do
79 resolved+=("$@") 37 seen+=("$@")
80 set -- $(difference <(immediate_dependencies "$@") \ 38 set -- $(difference <(immediate_dependencies "$@") \
81 <(printf '%s\n' "${resolved[@]}" | sort -u)) 39 <(printf '%s\n' "${seen[@]}" | sort -u))
82 done 40 done
83 printf '%s\n' "${resolved[@]}" 41 printf '%s\n' "${seen[@]}"
42}
43
44
45
46
47
48
49
50
51# Input: $BASH_RPC_REMOTE_DEST - hostname passed to ssh (uses ssh host aliases)
52# Input: $BASH_RPC_SSH_OPTIONS - option arguments passed to ssh (they precede '--')
53# Input: $1 - bash shell script source code to run remotely
54# Input: $2, $3, ... - command line arguments passed to the remote bash shell
55# Input: stdin, stdout, stderr: passed to ssh
56bash_rpc_remote_run_script()
57{
58 (
59 local script="$1"
60 shift
61 set -- "$SHELL" -c "${script@Q}" "$0" "${@@Q}"
62 set -x
63 exec ssh \
64 "${BASH_RPC_SSH_OPTIONS[@]}" \
65 -- \
66 "${BASH_RPC_REMOTE_DEST:-localhost}" \
67 "$@"
68 )
69}
70
71# Preserves the rest of stdin for the command.
72bash_rpc_eval_stdin()
73{
74 [ "$1" -gt 0 ] || return
75 read -N"$1" -r || return
76 shift # prepare "$@" for script execution context
77 source <(printf '%s' "$REPLY" | tr -d '\015')
78}
79
80remote_run_function_simple()
81{
82 script_source=$(declare -f "$1" && printf '"$@";\n')
83 bash_rpc_remote_run_script "$script_source" "$@"
84} 84}
85 85
86remote_run_function() 86remote_run_function()
87{ 87{
88 main=$1 88 main=$1
89 shift
90 funcs=$(recursive_dependencies "$main") 89 funcs=$(recursive_dependencies "$main")
91 90 stage2_source=$(
92 script=
93 read -N2147483647 -r script < <(
94 declare -f $funcs 91 declare -f $funcs
95 printf '%s "$@";\n' "$main" 92 printf '"$@"\n' "$main"
96 ) || true 93 )
97 [ "$script" ] 94 BASH_RPC_SSH_OPTIONS=(-tt)
98 95 {
99 remote_run_shell_script_arg1 "$script" "$@" 96 printf '%s' "$stage2_source"
97 if [ -t 0 ]
98 then
99 socat stdio PTY
100 else
101 cat
102 fi
103 } | remote_run_function_simple bash_rpc_eval_stdin "${#stage2_source}" "$@"
100} 104}
101 105