231 lines
6.2 KiB
Bash
Executable file
231 lines
6.2 KiB
Bash
Executable file
#!/bin/bash
|
|
export DEBUG="${DEBUG:-0}";
|
|
export KEIL_URL="${KEIL_URL:-https://armkeil.blob.core.windows.net/eval/MDK537.EXE}";
|
|
export PACK_URL="${PACK_URL:-https://ennis.zhaw.ch/pack/InES.CTBoard14_DFP.4.0.3.pack}";
|
|
|
|
installerExtension=".exe";
|
|
installer="$(mktemp --suffix="$installerExtension")";
|
|
installerName="$(basename "$installer" | sed "s/$installerExtension$//")";
|
|
|
|
export DISPLAY=:90;
|
|
mkdir -p --mode=777 /tmp/.X11-unix;
|
|
|
|
# Create a job for waiting for Xvfb to start
|
|
watchStarting="$(mktemp)";
|
|
{ 2>&1 inotifywait -e create /tmp/.X11-unix/ > /dev/null; } | { sed -u -e "/^Watches established.$/e rm \"$watchStarting\""; } &
|
|
displayResolver="$!";
|
|
|
|
# Wait for `inotifywait` to start
|
|
while [ -f "$watchStarting" ]; do sleep 0.5; done;
|
|
|
|
{
|
|
# Improve arguments for screenshots
|
|
ARGS="$([ "$DEBUG" -eq 1 ] && echo "-screen 0 640x480x24 -dpi 192" || echo "")";
|
|
Xvfb "${DISPLAY}" ${ARGS} &
|
|
};
|
|
|
|
displayPID="$!";
|
|
wget "${KEIL_URL}" --progress=bar:force:noscroll -O "$installer";
|
|
|
|
# Preparations for Debug Logs
|
|
if [ "$DEBUG" -eq 1 ]
|
|
then
|
|
dir="$(mktemp -d)";
|
|
TIV="$(mktemp)";
|
|
logDir="log";
|
|
screenDir="$logDir/screens";
|
|
git clone https://github.com/stefanhaustein/TerminalImageViewer.git "$dir";
|
|
git checkout "v1.1.1";
|
|
cd "$dir/src/main/cpp";
|
|
make;
|
|
mv tiv "$TIV";
|
|
cd -;
|
|
rm -rf "$dir";
|
|
mkdir -p "$logDir";
|
|
mkdir -p "$screenDir";
|
|
fi
|
|
|
|
function printHeading() {
|
|
local heading;
|
|
heading="=====================================================";
|
|
echo "$heading";
|
|
|
|
if [ -z "$1" ]
|
|
then
|
|
cat;
|
|
else
|
|
echo "$1";
|
|
fi;
|
|
|
|
echo "$heading";
|
|
}
|
|
|
|
function kill_installer() {
|
|
pkill -9 "$installerName" > /dev/null 2>&1;
|
|
}
|
|
|
|
function handle_output() {
|
|
# Pattern that is supposed to indicate that wine got stuck
|
|
pattern="fixme:win:NtUserLockWindowUpdate ((nil))";
|
|
# The number of occurences of the pattern which have to occur to assume wine got stuck
|
|
patternCount=2;
|
|
|
|
sed \
|
|
-u \
|
|
`# Handle the pattern and the chosen pattern count` \
|
|
-e "/$pattern/{ x; s/^x\{$(expr "$patternCount" - 1)\}$/\0/; x; t stuck; x; s/^\(x*\)$/\1x/; x; };" \
|
|
`# Return to start` \
|
|
-e "b;" \
|
|
`# Branch "stuck": delete output and exit with code 42` \
|
|
-e ":stuck q42;" \
|
|
`# Branch "end": exit with code 0` \
|
|
-e ":end q;";
|
|
|
|
exitCode="$?";
|
|
|
|
# Kill installer if it got stuck (based on the console output and the pattern)
|
|
if [ "$exitCode" -ne 0 ]
|
|
then
|
|
kill_installer;
|
|
return "$exitCode";
|
|
fi;
|
|
|
|
return 0;
|
|
}
|
|
|
|
# Install Keil uVision
|
|
function install_keil() {
|
|
try="$1";
|
|
logFile="$(mktemp)";
|
|
printHeading "Starting ARM Keil Installation";
|
|
|
|
# Run installer asynchronously
|
|
{
|
|
{
|
|
local exitCode;
|
|
exitCodeFile="$(mktemp)";
|
|
|
|
{
|
|
2>&1 WINEDEBUG=+all,trace-all,warn-all wine "$installer" --batch-install;
|
|
echo "$?" > "$exitCodeFile";
|
|
} | \
|
|
# Write output to a log file when debugging
|
|
{ [ "$DEBUG" -eq 1 ] && { tee "$logFile"; } || cat; } | \
|
|
# Pipe stdout and stderr to `handle_output` function
|
|
handle_output;
|
|
|
|
outputHandlerCode="$?";
|
|
exitCode="$(cat "$exitCodeFile")";
|
|
rm "$exitCodeFile";
|
|
|
|
if [ "$outputHandlerCode" -ne 0 ]
|
|
then
|
|
exitCode="$outputHandlerCode";
|
|
fi;
|
|
|
|
bash -c "exit $exitCode";
|
|
} &
|
|
};
|
|
|
|
pid="$!";
|
|
|
|
# Continuously display screenshots and iteration number when debugging
|
|
if [ "$DEBUG" -eq 1 ]
|
|
then
|
|
{
|
|
{
|
|
x=0;
|
|
maxCount=120;
|
|
|
|
while ps -p "$pid" > /dev/null && [ "$x" -ne "$maxCount" ]
|
|
do
|
|
# Create screenshot and print it to the console
|
|
fileName="$screenDir/install-try$try-$x.png";
|
|
import -window root "$fileName";
|
|
"$TIV" -w 10000 -h 10000 "$fileName";
|
|
x="$(expr "$x" + 1)";
|
|
echo "Frame #$x";
|
|
sleep 1;
|
|
done;
|
|
|
|
# Kill the installer once `maxCount` has been reached
|
|
if [ "$x" -eq "$maxCount" ]
|
|
then
|
|
kill_installer;
|
|
mv "$logFile" "./$logDir/log-timeout-try$try.log";
|
|
fi;
|
|
} &
|
|
};
|
|
fi;
|
|
|
|
wait "$pid";
|
|
exitCode="$?";
|
|
|
|
if [ "$DEBUG" -eq 1 ] && [ -f "$logFile" ]
|
|
then
|
|
if [ "$exitCode" -eq 0 ]
|
|
then
|
|
mv "$logFile" "./$logDir/success-try$try.log";
|
|
elif [ "$exitCode" -eq 42 ]
|
|
then
|
|
mv "$logFile" "./$logDir/timeout-handled-try$try.log";
|
|
else
|
|
mv "$logFile" "./$logDir§/fail-try$try.txt";
|
|
fi;
|
|
fi;
|
|
|
|
{
|
|
if [ "$exitCode" -ne 0 ]
|
|
then
|
|
if [ "$exitCode" -eq 42 ]
|
|
then
|
|
echo "The Installation Got Stuck";
|
|
else
|
|
echo "The Installation Failed";
|
|
fi;
|
|
else
|
|
echo "The Installation Was Successul";
|
|
fi;
|
|
|
|
echo "The Installation Process Exited With Code $exitCode";
|
|
} | printHeading;
|
|
|
|
return "$exitCode";
|
|
}
|
|
|
|
# Wait for Xvfb to start
|
|
wait "$displayResolver";
|
|
|
|
y=0;
|
|
|
|
while ! install_keil "$y"
|
|
do
|
|
printHeading "Restarting Installation";
|
|
y="$(expr "$y" + 1)";
|
|
done;
|
|
|
|
kill -9 "$displayPID" > /dev/null 2>&1;
|
|
|
|
# Delete unfinished installations
|
|
rm -rf "$(winepath 'C:\Keil_v5')/Backup."*;
|
|
rm "$installer";
|
|
rm -rf /tmp/.X*-lock;
|
|
|
|
# Fix incorrect `RTEPATH` setting
|
|
keilConfig="$(winepath 'C:\Keil_v5\TOOLS.INI')";
|
|
winAppData="$(wine cmd.exe /c 'echo %LOCALAPPDATA%' | tr -d '\r' | sed 's/\\/\\\\/g')";
|
|
packDir="$winAppData"'\Arm\Packs';
|
|
sed -i '/^RTEPATH=/d' "$keilConfig";
|
|
echo 'RTEPATH="'"$packDir"'"' | sed -i '/\[UV2\]/ r /dev/stdin' "$keilConfig";
|
|
|
|
# Install additional package
|
|
if [ ! -z "$PACK_URL" ]
|
|
then
|
|
packFile="$(mktemp)";
|
|
wget "${PACK_URL}" --progress=bar:force:noscroll --no-check-certificate -O "$packFile";
|
|
xvfb-run wine "C:\Keil_v5\UV4\PackUnzip.exe" --embedded --agree-license "$packFile" &
|
|
pid="$!"; \
|
|
wait "$pid"; \
|
|
rm "$packFile";
|
|
fi;
|