Skip to content

[ZTP] Add __ztp_profile_loaded guard to __discoverOnly() - #5

Open
gord1306 wants to merge 1 commit into
202311.X_4630_10g_prodfrom
fix/ztp-discoveronly-guard-hardening
Open

[ZTP] Add __ztp_profile_loaded guard to __discoverOnly()#5
gord1306 wants to merge 1 commit into
202311.X_4630_10g_prodfrom
fix/ztp-discoveronly-guard-hardening

Conversation

@gord1306

@gord1306 gord1306 commented Aug 6, 2026

Copy link
Copy Markdown

Why I did it

__discoverOnly() has no __ztp_profile_loaded guard, unlike the otherwise equivalent __loadZTPProfile(). In ZTPEngine.executeLoop() the discovery loop picks one of the two depending on use_config_db:

883| if (not use_config_db):
884|     self.__loadZTPProfile("discovery")   # guarded, runs once
887| else:
888|     self.__discoverOnly()                # unguarded, runs every iteration

use_config_db comes from the -o / --use-config-db command line flag (ztp-engine.py:940). On that path __discoverOnly() is called on every iteration of the discovery loop (discovery-interval, 10 s by default), and ztp-profile.sh discoverOnly (ztp-profile.sh:232-258) unconditionally runs systemctl restart rsyslog and systemctl restart interfaces-config.

Purpose

Running ztp-engine.py -o therefore restarts networking roughly every 10 seconds for the whole discovery phase, repeatedly killing the DHCP clients and tearing down the in-band interfaces instead of setting them up once. Each interfaces-config restart drops the in-band netdevs, which breaks anything that runs on them.

Guard __discoverOnly() with __ztp_profile_loaded, mirroring __loadZTPProfile().

Possible concerns and why they do not apply

  • Does this break periodic re-discovery? No. executeLoop() still restarts networking every restart-ztp-interval (300 s default); that is an independent code path and is untouched.
  • Does discovery setup still happen after a forced restart? Yes. __forceRestartDiscovery() resets __ztp_profile_loaded to False, so the setup is redone, exactly as it is for __loadZTPProfile().
  • Do any side effects need to be repeated on every iteration? All six side effects of the discoverOnly branch were checked individually and are one-time and persistent: the rsyslog configuration file and systemctl restart rsyslog, the four static ZTP|mode CONFIG_DB fields, the rsyslog exit-hook symlink, dhcp_policy_create, and the interfaces-config restart. Performing them once is sufficient.
  • Can the two paths interfere through the shared flag? No. use_config_db is fixed for the lifetime of executeLoop(), decided once from the command line in main(), so the __loadZTPProfile() and __discoverOnly() paths are mutually exclusive.

How to verify it

Run ZTP discovery with -o / --use-config-db and count the networking restarts during the discovery phase:

grep -c "Finished Update interfaces configuration" /var/log/syslog

Before this change interfaces-config is restarted about every 10 seconds. After it, once during discovery setup, then only on the restart-ztp-interval cadence or after a forced restart.

Notes

  • No automated test coverage: every case in tests/test_ztp_engine.py exercises the __loadZTPProfile() path, so the existing tests are unaffected but this change is not covered by them. The test suite could not be executed in the environment used here (ztp / swsscommon not importable), so this change was verified by code inspection only.
  • This is a latent defect fix. The default path (use_config_db false) is unaffected.

__discoverOnly() has no __ztp_profile_loaded guard, unlike the otherwise
equivalent __loadZTPProfile(). In ZTPEngine.executeLoop() the discovery loop
calls __discoverOnly() on the use_config_db path on every iteration
(discovery-interval, 10s by default), and ztp-profile.sh discoverOnly
unconditionally runs "systemctl restart rsyslog" and
"systemctl restart interfaces-config".

Running ztp-engine.py with -o/--use-config-db therefore restarts networking
roughly every 10 seconds for the whole discovery phase, repeatedly killing the
DHCP clients and tearing down the in-band interfaces instead of setting them
up once.

Guard __discoverOnly() with __ztp_profile_loaded, mirroring
__loadZTPProfile(). Periodic re-discovery is unaffected: executeLoop() still
restarts networking every restart-ztp-interval (300s default) and
__forceRestartDiscovery() resets the flag so discovery setup is redone after a
forced restart.

All side effects of the discoverOnly branch (rsyslog configuration and
restart, the static ZTP|mode CONFIG_DB fields, the rsyslog exit-hook symlink,
dhcp_policy_create and the interfaces-config restart) are one time and
persistent, so performing them once is sufficient.

Signed-off-by: gord_chen <gord_chen@edge-core.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant