189 lines
6.5 KiB
Docker
189 lines
6.5 KiB
Docker
ARG USER_NAME=keil
|
|
FROM scottyhardy/docker-wine:devel-8.4
|
|
ARG USER_NAME
|
|
ARG KEIL_URL=https://armkeil.blob.core.windows.net/eval/MDK537.EXE
|
|
ARG PACK_URL=https://ennis.zhaw.ch/pack/InES.CTBoard14_DFP.4.0.3.pack
|
|
ARG DEBUG=0
|
|
|
|
RUN \
|
|
apt-get update \
|
|
&& apt-get upgrade -y \
|
|
&& apt-get install -y \
|
|
dwm \
|
|
clangd \
|
|
gdb-multiarch \
|
|
htop \
|
|
inotify-tools \
|
|
python3 \
|
|
python-is-python3 \
|
|
python3-pip \
|
|
ssh \
|
|
vim \
|
|
xmlstarlet \
|
|
&& { \
|
|
[ $DEBUG -eq 1 ] \
|
|
&& apt-get install -y \
|
|
build-essential \
|
|
imagemagick \
|
|
|| true; \
|
|
} \
|
|
&& rm -rf /var/lib/apt/lists/
|
|
|
|
RUN pip install pyocd
|
|
|
|
RUN \
|
|
[ $DEBUG -eq 1 ] && { \
|
|
git clone https://github.com/stefanhaustein/TerminalImageViewer.git && \
|
|
cd TerminalImageViewer/src/main/cpp && \
|
|
make && \
|
|
make install && \
|
|
cd - && \
|
|
rm -rf TerminalImageViewer; \
|
|
} \
|
|
|| true
|
|
|
|
RUN \
|
|
wget ${KEIL_URL} --progress=bar:force:noscroll -O MDK537.exe; \
|
|
[ $DEBUG -eq 1 ] && { \
|
|
mkdir -p logs; \
|
|
mkdir -p screens; \
|
|
} \
|
|
|| true && \
|
|
# Handle console output of MDK537 installer
|
|
handle_output() { \
|
|
pattern="fixme:win:NtUserLockWindowUpdate ((nil))"; \
|
|
output=$( \
|
|
sed \
|
|
# Handle exit hints
|
|
-e "s/^exit \([[:digit:]]\+\)$/\1/; t end;" \
|
|
# Handle multiple occurrences of $pattern
|
|
-e "/$pattern/{ x; s/^x\{1\}$/\0/; t stuck; s/^\(x*\)$/\1x/; x; };" \
|
|
# Delete output and return to start
|
|
-e "d; b;" \
|
|
# Branch "stuck": delete output and exit with code 42
|
|
-e ":stuck s/.*//; q42;" \
|
|
# Branch "end": exit with code 0
|
|
-e ":end q;"); \
|
|
exitCode=$?; \
|
|
# Kill installer if it got stuck (according to console output)
|
|
[ $exitCode -eq 42 ] && pkill -9 MDK537.exe; \
|
|
# Use `sed`s exit code if non-zero
|
|
[ $exitCode -ne 0 ] && exit $exitCode; \
|
|
# Use `sed`s output otherwise
|
|
[ $exitCode -eq 0 ] && exit $output; \
|
|
}; \
|
|
# Run actual MDK537 installer
|
|
install_keil() { \
|
|
echo "Starting ARM Keil installation"; \
|
|
try=$1; \
|
|
# Run installer asynchronously
|
|
{ \
|
|
{ /usr/bin/entrypoint wine MDK537.exe --batch-install 2>&1 || echo "exit $?"; } \
|
|
# Write output to `log.txt`
|
|
| { [ $DEBUG -eq 1 ] && tee log.txt || cat; } \
|
|
# Pipe stdout and stderr to `handle_output` function
|
|
| handle_output & \
|
|
}; \
|
|
pid=$!; \
|
|
# Continuously display screenshots and iteration number
|
|
[ $DEBUG -eq 1 ] \
|
|
&& { \
|
|
{ \
|
|
x=0; \
|
|
maxCount=120; \
|
|
while ps -p $pid > /dev/null && [ $x -ne $maxCount ]; do \
|
|
# Create screenshot and print it to the console
|
|
fileName=screens/pit$try-$x.png; \
|
|
import -window root $fileName; \
|
|
tiv -w 10000 -h 10000 $fileName; \
|
|
x=$(bash -c "declare -i x=$x+1; echo "'$x'); \
|
|
echo $x; \
|
|
sleep 1; \
|
|
done; \
|
|
# Kill installer after timeout indicated by `maxCount`
|
|
[ $x -eq $maxCount ] && { pkill -9 MDK537.exe; mv log.txt logs/timeout-$try.txt; }; \
|
|
} & \
|
|
}; \
|
|
wait $pid; \
|
|
exitCode=$?; \
|
|
# Rename log file according to the state of the installer
|
|
[ $DEBUG -eq 1 ] \
|
|
&& [ -f log.txt ] \
|
|
&& { \
|
|
# Move logs to location based on exit code
|
|
[ $exitCode -eq 0 ] && mv log.txt logs/success-$try.txt; \
|
|
[ $exitCode -eq 42 ] && mv log.txt logs/timeout-prevented-$try.txt; \
|
|
[ $exitCode -ne 0 ] && mv log.txt logs/fail-$try.txt; \
|
|
}; \
|
|
[ $exitCode -ne 0 ] && { \
|
|
[ $exitCode -eq 42 ] && echo "The installation got stuck" || \
|
|
echo "The installation failed"; \
|
|
} || \
|
|
echo "The installation was successful"; \
|
|
echo "Installation process exited with code $exitCode"; \
|
|
bash -c "exit $exitCode"; \
|
|
}; \
|
|
display=:90; \
|
|
export DISPLAY=$display; \
|
|
mkdir -p --mode=777 /tmp/.X11-unix; \
|
|
# Create job for waiting for Xvfb to start
|
|
{ inotifywait -e create /tmp/.X11-unix/ 2>&1 > /dev/null & }; \
|
|
resolver=$!; \
|
|
{ \
|
|
# Improve arguments for screenshots
|
|
ARGS=$([ $DEBUG -eq 1 ] && echo "-screen 0 640x480x24 -dpi 192" || echo ""); \
|
|
Xvfb ${DISPLAY} ${ARGS} & \
|
|
}; \
|
|
displayPID=$!; \
|
|
# Wait for Xvfb to start
|
|
wait $resolver; \
|
|
y=0; \
|
|
while ! \
|
|
install_keil \
|
|
"$y" \
|
|
; \
|
|
do \
|
|
echo "Restarting Installation"; \
|
|
# Increase counter
|
|
y=$(bash -c "declare -i y=$y+1; echo "'$y'); \
|
|
done && \
|
|
kill -9 $displayPID > /dev/null 2>&1; \
|
|
# Delete unfinished installations
|
|
rm -rf "$(/usr/bin/entrypoint winepath 'C:\Keil_v5')/Backup."*; \
|
|
rm MDK537.exe; \
|
|
rm -f /tmp/.X*-lock;
|
|
|
|
RUN \
|
|
keilConfig=$(/usr/bin/entrypoint winepath 'C:\Keil_v5\TOOLS.INI') && \
|
|
winAppData="$(/usr/bin/entrypoint 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
|
|
|
|
RUN \
|
|
wget ${PACK_URL} --progress=bar:force:noscroll --no-check-certificate -O InES.pack; \
|
|
/usr/bin/entrypoint xvfb-run wine 'C:\Keil_v5\UV4\PackUnzip.exe' --embedded --agree-license InES.pack & \
|
|
pid=$!; \
|
|
wait $pid; \
|
|
pkill -P -9 $pid > /dev/null 2>&1; \
|
|
kill -9 $pid > /dev/null 2>&1; \
|
|
kill -9 $displayPID > /dev/null 2>&1; \
|
|
rm InES.pack; \
|
|
rm -f /tmp/.X*-lock;
|
|
|
|
RUN \
|
|
apt-get update && \
|
|
ln -s "$(which true)" /usr/bin/depmod && \
|
|
wget https://github.com/stlink-org/stlink/releases/download/v1.7.0/stlink_1.7.0-1_amd64.deb --progress=bar:force:noscroll -O stlink.deb && \
|
|
dpkg -i stlink.deb; \
|
|
apt-get install --fix-broken -y && \
|
|
rm -rf /var/lib/apt/lists/ && \
|
|
rm stlink.deb
|
|
|
|
RUN ln -s /usr/bin/gdb-multiarch /usr/bin/arm-none-eabi-gdb
|
|
RUN echo "${USER_NAME} ALL=(ALL:ALL) NOPASSWD: ALL" > /etc/sudoers.d/keil
|
|
|
|
COPY ./compile.sh /bin/st-compile
|
|
RUN chmod a+x /bin/st-compile
|
|
|
|
ENV USER_NAME=${USER_NAME}
|