-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Enhanced Feature Table state enable/disable for multi-asic platforms. #5358
Changes from 4 commits
f74afe2
2364973
524eb46
383aecd
75fa914
084e4ab
855658f
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 |
---|---|---|
|
@@ -10,6 +10,7 @@ import copy | |
import jinja2 | ||
import ipaddr as ipaddress | ||
from swsssdk import ConfigDBConnector | ||
from sonic_py_common import device_info | ||
|
||
# FILE | ||
PAM_AUTH_CONF = "/etc/pam.d/common-auth-sonic" | ||
|
@@ -42,45 +43,6 @@ def obfuscate(data): | |
return data | ||
|
||
|
||
def update_feature_state(feature_name, state, has_timer): | ||
feature_suffixes = ["service"] + (["timer"] if ast.literal_eval(has_timer) else []) | ||
if state == "enabled": | ||
start_cmds = [] | ||
for suffix in feature_suffixes: | ||
start_cmds.append("sudo systemctl unmask {}.{}".format(feature_name, suffix)) | ||
# If feature has timer associated with it, start/enable corresponding systemd .timer unit | ||
# otherwise, start/enable corresponding systemd .service unit | ||
start_cmds.append("sudo systemctl enable {}.{}".format(feature_name, feature_suffixes[-1])) | ||
start_cmds.append("sudo systemctl start {}.{}".format(feature_name, feature_suffixes[-1])) | ||
for cmd in start_cmds: | ||
syslog.syslog(syslog.LOG_INFO, "Running cmd: '{}'".format(cmd)) | ||
try: | ||
subprocess.check_call(cmd, shell=True) | ||
except subprocess.CalledProcessError as err: | ||
syslog.syslog(syslog.LOG_ERR, "'{}' failed. RC: {}, output: {}" | ||
.format(err.cmd, err.returncode, err.output)) | ||
continue | ||
syslog.syslog(syslog.LOG_INFO, "Feature '{}.{}' is enabled and started" | ||
.format(feature_name, feature_suffixes[-1])) | ||
elif state == "disabled": | ||
stop_cmds = [] | ||
for suffix in reversed(feature_suffixes): | ||
stop_cmds.append("sudo systemctl stop {}.{}".format(feature_name, suffix)) | ||
stop_cmds.append("sudo systemctl disable {}.{}".format(feature_name, suffix)) | ||
stop_cmds.append("sudo systemctl mask {}.{}".format(feature_name, suffix)) | ||
for cmd in stop_cmds: | ||
syslog.syslog(syslog.LOG_INFO, "Running cmd: '{}'".format(cmd)) | ||
try: | ||
subprocess.check_call(cmd, shell=True) | ||
except subprocess.CalledProcessError as err: | ||
syslog.syslog(syslog.LOG_ERR, "'{}' failed. RC: {}, output: {}" | ||
.format(err.cmd, err.returncode, err.output)) | ||
continue | ||
syslog.syslog(syslog.LOG_INFO, "Feature '{}' is stopped and disabled".format(feature_name)) | ||
else: | ||
syslog.syslog(syslog.LOG_ERR, "Unexpected state value '{}' for feature '{}'" | ||
.format(state, feature_name)) | ||
|
||
|
||
class Iptables(object): | ||
def __init__(self): | ||
|
@@ -280,6 +242,65 @@ class HostConfigDaemon: | |
self.iptables = Iptables() | ||
self.iptables.load(lpbk_table) | ||
|
||
def update_feature_state(self, feature_name, state, feature_table): | ||
has_timer = ast.literal_eval(feature_table[feature_name]['has_timer']) | ||
has_global_scope = ast.literal_eval(feature_table[feature_name]['has_global_scope']) | ||
has_per_asic_scope = ast.literal_eval(feature_table[feature_name]['has_per_asic_scope']) | ||
|
||
# Create feature name suffix depending feature is running in host or namespace or in both | ||
feature_name_suffix_list = (([feature_name] if has_global_scope or not device_info.is_multi_npu() else []) + | ||
([(feature_name + '@' + str(asic_inst)) for asic_inst in range(device_info.get_num_npus()) | ||
if has_per_asic_scope and device_info.is_multi_npu()])) | ||
|
||
if not feature_name_suffix_list: | ||
syslog.syslog(syslog.LOG_ERR, "Feature '{}' service not available" | ||
.format(feature_name)) | ||
|
||
feature_suffixes = ["service"] + (["timer"] if has_timer else []) | ||
|
||
if state == "enabled": | ||
start_cmds = [] | ||
for feature_name_suffix in feature_name_suffix_list: | ||
for suffix in feature_suffixes: | ||
start_cmds.append("sudo systemctl unmask {}.{}".format(feature_name_suffix, suffix)) | ||
Comment on lines
+265
to
+266
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. That's great work. I know it merged already, but wanted to follow up the story here if we have plan to support enabling/disabling services for particular asics in system? More specifically, says there are 2 asics in system, we want to disable lldp on asic 1, but not asic 2. I imagine that to do that, we need (1) Create entry like Or (2) Create |
||
# If feature has timer associated with it, start/enable corresponding systemd .timer unit | ||
# otherwise, start/enable corresponding systemd .service unit | ||
start_cmds.append("sudo systemctl enable {}.{}".format(feature_name_suffix, feature_suffixes[-1])) | ||
start_cmds.append("sudo systemctl start {}.{}".format(feature_name_suffix, feature_suffixes[-1])) | ||
for cmd in start_cmds: | ||
syslog.syslog(syslog.LOG_INFO, "Running cmd: '{}'".format(cmd)) | ||
try: | ||
subprocess.check_call(cmd, shell=True) | ||
except subprocess.CalledProcessError as err: | ||
syslog.syslog(syslog.LOG_ERR, "'{}' failed. RC: {}, output: {}" | ||
.format(err.cmd, err.returncode, err.output)) | ||
syslog.syslog(syslog.LOG_ERR, "Feature '{}.{}' failed to be enabled and started" | ||
.format(feature_name, feature_suffixes[-1])) | ||
return | ||
syslog.syslog(syslog.LOG_INFO, "Feature '{}.{}' is enabled and started" | ||
.format(feature_name, feature_suffixes[-1])) | ||
elif state == "disabled": | ||
stop_cmds = [] | ||
for feature_name_suffix in feature_name_suffix_list: | ||
for suffix in reversed(feature_suffixes): | ||
stop_cmds.append("sudo systemctl stop {}.{}".format(feature_name_suffix, suffix)) | ||
stop_cmds.append("sudo systemctl disable {}.{}".format(feature_name_suffix, suffix)) | ||
stop_cmds.append("sudo systemctl mask {}.{}".format(feature_name_suffix, suffix)) | ||
for cmd in stop_cmds: | ||
syslog.syslog(syslog.LOG_INFO, "Running cmd: '{}'".format(cmd)) | ||
try: | ||
subprocess.check_call(cmd, shell=True) | ||
except subprocess.CalledProcessError as err: | ||
syslog.syslog(syslog.LOG_ERR, "'{}' failed. RC: {}, output: {}" | ||
.format(err.cmd, err.returncode, err.output)) | ||
syslog.syslog(syslog.LOG_ERR, "Feature '{}' failed to be stopped and disabled".format(feature_name)) | ||
return | ||
syslog.syslog(syslog.LOG_INFO, "Feature '{}' is stopped and disabled".format(feature_name)) | ||
else: | ||
syslog.syslog(syslog.LOG_ERR, "Unexpected state value '{}' for feature '{}'" | ||
.format(state, feature_name)) | ||
|
||
|
||
def update_all_feature_states(self): | ||
feature_table = self.config_db.get_table('FEATURE') | ||
for feature_name in feature_table.keys(): | ||
|
@@ -292,7 +313,7 @@ class HostConfigDaemon: | |
syslog.syslog(syslog.LOG_WARNING, "Eanble state of feature '{}' is None".format(feature_name)) | ||
continue | ||
|
||
update_feature_state(feature_name, state, feature_table[feature_name]['has_timer']) | ||
self.update_feature_state(feature_name, state, feature_table) | ||
|
||
def aaa_handler(self, key, data): | ||
self.aaacfg.aaa_update(key, data) | ||
|
@@ -334,7 +355,7 @@ class HostConfigDaemon: | |
syslog.syslog(syslog.LOG_WARNING, "Enable state of feature '{}' is None".format(feature_name)) | ||
return | ||
|
||
update_feature_state(feature_name, state, feature_table[feature_name]['has_timer']) | ||
self.update_feature_state(feature_name, state, feature_table) | ||
|
||
def start(self): | ||
# Update all feature states once upon starting | ||
|
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.
can we make is_multi_npu() a class member?
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.
@tahmed-dev Done