docker-keil/Dockerfile

224 lines
8 KiB
Docker
Raw Normal View History

2023-03-23 12:08:06 +00:00
ARG USER_NAME=keil
2023-03-24 08:12:22 +00:00
FROM scottyhardy/docker-wine:devel-8.4
2023-03-23 12:08:06 +00:00
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 \
&& { \
2023-03-25 18:59:20 +00:00
[ "$DEBUG" -eq 1 ] \
2023-03-23 12:08:06 +00:00
|| true; \
} \
&& rm -rf /var/lib/apt/lists/
RUN pip install pyocd
RUN \
installerExtension=".exe"; \
installer="$(mktemp --suffix="$installerExtension")"; \
installerName="$(basename "$installer" | sed "s/$installerExtension$//")"; \
rm "$installer"; \
wget "${KEIL_URL}" --progress=bar:force:noscroll -O "$installer"; \
2023-03-25 17:43:13 +00:00
[ "$DEBUG" -eq 1 ] && { \
2023-03-25 20:30:33 +00:00
apt-get update; \
apt-get install -y \
build-essential \
imagemagick; \
rm -rf /var/lib/apt/lists; \
2023-03-25 20:32:56 +00:00
TIV="$(mktemp)"; \
2023-03-25 20:33:23 +00:00
logDir="logs"; \
screenDir="$logDir/screens"; \
2023-03-23 12:08:06 +00:00
git clone https://github.com/stefanhaustein/TerminalImageViewer.git && \
cd TerminalImageViewer/src/main/cpp && \
make && \
2023-03-25 20:30:33 +00:00
apt-get remove -y build-essential && \
apt-get autoremove -y && \
mv tiv "$TIV" && \
2023-03-23 12:08:06 +00:00
cd - && \
rm -rf TerminalImageViewer; \
2023-03-25 20:33:23 +00:00
mkdir -p "$logDir"; \
mkdir -p "$screenDir"; \
2023-03-25 20:30:33 +00:00
} || true; \
2023-03-25 18:50:24 +00:00
printHeading() { \
local heading; \
heading="====================================================="; \
echo "$heading"; \
[ -z "$1" ] && cat || echo "$1"; \
echo "$heading"; \
}; \
2023-03-25 20:50:19 +00:00
# Run actual Keil uVision installer
2023-03-23 12:08:06 +00:00
install_keil() { \
2023-03-25 12:39:57 +00:00
try="$1"; \
2023-03-25 12:41:48 +00:00
logFile="$(mktemp)"; \
2023-03-25 20:49:00 +00:00
printHeading "Starting ARM Keil installation"; \
2023-03-23 12:08:06 +00:00
# Run installer asynchronously
{ \
{ \
local exitCode; \
exitCodeFile="$(mktemp)"; \
{ \
2>&1 WINEDEBUG=+all,trace-all,warn-all /usr/bin/entrypoint 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"; \
2023-03-25 17:48:41 +00:00
bash -c "exit $([ "$outputHandlerCode" -ne 0 ] && echo "$outputHandlerCode" || echo "$exitCode")"; \
} & \
2023-03-23 12:08:06 +00:00
}; \
2023-03-25 12:39:57 +00:00
pid="$!"; \
2023-03-23 12:08:06 +00:00
# Continuously display screenshots and iteration number
2023-03-25 12:39:57 +00:00
[ "$DEBUG" -eq 1 ] \
2023-03-23 12:08:06 +00:00
&& { \
{ \
x=0; \
maxCount=120; \
2023-03-25 12:39:57 +00:00
while ps -p "$pid" > /dev/null && [ "$x" -ne "$maxCount" ]; do \
2023-03-23 12:08:06 +00:00
# Create screenshot and print it to the console
2023-03-25 20:33:23 +00:00
fileName="$screenDir/install-try$try-$x.png"; \
2023-03-25 12:39:57 +00:00
import -window root "$fileName"; \
2023-03-25 20:30:33 +00:00
"$TIV" -w 10000 -h 10000 "$fileName"; \
2023-03-25 12:40:33 +00:00
x="$(expr "$x" + 1)"; \
2023-03-25 19:03:59 +00:00
echo "Frame #$x"; \
2023-03-23 12:08:06 +00:00
sleep 1; \
done; \
# Kill installer after timeout indicated by `maxCount`
[ "$x" -eq "$maxCount" ] && { kill_installer; mv "$logFile" "$logDir/timeout-try$try.log"; }; \
2023-03-23 12:08:06 +00:00
} & \
}; \
2023-03-25 19:03:42 +00:00
wait "$pid"; \
exitCode="$?"; \
2023-03-23 12:08:06 +00:00
# Rename log file according to the state of the installer
2023-03-25 19:03:42 +00:00
[ "$DEBUG" -eq 1 ] \
2023-03-25 12:41:48 +00:00
&& [ -f "$logFile" ] \
2023-03-23 12:08:06 +00:00
&& { \
# Move logs to location based on exit code
2023-03-25 20:33:23 +00:00
[ "$exitCode" -eq 0 ] && mv "$logFile" "$logDir/success-try$try.log"; \
[ "$exitCode" -eq 42 ] && mv "$logFile" "$logDir/timeout-handled-try$try.log"; \
[ "$exitCode" -ne 0 ] && mv "$logFile" "$logDir/fail-try$try.log"; \
2023-03-23 12:08:06 +00:00
}; \
2023-03-25 18:50:24 +00:00
{ \
[ "$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"; \
} | printHeading; \
2023-03-25 18:31:00 +00:00
return "$exitCode"; \
2023-03-23 12:08:06 +00:00
}; \
2023-03-25 22:06:48 +00:00
# Handle console output of Keil uVision installer
handle_output() { \
# A pattern that is supposed to indicates that wine got stuck
pattern="fixme:win:NtUserLockWindowUpdate ((nil))"; \
# The amount of times the pattern should occur for the process to be considered stuck
patternCount=2; \
sed \
-u \
# Handle multiple occurrences of $pattern
-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 (according to console output)
[ "$exitCode" -eq 42 ] && kill_installer; \
2023-03-25 22:06:48 +00:00
# Use `sed`s exit code if non-zero
[ "$exitCode" -ne 0 ] && exit "$exitCode" || \
# Return true otherwise
true; \
}; \
kill_installer() { \
pkill -9 "$installerName" > /dev/null 2>&1; \
}; \
2023-03-23 12:08:06 +00:00
display=:90; \
2023-03-25 19:03:42 +00:00
export DISPLAY="$display"; \
2023-03-23 12:08:06 +00:00
mkdir -p --mode=777 /tmp/.X11-unix; \
# Create job for waiting for Xvfb to start
watchStarting="$(mktemp)"; \
{ 2>&1 inotifywait -e create /tmp/.X11-unix/; } | { sed -u -e "/^Watches established.\$/e rm \"$watchStarting\""; } & \
2023-03-25 12:39:57 +00:00
resolver="$!"; \
while [ -f "$watchStarting" ]; do true; done; \
2023-03-23 12:08:06 +00:00
{ \
# Improve arguments for screenshots
2023-03-25 12:39:57 +00:00
ARGS="$([ $DEBUG -eq 1 ] && echo "-screen 0 640x480x24 -dpi 192" || echo "")"; \
2023-03-25 17:43:13 +00:00
Xvfb "${DISPLAY}" ${ARGS} & \
2023-03-23 12:08:06 +00:00
}; \
2023-03-25 12:39:57 +00:00
displayPID="$!"; \
2023-03-23 12:08:06 +00:00
# Wait for Xvfb to start
2023-03-25 12:39:57 +00:00
wait "$resolver"; \
2023-03-23 12:08:06 +00:00
y=0; \
while ! \
install_keil \
"$y" \
; \
do \
2023-03-25 18:50:24 +00:00
printHeading "Restarting Installation"; \
2023-03-23 12:08:06 +00:00
# Increase counter
2023-03-25 12:40:33 +00:00
y="$(expr "$y" + 1)"; \
2023-03-23 12:08:06 +00:00
done && \
2023-03-25 12:39:57 +00:00
kill -9 "$displayPID" > /dev/null 2>&1; \
2023-03-25 20:30:33 +00:00
# Cleanup Unnecessary Files
rm -f "$TIV"; \
2023-03-23 12:08:06 +00:00
rm -rf "$(/usr/bin/entrypoint winepath 'C:\Keil_v5')/Backup."*; \
rm "$installer"; \
2023-03-25 20:30:33 +00:00
rm -f /tmp/.X*-lock; \
[ "$DEBUG" -eq 1 ] && { \
apt-get remove -y imagemagick; \
apt-get autoremove -y; \
2023-03-26 20:02:38 +00:00
} || true
2023-03-23 12:08:06 +00:00
RUN \
2023-03-25 12:39:57 +00:00
keilConfig="$(/usr/bin/entrypoint winepath 'C:\Keil_v5\TOOLS.INI')" && \
2023-03-23 12:08:06 +00:00
winAppData="$(/usr/bin/entrypoint wine cmd.exe /c 'echo %LOCALAPPDATA%' | tr -d '\r' | sed 's/\\/\\\\/g')" && \
packDir="$winAppData"'\Arm\Packs' && \
2023-03-25 12:39:57 +00:00
sed -i '/^RTEPATH=/d' "$keilConfig" && \
echo 'RTEPATH="'"$packDir"'"' | sed -i '/\[UV2\]/ r /dev/stdin' "$keilConfig"
2023-03-23 12:08:06 +00:00
RUN \
2023-03-25 12:39:57 +00:00
wget "${PACK_URL}" --progress=bar:force:noscroll --no-check-certificate -O InES.pack; \
2023-03-23 12:08:06 +00:00
/usr/bin/entrypoint xvfb-run wine 'C:\Keil_v5\UV4\PackUnzip.exe' --embedded --agree-license InES.pack & \
2023-03-25 12:39:57 +00:00
pid="$!"; \
wait "$pid"; \
2023-03-23 12:08:06 +00:00
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
2023-03-23 12:11:30 +00:00
COPY ./compile.sh /bin/st-compile
RUN chmod a+x /bin/st-compile
2023-03-23 12:08:06 +00:00
ENV USER_NAME=${USER_NAME}