worked poc
This commit is contained in:
Executable
+170
@@ -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."
|
||||
Reference in New Issue
Block a user