<#44 Retry failed osquery rollbacks, restart befor...
# osctrl
g
#44 Retry failed osquery rollbacks, restart before resuming a flags check, and restore old extensions when their state cannot be saved Pull request opened by javuto Problem • (High): a failed osquery rollback is recorded as complete.
rollbackUpgrade
logged and ignored a failed reinstall of the previous package, a failed snapshot restore and osqueryd not running, then cleared the pending state and deleted the stash. Later syncs could not retry, leaving an unconfirmed package or a stopped agent while status said the rollback finished. • (Medium): an interrupted flags update can be accepted without being loaded. If osctrld stopped between writing new flags and restarting osquery,
resumeFlagsCheck
verified without restarting, so the old osqueryd made the new flags look accepted. • (Medium): an extension state-save failure loses the rollback link. The old binary was moved aside and the new one installed before
Previous
was saved. If that save failed, a later failed check removed the new binary without restoring the old one. Change • Rollback: • Fails if the previous version is not installed afterwards, the snapshot cannot be loaded or restored, or osqueryd is not running. • A failure keeps
Pending
and the stash and returns an error, so
resumeUpgrade
retries on the next sync. • A reinstall error with the previous version already installed counts as success. • The new
RollbackAttempts
field is saved before each attempt. • After 3 attempts the target is recorded as
rejected
/
rollback_unavailable
. • Flags resume:
resumeFlagsCheck
restarts osquery before verifying. • Extensions: if saving the pending state fails, the previous files and autoload lines are restored right away and the step returns the error.
saveExtState
is now a test seam. • README: documents the rollback retry and cap, the restart on resume, and the extension restore. Security / operational impact • A host whose rollback keeps failing restarts osqueryd up to 3 times (once per sync) before reporting
rollback_unavailable
, instead of reporting a misleading
rejected
with the original reason. • A resumed flags check costs one extra osquery restart. • No new reason strings are sent to osctrl. Validation •
go test ./cmd/osctrld/ -race
passes •
golangci-lint run ./...
and `GOOS=windows golangci-lint run ./...`: 0 issues • New tests: •
TestUpgradeRollbackInstallErrorIsRetried
•
TestUpgradeRollbackGivesUpAfterMaxAttempts
•
TestResumeFlagsCheckRestartsBeforeAccepting
•
TestSyncExtensionsStateSaveFailureRestoresPrevious
(fails without the fix) • Existing rollback and resume tests updated to the new behaviour. • Not exercised against a real package manager or osctrl server. jmpsec/osctrld