mirror of
https://github.com/alexhopeoconnor/dnsmasq-webui.git
synced 2026-10-03 22:12:00 +10:00
Effective config: do-0x20-encode revert fix, validation UI, custom displays, option help
- Fix do-0x20-encode: clearing pending when toggling back to original (Disabled/Default) - Do0x20EncodeDisplay: uncheck uses pending.OldValue when present - EffectiveConfigFieldDisplay: use pending.OldValue as _valueAtActivation when re-entering with pending - Effective config: validation errors/warnings in toolbar and save modal, revert from modal - Custom displays: Do0x20EncodeDisplay (tri-state), KeyOnlyOrValueDisplay - ExplicitToggleState, config/apply support for do-0x20-encode, option help and tests
This commit is contained in:
@@ -171,6 +171,57 @@ OPTION_KEYS = [
|
||||
"keep-in-foreground",
|
||||
"no-daemon",
|
||||
"conntrack",
|
||||
"connmark-allowlist-enable",
|
||||
"no-round-robin",
|
||||
"dns-forward-max",
|
||||
"connmark-allowlist",
|
||||
"do-0x20-encode",
|
||||
"caa-record",
|
||||
"dns-rr",
|
||||
"synth-domain",
|
||||
"auth-zone",
|
||||
"auth-soa",
|
||||
"auth-sec-servers",
|
||||
"auth-peer",
|
||||
"leasequery",
|
||||
"dhcp-generate-names",
|
||||
"dhcp-broadcast",
|
||||
"dhcp-sequential-ip",
|
||||
"dhcp-ignore-clid",
|
||||
"bootp-dynamic",
|
||||
"no-ping",
|
||||
"script-arp",
|
||||
"script-on-renewal",
|
||||
"dhcp-no-override",
|
||||
"dhcp-alternate-port",
|
||||
"dhcp-duid",
|
||||
"dhcp-luascript",
|
||||
"dhcp-scriptuser",
|
||||
"dhcp-relay",
|
||||
"dhcp-circuitid",
|
||||
"dhcp-remoteid",
|
||||
"dhcp-subscrid",
|
||||
"dhcp-proxy",
|
||||
"tag-if",
|
||||
"bridge-interface",
|
||||
"shared-network",
|
||||
"dhcp-pxe-vendor",
|
||||
"dhcp-option-pxe",
|
||||
"dnssec-no-timecheck",
|
||||
"dnssec-debug",
|
||||
"add-cpe-id",
|
||||
"dnssec-timestamp",
|
||||
"dnssec-limits",
|
||||
"dumpfile",
|
||||
"dumpmask",
|
||||
"use-stale-cache",
|
||||
"add-mac",
|
||||
"add-subnet",
|
||||
"umbrella",
|
||||
"quiet-dhcp",
|
||||
"quiet-dhcp6",
|
||||
"quiet-ra",
|
||||
"quiet-tftp",
|
||||
]
|
||||
|
||||
long_opt_re = re.compile(r"--([a-z][a-z0-9-]*)(?:=[^,\s]*)?", re.IGNORECASE)
|
||||
|
||||
@@ -15,8 +15,10 @@ COMPOSE_FILE="docker-compose.test.yml"
|
||||
|
||||
SOURCE_DIR=""
|
||||
MOUNT_DIR=""
|
||||
DNSMASQ_VERSION=""
|
||||
PREPARE_ONLY=false
|
||||
BUILD=false
|
||||
NO_CACHE_BUILD=false
|
||||
RECREATE=false
|
||||
CLEAR=false
|
||||
STOP=false
|
||||
@@ -38,6 +40,9 @@ usage() {
|
||||
echo " --source DIR Source to copy from (default: testdata)"
|
||||
echo " --mount DIR Target mount directory (default: testdata-mount)"
|
||||
echo " Compose uses TESTDATA_MOUNT; script exports it if you use --mount."
|
||||
echo " --dnsmasq-version V Dnsmasq version for the harness image:"
|
||||
echo " latest (default), distro, or an exact upstream version like 2.91."
|
||||
echo " Non-default values require --build or --no-cache-build; script fails with --no-build."
|
||||
echo ""
|
||||
echo "Mount behaviour:"
|
||||
echo " (default) Preserve mount dir; sync source over existing contents."
|
||||
@@ -50,7 +55,10 @@ usage() {
|
||||
echo " Use to inspect or edit the mount before starting containers."
|
||||
echo " --build Pass --build to docker compose (rebuild images before starting)."
|
||||
echo " Use after changing the app or Dockerfile. Default: use existing images."
|
||||
echo " --no-cache-build Rebuild images with --pull --no-cache before starting."
|
||||
echo " Use to force a fresh image build and refresh 'latest' dnsmasq."
|
||||
echo " --no-build Do not rebuild (default). Use existing images for a quick restart."
|
||||
echo " With --no-build, 'latest' is not resolved (no network)."
|
||||
echo " --recreate Pass --force-recreate to docker compose (recreate containers)."
|
||||
echo " Use to ensure fresh container state and mounts."
|
||||
echo ""
|
||||
@@ -72,6 +80,9 @@ usage() {
|
||||
echo " $0 --recreate"
|
||||
echo " Sync, then up -d --force-recreate (fresh containers)."
|
||||
echo ""
|
||||
echo " $0 --no-cache-build"
|
||||
echo " Force a fresh image build (no Docker build cache), then start containers."
|
||||
echo ""
|
||||
echo " $0 --clear"
|
||||
echo " Clear mount, sync testdata, start (clean run, no rebuild)."
|
||||
echo ""
|
||||
@@ -91,6 +102,35 @@ usage() {
|
||||
echo ""
|
||||
echo " $0 --minimal-conf"
|
||||
echo " Use dnsmasq-test-minimal.conf (single file, few options) and start."
|
||||
echo ""
|
||||
echo " $0 --dnsmasq-version 2.91 --build"
|
||||
echo " Rebuild the harness image with dnsmasq 2.91."
|
||||
}
|
||||
|
||||
fetch_url() {
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
curl -fsSL "$1"
|
||||
return $?
|
||||
fi
|
||||
if command -v wget >/dev/null 2>&1; then
|
||||
wget -qO- "$1"
|
||||
return $?
|
||||
fi
|
||||
echo "Error: need curl or wget to resolve the latest upstream dnsmasq version." >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
resolve_dnsmasq_version() {
|
||||
if [ "$DNSMASQ_VERSION" != "latest" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
RESOLVED_VERSION="$(fetch_url "https://thekelleys.org.uk/dnsmasq/" | sed -n 's/.*LATEST_IS_\([0-9][0-9.]*\).*/\1/p' | head -n1)"
|
||||
if [ -z "$RESOLVED_VERSION" ]; then
|
||||
echo "Error: could not resolve the latest upstream dnsmasq version." >&2
|
||||
exit 1
|
||||
fi
|
||||
DNSMASQ_VERSION="$RESOLVED_VERSION"
|
||||
}
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
@@ -111,6 +151,12 @@ while [ $# -gt 0 ]; do
|
||||
MOUNT_DIR="$1"
|
||||
shift
|
||||
;;
|
||||
--dnsmasq-version)
|
||||
shift
|
||||
[ $# -gt 0 ] || { echo "Error: --dnsmasq-version requires VERSION" >&2; exit 1; }
|
||||
DNSMASQ_VERSION="$1"
|
||||
shift
|
||||
;;
|
||||
--clear)
|
||||
CLEAR=true
|
||||
shift
|
||||
@@ -123,8 +169,14 @@ while [ $# -gt 0 ]; do
|
||||
BUILD=true
|
||||
shift
|
||||
;;
|
||||
--no-cache-build)
|
||||
NO_CACHE_BUILD=true
|
||||
BUILD=true
|
||||
shift
|
||||
;;
|
||||
--no-build)
|
||||
BUILD=false
|
||||
NO_CACHE_BUILD=false
|
||||
shift
|
||||
;;
|
||||
--recreate)
|
||||
@@ -170,6 +222,7 @@ cd "$REPO_ROOT"
|
||||
|
||||
: "${SOURCE_DIR:=testdata}"
|
||||
: "${MOUNT_DIR:=testdata-mount}"
|
||||
: "${DNSMASQ_VERSION:=latest}"
|
||||
|
||||
# Stop and/or tidy: no prepare, no start
|
||||
if [ "$STOP" = true ] || [ "$TIDY" = true ]; then
|
||||
@@ -192,6 +245,17 @@ if [ ! -d "$SOURCE_DIR" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Resolve "latest" only when we will build; avoid network when doing a no-build run.
|
||||
WILL_BUILD=false
|
||||
[ "$BUILD" = true ] || [ "$NO_CACHE_BUILD" = true ] && WILL_BUILD=true
|
||||
if [ "$WILL_BUILD" = false ] && [ "$DNSMASQ_VERSION" != "latest" ] && [ "$DNSMASQ_VERSION" != "distro" ]; then
|
||||
echo "Error: --dnsmasq-version $DNSMASQ_VERSION has no effect without --build or --no-cache-build. Add --build or omit --dnsmasq-version for a no-build run." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ "$WILL_BUILD" = true ]; then
|
||||
resolve_dnsmasq_version
|
||||
fi
|
||||
|
||||
# Take the harness down so all containers (including one-shot DHCP clients) are recreated on up.
|
||||
echo "Stopping test harness: docker compose -f $COMPOSE_FILE down"
|
||||
docker compose -f "$COMPOSE_FILE" down
|
||||
@@ -220,9 +284,14 @@ if [ "$PREPARE_ONLY" = true ]; then
|
||||
/*) MOUNT_EXPORT="$MOUNT_DIR" ;;
|
||||
*) MOUNT_EXPORT="./$MOUNT_DIR" ;;
|
||||
esac
|
||||
START_CMD="TESTDATA_MOUNT=$MOUNT_EXPORT docker compose -f $COMPOSE_FILE up -d [--build]"
|
||||
START_PREFIX="TESTDATA_MOUNT=$MOUNT_EXPORT DNSMASQ_VERSION=$DNSMASQ_VERSION"
|
||||
if [ "$MINIMAL_CONF" = true ]; then
|
||||
START_CMD="TESTDATA_MOUNT=$MOUNT_EXPORT TEST_DNSMASQ_CONF=/data/dnsmasq-test-minimal.conf docker compose -f $COMPOSE_FILE up -d [--build]"
|
||||
START_PREFIX="$START_PREFIX TEST_DNSMASQ_CONF=/data/dnsmasq-test-minimal.conf"
|
||||
fi
|
||||
if [ "$NO_CACHE_BUILD" = true ]; then
|
||||
START_CMD="$START_PREFIX docker compose -f $COMPOSE_FILE build --pull --no-cache && $START_PREFIX docker compose -f $COMPOSE_FILE up -d"
|
||||
else
|
||||
START_CMD="$START_PREFIX docker compose -f $COMPOSE_FILE up -d [--build]"
|
||||
fi
|
||||
echo "To start the harness: $START_CMD"
|
||||
exit 0
|
||||
@@ -234,13 +303,30 @@ case "$MOUNT_DIR" in
|
||||
*) export TESTDATA_MOUNT="./$MOUNT_DIR" ;;
|
||||
esac
|
||||
|
||||
export DNSMASQ_VERSION
|
||||
|
||||
case "$DNSMASQ_VERSION" in
|
||||
distro)
|
||||
echo "Using distro-packaged dnsmasq for the harness image."
|
||||
;;
|
||||
*)
|
||||
echo "Using dnsmasq $DNSMASQ_VERSION for the harness image."
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "$MINIMAL_CONF" = true ]; then
|
||||
export TEST_DNSMASQ_CONF="/data/dnsmasq-test-minimal.conf"
|
||||
echo "Using minimal config: $TEST_DNSMASQ_CONF"
|
||||
fi
|
||||
|
||||
if [ "$NO_CACHE_BUILD" = true ]; then
|
||||
BUILD_CMD="docker compose -f $COMPOSE_FILE build --pull --no-cache"
|
||||
echo "Running: $BUILD_CMD"
|
||||
$BUILD_CMD
|
||||
fi
|
||||
|
||||
COMPOSE_CMD="docker compose -f $COMPOSE_FILE up -d"
|
||||
if [ "$BUILD" = true ]; then
|
||||
if [ "$BUILD" = true ] && [ "$NO_CACHE_BUILD" != true ]; then
|
||||
COMPOSE_CMD="$COMPOSE_CMD --build"
|
||||
fi
|
||||
if [ "$RECREATE" = true ]; then
|
||||
|
||||
Reference in New Issue
Block a user