Add baked-in image capability
Add capability to "bake in" a disk image into a container image. Rework deployment processmaster
parent
bd6050ea3e
commit
7911c7eefc
|
@ -1,5 +1,6 @@
|
||||||
*.xz
|
*.bak
|
||||||
*.dsk
|
*.dsk
|
||||||
|
*.gz
|
||||||
*.tgz
|
*.tgz
|
||||||
|
|
||||||
# generated from template
|
# generated from template
|
||||||
|
|
15
README.md
15
README.md
|
@ -3,18 +3,25 @@
|
||||||
## Docker
|
## Docker
|
||||||
To build the container, run `docker/build.sh [tag]` with the tag you want to apply to the image.
|
To build the container, run `docker/build.sh [tag]` with the tag you want to apply to the image.
|
||||||
|
|
||||||
|
**Important:** If you want to bake a disk image into the container which will be copied into /mnt and used if no image is found there on startup, make sure to put it as `rq0.dsk` in the build directory.
|
||||||
|
|
||||||
To run the container, use the following command adapted to your needs:
|
To run the container, use the following command adapted to your needs:
|
||||||
|
|
||||||
docker run -d --rm --privileged --name pdp -v `pwd`/rq0.dsk:/mnt/rq0.dsk <tag>
|
docker run -d --rm --privileged --name pdp -v `pwd`/rq0.dsk:/mnt/rq0.dsk <tag>
|
||||||
|
|
||||||
## Kubernetes
|
## Kubernetes
|
||||||
To run in Kubernetes, first you need to build the docker image and push it to a registry your cluster has access to.
|
To run in Kubernetes, first you need to build the docker image (preferably with a disk baked in) and push it to a registry your cluster has access to.
|
||||||
|
|
||||||
Once you've done that, run `./bootstrap-k8s.sh <tag> <disk_filename>`. `tag` should be a ref to the docker image, uploaded to a registry the cluster can access. `disk_filename` should be an xz-compressed PDP-11 disk image, which will be extracted and attached to the pdp as rq0.
|
Once you've done that, run `./bootstrap-k8s.sh <tag>`. `tag` should be a ref to the docker image, uploaded to a registry the cluster can access.
|
||||||
|
|
||||||
To expose the services on an external IP, first install MetalLB, and then use `./configure-metallb.sh <ip>`. `ip` should be an IP address on a broadcast domain the k8s nodes are on.
|
To expose the services on an external IP, first install MetalLB, and then use `./misc/configure-metallb.sh <ip>`. `ip` should be an IP address on a broadcast domain the k8s nodes are on.
|
||||||
|
|
||||||
|
### Imageless container
|
||||||
|
If you built the Docker container without a baked-in image, instead of using the normal `bootstrap-k8s.sh`, you'll need to use `misc/bootstrap-k8s-imageless.sh` as follows:
|
||||||
|
|
||||||
|
Run `./misc/bootstrap-k8s.sh <tag> <disk_filename>`. `tag` should be a ref to the docker image, uploaded to a registry the cluster can access. `disk_filename` should be a gzip-compressed PDP-11 disk image, which will be extracted and attached to the pdp as rq0.
|
||||||
|
|
||||||
### k3s
|
### k3s
|
||||||
To use an external IP, MetalLB is required. Therefore, the cluster must not have ServiceLB enabled, as it will conflict. For k3s, just add `--disable=servicelb` to the server command line options. For k3d, create the cluster as follows:
|
To use an external IP, MetalLB is required. Therefore, the cluster must not have ServiceLB enabled, as it will conflict. For k3s, just add `--disable=servicelb` to the server command line options. For k3d, create the cluster as follows:
|
||||||
|
|
||||||
k3d cluster create pdp --k3s-arg "--disable=servicelb@server:*"
|
k3d cluster create pdp --k3s-arg "--disable=servicelb@server:*"
|
||||||
|
|
|
@ -6,35 +6,17 @@ usage () {
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
[[ $# -eq 2 ]] || usage
|
[[ $# -eq 1 ]] || usage
|
||||||
tag="$1"
|
tag="$1"
|
||||||
disk_filename="$2"
|
|
||||||
|
|
||||||
cd "$(dirname $0)"
|
cd "$(dirname $0)"
|
||||||
[[ -f "$disk_filename" && -r "$disk_filename" ]] || { echo "$disk_filename does not exist, is not a regular file, or is not readable"; exit 1; }
|
|
||||||
[[ "$disk_filename" == *.xz ]] || { echo "$disk_filename does not appear to be an xz-compressed disk image"; exit 1; }
|
|
||||||
|
|
||||||
sed "s!<TAG>!${tag}!" ./k8s/deployment.yaml.template > ./k8s/deployment.yaml
|
sed "s!<TAG>!${tag}!" ./k8s/deployment.yaml.template > ./k8s/deployment.yaml
|
||||||
|
|
||||||
echo "Creating PVC..."
|
echo "Creating PVC..."
|
||||||
kubectl apply -f ./k8s/pvc.yaml
|
kubectl apply -f ./k8s/pvc.yaml
|
||||||
echo "Creating temporary pod..."
|
|
||||||
kubectl apply -f ./k8s/pod-tmp.yaml
|
|
||||||
echo "Waiting for temporary pod..."
|
|
||||||
while ! kubectl get pod pdp-tmp|grep -q Running; do sleep 1; done
|
|
||||||
echo "Checking for disk image..."
|
|
||||||
if ! kubectl exec -it pdp-tmp -- test -f /mnt/rq0.dsk &>/dev/null; then
|
|
||||||
echo "Uploading compressed disk image..."
|
|
||||||
kubectl exec pdp-tmp -- rm -f /mnt/rq0.dsk.xz
|
|
||||||
kubectl cp "$disk_filename" pdp-tmp:/mnt/rq0.dsk.xz
|
|
||||||
echo "Extracting disk image..."
|
|
||||||
kubectl exec pdp-tmp -- apk add xz
|
|
||||||
kubectl exec pdp-tmp -- xz -d /mnt/rq0.dsk.xz
|
|
||||||
fi
|
|
||||||
echo "Removing temporary pod..."
|
|
||||||
kubectl delete -f ./k8s/pod-tmp.yaml
|
|
||||||
echo "Creating PDP deployment..."
|
echo "Creating PDP deployment..."
|
||||||
kubectl apply -f ./k8s/deployment.yaml
|
kubectl apply -f ./k8s/deployment.yaml
|
||||||
echo "Creating services..."
|
echo "Creating services..."
|
||||||
for i in ./k8s/svc-*.yaml; do kubectl apply -f "$i"; done
|
for i in ./k8s/svc-*.yaml; do kubectl apply -f "$i"; done
|
||||||
echo "Done! Optionally, run ./k8s/configure-metallb.sh to put the services on an external IP."
|
echo "Done! Optionally, run ./misc/configure-metallb.sh to put the services on an external IP."
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
.:53 {
|
||||||
|
forward . /etc/resolv.conf
|
||||||
|
reload
|
||||||
|
}
|
|
@ -1,13 +1,27 @@
|
||||||
|
# Build container
|
||||||
FROM debian:11-slim AS builder
|
FROM debian:11-slim AS builder
|
||||||
RUN apt-get -y update && apt-get -y upgrade && apt-get -y install gcc libpcap-dev libvdeplug-dev libpcre3-dev libedit-dev libsdl2-dev libpng-dev libsdl2-ttf-dev build-essential && apt-get clean
|
RUN apt-get -y update && apt-get -y upgrade && apt-get -y install gcc libpcap-dev libvdeplug-dev libpcre3-dev libedit-dev libsdl2-dev libpng-dev libsdl2-ttf-dev build-essential && apt-get clean
|
||||||
ADD simh-3.9-0.tgz /
|
ADD simh-3.9-0.tgz /
|
||||||
WORKDIR /simh-3.9-0
|
WORKDIR /simh-3.9-0
|
||||||
RUN make pdp11
|
RUN make pdp11
|
||||||
|
|
||||||
|
# Final container
|
||||||
FROM debian:11-slim
|
FROM debian:11-slim
|
||||||
ENV DISK_FILENAME=rq0.dsk
|
ENV DISK_FILENAME=rq0.dsk
|
||||||
RUN apt-get -y update && apt-get -y upgrade && apt-get -y install ed libpcap-dev iproute2 iptables gcc vdeplug libpcre3 net-tools telnet
|
RUN apt-get -y update && apt-get -y upgrade && apt-get -y install curl ed gcc iproute2 iptables libpcap-dev libpcre3 net-tools telnet vdeplug
|
||||||
|
|
||||||
|
# Add Tini to handle reaping processes
|
||||||
|
ENV TINI_VERSION 0.19.0
|
||||||
|
ADD https://github.com/krallin/tini/releases/download/v${TINI_VERSION}/tini /tini
|
||||||
|
RUN chmod +x /tini
|
||||||
|
ENTRYPOINT ["/tini", "--"]
|
||||||
|
|
||||||
|
# Add CoreDNS to forward DNS based on /etc/resolv.conf
|
||||||
|
ENV COREDNS_VERSION 1.11.1
|
||||||
|
RUN curl -L https://github.com/coredns/coredns/releases/download/v${COREDNS_VERSION}/coredns_${COREDNS_VERSION}_linux_amd64.tgz|tar -xzC /usr/local/bin/
|
||||||
|
|
||||||
COPY --from=builder /simh-3.9-0/BIN/pdp11 /usr/local/bin/pdp11
|
COPY --from=builder /simh-3.9-0/BIN/pdp11 /usr/local/bin/pdp11
|
||||||
COPY boot.ini.template /
|
|
||||||
COPY startup.sh /
|
# Uses pattern matching to optionally copy rq0.dsk.gz if it exists
|
||||||
CMD /startup.sh
|
COPY startup.sh Corefile boot.ini.template rq0.dsk.g[z] /
|
||||||
|
CMD ["/startup.sh"]
|
||||||
|
|
|
@ -1,25 +1,43 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -ex
|
set -e
|
||||||
|
|
||||||
[ -n "$DISK_FILENAME" ] || DISK_FILENAME="rq0.dsk"
|
[ -n "$DISK_FILENAME" ] || DISK_FILENAME="rq0.dsk"
|
||||||
[ -f "/mnt/$DISK_FILENAME" ] || { echo "Unable to find tape /mnt/$DISK_FILENAME"; exit 1; }
|
|
||||||
[ -w "/mnt/$DISK_FILENAME" ] || { echo "Tape /mnt/$DISK_FILENAME is not writable"; exit 1; }
|
echo -n "Checking for disk... "
|
||||||
|
if [ -f "/mnt/$DISK_FILENAME" ]; then
|
||||||
|
[ -w "/mnt/$DISK_FILENAME" ] || { echo "Disk /mnt/$DISK_FILENAME exists and is not writable"; exit 1; }
|
||||||
|
echo "Disk found and is writable."
|
||||||
|
else
|
||||||
|
[ -w "/mnt/" ] || { echo "Disk /mnt/$DISK_FILENAME not found and /mnt not writable"; exit 1; }
|
||||||
|
[ -f "/rq0.dsk.gz" ] || { echo "Disk /mnt/$DISK_FILENAME not found and image was not built with a default disk"; exit 1; }
|
||||||
|
echo "Disk not found."
|
||||||
|
echo "Extracting default disk image..."
|
||||||
|
gzip -cd /rq0.dsk.gz > "/mnt/$DISK_FILENAME" || { echo "Failed to extract default disk image to /mnt/$DISK_FILENAME"; exit 1; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Start CoreDNS as soon as possible after validations done
|
||||||
|
echo "Starting CoreDNS..."
|
||||||
|
[ -z "$COREDNS_DEBUG" ] && COREDNS_QUIET="-quiet"
|
||||||
|
coredns "$COREDNS_QUIET" -conf /Corefile &
|
||||||
|
|
||||||
# Set exit command only if NOEXIT not set
|
# Set exit command only if NOEXIT not set
|
||||||
[ -z "$NOEXIT" ] && EXIT_CMD="exit" || EXIT_CMD=""
|
[ -z "$NOEXIT" ] && EXIT_CMD="exit" || EXIT_CMD=""
|
||||||
|
|
||||||
|
echo "Configuring simh..."
|
||||||
sed -e "s/<DISK_FILENAME>/${DISK_FILENAME}/" \
|
sed -e "s/<DISK_FILENAME>/${DISK_FILENAME}/" \
|
||||||
-e "s/<EXIT>/${EXIT_CMD}/" /boot.ini.template > /boot.ini
|
-e "s/<EXIT>/${EXIT_CMD}/" /boot.ini.template > /boot.ini
|
||||||
|
|
||||||
cidr=28
|
echo "Configuring networking..."
|
||||||
hostip=1.3.3.1
|
[ -z "$CIDR" ] && CIDR=28
|
||||||
pdpip=1.3.3.7
|
[ -z "$HOSTIP" ] && HOSTIP=1.3.3.1
|
||||||
|
[ -z "$PDPIP" ] && PDPIP=1.3.3.7
|
||||||
|
|
||||||
ip tuntap add pdp mode tap
|
ip tuntap add pdp mode tap
|
||||||
ip link set pdp up
|
ip link set pdp up
|
||||||
ip addr add "${hostip}/${cidr}" dev pdp
|
ip addr add "${HOSTIP}/${CIDR}" dev pdp
|
||||||
iptables -t nat -A PREROUTING ! -i pdp -p tcp --dport 4000 -j ACCEPT
|
iptables -t nat -A PREROUTING ! -i pdp -p tcp --dport 4000 -j ACCEPT # dz serial device
|
||||||
iptables -t nat -A PREROUTING ! -i pdp -j DNAT --to-destination 1.3.3.7
|
iptables -t nat -A PREROUTING ! -i pdp -j DNAT --to-destination "$PDPIP"
|
||||||
iptables -t nat -A POSTROUTING ! -o pdp -j MASQUERADE
|
iptables -t nat -A POSTROUTING ! -o pdp -j MASQUERADE
|
||||||
|
|
||||||
|
echo "Booting PDP-11..."
|
||||||
pdp11 /boot.ini
|
pdp11 /boot.ini
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
#
|
||||||
|
# This file is used to deploy a PDP-11 from a container image without a baked-in disk image.
|
||||||
|
#
|
||||||
|
|
||||||
|
usage () {
|
||||||
|
echo "usage: $0 tag disk_filename"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
[[ $# -eq 2 ]] || usage
|
||||||
|
tag="$1"
|
||||||
|
disk_filename="$2"
|
||||||
|
|
||||||
|
cd "$(dirname $(dirname $0))"
|
||||||
|
[[ -f "$disk_filename" && -r "$disk_filename" ]] || { echo "$disk_filename does not exist, is not a regular file, or is not readable"; exit 1; }
|
||||||
|
[[ "$disk_filename" == *.gz ]] || { echo "$disk_filename does not appear to be a gzip-compressed disk image"; exit 1; }
|
||||||
|
|
||||||
|
sed "s!<TAG>!${tag}!" ./k8s/deployment.yaml.template > ./k8s/deployment.yaml
|
||||||
|
|
||||||
|
echo "Creating PVC..."
|
||||||
|
kubectl apply -f ./k8s/pvc.yaml
|
||||||
|
echo "Creating temporary pod..."
|
||||||
|
kubectl apply -f ./k8s/pod-tmp.yaml
|
||||||
|
echo "Waiting for temporary pod..."
|
||||||
|
while ! kubectl get pod pdp-tmp|grep -q Running; do sleep 1; done
|
||||||
|
echo "Checking for disk image..."
|
||||||
|
if ! kubectl exec -it pdp-tmp -- test -f /mnt/rq0.dsk &>/dev/null; then
|
||||||
|
echo "Uploading compressed disk image..."
|
||||||
|
kubectl exec pdp-tmp -- rm -f /mnt/rq0.dsk.gz
|
||||||
|
kubectl cp "$disk_filename" pdp-tmp:/mnt/rq0.dsk.gz
|
||||||
|
echo "Extracting disk image..."
|
||||||
|
kubectl exec pdp-tmp -- gzip -d /mnt/rq0.dsk.gz
|
||||||
|
fi
|
||||||
|
echo "Removing temporary pod..."
|
||||||
|
kubectl delete -f ./k8s/pod-tmp.yaml
|
||||||
|
echo "Creating PDP deployment..."
|
||||||
|
kubectl apply -f ./k8s/deployment.yaml
|
||||||
|
echo "Creating services..."
|
||||||
|
for i in ./k8s/svc-*.yaml; do kubectl apply -f "$i"; done
|
||||||
|
echo "Done! Optionally, run ./misc/configure-metallb.sh to put the services on an external IP."
|
|
@ -9,7 +9,7 @@ usage () {
|
||||||
[[ $# -eq 1 ]] || usage
|
[[ $# -eq 1 ]] || usage
|
||||||
ip="$1"
|
ip="$1"
|
||||||
|
|
||||||
cd "$(dirname $0)"
|
cd "$(dirname $(dirname $0))/k8s/"
|
||||||
|
|
||||||
sed "s!<IP>!${ip}!" ./metallb.yaml.template > ./metallb.yaml
|
sed "s!<IP>!${ip}!" ./metallb.yaml.template > ./metallb.yaml
|
||||||
|
|
Loading…
Reference in New Issue