2013-04-08 19:17:59 +00:00
|
|
|
#!/bin/bash
|
|
|
|
|
2015-03-03 23:12:00 +00:00
|
|
|
# Check servers up on http://www.polarhome.com/service/status/
|
2018-05-22 23:07:40 +00:00
|
|
|
unset TIMEOUT
|
|
|
|
. `which env_parallel.bash`
|
|
|
|
env_parallel --session
|
|
|
|
|
2018-08-26 23:54:11 +00:00
|
|
|
P_ALL="openstep qnx pidora alpha tru64 hpux-ia64 syllable raspbian solaris openindiana aix hpux debian-ppc suse solaris-x86 mandriva ubuntu scosysv unixware centos miros macosx redhat netbsd openbsd freebsd debian dragonfly vax ultrix minix irix hurd beaglebone cubieboard2"
|
2019-04-21 18:16:33 +00:00
|
|
|
# Skip ultrix
|
|
|
|
# Skip irix until Perl is upgraded (I cannot due to too small disk quota)
|
|
|
|
P_ALL="openstep qnx pidora alpha tru64 hpux-ia64 syllable raspbian solaris openindiana aix hpux debian-ppc suse solaris-x86 mandriva ubuntu scosysv unixware centos miros macosx redhat netbsd openbsd freebsd debian dragonfly vax minix hurd beaglebone cubieboard2"
|
2018-08-22 22:21:29 +00:00
|
|
|
P="$P_ALL"
|
2018-05-22 23:07:40 +00:00
|
|
|
|
2018-09-20 22:15:14 +00:00
|
|
|
# tru64 takes 22s to run 4 parallels
|
|
|
|
MAXTIME=50
|
2019-01-19 01:20:44 +00:00
|
|
|
RETRIES=3
|
2019-01-29 05:58:12 +00:00
|
|
|
# 11 too much for debian
|
|
|
|
MAXPROC=${maxproc:-9}
|
2018-09-20 22:15:14 +00:00
|
|
|
MAXINNERPROC=${maxinnerproc:-3}
|
2018-08-26 23:54:11 +00:00
|
|
|
|
2018-09-20 22:15:14 +00:00
|
|
|
export PARALLEL_SSH="ssh -oLogLevel=quiet"
|
|
|
|
|
2018-11-22 23:30:23 +00:00
|
|
|
# select a running master (debian-ppc, suse, ubuntu, or debian)
|
2018-09-20 22:15:14 +00:00
|
|
|
MASTER=$(parallel -j0 --delay 0.1 --halt now,success=1 $PARALLEL_SSH {} echo {} \
|
2018-11-22 23:30:23 +00:00
|
|
|
::: {debian-ppc,ubuntu,debian,suse}.polarhome.com)
|
2013-04-08 19:17:59 +00:00
|
|
|
|
2018-08-26 23:54:11 +00:00
|
|
|
parallel -j0 --delay 0.1 --retries $RETRIES \
|
2018-10-22 22:46:38 +00:00
|
|
|
rsync -L /usr/local/bin/{parallel,env_parallel,env_parallel.*[^~],parcat,stdout} \
|
2018-08-26 23:54:11 +00:00
|
|
|
::: $MASTER:bin/
|
2018-04-22 21:32:22 +00:00
|
|
|
|
|
|
|
doit() {
|
|
|
|
# Avoid the stupid /etc/issue.net banner at Polarhome: -oLogLevel=quiet
|
|
|
|
PARALLEL_SSH="ssh -oLogLevel=quiet"
|
|
|
|
export PARALLEL_SSH
|
2018-07-14 04:11:58 +00:00
|
|
|
export MAXTIME
|
2018-05-22 23:07:40 +00:00
|
|
|
export RETRIES
|
2018-08-26 23:54:11 +00:00
|
|
|
export MAXPROC
|
2019-01-19 01:20:44 +00:00
|
|
|
export RET_TIME_K="--memfree 150m -k --retries $RETRIES --timeout $MAXTIME"
|
2018-10-22 22:46:38 +00:00
|
|
|
LC_ALL=C
|
|
|
|
|
2019-01-19 01:20:44 +00:00
|
|
|
MAXPROC=$(echo $(seq 300 | parallel -j0 echo {%} | sort -n | tail -n1) /$MAXINNERPROC | bc)
|
2018-09-20 22:15:14 +00:00
|
|
|
echo MAXTIME=$MAXTIME RETRIES=$RETRIES MAXPROC=$MAXPROC MAXINNERPROC=$MAXINNERPROC
|
2018-04-22 21:32:22 +00:00
|
|
|
|
2018-08-22 22:21:29 +00:00
|
|
|
echo '### Filter out working servers'
|
2018-09-20 22:15:14 +00:00
|
|
|
# syllable often gives false positive
|
|
|
|
parallel --timeout $MAXTIME -j10 ssh syllable true ::: {1..10} 2>/dev/null >/dev/null &
|
2019-01-19 01:20:44 +00:00
|
|
|
POLAR_ALL="`bin/parallel --memfree 200m -j0 -k --timeout 10 echo {} ::: $P`"
|
|
|
|
POLAR="`bin/parallel --memfree 200m -j0 -k --timeout 10 $PARALLEL_SSH {} echo {} ::: $P`"
|
2018-09-20 22:15:14 +00:00
|
|
|
diff <(echo "$POLAR_ALL") <(echo "$POLAR")
|
2018-08-26 23:54:11 +00:00
|
|
|
S_POLAR=`bin/parallel -j0 $RET_TIME_K echo -S 1/{} ::: $POLAR`
|
2018-09-20 22:15:14 +00:00
|
|
|
|
|
|
|
sshwithpass() {
|
|
|
|
# Minix requires sshpass. The other servers will use ssh-keys
|
2019-01-29 05:58:12 +00:00
|
|
|
host="$1"
|
|
|
|
shift
|
|
|
|
if [ "$host" == "minix" ] ; then
|
|
|
|
q="$(parallel --shellquote ::: "$@")"
|
|
|
|
# This only works from suse and redhat
|
|
|
|
ssh -T -oLogLevel=quiet suse \
|
|
|
|
sshpass -f ~/.ssh/minix.password ssh -T -oLogLevel=quiet $host $q
|
|
|
|
else
|
|
|
|
ssh -oLogLevel=quiet $host "$@"
|
|
|
|
fi
|
2018-09-20 22:15:14 +00:00
|
|
|
}
|
|
|
|
export -f sshwithpass
|
2019-01-29 05:58:12 +00:00
|
|
|
|
2018-04-22 21:32:22 +00:00
|
|
|
copy() {
|
|
|
|
# scp, but atomic (avoid half files if disconnected)
|
|
|
|
host=$1
|
|
|
|
src="$2"
|
|
|
|
dst="$3"
|
|
|
|
cat "$src" |
|
2018-09-20 22:15:14 +00:00
|
|
|
sshwithpass $host "mkdir -p bin;cat > bin/'$dst'.tmp && chmod 755 bin/'$dst'.tmp && mv bin/'$dst'.tmp bin/'$dst'" 2>&1
|
2018-04-22 21:32:22 +00:00
|
|
|
}
|
|
|
|
export -f copy
|
2018-09-20 22:15:14 +00:00
|
|
|
|
2018-04-22 21:32:22 +00:00
|
|
|
par_nonall() {
|
2018-08-26 23:54:11 +00:00
|
|
|
parallel -j$MAXPROC $RET_TIME_K --delay 0.1 --tag \
|
2018-10-22 22:46:38 +00:00
|
|
|
--nonall $S_POLAR -S "1/sshwithpass minix" --argsep ,:- \
|
2018-04-22 21:32:22 +00:00
|
|
|
'source setupenv >&/dev/null || . `pwd`/setupenv;' "$@"
|
2019-01-29 05:58:12 +00:00
|
|
|
# setupenv contains something like this (adapted to the local path and shell)
|
|
|
|
#
|
|
|
|
# PATH=$HOME/bin:$PATH:/usr/local/bin
|
|
|
|
# export PATH
|
|
|
|
# . bin/env_parallel.sh
|
2018-04-22 21:32:22 +00:00
|
|
|
}
|
|
|
|
export -f par_nonall
|
|
|
|
|
|
|
|
echo '### Copy commands to servers'
|
2019-01-19 01:20:44 +00:00
|
|
|
# Dont copy stdout - it depends on /bin/bash
|
2018-08-26 23:54:11 +00:00
|
|
|
env_parallel -vj$MAXPROC $RET_TIME_K --delay 0.03 --tag copy {2} {1} {1/} \
|
2019-01-19 01:20:44 +00:00
|
|
|
::: bin/{parallel,env_parallel,env_parallel.*[^~],parcat} \
|
2018-09-20 22:15:14 +00:00
|
|
|
::: $POLAR minix
|
2018-04-22 21:32:22 +00:00
|
|
|
echo Done copying
|
2018-07-14 04:11:58 +00:00
|
|
|
|
2018-09-20 22:15:14 +00:00
|
|
|
env_parallel -d '\n\n' -vkj$MAXINNERPROC --delay 2 <<'EOF'
|
|
|
|
|
2018-08-22 22:21:29 +00:00
|
|
|
echo
|
|
|
|
echo '### Works on ...'
|
|
|
|
echo
|
|
|
|
par_nonall parallel echo Works on {} ::: '`hostname`' 2>&1
|
|
|
|
|
2018-07-14 04:11:58 +00:00
|
|
|
echo
|
|
|
|
echo '### --number-of-cores/--number-of-cpus should work with no error'
|
|
|
|
echo
|
2018-09-20 22:15:14 +00:00
|
|
|
par_nonall 'parallel --number-of-sockets; parallel --number-of-cores' 2>&1
|
|
|
|
par_nonall 'parallel --number-of-threads; parallel --number-of-cpus' 2>&1
|
2018-07-14 04:11:58 +00:00
|
|
|
|
2018-04-22 21:32:22 +00:00
|
|
|
echo
|
2018-09-20 22:15:14 +00:00
|
|
|
echo '### Fails if tmpdir is R/O'
|
2018-04-22 21:32:22 +00:00
|
|
|
echo
|
2018-09-20 22:15:14 +00:00
|
|
|
par_nonall "stdout parallel --tmpdir / echo ::: test read-only tmp |
|
|
|
|
perl -pe '\$exit += s:/[a-z0-9_]+.arg:/XXXXXXXX.arg:gi; \$exit += s/[0-9][0-9][0-9][0-9]/0000/gi; END { exit not \$exit }' &&
|
|
|
|
echo OK readonly tmp" 2>&1
|
2017-12-04 21:44:34 +00:00
|
|
|
|
2018-04-22 21:32:22 +00:00
|
|
|
echo
|
2018-09-20 22:15:14 +00:00
|
|
|
echo '### Does exporting a bash function make parallel fail?'
|
|
|
|
echo 'If login shell is not bash compatible it fails'
|
2018-04-22 21:32:22 +00:00
|
|
|
echo
|
2018-09-20 22:15:14 +00:00
|
|
|
# http://zmwangx.github.io/blog/2015-11-25-bash-function-exporting-fiasco.html
|
|
|
|
par_nonall 'echo test funcA
|
|
|
|
funcA() {
|
|
|
|
cat <(echo bash only A)
|
|
|
|
}
|
|
|
|
export -f funcA;
|
2019-01-29 05:58:12 +00:00
|
|
|
bin/parallel funcA ::: 1' 2>&1 | sort
|
2018-09-20 22:15:14 +00:00
|
|
|
|
|
|
|
echo
|
|
|
|
echo '### Does PARALLEL_SHELL help exporting a bash function'
|
|
|
|
echo 'If login shell is not bash compatible it should work'
|
|
|
|
echo
|
|
|
|
mkdir -p tmp/bin
|
|
|
|
cp /bin/bash tmp/bin
|
|
|
|
cd tmp
|
|
|
|
export PARALLEL_SHELL=bin/bash
|
|
|
|
par_nonall 'echo test funcB
|
|
|
|
funcB() {
|
|
|
|
cat <(echo bash only B)
|
|
|
|
}
|
|
|
|
export -f funcB
|
|
|
|
export PARALLEL_SHELL=bin/bash
|
|
|
|
bin/parallel funcB ::: 1' 2>&1
|
2017-12-04 21:44:34 +00:00
|
|
|
|
2018-04-22 21:32:22 +00:00
|
|
|
echo
|
|
|
|
echo '### env_parallel echo :::: <(echo OK)'
|
2018-08-22 22:21:29 +00:00
|
|
|
echo '(bash ksh mksh zsh only)'
|
2018-04-22 21:32:22 +00:00
|
|
|
echo
|
|
|
|
par_nonall 'bin/env_parallel --install && echo install-OK' 2>&1
|
|
|
|
par_nonall 'env_parallel echo env_parallel ::: run-OK' 2>&1
|
2018-09-20 22:15:14 +00:00
|
|
|
# csh on NetBSD does not support process substitution
|
|
|
|
par_nonall 'env_parallel echo reading from process substitution :::: <(echo OK)' 2>&1 |
|
2018-04-22 21:32:22 +00:00
|
|
|
grep -v ': /tmp/.*: No such file or directory'
|
2013-12-19 01:19:19 +00:00
|
|
|
|
2018-09-20 22:15:14 +00:00
|
|
|
# Test empty command name in process list
|
|
|
|
test_empty_cmd() {
|
|
|
|
echo '### Test if empty command name in process list causes problems'
|
|
|
|
perl -e '$0=" ";sleep 1000' &
|
|
|
|
pid=$!
|
|
|
|
parallel echo ::: OK_with_empty_cmd
|
|
|
|
kill $pid
|
|
|
|
}
|
|
|
|
export -f test_empty_cmd
|
|
|
|
export PARALLEL_SHELL=bin/bash
|
|
|
|
PARALLEL='--env test_empty_cmd' par_nonall test_empty_cmd 2>&1
|
|
|
|
|
2016-04-05 22:57:07 +00:00
|
|
|
echo
|
2018-04-22 21:32:22 +00:00
|
|
|
echo '### parset arr seq ::: 2 3 4'
|
2018-08-22 22:21:29 +00:00
|
|
|
echo '(bash ksh mksh zsh only)'
|
2016-04-05 22:57:07 +00:00
|
|
|
echo
|
2018-04-22 21:32:22 +00:00
|
|
|
par_nonall 'parset arr seq ::: 2 3 4; echo ${arr[*]}' 2>&1
|
|
|
|
echo '### env_parset arr seq ::: 2 3 4'
|
|
|
|
par_nonall 'start=2;env_parset arr seq \$start ::: 2 3 4; echo ${arr[*]}' 2>&1
|
|
|
|
|
|
|
|
echo
|
|
|
|
echo '### parset var1,var2,var3 seq ::: 2 3 4'
|
2018-08-22 22:21:29 +00:00
|
|
|
echo '(bash ksh mksh zsh ash dash only)'
|
2018-04-22 21:32:22 +00:00
|
|
|
echo
|
|
|
|
par_nonall 'parset var1,var2,var3 seq ::: 2 3 4; echo $var1,$var2,$var3' 2>&1
|
|
|
|
echo '### env_parset var1,var2,var3 seq ::: 2 3 4'
|
|
|
|
par_nonall 'start=2; env_parset var1,var2,var3 seq \$start ::: 2 3 4; echo $var1,$var2,$var3' 2>&1
|
2018-09-20 22:15:14 +00:00
|
|
|
EOF
|
|
|
|
|
2013-07-19 17:13:00 +00:00
|
|
|
}
|
2017-12-22 23:01:20 +00:00
|
|
|
|
2018-08-26 23:54:11 +00:00
|
|
|
env_parallel -u -S$MASTER doit ::: 1
|
2017-12-22 23:01:20 +00:00
|
|
|
|
2017-07-06 15:22:50 +00:00
|
|
|
# eval 'myfunc() { echo '$(perl -e 'print "x"x20000')'; }'
|
|
|
|
# env_parallel myfunc ::: a | wc # OK
|
|
|
|
# eval 'myfunc2() { echo '$(perl -e 'print "x"x120000')'; }'
|
|
|
|
# env_parallel myfunc ::: a | wc # Fail too big env
|