Skip to content

Commit be7e11d

Browse files
MichaelUrayclaude
authored andcommitted
[fix] Retry pending report_status instead of forcing re-download #251
When report_status fails after a configuration apply (e.g. due to a transient HTTP 502 from the controller), the agent previously deleted the local checksum files to trigger a full re-download on the next cycle. That worked but wasted bandwidth and caused the controller to stay stuck on "modified" until the next real config change. Instead persist the unreported status in a pending_report marker file and retry just report_status on the next polling cycle. Key details addressed from the review: - Define retry_pending_report as a shell function so "local" is valid on BusyBox ash, where "local" outside a function is a parse error that silently crashes the script mid-loop. - Persist the marker BEFORE calling retry_with_backoff report_status so a crash or reboot between the retry attempt and the PENDING_REPORT write does not lose the status. - Validate the marker contents against the known-good status set (applied/error) and discard a malformed marker rather than retrying forever. - Only remove the marker after a successful report_status. Closes #251 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 1f8beaa commit be7e11d

2 files changed

Lines changed: 57 additions & 6 deletions

File tree

CHANGELOG.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@ Change log
44
1.3.0 [unreleased]
55
------------------
66

7-
WIP.
7+
Bugfixes
8+
~~~~~~~~
9+
10+
- Fixed retrying pending ``report_status`` instead of forcing a
11+
re-download after a transient HTTP error `#251
12+
<https://github.com/openwisp/openwisp-config/pull/251>`_.
813

914
1.2.1 [2026-04-09]
1015
------------------

openwisp-config/files/openwisp.agent

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ REGISTRATION_PARAMETERS="$WORKING_DIR/registration_parameters"
200200
TEST_CHECKSUM="$WORKING_DIR/test_checksum"
201201
UPDATE_INFO="$WORKING_DIR/update_info"
202202
STATUS_REPORT="$WORKING_DIR/status_report"
203+
PENDING_REPORT="$WORKING_DIR/pending_report"
203204
APPLYING_CONF="$WORKING_DIR/applying_conf"
204205
UPDATE_CONFIG_LOG="$WORKING_DIR/update-config.log"
205206
BOOTUP="$WORKING_DIR/bootup"
@@ -825,6 +826,7 @@ update_configuration() {
825826
result=$?
826827
fi
827828

829+
local status_to_report
828830
if [ "$result" -eq "0" ]; then
829831
logger "Configuration applied successfully" \
830832
-t openwisp \
@@ -833,14 +835,24 @@ update_configuration() {
833835
env -i ACTION="config-applied" /sbin/hotplug-call openwisp
834836
# store the new checksum as last known checksum
835837
cp "$CONFIGURATION_CHECKSUM" "$PERSISTENT_CHECKSUM"
836-
retry_with_backoff report_status "applied"
838+
status_to_report="applied"
837839
else
838-
retry_with_backoff report_status "error"
840+
status_to_report="error"
839841
fi
840-
# if reporting of the status fails, let it retry in the next cycle
842+
843+
# Persist the pending status BEFORE calling report_status so that a
844+
# crash or reboot between the retry attempt and success does not lose
845+
# the status. The marker is removed only after report_status succeeds.
846+
printf '%s\n' "$status_to_report" >"$PENDING_REPORT"
847+
848+
retry_with_backoff report_status "$status_to_report"
841849
# shellcheck disable=SC2181
842-
if [ "$?" -ne "0" ]; then
843-
rm -f $CONFIGURATION_CHECKSUM $PERSISTENT_CHECKSUM
850+
if [ "$?" -eq "0" ]; then
851+
rm -f "$PENDING_REPORT"
852+
else
853+
logger -s "report_status failed, will retry in the next cycle" \
854+
-t openwisp \
855+
-p daemon.warning
844856
fi
845857

846858
rm $APPLYING_CONF
@@ -977,6 +989,35 @@ else
977989
env -i ACTION="restart" /sbin/hotplug-call openwisp
978990
fi
979991

992+
retry_pending_report() {
993+
local pending_status
994+
if [ ! -f "$PENDING_REPORT" ]; then
995+
return 0
996+
fi
997+
# Trim whitespace to tolerate an occasional trailing newline.
998+
pending_status=$(tr -d '[:space:]' <"$PENDING_REPORT")
999+
# Validate against the same known-good set accepted by report_status.
1000+
# update_configuration() only ever writes "applied" or "error" today.
1001+
case "$pending_status" in
1002+
applied | error) ;;
1003+
*)
1004+
logger -s "Pending report marker has invalid status '$pending_status', discarding" \
1005+
-t openwisp \
1006+
-p daemon.err
1007+
rm -f "$PENDING_REPORT"
1008+
return 1
1009+
;;
1010+
esac
1011+
logger "Retrying pending report_status: $pending_status" \
1012+
-t openwisp \
1013+
-p daemon.info
1014+
retry_with_backoff report_status "$pending_status"
1015+
# shellcheck disable=SC2181
1016+
if [ "$?" -eq "0" ]; then
1017+
rm -f "$PENDING_REPORT"
1018+
fi
1019+
}
1020+
9801021
while true; do
9811022
# check management interface at each iteration
9821023
# (because the address may change due to
@@ -987,6 +1028,11 @@ while true; do
9871028

9881029
if [ "$?" -eq "1" ]; then
9891030
update_configuration
1031+
elif [ -f "$PENDING_REPORT" ]; then
1032+
# Retry a previously failed report_status without re-downloading.
1033+
# This handles the case where the config was applied successfully
1034+
# but report_status failed due to a transient server error.
1035+
retry_pending_report
9901036
fi
9911037
env -i ACTION="end-of-cycle" /sbin/hotplug-call openwisp
9921038

0 commit comments

Comments
 (0)