From 596e5dc33f0d3f15a3a7deec27c7b22b4b258e5f Mon Sep 17 00:00:00 2001 From: peter_yu Date: Tue, 23 Apr 2024 08:54:18 +0000 Subject: [PATCH] [ZTP] Use config db instead of ZTP configuration profile By adding USE_DEFAULT_CONFIG="no" in /etc/default/ztp, it won't generate /tmp/ztp_config_db.json, but using current redis config db during dhcp discovery. It will solve the breakout config reset to default mode issue. == [ZTP] Use config db for connectivity when process ZTP Json When process ztp json, it will call loadZTPProfile("resume"), which will also reset breakout config default mode. Skip it when use_config_db. --- src/etc/default/ztp | 3 ++ src/usr/lib/ztp/sonic-ztp | 6 +++- src/usr/lib/ztp/ztp-engine.py | 66 ++++++++++++++++++++++------------ src/usr/lib/ztp/ztp-profile.sh | 28 +++++++++++++++ 4 files changed, 80 insertions(+), 23 deletions(-) diff --git a/src/etc/default/ztp b/src/etc/default/ztp index 0089c16..621e668 100644 --- a/src/etc/default/ztp +++ b/src/etc/default/ztp @@ -18,3 +18,6 @@ COVERAGE="" # Change below to provide command coverage.py tool. # (python3-coverage run --append is used if not specified) COVERAGE_CMD="" + +# Use ZTP configuration profile (default) or config_db +USE_DEFAULT_CONFIG="yes" diff --git a/src/usr/lib/ztp/sonic-ztp b/src/usr/lib/ztp/sonic-ztp index 5239d94..39cdc35 100755 --- a/src/usr/lib/ztp/sonic-ztp +++ b/src/usr/lib/ztp/sonic-ztp @@ -37,6 +37,10 @@ start() # Custom ztp_cfg.json file [ "${CONFIG_JSON}" != "" ] && CONFIG_JSON_ARGS="-C ${CONFIG_JSON}" + # Use ZTP configuration profile (default) or config_db + [ "${USE_DEFAULT_CONFIG}" = "no" ] && CONFIG_DB_ARGS="-o" + + if [ "${COVERAGE}" = "yes" ]; then if which python3-coverage > /dev/null; then [ "${COVERAGE_CMD}" = "" ] && COVERAGE_EXP="python3-coverage run --append" @@ -49,7 +53,7 @@ start() fi # Kickstart ZTP service daemon - ${COVERAGE_EXP} ${ZTP_ENGINE} ${DEBUG_ARGS} ${TEST_ARGS} ${CONFIG_JSON_ARGS} & + ${COVERAGE_EXP} ${ZTP_ENGINE} ${DEBUG_ARGS} ${TEST_ARGS} ${CONFIG_JSON_ARGS} ${CONFIG_DB_ARGS}& ztp_engine_pid=$! wait "$ztp_engine_pid" diff --git a/src/usr/lib/ztp/ztp-engine.py b/src/usr/lib/ztp/ztp-engine.py index 3edd5e1..765ea03 100755 --- a/src/usr/lib/ztp/ztp-engine.py +++ b/src/usr/lib/ztp/ztp-engine.py @@ -202,7 +202,7 @@ def __is_ztp_profile_active(self): profile_active = True return profile_active - def __link_scan(self): + def __link_scan(self, use_config_db): '''! Scan all in-band interface's operational status to detect a link up event @return False - If a link scan did not detect at least one switch port link up event @@ -217,15 +217,17 @@ def __link_scan(self): self.__link_scan_enabled = None return False - if self.__link_scan_enabled is None: - # Check if ZTP configuration is active - if self.__is_ztp_profile_active(): - self.__link_scan_enabled = 'True' - else: - self.__link_scan_enabled = 'False' + if (not use_config_db) : - if self.__link_scan_enabled == 'False': - return False + if self.__link_scan_enabled is None: + # Check if ZTP configuration is active + if self.__is_ztp_profile_active(): + self.__link_scan_enabled = 'True' + else: + self.__link_scan_enabled = 'False' + + if self.__link_scan_enabled == 'False': + return False # Populate data of all ztp eligible interfaces link_scan_result = self.__detect_intf_state() @@ -303,6 +305,15 @@ def __loadZTPProfile(self, event): return True return False + def __discoverOnly(self): + # 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 + def __createProvScriptJson(self): '''! Create ZTP JSON data to execute provisioning script specified by DHCP Option 239 URL. @@ -545,7 +556,7 @@ def __processConfigSections(self): # Check reboot on result flags self.__rebootAction(section) - def __processZTPJson(self): + def __processZTPJson(self, use_config_db): '''! Process ZTP JSON file downloaded using URL provided by DHCP Option 67, DHCPv6 Option 59 or local ZTP JSON file. @@ -601,8 +612,9 @@ def __processZTPJson(self): logger.info('Starting ZTP using JSON file %s at %s.' % (self.json_src, self.objztpJson['timestamp'])) - # Initialize connectivity if not done already - self.__loadZTPProfile("resume") + if (not use_config_db): + # Initialize connectivity if not done already + self.__loadZTPProfile("resume") # Process available configuration sections in ZTP JSON self.__processConfigSections() @@ -795,11 +807,12 @@ def __forceRestartDiscovery(self, msg): # Restart link-scan self.__intf_state = dict() - def executeLoop(self, test_mode=False): + def executeLoop(self, test_mode=False, use_config_db = False): '''! ZTP service loop which peforms provisioning data discovery and initiates processing. ''' - + if (use_config_db == True): + logger.info('use config db...') updateActivity('Initializing') # Set testing mode @@ -838,26 +851,29 @@ def executeLoop(self, test_mode=False): logger.debug(' ' + str(l[3])) self.__forceRestartDiscovery("Invalid provisioning data received") continue - + if result: if self.ztp_mode == 'MANUAL_CONFIG': logger.info("Configuration file '%s' detected. Shutting down ZTP service." % (getCfg('config-db-json'))) break elif self.ztp_mode != 'DISCOVERY': - (rv, msg) = self.__processZTPJson() + (rv, msg) = self.__processZTPJson(use_config_db) if rv == "retry": self.ztp_mode = 'DISCOVERY' elif rv == "restart": self.__forceRestartDiscovery(msg) else: break - - # Initialize in-band interfaces to establish connectivity if not done already - self.__loadZTPProfile("discovery") - logger.debug('Provisioning data not found.') + if (not use_config_db): + # Initialize in-band interfaces to establish connectivity if not done already + self.__loadZTPProfile("discovery") + logger.debug('Provisioning data not found.') + else: + logger.debug('calling __discoverOnly...') + self.__discoverOnly() # Scan for inband interfaces to link up and restart interface connectivity - if self.__link_scan(): + if self.__link_scan(use_config_db): updateActivity('Restarting network discovery after link scan') logger.info('Restarting network discovery after link scan.') runCommand('systemctl restart interfaces-config', capture_stdout=False) @@ -905,6 +921,7 @@ def main(): parser.add_argument("-d", "--debug", action="store_true", help="Turn on debug level logging") parser.add_argument("-t", "--test", action="store_true", default=False, help="Start service in test mode with restricted functionality") parser.add_argument("-C", "--config-json", metavar='FILE', default=None, help="ZTP service configuration file") + parser.add_argument("-o", "--use-config-db", action="store_true", default=False, help="Use current config_db, don't install ztp_config") # Parse provided arguments options = parser.parse_args() @@ -920,6 +937,11 @@ def main(): else: _test_mode = False + if options.use_config_db: + _use_config_db = True + else: + _use_config_db = False + # Parse user provided configuration file cfg_json = options.config_json @@ -967,7 +989,7 @@ def main(): objEngine = ZTPEngine() # Run ZTP service to completion - objEngine.executeLoop(_test_mode) + objEngine.executeLoop(_test_mode, _use_config_db) sys.exit(0) diff --git a/src/usr/lib/ztp/ztp-profile.sh b/src/usr/lib/ztp/ztp-profile.sh index d8afbe8..c447389 100755 --- a/src/usr/lib/ztp/ztp-profile.sh +++ b/src/usr/lib/ztp/ztp-profile.sh @@ -229,6 +229,34 @@ if [ "$CMD" = "install" ] ; then fi fi +if [ "$CMD" = "discoverOnly" ] ; then + echo "System is discoverOnly" + # setup rsyslog forwarding + touch ${SYSLOG_CONF_FILE} + if [ "$(get_feature console-logging)" = "true" ]; then + echo ":programname, contains, \"sonic-ztp\" /dev/console" > ${SYSLOG_CONSOLE_CONF_FILE} + fi + systemctl restart rsyslog + + #setup db + sonic-db-cli CONFIG_DB HSET "ZTP|mode" "inband" "true" + sonic-db-cli CONFIG_DB HSET "ZTP|mode" "out-of-band" "true" + sonic-db-cli CONFIG_DB HSET "ZTP|mode" "ipv4" "true" + sonic-db-cli CONFIG_DB HSET "ZTP|mode" "ipv6" "true" + + ln -sf /usr/lib/ztp/dhcp/ztp-rsyslog /etc/dhcp/dhclient-exit-hooks.d/ztp-rsyslog + echo "Initiating ZTP discovery." + + + # Install DHCP policy for interfaces participating in ZTP + dhcp_policy_create + echo "Restarting network configuration." + updateActivity "Restarting network configuration" + systemctl restart interfaces-config + echo "Restarted network configuration." + +fi + # Process ZTP profile remove request if [ "$CMD" = "remove" ] ; then