diff --git a/dockers/docker-teamd/Dockerfile.j2 b/dockers/docker-teamd/Dockerfile.j2 index 9fded5183c3c..f604433a6c3f 100644 --- a/dockers/docker-teamd/Dockerfile.j2 +++ b/dockers/docker-teamd/Dockerfile.j2 @@ -22,10 +22,11 @@ RUN dpkg -i \ debs/{{ deb }}{{' '}} {%- endfor %} -COPY ["docker-teamd-init.sh", "docker-teamd-start.sh", "teamd.sh", "/usr/bin/"] -COPY ["docker-teamd.supervisord.conf.j2", "teamd.j2", "/usr/share/sonic/templates/"] +COPY ["start.sh", "teamd.sh", "/usr/bin/"] +COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["teamd.j2", "/usr/share/sonic/templates/"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs -ENTRYPOINT ["/usr/bin/docker-teamd-init.sh"] +ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-teamd/docker-teamd-init.sh b/dockers/docker-teamd/docker-teamd-init.sh deleted file mode 100755 index a06ca4e8f890..000000000000 --- a/dockers/docker-teamd/docker-teamd-init.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env bash - -TEAMD_CONF_PATH="/etc/teamd" - -rm -rf $TEAMD_CONF_PATH -mkdir -p $TEAMD_CONF_PATH - -SONIC_ASIC_TYPE=$(sonic-cfggen -y /etc/sonic/sonic_version.yml -v asic_type) -MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') - -# Align last byte -if [ "$SONIC_ASIC_TYPE" == "mellanox" -o "$SONIC_ASIC_TYPE" == "centec" ]; then - last_byte=$(python -c "print '$MAC_ADDRESS'[-2:]") - aligned_last_byte=$(python -c "print format(int(int('$last_byte', 16) & 0b11000000), '02x')") # put mask and take away the 0x prefix - MAC_ADDRESS=$(python -c "print '$MAC_ADDRESS'[:-2] + '$aligned_last_byte'") # put aligned byte into the end of MAC -fi - -for pc in `sonic-cfggen -d -v "PORTCHANNEL.keys() | join(' ') if PORTCHANNEL"`; do - sonic-cfggen -d -a '{"pc":"'$pc'","hwaddr":"'$MAC_ADDRESS'"}' -t /usr/share/sonic/templates/teamd.j2 > $TEAMD_CONF_PATH/$pc.conf - # bring down all member ports before starting teamd - for member in $(sonic-cfggen -d -v "PORTCHANNEL['$pc']['members'] | join(' ')" ); do - if [ -L /sys/class/net/$member ]; then - ip link set $member down - fi - done -done - -# Create a Python dictionary where the key is the Jinja2 variable name -# "lags" and the value is a list of dctionaries containing the name of -# the LAG and the path of the LAG config file. Then output this in -# JSON format, as we will pass it to sonic-cfggen as additional data -# below for generating the supervisord config file. -# Example output: {"lags": [{"name": "PortChannel1", "file": "/etc/teamd/PortChannel1.conf"}, {"name": "PortChannel2", "file": "/etc/teamd/PortChannel2.conf"}]} -LAG_INFO_DICT=$(python -c "import json,os,sys; lags_dict = {}; lags_dict['lags'] = [{'name': os.path.basename(file).split('.')[0], 'file': os.path.join('${TEAMD_CONF_PATH}', file)} for file in sorted(os.listdir('${TEAMD_CONF_PATH}'))]; sys.stdout.write(json.dumps(lags_dict))") - -# Generate supervisord config file -mkdir -p /etc/supervisor/conf.d/ -sonic-cfggen -d -a "${LAG_INFO_DICT}" -t /usr/share/sonic/templates/docker-teamd.supervisord.conf.j2 > /etc/supervisor/conf.d/docker-teamd.supervisord.conf - -# The Docker container should start this script as PID 1, so now that we -# have generated the proper supervisord configuration, we exec supervisord -# so that it runs as PID 1 for the duration of the container's lifetime -exec /usr/bin/supervisord diff --git a/dockers/docker-teamd/docker-teamd-start.sh b/dockers/docker-teamd/docker-teamd-start.sh deleted file mode 100755 index 95b167d22b40..000000000000 --- a/dockers/docker-teamd/docker-teamd-start.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -rm -f /var/run/rsyslogd.pid - -supervisorctl start rsyslogd - -supervisorctl start teamd:* - -supervisorctl start teamsyncd diff --git a/dockers/docker-teamd/docker-teamd.supervisord.conf.j2 b/dockers/docker-teamd/docker-teamd.supervisord.conf.j2 deleted file mode 100644 index abd3203b3477..000000000000 --- a/dockers/docker-teamd/docker-teamd.supervisord.conf.j2 +++ /dev/null @@ -1,52 +0,0 @@ -[supervisord] -logfile_maxbytes=1MB -logfile_backups=2 -nodaemon=true - -[program:docker-teamd-start.sh] -command=/usr/bin/docker-teamd-start.sh -priority=1 -autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - -{# If there are LAGs... #} -{% if lags -%} -[group:teamd] -programs= -{%- set add_preceding_comma = { 'flag': False } -%} -{%- for lag in lags -%} -{%- if add_preceding_comma.flag %},{% endif -%} -{%- set _dummy = add_preceding_comma.update({'flag': True}) -%} -teamd-{{ lag['name'] }} -{%- endfor %} - -{# Create a program entry for each teamd instance #} -{% for lag in lags %} - -[program:teamd-{{ lag['name'] }}] -command=/usr/bin/teamd.sh {{ lag['file'] }} -priority=3 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog -{% endfor %} - -[program:teamsyncd] -command=/usr/bin/teamsyncd -priority=4 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog -{% endif %} diff --git a/dockers/docker-teamd/start.sh b/dockers/docker-teamd/start.sh new file mode 100755 index 000000000000..6e80f6eb9a83 --- /dev/null +++ b/dockers/docker-teamd/start.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +TEAMD_CONF_PATH=/etc/teamd + +rm -rf $TEAMD_CONF_PATH +mkdir -p $TEAMD_CONF_PATH + +SONIC_ASIC_TYPE=$(sonic-cfggen -y /etc/sonic/sonic_version.yml -v asic_type) +MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') + +# Align last byte +if [ "$SONIC_ASIC_TYPE" == "mellanox" -o "$SONIC_ASIC_TYPE" == "centec" ]; then + last_byte=$(python -c "print '$MAC_ADDRESS'[-2:]") + aligned_last_byte=$(python -c "print format(int(int('$last_byte', 16) & 0b11000000), '02x')") # put mask and take away the 0x prefix + MAC_ADDRESS=$(python -c "print '$MAC_ADDRESS'[:-2] + '$aligned_last_byte'") # put aligned byte into the end of MAC +fi + +for pc in `sonic-cfggen -d -v "PORTCHANNEL.keys() | join(' ') if PORTCHANNEL"`; do + sonic-cfggen -d -a '{"pc":"'$pc'","hwaddr":"'$MAC_ADDRESS'"}' -t /usr/share/sonic/templates/teamd.j2 > $TEAMD_CONF_PATH/$pc.conf + # bring down all member ports before starting teamd + for member in $(sonic-cfggen -d -v "PORTCHANNEL['$pc']['members'] | join(' ')" ); do + if [ -L /sys/class/net/$member ]; then + ip link set $member down + fi + done +done + +mkdir -p /var/sonic +echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status + +rm -f /var/run/rsyslogd.pid + +supervisorctl start rsyslogd + +supervisorctl start teamd diff --git a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf b/dockers/docker-teamd/supervisord.conf similarity index 58% rename from src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf rename to dockers/docker-teamd/supervisord.conf index f955546cdc09..48ef0ca9f29e 100644 --- a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf +++ b/dockers/docker-teamd/supervisord.conf @@ -19,15 +19,10 @@ autorestart=false stdout_logfile=syslog stderr_logfile=syslog -[group:isc-dhcp-relay] -programs=isc-dhcp-relay-Vlan1000 - -[program:isc-dhcp-relay-Vlan1000] -command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -i Vlan1000 -i PortChannel02 -i PortChannel03 -i PortChannel04 -i PortChannel01 192.0.0.1 192.0.0.2 +[program:teamd] +command=/usr/bin/teamd.sh priority=3 autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog - - diff --git a/dockers/docker-teamd/teamd.sh b/dockers/docker-teamd/teamd.sh index 7192a2bdeca2..2b6d9fb53970 100755 --- a/dockers/docker-teamd/teamd.sh +++ b/dockers/docker-teamd/teamd.sh @@ -1,15 +1,28 @@ #!/usr/bin/env bash -TEAMD_CONF_FILE=$1 +TEAMD_CONF_PATH=/etc/teamd + +function start_app { + rm -f /var/run/teamd/* + if [ "$(ls -A $TEAMD_CONF_PATH)" ]; then + for f in $TEAMD_CONF_PATH/*; do + teamd -f $f -d + done + fi + teamsyncd & +} function clean_up { - teamd -f $TEAMD_CONF_FILE -k - exit $? + if [ "$(ls -A $TEAMD_CONF_PATH)" ]; then + for f in $TEAMD_CONF_PATH/*; do + teamd -f $f -k + done + fi + pkill -9 teamsyncd + exit } trap clean_up SIGTERM SIGKILL -teamd -f $TEAMD_CONF_FILE & -TEAMD_PID=$! -wait $TEAMD_PID -exit $? +start_app +read diff --git a/src/sonic-config-engine/tests/sample_output/docker-teamd.supervisord.conf b/src/sonic-config-engine/tests/sample_output/docker-teamd.supervisord.conf deleted file mode 100644 index 83feaf05b8c8..000000000000 --- a/src/sonic-config-engine/tests/sample_output/docker-teamd.supervisord.conf +++ /dev/null @@ -1,64 +0,0 @@ -[supervisord] -logfile_maxbytes=1MB -logfile_backups=2 -nodaemon=true - -[program:docker-teamd-start.sh] -command=/usr/bin/docker-teamd-start.sh -priority=1 -autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - -[program:rsyslogd] -command=/usr/sbin/rsyslogd -n -priority=2 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - -[group:teamd] -programs=teamd-PortChannel01,teamd-PortChannel02,teamd-PortChannel03,teamd-PortChannel04 - -[program:teamd-PortChannel01] -command=/usr/bin/teamd.sh /sonic/src/sonic-config-engine/tests/sample_output/t0_sample_output/PortChannel01.conf -priority=3 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - -[program:teamd-PortChannel02] -command=/usr/bin/teamd.sh /sonic/src/sonic-config-engine/tests/sample_output/t0_sample_output/PortChannel02.conf -priority=3 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - -[program:teamd-PortChannel03] -command=/usr/bin/teamd.sh /sonic/src/sonic-config-engine/tests/sample_output/t0_sample_output/PortChannel03.conf -priority=3 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - -[program:teamd-PortChannel04] -command=/usr/bin/teamd.sh /sonic/src/sonic-config-engine/tests/sample_output/t0_sample_output/PortChannel04.conf -priority=3 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - -[program:teamsyncd] -command=/usr/bin/teamsyncd -priority=4 -autostart=false -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - diff --git a/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh b/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh deleted file mode 100644 index 26c453d487af..000000000000 --- a/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env bash - -function wait_until_iface_exists -{ - IFACE=$1 - - echo "Waiting for interface ${IFACE}..." - - # Wait for the interface to come up (i.e., 'ip link show' returns 0) - until ip link show $IFACE > /dev/null 2>&1; do - sleep 1 - done - - echo "Interface ${IFACE} is created" -} - - -# Wait for all interfaces to come up before starting the DHCP relay -wait_until_iface_exists Vlan1000 -wait_until_iface_exists PortChannel04 -wait_until_iface_exists PortChannel02 -wait_until_iface_exists PortChannel03 -wait_until_iface_exists PortChannel03 -wait_until_iface_exists PortChannel01 -wait_until_iface_exists PortChannel02 -wait_until_iface_exists PortChannel04 -wait_until_iface_exists PortChannel01 - diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index fb450ba77ae2..d1cc0d2a3296 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -33,19 +33,6 @@ def test_alias_map(self): data = json.loads(output) self.assertEqual(data["Ethernet4"], "fortyGigE0/4") - def test_dhcp_relay(self): - # Test generation of wait_for_intf.sh - template_path = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-dhcp-relay', 'wait_for_intf.sh.j2') - argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + template_path + ' > ' + self.output_file - self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'wait_for_intf.sh'), self.output_file)) - - # Test generation of docker-dhcp-relay.supervisord.conf - 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.output_file - self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'docker-dhcp-relay.supervisord.conf'), self.output_file)) - def test_lldp(self): lldpd_conf_template = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-lldp-sv2', 'lldpd.conf.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + lldpd_conf_template + ' > ' + self.output_file @@ -62,7 +49,7 @@ def test_render_teamd(self, pc, minigraph, sample_output): # Test T0 minigraph argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -v "PORTCHANNEL.keys() | join(\' \') if PORTCHANNEL"' - output = self.run_script(argument) # Mock the output via docker-teamd-init.sh in docker-teamd + output = self.run_script(argument) # Mock the output via config.sh in docker-teamd pc_list = output.split() for i in range(1, 5): @@ -71,9 +58,9 @@ def test_render_teamd(self, pc, minigraph, sample_output): sample_output = os.path.join(self.test_dir, 'sample_output', 't0_sample_output', pc_name + '.conf') test_render_teamd(self, pc_name, self.t0_minigraph, sample_output) - # Test port channel test minigraph (for testing proper 'min_ports' attribute generation) + # Test port channel test minigraph argument = '-m ' + self.pc_minigraph + ' -p ' + self.t0_port_config + ' -v "PORTCHANNEL.keys() | join(\' \') if PORTCHANNEL"' - output = self.run_script(argument) # Mock the output via docker-teamd-init.sh in docker-teamd + output = self.run_script(argument) # Mock the output via config.sh in docker-teamd pc_list = output.split() pc_name = 'PortChannel01' @@ -81,17 +68,6 @@ def test_render_teamd(self, pc, minigraph, sample_output): sample_output = os.path.join(self.test_dir, 'sample_output', 'pc_sample_output', pc_name + '.conf') test_render_teamd(self, pc_name, self.pc_minigraph, sample_output) - # Test generation of docker-teamd.supervisord.conf - template_path = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-teamd', 'docker-teamd.supervisord.conf.j2') - teamd_conf_dir = os.path.join(self.test_dir, 'sample_output', 't0_sample_output') - - lags_dict = {} - lags_dict['lags'] = [{'name': os.path.basename(file).split('.')[0], 'file': os.path.join(teamd_conf_dir, file)} for file in sorted(os.listdir(teamd_conf_dir))] - argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -a \'' + json.dumps(lags_dict) + '\' -t ' + template_path + ' > ' + self.output_file - - self.run_script(argument) - self.assertTrue(filecmp.cmp(os.path.join(self.test_dir, 'sample_output', 'docker-teamd.supervisord.conf'), self.output_file)) - def test_ipinip(self): ipinip_file = os.path.join(self.test_dir, '..', '..', '..', 'dockers', 'docker-orchagent', 'ipinip.json.j2') argument = '-m ' + self.t0_minigraph + ' -p ' + self.t0_port_config + ' -t ' + ipinip_file + ' > ' + self.output_file