Newansage v0.4.0 is out
Guides / Upgrades without dropping routes

Upgrades without dropping routes

Replace the binary while neighbors keep forwarding to you, with Graceful Restart.

With graceful_restart = true (off by default; restart_time, default 30 s, also per neighbor), ansage and its neighbors use Graceful Restart (RFC 4724) with the N bit (RFC 8538). How ansage goes away then decides what the neighbors do with our routes:

Eventansage sendsNeighbors
ansage upgradeCease 6/2 "ansage restarting" (N bit) or nothingkeep our routes as stale, then refresh them
systemctl stop / SIGTERM, peer disableHard Reset (N bit) or Cease (after drain_time)withdraw at once
ansage panicsHard Reset / Cease from the panic hookwithdraw at once
kill -9, OOM killnothingkeep the routes for restart_time

Deploying a new binary

ansage upgrade --dry-run                  # per neighbor: keeps or withdraws our routes
install -m 0755 ansage /usr/local/bin/ansage.new
mv -f /usr/local/bin/ansage.new /usr/local/bin/ansage   # atomic; the running one is unaffected
ansage upgrade --binary /usr/local/bin/ansage || rollback

ansage upgrade checks the binary (--version, check against the running config) before anything happens. It refuses if an Established neighbor has no graceful restart (it would withdraw) or if nothing would start ansage again (not under systemd), unless --force.

Then it exits ansage with status 75, which the unit restarts at once, and waits until every neighbor is back with our full table. It exits 0 only then, so a deploy script can roll back.

A deploy script with rollback

deploy-ansage.sh
#!/bin/sh
set -eu
new=$1                                     # the new binary
bin=/usr/local/bin/ansage

ansage upgrade --dry-run
cp -p "$bin" "$bin.prev"
install -m 0755 "$new" "$bin.new" && mv -f "$bin.new" "$bin"

if ! ansage upgrade --binary "$bin"; then
    echo "upgrade failed, rolling back" >&2
    mv -f "$bin.prev" "$bin"
    systemctl restart ansage
    exit 1
fi
rm -f "$bin.prev"
ansage show summary

ansage upgrade checks the new binary before it stops anything, so a binary that does not run or rejects the config leaves the old ansage running.

Enable Graceful Restart

graceful_restart = true
restart_time = 60          # neighbors keep our routes this long (1 to 4095 s)

[[neighbor]]
address = "10.0.0.1"
asn = 64501
# graceful_restart = false   # per neighbor, e.g. for a router that cannot do it

The router has to support it as well, see Router configs. ansage show peer and ansage_peer_graceful_restart show whether it was negotiated.

Esc to close