Skip to content

Commit

Permalink
[featured] Add support for dhcp_server in featured
Browse files Browse the repository at this point in the history
  • Loading branch information
yaqiangz committed Nov 16, 2023
1 parent 586b1e9 commit ead4919
Show file tree
Hide file tree
Showing 3 changed files with 203 additions and 4 deletions.
44 changes: 41 additions & 3 deletions scripts/featured
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,48 @@ DEFAULT_SELECT_TIMEOUT = 1000 # 1sec
PORT_INIT_TIMEOUT_SEC = 180


def run_cmd(cmd, log_err=True, raise_exception=False):
def run_cmd(cmd, log_err=True, raise_exception=False, return_res=False):
try:
subprocess.check_call(cmd)
if return_res:
return 0, subprocess.check_output(cmd, universal_newlines=True)
else:
subprocess.check_call(cmd)
except Exception as err:
if log_err:
syslog.syslog(syslog.LOG_ERR, "{} - failed: return code - {}, output:\n{}"
.format(err.cmd, err.returncode, err.output))
if raise_exception:
raise
if return_res:
return err.returncode, str("Encouter error: {}".format(err.output))


def is_service_enabled(service_name):
"""
Check whether service is enabled
Args:
service_name: Name of service to be checked
Returns:
If service is enabled, return True. Else return False
"""
state, output = run_cmd(["systemctl", "is-enabled", service_name], return_res=True)
return state == 0 and output.strip() == "enabled"


def restart_service(service_name):
"""
Restart service by name
Args:
service_name: Name of service to be restarted
"""
if is_service_enabled(service_name):
syslog.syslog(syslog.LOG_INFO, "Restarting {}".format(service_name))
run_cmd(["sudo", "systemctl", "stop", service_name])
run_cmd(["sudo", "systemctl", "reset-failed", service_name])
run_cmd(["sudo", "systemctl", "start", service_name], raise_exception=True)
syslog.syslog(syslog.LOG_INFO, "{} restarted successfully".format(service_name))
else:
syslog.syslog(syslog.LOG_ERR, "Cannot restart {} because it's not enabled".format(service_name))


def signal_handler(sig, frame):
Expand Down Expand Up @@ -414,7 +447,9 @@ class FeatureHandler(object):
.format(feature.name, feature_suffixes[-1]))
self.set_feature_state(feature, self.FEATURE_STATE_FAILED)
return

if feature_name == "dhcp_server":
# For dhcp_server feature change, we need to restart dhcp_relay container too
restart_service("dhcp_relay")
self.set_feature_state(feature, self.FEATURE_STATE_ENABLED)

def disable_feature(self, feature):
Expand All @@ -438,6 +473,9 @@ class FeatureHandler(object):
.format(feature.name, feature_suffixes[-1]))
self.set_feature_state(feature, self.FEATURE_STATE_FAILED)
return
if feature.name == "dhcp_server":
# For dhcp_server feature change, we need to restart dhcp_relay container too
restart_service("dhcp_relay")

self.set_feature_state(feature, self.FEATURE_STATE_DISABLED)

Expand Down
5 changes: 4 additions & 1 deletion tests/featured/featured_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,11 +203,14 @@ def test_handler(self, test_scenario_name, config_data, fs):
with mock.patch('featured.subprocess') as mocked_subprocess:
with mock.patch("sonic_py_common.device_info.get_device_runtime_metadata", return_value=config_data['device_runtime_metadata']):
with mock.patch("sonic_py_common.device_info.is_multi_npu", return_value=True if 'num_npu' in config_data else False):
with mock.patch("sonic_py_common.device_info.get_num_npus", return_value=config_data['num_npu'] if 'num_npu' in config_data else 1):
with mock.patch("sonic_py_common.device_info.get_num_npus", return_value=config_data['num_npu'] if 'num_npu' in config_data else 1), \
mock.patch("featured.is_service_enabled") as mock_is_service_enabled:
popen_mock = mock.Mock()
attrs = config_data['popen_attributes']
popen_mock.configure_mock(**attrs)
mocked_subprocess.Popen.return_value = popen_mock
if "is_service_enabled_side_effict" in config_data:
mock_is_service_enabled.side_effect = config_data["is_service_enabled_side_effict"]

device_config = {}
device_config['DEVICE_METADATA'] = MockConfigDb.CONFIG_DB['DEVICE_METADATA']
Expand Down
158 changes: 158 additions & 0 deletions tests/featured/test_vectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,164 @@
},
},
],
[
"SingleToRCase_DHCP_Server_Enabled",
{
"device_runtime_metadata": {
"DEVICE_RUNTIME_METADATA": {
"ETHERNET_PORTS_PRESENT": True
}
},
"config_db": {
"DEVICE_METADATA": {
"localhost": {
"type": "ToR",
}
},
"FEATURE": {
"dhcp_server": {
"auto_restart": "enabled",
"has_global_scope": "True",
"has_per_asic_scope": "False",
"delayed": "False",
"high_mem_alert": "disabled",
"set_owner": "local",
"state": "enabled"
}
},
},
"expected_config_db": {
"FEATURE": {
"dhcp_server": {
"auto_restart": "enabled",
"has_global_scope": "True",
"has_per_asic_scope": "False",
"delayed": "False",
"high_mem_alert": "disabled",
"set_owner": "local",
"state": "enabled"
}
},
},
"enable_feature_subprocess_calls": [
call(["sudo", "systemctl", "unmask", "dhcp_server.service"]),
call(["sudo", "systemctl", "enable", "dhcp_server.service"]),
call(["sudo", "systemctl", "start", "dhcp_server.service"])
],
"daemon_reload_subprocess_call": [
call(["sudo", "systemctl", "daemon-reload"]),
],
"popen_attributes": {
'communicate.return_value': ('output', 'error')
},
"is_service_enabled_side_effict": [True]
},
],
[
"SingleToRCase_DHCP_Server_Enabled_Dhcp_Relay_Disabled",
{
"device_runtime_metadata": {
"DEVICE_RUNTIME_METADATA": {
"ETHERNET_PORTS_PRESENT": True
}
},
"config_db": {
"DEVICE_METADATA": {
"localhost": {
"type": "ToR",
}
},
"FEATURE": {
"dhcp_server": {
"auto_restart": "enabled",
"has_global_scope": "True",
"has_per_asic_scope": "False",
"delayed": "False",
"high_mem_alert": "disabled",
"set_owner": "local",
"state": "enabled"
}
},
},
"expected_config_db": {
"FEATURE": {
"dhcp_server": {
"auto_restart": "enabled",
"has_global_scope": "True",
"has_per_asic_scope": "False",
"delayed": "False",
"high_mem_alert": "disabled",
"set_owner": "local",
"state": "enabled"
}
},
},
"enable_feature_subprocess_calls": [
call(["sudo", "systemctl", "unmask", "dhcp_server.service"]),
call(["sudo", "systemctl", "enable", "dhcp_server.service"]),
call(["sudo", "systemctl", "start", "dhcp_server.service"])
],
"daemon_reload_subprocess_call": [
call(["sudo", "systemctl", "daemon-reload"]),
],
"popen_attributes": {
'communicate.return_value': ('output', 'error')
},
"is_service_enabled_side_effict": [False]
},
],
[
"SingleToRCase_DHCP_Server_Disabled",
{
"device_runtime_metadata": {
"DEVICE_RUNTIME_METADATA": {
"ETHERNET_PORTS_PRESENT": True
}
},
"config_db": {
"DEVICE_METADATA": {
"localhost": {
"type": "ToR",
}
},
"FEATURE": {
"dhcp_server": {
"auto_restart": "enabled",
"has_global_scope": "True",
"has_per_asic_scope": "False",
"delayed": "False",
"high_mem_alert": "disabled",
"set_owner": "local",
"state": "disabled"
}
},
},
"expected_config_db": {
"FEATURE": {
"dhcp_server": {
"auto_restart": "enabled",
"has_global_scope": "True",
"has_per_asic_scope": "False",
"delayed": "False",
"high_mem_alert": "disabled",
"set_owner": "local",
"state": "disabled"
}
},
},
"enable_feature_subprocess_calls": [
call(["sudo", "systemctl", "stop", "dhcp_server.service"]),
call(["sudo", "systemctl", "disable", "dhcp_server.service"]),
call(["sudo", "systemctl", "mask", "dhcp_server.service"])
],
"daemon_reload_subprocess_call": [
call(["sudo", "systemctl", "daemon-reload"]),
],
"popen_attributes": {
'communicate.return_value': ('output', 'error')
},
},
],
[
"DualTorCaseWithNoSystemCalls",
{
Expand Down

0 comments on commit ead4919

Please sign in to comment.