From ab966a368c364304ffa5c4622f1ce5fe8fa5de8f Mon Sep 17 00:00:00 2001 From: gord_chen Date: Thu, 6 Aug 2026 10:21:55 +0800 Subject: [PATCH] [ZTP] Add __ztp_profile_loaded guard to __discoverOnly() __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 --- src/usr/lib/ztp/ztp-engine.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/usr/lib/ztp/ztp-engine.py b/src/usr/lib/ztp/ztp-engine.py index 765ea03..b42a540 100755 --- a/src/usr/lib/ztp/ztp-engine.py +++ b/src/usr/lib/ztp/ztp-engine.py @@ -306,13 +306,29 @@ def __loadZTPProfile(self, event): return False def __discoverOnly(self): + '''! + Prepare the system for ZTP discovery when a saved configuration is being + used (use_config_db). This is a one time setup, mirroring the behavior of + __loadZTPProfile(). + + ztp-profile.sh discoverOnly restarts rsyslog and interfaces-config. Without + the __ztp_profile_loaded guard it is re-executed on every iteration of the + discovery loop (discovery-interval, 10s by default), which repeatedly tears + down in-band interfaces and their DHCP clients. + + @return False - If discovery setup was already performed + True - If discovery setup was performed + ''' # Do not attempt to install ZTP configuration if working in unit test mode if self.test_mode: return False - cmd = getCfg('ztp-lib-dir')+'/ztp-profile.sh discoverOnly' - rc = runCommand(cmd, capture_stdout=False) - return True + if self.__ztp_profile_loaded is False: + cmd = getCfg('ztp-lib-dir')+'/ztp-profile.sh discoverOnly' + rc = runCommand(cmd, capture_stdout=False) + self.__ztp_profile_loaded = True + return True + return False def __createProvScriptJson(self): '''!