it boots
This commit is contained in:
parent
48372efb6d
commit
daae8bd74e
9 changed files with 184 additions and 34 deletions
36
Dockerfile
36
Dockerfile
|
|
@ -1,23 +1,31 @@
|
||||||
FROM debian:bookworm-slim
|
FROM ubuntu:22.04
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND=noninteractive
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
# Install packages
|
# Install base packages and enable the dosemu2 PPA
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y --no-install-recommends \
|
apt-get install -y --no-install-recommends \
|
||||||
|
software-properties-common \
|
||||||
|
gnupg \
|
||||||
openssh-server \
|
openssh-server \
|
||||||
dosemu2 \
|
|
||||||
dosbox-staging \
|
|
||||||
busybox-static \
|
busybox-static \
|
||||||
sudo \
|
sudo \
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
curl \
|
curl \
|
||||||
|
mtools \
|
||||||
|
unzip \
|
||||||
|
file \
|
||||||
|
&& add-apt-repository -y ppa:dosemu2/ppa && \
|
||||||
|
apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
dosemu2 \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Provide DOS wrapper and service supervisor
|
# Provide DOS wrapper, SvarDOS bootstrapper, and service supervisor
|
||||||
COPY dos-shell /usr/local/bin/dos-shell
|
COPY scripts/dos-shell /usr/local/bin/dos-shell
|
||||||
COPY start-services.sh /usr/local/bin/start-dos-services
|
COPY scripts/prepare-svardos.sh /usr/local/bin/prepare-svardos
|
||||||
RUN chmod +x /usr/local/bin/dos-shell /usr/local/bin/start-dos-services && \
|
COPY scripts/start-services.sh /usr/local/bin/start-dos-services
|
||||||
|
RUN chmod +x /usr/local/bin/dos-shell /usr/local/bin/start-dos-services /usr/local/bin/prepare-svardos && \
|
||||||
echo "/usr/local/bin/dos-shell" >> /etc/shells
|
echo "/usr/local/bin/dos-shell" >> /etc/shells
|
||||||
|
|
||||||
# Create sshd runtime directory
|
# Create sshd runtime directory
|
||||||
|
|
@ -29,14 +37,20 @@ RUN useradd -m -s /usr/local/bin/dos-shell dosuser && \
|
||||||
echo "dosuser:dosuser" | chpasswd
|
echo "dosuser:dosuser" | chpasswd
|
||||||
|
|
||||||
# Create directories for allowed DOS files and the C: drive mount
|
# Create directories for allowed DOS files and the C: drive mount
|
||||||
RUN mkdir -p /opt/allowed_repo /cdrive /etc/dos_env && \
|
RUN mkdir -p /opt/allowed_repo /cdrive /etc/dos_env /opt/svardos && \
|
||||||
chown -R dosuser:dosuser /opt/allowed_repo /cdrive
|
chown -R dosuser:dosuser /opt/allowed_repo /cdrive
|
||||||
|
|
||||||
|
# Download and stage SvarDOS base files
|
||||||
|
ARG SVARDOS_IMG_URL
|
||||||
|
ENV SVARDOS_IMG_URL=${SVARDOS_IMG_URL}
|
||||||
|
RUN /usr/local/bin/prepare-svardos && \
|
||||||
|
chown -R dosuser:dosuser /opt/svardos
|
||||||
|
|
||||||
# Default allowed list (can be overridden with a bind mount)
|
# Default allowed list (can be overridden with a bind mount)
|
||||||
COPY dos_allowed /etc/dos_allowed
|
COPY config/dos_allowed /etc/dos_allowed
|
||||||
|
|
||||||
# Configure sshd to force command for dosuser
|
# Configure sshd to force command for dosuser
|
||||||
COPY sshd_config /etc/ssh/sshd_config
|
COPY config/sshd_config /etc/ssh/sshd_config
|
||||||
|
|
||||||
EXPOSE 22 23
|
EXPOSE 22 23
|
||||||
CMD ["/usr/local/bin/start-dos-services"]
|
CMD ["/usr/local/bin/start-dos-services"]
|
||||||
|
|
|
||||||
1
allowed_repo/.gitkeep
Normal file
1
allowed_repo/.gitkeep
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
*** End Patch
|
||||||
21
compose.yml
Normal file
21
compose.yml
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
services:
|
||||||
|
dos:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
args:
|
||||||
|
SVARDOS_IMG_URL: ${SVARDOS_IMG_URL:-}
|
||||||
|
image: ${DOS_IMAGE_NAME:-dos-env}
|
||||||
|
container_name: ${DOS_CONTAINER_NAME:-dos-env}
|
||||||
|
ports:
|
||||||
|
- "${DOS_SSH_PORT:-2222}:22"
|
||||||
|
- "${DOS_TELNET_PORT:-2323}:23"
|
||||||
|
environment:
|
||||||
|
DOS_ALLOW_MODE: ${DOS_ALLOW_MODE:-all}
|
||||||
|
ENABLE_TELNET: ${ENABLE_TELNET:-1}
|
||||||
|
TELNET_PORT: ${TELNET_PORT:-23}
|
||||||
|
TELNET_LOGIN: /bin/login
|
||||||
|
volumes:
|
||||||
|
- ./allowed_repo:/opt/allowed_repo
|
||||||
|
- ./config/dos_allowed:/etc/dos_allowed:ro
|
||||||
|
- ./dos_env:/etc/dos_env
|
||||||
|
restart: unless-stopped
|
||||||
8
dos_env/README.md
Normal file
8
dos_env/README.md
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
# DOS Environment Templates
|
||||||
|
|
||||||
|
Place optional template files here to customize the boot process:
|
||||||
|
|
||||||
|
- `AUTOEXEC.BAT` – copied verbatim to `C:\AUTOEXEC.BAT` on each login.
|
||||||
|
- `CONFIG.SYS` – copied to `C:\CONFIG.SYS` on each login.
|
||||||
|
|
||||||
|
Leave this directory empty to use the defaults generated by `dos-shell`.
|
||||||
|
|
@ -11,6 +11,8 @@ C_DRIVE="/cdrive"
|
||||||
ENV_DIR="/etc/dos_env"
|
ENV_DIR="/etc/dos_env"
|
||||||
AUTOEXEC_TEMPLATE="${ENV_DIR}/AUTOEXEC.BAT"
|
AUTOEXEC_TEMPLATE="${ENV_DIR}/AUTOEXEC.BAT"
|
||||||
CONFIG_TEMPLATE="${ENV_DIR}/CONFIG.SYS"
|
CONFIG_TEMPLATE="${ENV_DIR}/CONFIG.SYS"
|
||||||
|
SVARDOS_BASE="/opt/svardos/base"
|
||||||
|
ALLOW_MODE="${DOS_ALLOW_MODE:-all}" # default to exposing everything from the repo
|
||||||
|
|
||||||
if [ "$(id -u)" -eq 0 ] && [ ! -d "${ENV_DIR}" ]; then
|
if [ "$(id -u)" -eq 0 ] && [ ! -d "${ENV_DIR}" ]; then
|
||||||
mkdir -p "${ENV_DIR}"
|
mkdir -p "${ENV_DIR}"
|
||||||
|
|
@ -20,31 +22,54 @@ fi
|
||||||
rm -rf "${C_DRIVE:?}/"*
|
rm -rf "${C_DRIVE:?}/"*
|
||||||
mkdir -p "${C_DRIVE}"
|
mkdir -p "${C_DRIVE}"
|
||||||
|
|
||||||
# Collect the list of allowed files and sync them into the C: drive
|
# Seed the C: drive with the SvarDOS base image
|
||||||
allowed_entries=()
|
if [ -e "${SVARDOS_BASE}/COMMAND.COM" ] || [ -e "${SVARDOS_BASE}/command.com" ]; then
|
||||||
if [ -f "${ALLOWED_LIST}" ]; then
|
cp -a "${SVARDOS_BASE}/." "${C_DRIVE}/"
|
||||||
while IFS= read -r line || [ -n "$line" ]; do
|
else
|
||||||
# trim whitespace
|
echo "SvarDOS base not found in ${SVARDOS_BASE}. Aborting." >&2
|
||||||
line="$(printf '%s' "$line" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
|
exit 1
|
||||||
# skip blank/comment lines
|
|
||||||
case "$line" in
|
|
||||||
''|\#*) continue ;;
|
|
||||||
esac
|
|
||||||
allowed_entries+=("$line")
|
|
||||||
done < "${ALLOWED_LIST}"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Copy allowed files into the DOS C: drive
|
# Sync additional DOS files into the C: drive
|
||||||
for entry in "${allowed_entries[@]}"; do
|
allowed_entries=()
|
||||||
src="${ALLOWED_REPO}/${entry}"
|
case "${ALLOW_MODE}" in
|
||||||
if [ -e "$src" ]; then
|
all)
|
||||||
dst_dir="$(dirname "${entry}")"
|
if [ -d "${ALLOWED_REPO}" ] && [ "$(ls -A "${ALLOWED_REPO}")" ]; then
|
||||||
mkdir -p "${C_DRIVE}/${dst_dir}"
|
cp -a "${ALLOWED_REPO}/." "${C_DRIVE}/"
|
||||||
cp -a "$src" "${C_DRIVE}/${dst_dir}/"
|
fi
|
||||||
else
|
;;
|
||||||
echo "Warning: allowed file not found: $src" >&2
|
list|allowlist)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown DOS_ALLOW_MODE '${ALLOW_MODE}', falling back to allowlist mode." >&2
|
||||||
|
ALLOW_MODE="list"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ "${ALLOW_MODE}" != "all" ]; then
|
||||||
|
if [ -f "${ALLOWED_LIST}" ]; then
|
||||||
|
while IFS= read -r line || [ -n "$line" ]; do
|
||||||
|
# trim whitespace
|
||||||
|
line="$(printf '%s' "$line" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
|
||||||
|
# skip blank/comment lines
|
||||||
|
case "$line" in
|
||||||
|
''|\#*) continue ;;
|
||||||
|
esac
|
||||||
|
allowed_entries+=("$line")
|
||||||
|
done < "${ALLOWED_LIST}"
|
||||||
fi
|
fi
|
||||||
done
|
|
||||||
|
for entry in "${allowed_entries[@]}"; do
|
||||||
|
src="${ALLOWED_REPO}/${entry}"
|
||||||
|
if [ -e "$src" ]; then
|
||||||
|
dst_dir="$(dirname "${entry}")"
|
||||||
|
mkdir -p "${C_DRIVE}/${dst_dir}"
|
||||||
|
cp -a "$src" "${C_DRIVE}/${dst_dir}/"
|
||||||
|
else
|
||||||
|
echo "Warning: allowed file not found: $src" >&2
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
# Optional: create an AUTOEXEC.BAT and CONFIG.SYS or other DOS boot files
|
# Optional: create an AUTOEXEC.BAT and CONFIG.SYS or other DOS boot files
|
||||||
autoexec_path="${C_DRIVE}/AUTOEXEC.BAT"
|
autoexec_path="${C_DRIVE}/AUTOEXEC.BAT"
|
||||||
|
|
@ -60,7 +85,9 @@ echo Welcome to the containerized DOS environment.
|
||||||
EOF
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ${#allowed_entries[@]} -gt 0 ]; then
|
if [ "${ALLOW_MODE}" = "all" ]; then
|
||||||
|
printf 'echo All repository programs are currently enabled.\r\n' >> "${autoexec_path}"
|
||||||
|
elif [ ${#allowed_entries[@]} -gt 0 ]; then
|
||||||
{
|
{
|
||||||
printf 'echo Allowed programs:\r\n'
|
printf 'echo Allowed programs:\r\n'
|
||||||
for entry in "${allowed_entries[@]}"; do
|
for entry in "${allowed_entries[@]}"; do
|
||||||
79
scripts/prepare-svardos.sh
Normal file
79
scripts/prepare-svardos.sh
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SVARDOS_BASE_DIR="/opt/svardos/base"
|
||||||
|
SVARDOS_CACHE="/opt/svardos/cache"
|
||||||
|
SVARDOS_IMG="${SVARDOS_CACHE}/svardos.img"
|
||||||
|
DEFAULT_REL="download/20250427/svardos-20250427-floppy-1.44M.zip"
|
||||||
|
DEFAULT_BASE="http://svardos.org"
|
||||||
|
|
||||||
|
if [ -z "${SVARDOS_IMG_URL:-}" ]; then
|
||||||
|
homepage="$(
|
||||||
|
curl -fsSL "${DEFAULT_BASE}/" 2>/dev/null || true
|
||||||
|
)"
|
||||||
|
discovered_rel=""
|
||||||
|
if [ -n "$homepage" ]; then
|
||||||
|
for pattern in 'download/[0-9]+/svardos-[0-9]+-floppy-1\.44M\.zip' 'download/[0-9]+/svardos-[0-9]+-usb\.zip'; do
|
||||||
|
candidate="$(printf '%s' "$homepage" | grep -Eo "$pattern" | head -n1)"
|
||||||
|
if [ -n "$candidate" ]; then
|
||||||
|
discovered_rel="$candidate"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
if [ -n "$discovered_rel" ]; then
|
||||||
|
SVARDOS_IMG_URL="${DEFAULT_BASE}/${discovered_rel}"
|
||||||
|
else
|
||||||
|
SVARDOS_IMG_URL="${DEFAULT_BASE}/${DEFAULT_REL}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -e "${SVARDOS_BASE_DIR}/COMMAND.COM" ] || [ -e "${SVARDOS_BASE_DIR}/command.com" ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "${SVARDOS_BASE_DIR}" "${SVARDOS_CACHE}"
|
||||||
|
|
||||||
|
tmp_archive="${SVARDOS_CACHE}/svardos_download"
|
||||||
|
rm -f "${tmp_archive}" "${SVARDOS_IMG}"
|
||||||
|
|
||||||
|
echo "Fetching SvarDOS base from ${SVARDOS_IMG_URL}"
|
||||||
|
curl -fsSL "${SVARDOS_IMG_URL}" -o "${tmp_archive}"
|
||||||
|
|
||||||
|
mime_type="$(file -b --mime-type "${tmp_archive}")"
|
||||||
|
case "${mime_type}" in
|
||||||
|
application/zip)
|
||||||
|
unzip -o "${tmp_archive}" -d "${SVARDOS_CACHE}" >/dev/null
|
||||||
|
;;
|
||||||
|
application/x-bzip2|application/x-gzip|application/x-xz)
|
||||||
|
tar -xf "${tmp_archive}" -C "${SVARDOS_CACHE}"
|
||||||
|
;;
|
||||||
|
application/octet-stream)
|
||||||
|
# assume this is already a raw image
|
||||||
|
cp "${tmp_archive}" "${SVARDOS_IMG}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unsupported SvarDOS payload type: ${mime_type}" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ ! -f "${SVARDOS_IMG}" ]; then
|
||||||
|
# try to locate the image file
|
||||||
|
candidate="$(find "${SVARDOS_CACHE}" -maxdepth 1 -type f \( -iname '*svardos*.img' -o -iname '*.ima' -o -iname '*.img' \) | head -n1)"
|
||||||
|
if [ -z "${candidate}" ]; then
|
||||||
|
echo "Could not locate a SvarDOS disk image after extraction." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
mv "${candidate}" "${SVARDOS_IMG}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -rf "${SVARDOS_BASE_DIR}"/*
|
||||||
|
mkdir -p "${SVARDOS_BASE_DIR}"
|
||||||
|
|
||||||
|
# Copy contents of FAT image into the base directory
|
||||||
|
mcopy -s -i "${SVARDOS_IMG}" ::* "${SVARDOS_BASE_DIR}/"
|
||||||
|
|
||||||
|
rm -f "${SVARDOS_IMG}" "${tmp_archive}"
|
||||||
|
rm -rf "${SVARDOS_CACHE}"
|
||||||
|
echo "SvarDOS base copied to ${SVARDOS_BASE_DIR}"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue