worked poc

This commit is contained in:
Mateusz Gruszczyński
2026-08-14 11:33:01 +02:00
parent adfdb0b86c
commit fc3a2944b2
94 changed files with 2931 additions and 3412 deletions
+170
View File
@@ -0,0 +1,170 @@
#!/bin/sh
set -eu
cd "$(dirname "$0")/.."
CONFIG_FILE="${DEPLOY_CONFIG:-deploy-routeros.env}"
if [ -f "$CONFIG_FILE" ]; then
# shellcheck disable=SC1090
case "$CONFIG_FILE" in
/*) . "$CONFIG_FILE" ;;
*) . "./$CONFIG_FILE" ;;
esac
fi
VERSION="$(tr -d '[:space:]' < VERSION)"
[ -n "$VERSION" ] || { echo "VERSION is empty" >&2; exit 2; }
case "$VERSION" in
*[!A-Za-z0-9._-]*) echo "VERSION contains unsupported characters: $VERSION" >&2; exit 2 ;;
esac
CONTAINER_NAME="suricata_${VERSION}"
ROOT_DIR="/containers/${CONTAINER_NAME}/root"
: "${ROUTER_HOST:=192.168.88.1}"
: "${ROUTER_USER:=admin}"
: "${ROUTER_PORT:=22}"
: "${ROUTER_IDENTITY_FILE:=}"
: "${CONTAINER_VETH:=veth-ids}"
: "${CONTAINER_ENVLIST:=IDS_ENV}"
: "${CONTAINER_MOUNTLIST:=IDS_MOUNTS}"
usage() {
cat <<USAGE
Usage: $0 <TAR already uploaded to RouterOS>
This is an image-only container upgrade. It DOES NOT change:
- bridge/IP/NAT/veth configuration,
- TZSP/sniffer configuration,
- firewall or REST configuration,
- envlist or mount definitions.
It only disables/stops older suricata_* containers, creates:
name=${CONTAINER_NAME}
file=<TAR>
root-dir=${ROOT_DIR}
and reuses:
interface=${CONTAINER_VETH}
envlist=${CONTAINER_ENVLIST}
mountlists=${CONTAINER_MOUNTLIST}
USAGE
}
IMAGE_TAR_ROS="${1:-}"
if [ -z "$IMAGE_TAR_ROS" ]; then
usage >&2
exit 2
fi
case "$IMAGE_TAR_ROS" in
*.tar) ;;
*) echo "RouterOS image path must point to a .tar file: $IMAGE_TAR_ROS" >&2; exit 2 ;;
esac
command -v ssh >/dev/null 2>&1 || { echo "ssh is required" >&2; exit 2; }
command -v scp >/dev/null 2>&1 || { echo "scp is required" >&2; exit 2; }
case "$ROUTER_PORT" in
*[!0-9]*|'') echo "ROUTER_PORT must be numeric" >&2; exit 2 ;;
esac
for value in "$IMAGE_TAR_ROS" "$CONTAINER_VETH" "$CONTAINER_ENVLIST" "$CONTAINER_MOUNTLIST"; do
case "$value" in
*'"'*|*'\\'*|*'$'*|*';'*|*'`'*) echo "Unsupported character in RouterOS value: $value" >&2; exit 3 ;;
esac
done
SSH_TARGET="${ROUTER_USER}@${ROUTER_HOST}"
ssh_run() {
if [ -n "$ROUTER_IDENTITY_FILE" ]; then
ssh -i "$ROUTER_IDENTITY_FILE" -p "$ROUTER_PORT" "$SSH_TARGET" "$1"
else
ssh -p "$ROUTER_PORT" "$SSH_TARGET" "$1"
fi
}
printf '[upgrade] version: %s\n' "$VERSION"
printf '[upgrade] new container: %s\n' "$CONTAINER_NAME"
printf '[upgrade] image on RouterOS: %s\n' "$IMAGE_TAR_ROS"
printf '[upgrade] root-dir: %s\n' "$ROOT_DIR"
printf '[upgrade] reusing interface/env/mounts: %s / %s / %s\n' "$CONTAINER_VETH" "$CONTAINER_ENVLIST" "$CONTAINER_MOUNTLIST"
echo '[upgrade] read-only preflight'
ssh_run '/container/print' >/dev/null
ssh_run "/file/print without-paging where name=\"${IMAGE_TAR_ROS}\"" | grep -F "$IMAGE_TAR_ROS" >/dev/null 2>&1 || {
echo "Image TAR not found on RouterOS: $IMAGE_TAR_ROS" >&2
echo "Upload it first with scripts/upload-routeros-image.sh." >&2
exit 4
}
ssh_run "/interface/veth/print without-paging where name=\"${CONTAINER_VETH}\"" | grep -F "$CONTAINER_VETH" >/dev/null 2>&1 || {
echo "Existing veth not found: $CONTAINER_VETH" >&2
echo "Run the normal deploy once before using image-only upgrades." >&2
exit 5
}
if ! ssh_run "/container/envs/print without-paging where list=\"${CONTAINER_ENVLIST}\"" | grep -F "$CONTAINER_ENVLIST" >/dev/null 2>&1; then
echo "Existing envlist not found or empty: $CONTAINER_ENVLIST" >&2
exit 5
fi
if ! ssh_run "/container/mounts/print without-paging where list=\"${CONTAINER_MOUNTLIST}\"" | grep -F "$CONTAINER_MOUNTLIST" >/dev/null 2>&1; then
echo "Existing mountlist not found or empty: $CONTAINER_MOUNTLIST" >&2
exit 5
fi
if ssh_run "/container/print without-paging where name=\"${CONTAINER_NAME}\"" | grep -F "$CONTAINER_NAME" >/dev/null 2>&1; then
echo "Container already exists: $CONTAINER_NAME" >&2
echo "Bump VERSION or remove that container explicitly before retrying." >&2
exit 6
fi
DEPLOY_ID="$(date -u +%Y%m%d%H%M%S)"
mkdir -p build
LOCAL_RSC="build/upgrade-${CONTAINER_NAME}-${DEPLOY_ID}.rsc"
REMOTE_RSC_NAME="upgrade-${CONTAINER_NAME}-${DEPLOY_ID}.rsc"
cat > "$LOCAL_RSC" <<RSC
# Image-only Suricata container upgrade.
# This script intentionally does not modify networking, sniffer, firewall,
# envlist definitions or mount definitions.
:foreach c in=[/container/find where name~"^suricata_"] do={
/container/set \$c start-on-boot=no
}
:local running [/container/find where name~"^suricata_" and status="running"]
:if ([:len \$running] > 0) do={
/container/stop \$running
:delay 3s
}
/container/add name="${CONTAINER_NAME}" file="${IMAGE_TAR_ROS}" interface="${CONTAINER_VETH}" root-dir="${ROOT_DIR}" mountlists="${CONTAINER_MOUNTLIST}" envlist="${CONTAINER_ENVLIST}" start-on-boot=yes logging=yes
:local tries 0
:while (\$tries < 180) do={
:if ([:len [/container/find where name="${CONTAINER_NAME}" and status="stopped"]] > 0) do={
:set tries 999
} else={
:delay 2s
:set tries (\$tries + 1)
}
}
:if ([:len [/container/find where name="${CONTAINER_NAME}" and status="stopped"]] = 0) do={
:error "Container extraction did not reach stopped state"
}
/container/start [find where name="${CONTAINER_NAME}"]
:delay 5s
/container/print detail where name="${CONTAINER_NAME}"
RSC
if [ -n "$ROUTER_IDENTITY_FILE" ]; then
scp -i "$ROUTER_IDENTITY_FILE" -P "$ROUTER_PORT" "$LOCAL_RSC" "${SSH_TARGET}:/${REMOTE_RSC_NAME}"
else
scp -P "$ROUTER_PORT" "$LOCAL_RSC" "${SSH_TARGET}:/${REMOTE_RSC_NAME}"
fi
echo "[upgrade] creating ${CONTAINER_NAME} without touching existing network configuration"
ssh_run "/import file-name=\"${REMOTE_RSC_NAME}\""
ssh_run "/file/remove [find where name=\"${REMOTE_RSC_NAME}\"]" || true
echo '[upgrade] done'
echo "New container: ${CONTAINER_NAME}"
echo "Root dir: ${ROOT_DIR}"
echo "Older suricata_* containers were left in place, stopped and start-on-boot=no."