Skip to content
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

[dhcp_relay] Use dhcprelayd to manage critical processes #17236

Merged
merged 1 commit into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions dockers/docker-dhcp-relay/Dockerfile.j2
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,11 @@ ENV IMAGE_VERSION=$image_version
# Update apt's cache of available packages
RUN apt-get update

RUN apt-get install -y libjsoncpp-dev {%- if INCLUDE_DHCP_SERVER == "y" %}\
python3-dev \
build-essential{%- endif %}
RUN apt-get install -y libjsoncpp-dev \
python3-dev \
build-essential

{% if INCLUDE_DHCP_SERVER == "y" -%}
RUN pip3 install psutil
{%- endif %}

RUN apt-get install -y libjsoncpp-dev

Expand All @@ -40,10 +38,8 @@ RUN apt-get install -y libjsoncpp-dev
{% endif %}

# Clean up
{% if INCLUDE_DHCP_SERVER == "y" -%}
RUN apt-get remove -y build-essential \
python3-dev
{%- endif %}
RUN apt-get clean -y && \
apt-get autoclean -y && \
apt-get autoremove -y && \
Expand Down
10 changes: 1 addition & 9 deletions dockers/docker-dhcp-relay/dhcp-relay.programs.j2
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
[group:dhcp-relay]
programs=
programs=dhcprelayd,
{%- set relay_for_ipv6 = { 'flag': False } %}
{%- set add_preceding_comma = { 'flag': False } %}
{% if dhcp_server_ipv4_enabled %}
{% set _dummy = add_preceding_comma.update({'flag': True}) %}
dhcprelayd
{%- endif %}
{% for vlan_name in VLAN_INTERFACE %}
{# Append DHCPv4 agents #}
{% if not dhcp_server_ipv4_enabled and VLAN and vlan_name in VLAN and 'dhcp_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcp_servers']|length > 0 %}
{% if add_preceding_comma.flag %},{% endif %}
{% set _dummy = add_preceding_comma.update({'flag': True}) %}
isc-dhcpv4-relay-{{ vlan_name }}
{%- endif %}
{% if DHCP_RELAY and vlan_name in DHCP_RELAY and DHCP_RELAY[vlan_name]['dhcpv6_servers']|length > 0 %}
{% set _dummy = relay_for_ipv6.update({'flag': True}) %}
{%- endif %}
Expand Down
13 changes: 2 additions & 11 deletions dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ stderr_logfile=syslog
dependent_startup=true
dependent_startup_wait_for=rsyslogd:running

{% set dhcp_server_ipv4_enabled = False %}
{% if FEATURE and 'dhcp_server' in FEATURE and 'state' in FEATURE['dhcp_server'] and FEATURE['dhcp_server']['state'] == 'enabled' %}
{% set dhcp_server_ipv4_enabled = True %}
{% endif %}
{# If our configuration has VLANs... #}
{% if VLAN_INTERFACE %}
{# Count how many VLANs require a DHCP relay agent... #}
Expand All @@ -63,16 +59,14 @@ dependent_startup_wait_for=rsyslogd:running
{# Create a program entry for each DHCP relay agent instance #}
{% set relay_for_ipv4 = { 'flag': False } %}
{% set relay_for_ipv6 = { 'flag': False } %}
{% if not dhcp_server_ipv4_enabled %}
{% for vlan_name in VLAN_INTERFACE %}
{% include 'dhcpv4-relay.agents.j2' %}
{% endfor %}

{% endif %}
{% include 'dhcpv6-relay.agents.j2' %}
{% if not dhcp_server_ipv4_enabled %}
{% include 'dhcp-relay.monitors.j2' %}
{% else %}
{% endif %}
{% endif %}
[program:dhcprelayd]
command=/usr/local/bin/dhcprelayd
priority=3
Expand All @@ -82,6 +76,3 @@ stdout_logfile=syslog
stderr_logfile=syslog
dependent_startup=true
dependent_startup_wait_for=start:exited
{% endif %}
{% endif %}
{% endif %}
2 changes: 0 additions & 2 deletions rules/docker-dhcp-relay.mk
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ $(DOCKER_DHCP_RELAY)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_BULLSEYE)

$(DOCKER_DHCP_RELAY)_INSTALL_PYTHON_WHEELS = $(SONIC_UTILITIES_PY3)
$(DOCKER_DHCP_RELAY)_INSTALL_DEBS = $(PYTHON3_SWSSCOMMON)
ifeq ($(INCLUDE_DHCP_SERVER), y)
$(DOCKER_DHCP_RELAY)_PYTHON_WHEELS += $(SONIC_DHCP_SERVER_PY3)
endif

$(DOCKER_DHCP_RELAY)_VERSION = 1.0.0
$(DOCKER_DHCP_RELAY)_PACKAGE_NAME = dhcp-relay
Expand Down
2 changes: 0 additions & 2 deletions rules/sonic-dhcp-server.mk
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,4 @@ $(SONIC_DHCP_SERVER_PY3)_SRC_PATH = $(SRC_PATH)/sonic-dhcp-server
$(SONIC_DHCP_SERVER_PY3)_DEPENDS += $(SONIC_PY_COMMON_PY3)
$(SONIC_DHCP_SERVER_PY3)_DEBS_DEPENDS = $(LIBSWSSCOMMON) $(PYTHON3_SWSSCOMMON)
$(SONIC_DHCP_SERVER_PY3)_PYTHON_VERSION = 3
ifeq ($(INCLUDE_DHCP_SERVER), y)
SONIC_PYTHON_WHEELS += $(SONIC_DHCP_SERVER_PY3)
endif

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ dependent_startup=true
dependent_startup_wait_for=rsyslogd:running

[group:dhcp-relay]
programs=isc-dhcpv4-relay-Vlan1000,dhcp6relay
programs=dhcprelayd,dhcp6relay

[program:isc-dhcpv4-relay-Vlan1000]
command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id Vlan1000 -iu Vlan2000 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 -iu PortChannel01 192.0.0.1 192.0.0.2
Expand Down Expand Up @@ -76,4 +76,12 @@ stderr_logfile=syslog
dependent_startup=true
dependent_startup_wait_for=isc-dhcpv4-relay-Vlan1000:running


[program:dhcprelayd]
command=/usr/local/bin/dhcprelayd
priority=3
autostart=false
autorestart=false
stdout_logfile=syslog
stderr_logfile=syslog
dependent_startup=true
dependent_startup_wait_for=start:exited
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ dependent_startup=true
dependent_startup_wait_for=rsyslogd:running

[group:dhcp-relay]
programs=isc-dhcpv4-relay-Vlan1000,isc-dhcpv4-relay-Vlan2000,dhcp6relay
programs=dhcprelayd,dhcp6relay

[program:isc-dhcpv4-relay-Vlan1000]
command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id Vlan1000 -iu Vlan2000 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 -iu PortChannel01 192.0.0.1 192.0.0.2
Expand Down Expand Up @@ -96,4 +96,12 @@ stderr_logfile=syslog
dependent_startup=true
dependent_startup_wait_for=isc-dhcpv4-relay-Vlan2000:running


[program:dhcprelayd]
command=/usr/local/bin/dhcprelayd
priority=3
autostart=false
autorestart=false
stdout_logfile=syslog
stderr_logfile=syslog
dependent_startup=true
dependent_startup_wait_for=start:exited
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ dependent_startup=true
dependent_startup_wait_for=rsyslogd:running

[group:dhcp-relay]
programs=isc-dhcpv4-relay-Vlan1000,dhcp6relay
programs=dhcprelayd,dhcp6relay

[program:isc-dhcpv4-relay-Vlan1000]
command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id Vlan1000 -iu Vlan2000 -iu PortChannel01 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 192.0.0.1 192.0.0.2
Expand Down Expand Up @@ -76,4 +76,12 @@ stderr_logfile=syslog
dependent_startup=true
dependent_startup_wait_for=isc-dhcpv4-relay-Vlan1000:running


[program:dhcprelayd]
command=/usr/local/bin/dhcprelayd
priority=3
autostart=false
autorestart=false
stdout_logfile=syslog
stderr_logfile=syslog
dependent_startup=true
dependent_startup_wait_for=start:exited
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ dependent_startup=true
dependent_startup_wait_for=rsyslogd:running

[group:dhcp-relay]
programs=isc-dhcpv4-relay-Vlan1000,isc-dhcpv4-relay-Vlan2000,dhcp6relay
programs=dhcprelayd,dhcp6relay

[program:isc-dhcpv4-relay-Vlan1000]
command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id Vlan1000 -iu Vlan2000 -iu PortChannel01 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 192.0.0.1 192.0.0.2
Expand Down Expand Up @@ -96,4 +96,12 @@ stderr_logfile=syslog
dependent_startup=true
dependent_startup_wait_for=isc-dhcpv4-relay-Vlan2000:running


[program:dhcprelayd]
command=/usr/local/bin/dhcprelayd
priority=3
autostart=false
autorestart=false
stdout_logfile=syslog
stderr_logfile=syslog
dependent_startup=true
dependent_startup_wait_for=start:exited
20 changes: 0 additions & 20 deletions src/sonic-config-engine/tests/test_j2files.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,36 +154,16 @@ def test_ports_json(self):
def test_dhcp_relay(self):
# Test generation of wait_for_intf.sh
dhc_sample_data = os.path.join(self.test_dir, "dhcp-relay-sample.json")
enable_dhcp_server_sample_data = os.path.join(self.test_dir, "dhcp-relay-enable-dhcp-server-sample.json")
template_path = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-dhcp-relay', 'wait_for_intf.sh.j2')
argument = ['-m', self.t0_minigraph, '-j', dhc_sample_data, '-p', self.t0_port_config, '-t', template_path]
self.run_script(argument, output_file=self.output_file)
self.assertTrue(utils.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'wait_for_intf.sh'), self.output_file))

# Test generation of docker-dhcp-relay.supervisord.conf witout dhcp_server feature entry
template_path = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-dhcp-relay', 'docker-dhcp-relay.supervisord.conf.j2')
argument = ['-m', self.t0_minigraph, '-p', self.t0_port_config, '-t', template_path]
self.run_script(argument, output_file=self.output_file)
self.assertTrue(utils.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'docker-dhcp-relay.supervisord.conf'), self.output_file))

# Test generation of docker-dhcp-relay.supervisord.conf with disabled dhcp_server feature
template_path = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-dhcp-relay',
'docker-dhcp-relay.supervisord.conf.j2')
argument = ['-m', self.t0_minigraph, '-j', dhc_sample_data, '-p', self.t0_port_config, '-t', template_path]
self.run_script(argument, output_file=self.output_file)
self.assertTrue(utils.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR,
'docker-dhcp-relay.supervisord.conf'), self.output_file))

# Test generation of docker-dhcp-relay.supervisord.conf with enabled dhcp_server feature
template_path = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-dhcp-relay',
'docker-dhcp-relay.supervisord.conf.j2')
argument = ['-m', self.t0_minigraph, '-j', enable_dhcp_server_sample_data, '-p', self.t0_port_config, '-t',
template_path]
self.run_script(argument, output_file=self.output_file)
self.assertTrue(utils.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR,
'docker-dhcp-relay-enable-dhcp-server.supervisord.conf'),
self.output_file))

# Test generation of docker-dhcp-relay.supervisord.conf when a vlan is missing ip/ipv6 helpers
template_path = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-dhcp-relay',
'docker-dhcp-relay.supervisord.conf.j2')
Expand Down
94 changes: 74 additions & 20 deletions src/sonic-dhcp-server/dhcp_server/common/dhcp_db_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
VLAN = "VLAN"
VLAN_MEMBER = "VLAN_MEMBER"
VLAN_INTERFACE = "VLAN_INTERFACE"
FEATURE = "FEATURE"


class ConfigDbEventChecker(object):
Expand Down Expand Up @@ -343,6 +344,60 @@ def _process_check(self, key, op, entry, enabled_dhcp_interfaces):
return False


class DhcpServerFeatureStateChecker(ConfigDbEventChecker):
"""
This event checker interested in dhcp_server feature state change in FEATURE table
"""
table_name = FEATURE

def __init__(self, sel, db):
self.table_name = FEATURE
ConfigDbEventChecker.__init__(self, sel, db)

def _get_parameter(self, db_snapshot):
return ConfigDbEventChecker.get_parameter_by_name(db_snapshot, "dhcp_server_feature_enabled")

def _process_check(self, key, op, entry, dhcp_server_feature_enabled):
if key != "dhcp_server":
return False
if op == "DEL":
yaqiangz marked this conversation as resolved.
Show resolved Hide resolved
return dhcp_server_feature_enabled
for field, value in entry:
if field != "state":
continue
return value == "enabled" and not dhcp_server_feature_enabled or \
value == "disabled" and dhcp_server_feature_enabled
return False


def _enable_monitor_checkers(checker_names, checker_dict):
"""
Enable checkers
Args:
checker_names: set of tables checker to be enable
checker_dict: check_dict in monitor
"""
for checker in checker_names:
if checker not in checker_dict:
syslog.syslog(syslog.LOG_ERR, "Cannot find checker for {} in checker_dict".format(checker))
continue
checker_dict[checker].enable()


def _disable_monitor_checkers(checker_names, checker_dict):
"""
Disable checkers
Args:
checker_names: set contains name of tables need to be disable
checker_dict: check_dict in monitor
"""
for checker in checker_names:
if checker not in checker_dict:
syslog.syslog(syslog.LOG_ERR, "Cannot find checker for {} in checker_dict".format(checker))
continue
checker_dict[checker].disable()


class DhcpRelaydDbMonitor(object):
checker_dict = {}

Expand All @@ -354,17 +409,21 @@ def __init__(self, db_connector, sel, checkers, select_timeout=DEFAULT_SELECT_TI
for checker in checkers:
self.checker_dict[checker.get_class_name()] = checker

def enable_checker(self, checker_names):
def enable_checkers(self, checker_names):
"""
Enable checkers
Args:
checker_names: set of tables checker to be enable
"""
for table in checker_names:
if table not in self.checker_dict:
syslog.syslog(syslog.LOG_ERR, "Cannot find checker for {} in checker_dict".format(table))
continue
self.checker_dict[table].enable()
_enable_monitor_checkers(checker_names, self.checker_dict)

def disable_checkers(self, checker_names):
"""
Disable checkers
Args:
checker_names: set contains name of tables need to be disable
"""
_disable_monitor_checkers(checker_names, self.checker_dict)

def check_db_update(self, db_snapshot):
"""
Expand All @@ -376,10 +435,13 @@ def check_db_update(self, db_snapshot):
"""
state, _ = self.sel.select(self.select_timeout)
if state == swsscommon.Select.TIMEOUT or state != swsscommon.Select.OBJECT:
return (False, False, False)
return (self.checker_dict["DhcpServerTableIntfEnablementEventChecker"].check_update_event(db_snapshot),
self.checker_dict["VlanTableEventChecker"].check_update_event(db_snapshot),
self.checker_dict["VlanIntfTableEventChecker"].check_update_event(db_snapshot))
return {}
check_res = {}
for name, checker in self.checker_dict.items():
if not checker.is_enabled():
continue
check_res[name] = checker.check_update_event(db_snapshot)
return check_res


class DhcpServdDbMonitor(object):
Expand All @@ -399,23 +461,15 @@ def disable_checkers(self, checker_names):
Args:
checker_names: set contains name of tables need to be disable
"""
for table in checker_names:
if table not in self.checker_dict:
syslog.syslog(syslog.LOG_ERR, "Cannot find checker for {} in checker_dict".format(table))
continue
self.checker_dict[table].disable()
_disable_monitor_checkers(checker_names, self.checker_dict)

def enable_checkers(self, checker_names):
"""
Enable checkers
Args:
checker_names: set contains name of tables need to be enable
"""
for table in checker_names:
if table not in self.checker_dict:
syslog.syslog(syslog.LOG_ERR, "Cannot find checker for {} in checker_dict".format(table))
continue
self.checker_dict[table].enable()
_enable_monitor_checkers(checker_names, self.checker_dict)

def check_db_update(self, db_snapshot):
"""
Expand Down
Loading