-
Notifications
You must be signed in to change notification settings - Fork 117
Added code to start a new service to configure TSA as soon as Linecard comes up, start a timer to configure TSB and configure TSB when the timer expires #206
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| STARTUP_TSB_TIMER=900 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| [Unit] | ||
| Description= STARTUP TSA-TSB SERVICE | ||
| Requires=updategraph.service database.service | ||
| After=updategraph.service database.service | ||
| Before=bgp.service | ||
| ConditionPathExists=!/etc/sonic/chassisdb.conf | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what is need for this ?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. updategraph dependency is to start the tsa-tsb service after config is loaded and chassisdb.conf file check is to start the service only in IMM. |
||
|
|
||
| [Service] | ||
| Environment="STARTED_BY_TSA_TSB_SERVICE=1" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. after the service is stopped do we need to reset
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reset the env variable |
||
| ExecStart=/usr/bin/python3 -u /usr/local/bin/startup_tsa_tsb.py start | ||
| ExecStop=/usr/bin/python3 -u /usr/local/bin/startup_tsa_tsb.py stop | ||
| RemainAfterExit=yes | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what is the behavior of this services in case of config reload and if the swss docker restart ?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. config reload or swss restart doesn't restart the tsa service |
||
|
|
||
| [Install] | ||
| WantedBy=multi-user.target | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,156 @@ | ||
| #!/usr/bin/env python3 | ||
|
|
||
| # Name: startup_tsa_tsb.py, version: 1.0 | ||
| # | ||
| # Description: Module contains the definitions to the VOQ Startup TSA-TSB service | ||
| from sonic_py_common import multi_asic, device_info | ||
| from sonic_py_common.logger import Logger | ||
| import subprocess | ||
| import sys, getopt | ||
| from threading import Timer | ||
| import os | ||
|
|
||
| # Global Logger class instance | ||
| logger = Logger("startup_tsa_tsb") | ||
| logger.set_min_log_priority_info() | ||
|
|
||
| def get_tsb_timer_interval(): | ||
| platform = device_info.get_platform() | ||
| conf_file = '/usr/share/sonic/device/{}/startup-tsa-tsb.conf'.format(platform) | ||
| file = open(conf_file, 'r') | ||
| Lines = file.readlines() | ||
| for line in Lines: | ||
| field = line.split('=')[0].strip() | ||
| if field == "STARTUP_TSB_TIMER": | ||
| return line.split('=')[1].strip() | ||
| return 0 | ||
|
|
||
| def get_sonic_config(ns, config_name): | ||
| if ns == "": | ||
| return subprocess.check_output(['sonic-cfggen', '-d', '-v', config_name.replace('"', "'"), ]).strip() | ||
| else: | ||
| return subprocess.check_output(['sonic-cfggen', '-d', '-v', config_name.replace('"', "'"), '-n', ns.replace('"', "'")]).strip() | ||
|
|
||
| def get_sub_role(asic_ns): | ||
| sub_role_config = "DEVICE_METADATA['localhost']['sub_role']" | ||
| sub_role = (get_sonic_config(asic_ns, sub_role_config)).decode() | ||
| return sub_role | ||
|
|
||
| def get_tsa_config(asic_ns): | ||
| tsa_config = 'BGP_DEVICE_GLOBAL.STATE.tsa_enabled' | ||
| tsa_ena = (get_sonic_config(asic_ns, tsa_config)).decode() | ||
| if asic_ns == "": | ||
| logger.log_info('CONFIG_DB.{} : {}'.format(tsa_config, tsa_ena)) | ||
| else: | ||
| logger.log_info('{} - CONFIG_DB.{} : {}'.format(asic_ns, tsa_config, tsa_ena)) | ||
| return tsa_ena | ||
|
|
||
| def get_tsa_status(num_asics): | ||
| if num_asics > 1: | ||
| counter = 0 | ||
| for asic_id in range(int(asic_num)): | ||
| asic_ns = 'asic{}'.format(asic_id) | ||
| sub_role = get_sub_role(asic_ns) | ||
| if sub_role == 'FrontEnd': | ||
| tsa_enabled = get_tsa_config(asic_ns) | ||
| if tsa_enabled == 'false': | ||
| counter += 1 | ||
| if counter == int(asic_num): | ||
| return True; | ||
| else: | ||
| tsa_enabled = get_tsa_config("") | ||
| if tsa_enabled == 'false': | ||
| return True; | ||
| return False; | ||
|
|
||
| def config_tsa(): | ||
| num_asics = multi_asic.get_num_asics() | ||
| tsa_ena = get_tsa_status(num_asics) | ||
| if tsa_ena == True: | ||
| logger.log_info("Configuring TSA") | ||
| subprocess.check_output(['TSA']).strip() | ||
| else: | ||
| if num_asics > 1: | ||
| logger.log_info("Either TSA is already configured or switch sub_role is not Frontend - not configuring TSA") | ||
| else: | ||
| logger.log_info("Either TSA is already configured - not configuring TSA") | ||
| return tsa_ena | ||
|
|
||
| def config_tsb(): | ||
| logger.log_info("Configuring TSB") | ||
| subprocess.check_output(['TSB']).strip() | ||
| tsb_issued = True | ||
| return | ||
|
|
||
| def start_tsb_timer(interval): | ||
| global timer | ||
| logger.log_info("Starting timer with interval {} seconds to configure TSB".format(interval)) | ||
| timer = Timer(int(interval), config_tsb) | ||
| timer.start() | ||
| timer.join() | ||
| return | ||
|
|
||
| def print_usage(): | ||
| logger.log_info("Usage: startup_tsa_tsb.py [options] command") | ||
| logger.log_info("options:") | ||
| logger.log_info(" -h | --help : this help message") | ||
| logger.log_info("command:") | ||
| logger.log_info("start : start the TSA/TSB") | ||
| logger.log_info("stop : stop the TSA/TSB") | ||
| return | ||
|
|
||
| def reset_env_variables(): | ||
| logger.log_info("Resetting environment variable") | ||
| os.environ.pop('STARTED_BY_TSA_TSB_SERVICE') | ||
| return | ||
|
|
||
| def start_tsa_tsb(timer): | ||
| #Configure TSA if it was not configured already in CONFIG_DB | ||
| tsa_enabled = config_tsa() | ||
| if tsa_enabled == True: | ||
| #Start the timer to configure TSB | ||
| start_tsb_timer(timer) | ||
| return | ||
|
|
||
| def stop_tsa_tsb(): | ||
| reset_env_variables() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In case the user entered TSA/TSB command manually, shouldn't we explicitly stop/cancel timer thread which we started earlier in start_tsb_timer() ? Or does the systemd cleans it up during exit Here we just reset the env variables only.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will set the daemon flag for the Timer thread so that the thread will exit when the main thread is killed by the service stop
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @judyjoseph , i tested with prctl and the threads started by the main thread are stopped when the service is stopped and main python script is killed with SIGTERM. So we don't need to explicitly stop the timer. |
||
| return | ||
|
|
||
| def main(): | ||
| platform = device_info.get_platform() | ||
| conf_file = '/usr/share/sonic/device/{}/startup-tsa-tsb.conf'.format(platform) | ||
| #This check should be moved to service file or make this feature as configurable. | ||
| #Adding it here for now. | ||
| if not os.path.exists(conf_file): | ||
| logger.log_info("{} does not exist, exiting the service".format(conf_file)) | ||
| return | ||
| if len(sys.argv) <= 1: | ||
| print_usage() | ||
| return | ||
|
|
||
| # parse command line options: | ||
| try: | ||
| opts, args = getopt.getopt(sys.argv[1:], 'h:', ['help' ]) | ||
| except getopt.GetoptError: | ||
| print_usage() | ||
| return | ||
|
|
||
| for opt, arg in opts: | ||
| if opt in ("-h", "--help"): | ||
| print_usage() | ||
| return | ||
|
|
||
| for arg in args: | ||
| if arg == 'start': | ||
| tsb_timer = get_tsb_timer_interval() | ||
| start_tsa_tsb(tsb_timer) | ||
| elif arg == 'stop': | ||
| stop_tsa_tsb() | ||
| else: | ||
| print_usage() | ||
| return | ||
|
|
||
| return | ||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sure we are running this service before swss/syncd/teamd/bgp services comes up ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no dependency on these services right now. Ensure this service starts before bgp should be sufficient right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added "Before=bgp.service"