From 289544a2990aa2a526cad9b8b66b7f7da9716fc1 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Mon, 26 Jan 2026 12:11:06 +0100 Subject: [PATCH 1/8] package/feature-wifi: add support for mediatek type wifi devices Signed-off-by: Joachim Wiberg --- configs/aarch64_defconfig | 3 ++- package/feature-wifi/Config.in | 19 ++++++++++++++++--- package/feature-wifi/feature-wifi.mk | 20 ++++++++++++++++++-- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/configs/aarch64_defconfig b/configs/aarch64_defconfig index cda0e2e68..54667d3e6 100644 --- a/configs/aarch64_defconfig +++ b/configs/aarch64_defconfig @@ -149,7 +149,8 @@ BR2_PACKAGE_MARVELL_CN9130_CRB=y BR2_PACKAGE_MARVELL_ESPRESSOBIN=y BR2_PACKAGE_RASPBERRYPI_RPI64=y BR2_PACKAGE_STYX_DCP_SC_28P=y -BR2_PACKAGE_FEATURE_WIFI_DONGLE_REALTEK=y +BR2_PACKAGE_FEATURE_WIFI_MEDIATEK=y +BR2_PACKAGE_FEATURE_WIFI_REALTEK=y BR2_PACKAGE_CONFD=y BR2_PACKAGE_CONFD_TEST_MODE=y BR2_PACKAGE_CURIOS_HTTPD=y diff --git a/package/feature-wifi/Config.in b/package/feature-wifi/Config.in index bbf293f30..d0a72aa8d 100644 --- a/package/feature-wifi/Config.in +++ b/package/feature-wifi/Config.in @@ -14,12 +14,25 @@ config BR2_PACKAGE_FEATURE_WIFI help Enables WiFi in Infix. Enables all requried applications. -config BR2_PACKAGE_FEATURE_WIFI_DONGLE_REALTEK - bool "Realtek USB WiFi Dongles" +config BR2_PACKAGE_FEATURE_WIFI_MEDIATEK + bool "Mediatek WiFi Devices" + depends on BR2_PACKAGE_FEATURE_WIFI + select BR2_PACKAGE_LINUX_FIRMWARE + select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7601U + select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7610E + select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT76X2E + select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7921 + select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7922 + select BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7925 + help + Enables support for various Mediatek WiFi devices. + +config BR2_PACKAGE_FEATURE_WIFI_REALTEK + bool "Realtek WiFi Devices" depends on BR2_PACKAGE_FEATURE_WIFI select BR2_PACKAGE_LINUX_FIRMWARE select BR2_PACKAGE_LINUX_FIRMWARE_RTL_81XX select BR2_PACKAGE_LINUX_FIRMWARE_RTL_RTW88 select BR2_PACKAGE_LINUX_FIRMWARE_RTL_RTW89 help - Enables Support for RTW88 and RTW89 USB dongles. + Enables support for RTL81xx, RTW88, and RTW89 WiFi devices. diff --git a/package/feature-wifi/feature-wifi.mk b/package/feature-wifi/feature-wifi.mk index 07e665f48..b7c2d3b92 100644 --- a/package/feature-wifi/feature-wifi.mk +++ b/package/feature-wifi/feature-wifi.mk @@ -13,7 +13,24 @@ define FEATURE_WIFI_LINUX_CONFIG_FIXUPS $(call KCONFIG_SET_OPT,CONFIG_MAC80211,m) $(call KCONFIG_SET_OPT,CONFIG_CFG80211,m) - $(if $(filter y,$(BR2_PACKAGE_FEATURE_WIFI_DONGLE_REALTEK)), + $(if $(filter y,$(BR2_PACKAGE_FEATURE_WIFI_MEDIATEK)), + $(call KCONFIG_ENABLE_OPT,CONFIG_MT7601U) + $(call KCONFIG_ENABLE_OPT,CONFIG_MT76x0U) + $(call KCONFIG_ENABLE_OPT,CONFIG_MT76x0E) + $(call KCONFIG_ENABLE_OPT,CONFIG_MT76x2E) + $(call KCONFIG_ENABLE_OPT,CONFIG_MT76x2U) + $(call KCONFIG_ENABLE_OPT,CONFIG_MT7603E) + $(call KCONFIG_ENABLE_OPT,CONFIG_MT7615E) + $(call KCONFIG_ENABLE_OPT,CONFIG_MT7663U) + $(call KCONFIG_ENABLE_OPT,CONFIG_MT7915E) + $(call KCONFIG_ENABLE_OPT,CONFIG_MT798X_WMAC) + $(call KCONFIG_ENABLE_OPT,CONFIG_MT7921E) + $(call KCONFIG_ENABLE_OPT,CONFIG_MT7921U) + $(call KCONFIG_ENABLE_OPT,CONFIG_MT7996E) + $(call KCONFIG_ENABLE_OPT,CONFIG_MT7925E) + $(call KCONFIG_ENABLE_OPT,CONFIG_MT7925U) + ) + $(if $(filter y,$(BR2_PACKAGE_FEATURE_WIFI_REALTEK)), $(call KCONFIG_ENABLE_OPT,CONFIG_WLAN_VENDOR_REALTEK) $(call KCONFIG_ENABLE_OPT,CONFIG_RTL8XXXU) $(call KCONFIG_ENABLE_OPT,CONFIG_RTL8XXXU_UNTESTED) @@ -47,5 +64,4 @@ define FEATURE_WIFI_LINUX_CONFIG_FIXUPS ) endef - $(eval $(generic-package)) From 6c0fd3e96bcfe48cb786b8d9750bd8e7f6a9bac0 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Mon, 26 Jan 2026 18:19:28 +0100 Subject: [PATCH 2/8] board/common: fix shell and clish 'follow' commands We want the command to show the entire log file, but fast forward to and tail at the end, handling any file rotations from syslogd. Signed-off-by: Joachim Wiberg --- board/common/rootfs/etc/bash.bashrc | 5 +++-- src/klish-plugin-infix/xml/infix.xml | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/board/common/rootfs/etc/bash.bashrc b/board/common/rootfs/etc/bash.bashrc index 2d4c139a5..8e916c939 100644 --- a/board/common/rootfs/etc/bash.bashrc +++ b/board/common/rootfs/etc/bash.bashrc @@ -40,11 +40,12 @@ log() less +G -r "$fn" } -follow() +follow () { local fn="/var/log/syslog" [ -n "$1" ] && fn="/var/log/$1" - less +F -r "$fn" + + tail -F -n +1 "$fn" } _logfile_completions() diff --git a/src/klish-plugin-infix/xml/infix.xml b/src/klish-plugin-infix/xml/infix.xml index b6786a434..e6b29cbf8 100644 --- a/src/klish-plugin-infix/xml/infix.xml +++ b/src/klish-plugin-infix/xml/infix.xml @@ -744,7 +744,7 @@ file=${KLISH_PARAM_fn:-syslog} echo -e "\e[1mPress Ctrl-C to abort ────────────────────────────────────────────\e[0m" - tail -F /log/$file + tail -F -n +1 /log/$file From 8d64f3d34bf02a62417469ab6d315c699044e179 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Mon, 26 Jan 2026 19:44:21 +0100 Subject: [PATCH 3/8] board/common: reduce nginx and rouset default log level Fixes #1349 Signed-off-by: Joachim Wiberg --- .../rootfs/etc/finit.d/available/restconf.conf | 2 +- board/common/rootfs/etc/nginx/nginx.conf | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/board/common/rootfs/etc/finit.d/available/restconf.conf b/board/common/rootfs/etc/finit.d/available/restconf.conf index cf32c4dfe..a8120ec3e 100644 --- a/board/common/rootfs/etc/finit.d/available/restconf.conf +++ b/board/common/rootfs/etc/finit.d/available/restconf.conf @@ -1,3 +1,3 @@ -service name:rousette notify:none log env:/etc/default/confd \ +service name:rousette notify:none log:console env:/etc/default/confd \ [12345] rousette --syslog -t $CONFD_TIMEOUT \ -- RESTCONF server diff --git a/board/common/rootfs/etc/nginx/nginx.conf b/board/common/rootfs/etc/nginx/nginx.conf index baf6b6b07..5719371e8 100644 --- a/board/common/rootfs/etc/nginx/nginx.conf +++ b/board/common/rootfs/etc/nginx/nginx.conf @@ -19,6 +19,14 @@ http { include /etc/nginx/enabled/*.conf; - access_log syslog:server=unix:/dev/log,nohostname,facility=local7,severity=info; - error_log syslog:server=unix:/dev/log,nohostname,facility=local7 info; + # Skip 2xx and 3xx + # Skip 400 (e.g., rrousette syntax errors) + map $status $loggable { + ~^[23] 0; + 400 0; + default 1; + } + + access_log syslog:server=unix:/dev/log,nohostname,facility=local7,severity=warn combined if=$loggable; + error_log syslog:server=unix:/dev/log,nohostname,facility=local7 warn; } From ff197d9b1068d6a62de05d0ab502346b47ece9bb Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Mon, 26 Jan 2026 12:13:59 +0100 Subject: [PATCH 4/8] confd: reduce Frr default log level Was set to informational, and Zebra to debug, which is mostly useful for developers when debugging the integration of Frr daemons. Example of before this patch: Nov 4 13:44:09 infix-6f-05-e1 finit[1]: staticd[4366], stopping, sending SIGTERM ... Nov 4 13:44:09 infix-6f-05-e1 staticd[4366]: Terminating on signal Nov 4 13:44:09 infix-6f-05-e1 zebra[4221]: [N5M5Y-J5BPG][EC 4043309121] Client 'static' (session id 0) encountered an error and is shutting down. Nov 4 13:44:09 infix-6f-05-e1 zebra[4221]: [KQB7H-NPVW9] zebra/zebra_ptm.c:1333 failed to find process pid registration Nov 4 13:44:09 infix-6f-05-e1 zebra[4221]: [JPSA8-5KYEA] client 26 disconnected 1 static routes removed from the rib Nov 4 13:44:09 infix-6f-05-e1 zebra[4221]: [S929C-NZR3N] client 26 disconnected 0 static nhgs removed from the rib Nov 4 13:44:09 infix-6f-05-e1 finit[1]: Starting staticd[5529] Nov 4 13:44:09 infix-6f-05-e1 zebra[4221]: [V98V0-MTWPF] client 26 says hello and bids fair to announce only static routes vrf=0 Signed-off-by: Joachim Wiberg --- board/common/rootfs/etc/default/zebra | 2 +- src/confd/src/routing.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/board/common/rootfs/etc/default/zebra b/board/common/rootfs/etc/default/zebra index 5ce4e34c3..4467b9af2 100644 --- a/board/common/rootfs/etc/default/zebra +++ b/board/common/rootfs/etc/default/zebra @@ -1,2 +1,2 @@ # --log-level debug -ZEBRA_ARGS="-A 127.0.0.1 -u frr -g frr --log syslog " +ZEBRA_ARGS="-A 127.0.0.1 -u frr -g frr --log syslog --log-level err" diff --git a/src/confd/src/routing.c b/src/confd/src/routing.c index 194b503ad..e9110e42a 100644 --- a/src/confd/src/routing.c +++ b/src/confd/src/routing.c @@ -26,7 +26,7 @@ hostname Router\n\ password zebra \n\ enable password zebra\n\ no log unique-id\n\ -log syslog informational\n\ +log syslog warnings\n\ log facility local2\n" int parse_rip_redistribute(sr_session_ctx_t *session, struct lyd_node *redistributes, FILE *fp) From c0fd39f069a0fc334061503fe6f26620a5ff835f Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Mon, 26 Jan 2026 18:17:03 +0100 Subject: [PATCH 5/8] confd: drop wifi-scanner in favor of wpa_supplicant autoscan The trick to starting the scanner mode is to have a dummy network that cannot associate with anything. Fixes #1193 Signed-off-by: Joachim Wiberg --- .../rootfs/etc/finit.d/available/wifi@.conf | 6 ++--- .../rootfs/usr/libexec/infix/wifi-scanner | 16 ------------ src/confd/src/if-wifi.c | 25 ++++++++++++++++--- 3 files changed, 23 insertions(+), 24 deletions(-) delete mode 100755 board/common/rootfs/usr/libexec/infix/wifi-scanner diff --git a/board/common/rootfs/etc/finit.d/available/wifi@.conf b/board/common/rootfs/etc/finit.d/available/wifi@.conf index e530b39c8..7f7bfcee6 100644 --- a/board/common/rootfs/etc/finit.d/available/wifi@.conf +++ b/board/common/rootfs/etc/finit.d/available/wifi@.conf @@ -1,5 +1,3 @@ service name:wpa_supplicant :%i \ - [2345] wpa_supplicant -s -i %i -c /etc/wpa_supplicant-%i.conf -P/var/run/wpa_supplicant-%i.pid \ - -- Wi-Fi Station @%i - -task name:wifi-scanner :%i [2345] /usr/libexec/infix/wifi-scanner %i -- Start scanning for SSID @%i + [2345] wpa_supplicant -s -i %i -c /etc/wpa_supplicant-%i.conf -P/var/run/wpa_supplicant-%i.pid \ + -- Wi-Fi Station @%i diff --git a/board/common/rootfs/usr/libexec/infix/wifi-scanner b/board/common/rootfs/usr/libexec/infix/wifi-scanner deleted file mode 100755 index b34c698bb..000000000 --- a/board/common/rootfs/usr/libexec/infix/wifi-scanner +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -if [ $# -ne 1 ]; then - echo "usage: $0 " - exit 1 -fi -ifname=$1 - -TIMEOUT=300 -status=$(wpa_cli -i $ifname scan) -while [ "$status" != "OK" ]; do - status=$(wpa_cli -i $ifname scan) - TIMEOUT=$((TIMEOUT-1)) - [ $TIMEOUT -eq 0 ] && logger -t wifi-scanner "Failed to start scanning $ifname" && exit 1 - sleep 0.5 -done diff --git a/src/confd/src/if-wifi.c b/src/confd/src/if-wifi.c index d6567d6b4..43a1e43c2 100644 --- a/src/confd/src/if-wifi.c +++ b/src/confd/src/if-wifi.c @@ -103,6 +103,10 @@ static int wifi_gen_station(struct lyd_node *cif) goto out; } + /* + * Background scanning every 10 seconds while not associated, when we + * have an SSID (below), bgscan assumes this task. + */ fprintf(wpa_supplicant, "ctrl_interface=/run/wpa_supplicant\n" "autoscan=periodic:10\n" @@ -121,14 +125,27 @@ static int wifi_gen_station(struct lyd_node *cif) } fprintf(wpa_supplicant, "network={\n" - "bgscan=\"simple: 30:-45:300\"\n" - "ssid=\"%s\"\n" - "%s\n" + " bgscan=\"simple: 30:-45:300\"\n" + " ssid=\"%s\"\n" + " %s\n" "}\n", ssid, security_str); free(security_str); } else { /* Scan-only mode - no station container configured */ - fprintf(wpa_supplicant, "# Scan-only mode - no network configured\n"); + fprintf(wpa_supplicant, "# Scan-only - need dummy network for state machine\n"); + /* + * This prevents the daemon from actually trying to associate and fail, + * 'bssid' with a reserved/impossible MAC address prevents it from ever + * actually \"finding\" and joining a random open AP + */ + fprintf(wpa_supplicant, + "network={\n" + " ssid=\"\"\n" + " key_mgmt=NONE\n" + " disabled=0\n" + " bssid=00:00:00:00:00:01\n" + " scan_ssid=1\n" + "}\n"); } out: From 76574fdd2b396c56a582f3e3a29dd2322cc459cd Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Mon, 26 Jan 2026 18:18:21 +0100 Subject: [PATCH 6/8] confd: minor, coding style Also, gcc complains that ap_op may be used unset, so let's set it to the only safe default there is. Signed-off-by: Joachim Wiberg --- src/confd/src/if-wifi.c | 42 +++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/confd/src/if-wifi.c b/src/confd/src/if-wifi.c index 43a1e43c2..39b61c36a 100644 --- a/src/confd/src/if-wifi.c +++ b/src/confd/src/if-wifi.c @@ -1,11 +1,4 @@ /* SPDX-License-Identifier: BSD-3-Clause */ -#include -#include - -#include "interfaces.h" - -#define WPA_SUPPLICANT_CONF "/etc/wpa_supplicant-%s.conf" - /* * WiFi Interface Management * @@ -14,6 +7,13 @@ * configuration (hostapd) is handled by hardware.c. */ +#include +#include + +#include "interfaces.h" + +#define WPA_SUPPLICANT_CONF "/etc/wpa_supplicant-%s.conf" + /* * Determine WiFi mode from YANG configuration */ @@ -25,28 +25,35 @@ typedef enum wifi_mode_t { static wifi_mode_t wifi_get_mode(struct lyd_node *wifi) { - struct lyd_node *ap = lydx_get_child(wifi, "access-point"); + struct lyd_node *ap; - if (ap && (lydx_get_op(ap) != LYDX_OP_DELETE)) - return wifi_ap; - else - return wifi_station; /* Need to return station even if "station" also is false, since that is the default scanning mode */ + ap = lydx_get_child(wifi, "access-point"); + if (ap) { + if (lydx_get_op(ap) != LYDX_OP_DELETE) + return wifi_ap; + } + + /* + * Need to return station even if "station" also is false, + * because station is the default scanning mode. + */ + return wifi_station; } int wifi_mode_changed(struct lyd_node *wifi) { + enum lydx_op ap_op = LYDX_OP_DELETE; struct lyd_node *ap; - enum lydx_op ap_op; if (!wifi) return 0; ap = lydx_get_child(wifi, "access-point"); - if (ap) ap_op = lydx_get_op(ap); - ERROR("MODE CHANGED: %d", ap && (ap_op == LYDX_OP_CREATE || ap_op == LYDX_OP_DELETE)); + DEBUG("MODE CHANGED: %d", ap && (ap_op == LYDX_OP_CREATE || ap_op == LYDX_OP_DELETE)); + return (ap && (ap_op == LYDX_OP_CREATE || ap_op == LYDX_OP_DELETE)); } @@ -70,21 +77,20 @@ static int wifi_gen_station(struct lyd_node *cif) radio = lydx_get_cattr(wifi, "radio"); station = lydx_get_child(wifi, "station"); - /* If station is NULL, we're in scan-only mode (no station container) */ if (station) { ssid = lydx_get_cattr(station, "ssid"); security = lydx_get_child(station, "security"); security_mode = lydx_get_cattr(security, "mode"); secret_name = lydx_get_cattr(security, "secret"); } else { + /* If station is NULL, we're in scan-only mode (no station container) */ ssid = NULL; security = NULL; security_mode = "disabled"; secret_name = NULL; } - radio_node = lydx_get_xpathf(cif, - "../../hardware/component[name='%s']/wifi-radio", radio); + radio_node = lydx_get_xpathf(cif, "../../hardware/component[name='%s']/wifi-radio", radio); country = lydx_get_cattr(radio_node, "country-code"); if (secret_name && strcmp(security_mode, "disabled") != 0) { From 0a6a1ce05539910a4599a19c17702884cfe958ae Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Mon, 26 Jan 2026 18:20:33 +0100 Subject: [PATCH 7/8] confd: ensure dhcp client default behavior, register hostname For some reason, during the last refactor possibly, the dhcp client stopped sending the current hostname to the dhcp server. This is very useful to check what devices are on your network by asking the home router's dhcp server. Signed-off-by: Joachim Wiberg --- src/confd/src/dhcp-common.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/confd/src/dhcp-common.c b/src/confd/src/dhcp-common.c index 49ba3d983..282af1dd6 100644 --- a/src/confd/src/dhcp-common.c +++ b/src/confd/src/dhcp-common.c @@ -194,7 +194,6 @@ static void infer_options_v4(sr_session_ctx_t *session, const char *xpath) "broadcast", "router", "domain", - "hostname", /* server may use this to register our current name */ "dns-server", "ntp-server" /* will not be activated unless ietf-system also is */ }; @@ -203,6 +202,10 @@ static void infer_options_v4(sr_session_ctx_t *session, const char *xpath) for (i = 0; i < NELEMS(opt); i++) srx_set_item(session, NULL, 0, "%s/option[id='%s']", xpath, opt[i]); + /* server may use this to register our current name */ + val.data.string_val = "auto"; + srx_set_item(session, &val, 0, "%s/option[id='hostname']/value", xpath); + product_name = json_object_get(confd.root, "product-name"); if (product_name) { val.data.string_val = (char *)json_string_value(product_name); From 2ed84c2363f29f521e58c4809ef04766892a280c Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Mon, 26 Jan 2026 19:53:47 +0100 Subject: [PATCH 8/8] doc: fix syntax errors in restconf helper script Also, add a check() function with a user-friendly reminder if the forget to include the model prefix in the URL. Signed-off-by: Joachim Wiberg --- doc/scripting-restconf.md | 143 ++++++++++++++++++++++++-------------- 1 file changed, 91 insertions(+), 52 deletions(-) diff --git a/doc/scripting-restconf.md b/doc/scripting-restconf.md index cf466afb6..3aa637dba 100644 --- a/doc/scripting-restconf.md +++ b/doc/scripting-restconf.md @@ -18,77 +18,116 @@ To simplify RESTCONF operations, create a `curl.sh` wrapper script: #!/bin/sh # RESTCONF CLI wrapper for curl -# Show usage and exit +HOST=${HOST:-infix.local} +DATASTORE=running +AUTH=admin:admin + usage() { - cat <<-EOF >&2 - Usage: $0 [-h HOST] [-d DATASTORE] [-u USER:PASS] METHOD PATH [CURL_ARGS...] - - Options: - -h HOST Target host (default: infix.local) - -d DS Datastore: running, operational, startup (default: running) - -u CREDS Credentials as user:pass (default: admin:admin) - - Methods: GET, POST, PUT, PATCH, DELETE - EOF - exit "$1" + cat <&2 +Usage: $0 [-v] [-h HOST] [-d DATASTORE] [-u USER:PASS] METHOD XPATH [CURL_ARGS...] + +Options: + -h HOST Target host (default: infix.local) + -d DS Datastore: running, operational, startup (default: running) + -u CREDS Credentials as user:pass (default: admin:admin) + -v Verbose mode, use it to display variables and curl command + +Methods: GET, POST, PUT, PATCH, DELETE +EOF + exit "$1" } -# Default values -HOST=${HOST:-infix.local} -DATASTORE=running -AUTH=admin:admin +check() +{ + hint="Note: URL may be missing a module prefix (e.g., ietf-system:system)" + resp="$1" + url="$2" + + if ! command -v jq >/dev/null 2>&1; then + printf "%s\n" "$resp" + return + fi + + case "$resp" in + *"Syntax error"*) + path_only="${url#*//}" + + # Check for common URL error(s), e.g., missing module prefix + case "$path_only" in + *":"*) + printf "%s\n" "$resp" | jq . + ;; + *) + printf "%s\n" "$resp" | jq --arg hint "$hint" \ + '.["ietf-restconf:errors"].error[] |= . + {comment: $hint}' + ;; + esac + ;; + *) + printf "%s\n" "$resp" | jq . + ;; + esac +} -# Parse options -while getopts "h:d:u:" opt; do - case $opt in - h) HOST="$OPTARG" ;; - d) DATASTORE="$OPTARG" ;; - u) AUTH="$OPTARG" ;; - *) usage 1 ;; - esac +while getopts "h:d:u:v" opt; do + case $opt in + h) HOST="$OPTARG" ;; + d) DATASTORE="$OPTARG" ;; + u) AUTH="$OPTARG" ;; + v) VERBOSE=1 ;; + *) usage 1 ;; + esac done shift $((OPTIND - 1)) -# Validate required arguments if [ $# -lt 2 ]; then - echo "Error: METHOD and PATH are required" >&2 - usage 1 + echo "Error: METHOD and XPATH are required" >&2 + usage 1 fi METHOD=$1 -PATH=$2 +XPATH=$2 shift 2 -# Ensure PATH starts with / -case "$PATH" in - /*) ;; - *) PATH="/$PATH" ;; +# Ensure XPATH starts with / +case "$XPATH" in + /*) ;; + *) XPATH="/$XPATH" ;; esac -# Build URL based on datastore case "$DATASTORE" in - running|startup) - URL="https://${HOST}/restconf/data${PATH}" - ;; - operational) - URL="https://${HOST}/restconf/data${PATH}" - ;; - *) - echo "Error: Invalid datastore '$DATASTORE'. Use: running, operational, or startup" >&2 - exit 1 - ;; + running|startup) + URL="https://${HOST}/restconf/data${XPATH}" + ;; + operational) + URL="https://${HOST}/restconf/data${XPATH}" + ;; + *) + echo "Error: Invalid datastore '$DATASTORE'. Use: running, operational, or startup" >&2 + exit 1 + ;; esac -# Execute curl with all remaining arguments passed through -exec /usr/bin/curl \ - --insecure \ - --user "${AUTH}" \ - --request "${METHOD}" \ - --header "Content-Type: application/yang-data+json" \ - --header "Accept: application/yang-data+json" \ - "$@" \ - "${URL}" +if [ "$VERBOSE" ]; then + echo "DS : $DATASTORE" + echo "OP : $METHOD" + echo "XPATH : $XPATH" + echo "AUTH : $AUTH" + echo "=> URL : $URL" + set -x +fi + +RESP=$(/usr/bin/curl --silent \ + --insecure \ + --user "${AUTH}" \ + --request "${METHOD}" \ + --header "Content-Type: application/yang-data+json" \ + --header "Accept: application/yang-data+json" \ + "$@" \ + "${URL}") + +check "$RESP" "$URL" ``` Make it executable: