sonic-cfggen with sonicv2 dockers (#190)

Add a sonic-config-engine to help generate config file based on minigraph and other data on runtime. Modify fpm, teamd, lldp, snmp, and platform-monitor docker to use sonic-config-engine to generate config in docker upon load.
This commit is contained in:
Taoyu Li 2017-01-19 20:56:26 -08:00 committed by GitHub
parent 0d6b1e86a8
commit 4fe1bdcf87
37 changed files with 733 additions and 61 deletions

View File

@ -2,7 +2,10 @@ FROM docker-base
RUN apt-get update RUN apt-get update
RUN apt-get install -y libdbus-1-3 libdaemon0 libjansson4 RUN apt-get install -y libdbus-1-3 libdaemon0 libjansson4
# Dependencies for sonic-cfggen
RUN apt-get install -y python-lxml python-jinja2 python-netaddr python-ipaddr python-yaml
COPY \ COPY \
{% for deb in docker_fpm_debs.split(' ') -%} {% for deb in docker_fpm_debs.split(' ') -%}
@ -19,7 +22,9 @@ debs/{{ deb }}{{' '}}
RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y
RUN rm -rf /debs RUN rm -rf /debs
COPY ["start.sh", "/usr/bin/"] COPY ["*.j2", "/etc/swss/bgp/"]
COPY ["start.sh", "config.sh", "/usr/bin/"]
ENTRYPOINT /usr/bin/start.sh \ ENTRYPOINT /usr/bin/config.sh \
&& /usr/bin/start.sh \
&& /bin/bash && /bin/bash

View File

@ -0,0 +1,63 @@
!
{% block banner %}
! =========== Managed by sonic-cfggen DO NOT edit manually! ====================
! generated by templates/quagga/bgpd.conf.j2 using minigraph_facts.py
! file: bgpd.conf
!
{% endblock banner %}
!
{% block system_init %}
hostname {{ inventory_hostname }}
password zebra
log syslog informational
log facility local4
! enable password {# {{ en_passwd }} TODO: param needed #}
{% endblock system_init %}
!
{% block bgp_init %}
!
! bgp multiple-instance
!
router bgp {{ minigraph_bgp_asn }}
bgp log-neighbor-changes
bgp bestpath as-path multipath-relax
{# TODO: use lo[0] for backward compatibility, will revisit the case with multiple lo interfaces #}
bgp router-id {{ minigraph_lo_interfaces[0]['addr'] }}
{# advertise loopback #}
{% for lo in minigraph_lo_interfaces %}
{% if lo['addr'] | ipv4 %}
network {{ lo['addr'] }}/32
{% elif lo['addr'] | ipv6 %}
address-family ipv6
network {{ lo['addr'] }}/128
exit-address-family
{% endif %}
{% endfor %}
{% endblock bgp_init %}
{% block vlan_advertisement %}
{% for interface in minigraph_interfaces %}
{% if interface['name'].startswith('Vlan') %}
network {{ interface['subnet'] }}
{% endif %}
{% endfor %}
{% endblock vlan_advertisement %}
{% block bgp_sessions %}
{% for bgp_session in minigraph_bgp %}
{% if bgp_session['asn'] != 0 %}
neighbor {{ bgp_session['addr'] }} remote-as {{ bgp_session['asn'] }}
neighbor {{ bgp_session['addr'] }} description {{ bgp_session['name'] }}
{% if bgp_session['addr'] | ipv6 %}
address-family ipv6
neighbor {{ bgp_session['addr'] }} activate
maximum-paths 64
exit-address-family
{% endif %}
{% endif %}
{% endfor %}
{% endblock bgp_sessions %}
!
maximum-paths 64
!
route-map ISOLATE permit 10
set as-path prepend {{ minigraph_bgp_asn }}
!

14
dockers/docker-fpm/config.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/bash
mkdir -p /etc/quagga
sonic-cfggen -m /etc/sonic/minigraph.xml -t /etc/swss/bgp/bgpd.conf.j2 >/etc/quagga/bgpd.conf
sonic-cfggen -m /etc/sonic/minigraph.xml -t /etc/swss/bgp/zebra.conf.j2 >/etc/quagga/zebra.conf
sonic-cfggen -m /etc/sonic/minigraph.xml -t /etc/swss/bgp/isolate.j2 >/usr/sbin/bgp-isolate
chown root:root /usr/sbin/bgp-isolate
chmod 0755 /usr/sbin/bgp-isolate
sonic-cfggen -m /etc/sonic/minigraph.xml -t /etc/swss/bgp/unisolate.j2 >/usr/sbin/bgp-unisolate
chown root:root /usr/sbin/bgp-unisolate
chmod 0755 /usr/sbin/bgp-unisolate

20
dockers/docker-fpm/isolate.j2 Executable file
View File

@ -0,0 +1,20 @@
#!/bin/bash
## vtysh only accepts script in stdin, so cannot be directly used in shebang
## Cut the tail of this script and feed vtysh stdin
sed -n -e '9,$p' < "$0" | vtysh "$@"
## Exit with vtysh return code
exit $?
## vtysh script start from next line, which line number MUST eqaul in 'sed' command above
configure terminal
router bgp {{ minigraph_bgp_asn }}
{% for bgp_session in minigraph_bgp %}
neighbor {{ bgp_session['addr'] }} route-map ISOLATE out
{% endfor %}
exit
exit
{% for bgp_session in minigraph_bgp %}
clear ip bgp {{ bgp_session['addr'] }} soft out
{% endfor %}

20
dockers/docker-fpm/unisolate.j2 Executable file
View File

@ -0,0 +1,20 @@
#!/bin/bash
## vtysh only accepts script in stdin, so cannot be directly used in shebang
## Cut the tail of this script and feed vtysh stdin
sed -n -e '9,$p' < "$0" | vtysh "$@"
## Exit with vtysh return code
exit $?
## vtysh script start from next line, which line number MUST eqaul in 'sed' command above
configure terminal
router bgp {{ minigraph_bgp_asn }}
{% for bgp_session in minigraph_bgp %}
no neighbor {{ bgp_session['addr'] }} route-map ISOLATE out
{% endfor %}
exit
exit
{% for bgp_session in minigraph_bgp %}
clear ip bgp {{ bgp_session['addr'] }} soft out
{% endfor %}

View File

@ -0,0 +1,61 @@
!
{% block banner %}
! =========== Managed by sonic-cfggen DO NOT edit manually! ====================
! generated by templates/quagga/zebra.conf.j2 using minigraph_facts.py
! file: zebra.conf
!
{% endblock banner %}
!
{% block sys_init %}
hostname {{ inventory_hostname }}
password zebra
enable password zebra
{% endblock sys_init %}
!
{% block interfaces %}
! Enable link-detect (default disabled)
{% for interface in minigraph_interfaces %}
interface {{ interface['alias'] }}
link-detect
!
{% endfor %}
{% endblock interfaces %}
!
{% block default_route %}
! set static default route to mgmt gateway as a backup to learned default
ip route 0.0.0.0/0 {{ minigraph_mgmt_interface['gwaddr'] }} 200
{% endblock default_route %}
!
{% block source_loopback %}
! Set ip source to loopback for bgp learned routes
route-map RM_SET_SRC permit 10
set src {{ minigraph_lo_interfaces[0]['addr'] }}
!
{% set lo_ipv6_addrs = [] %}
{% if minigraph_lo_interfaces is defined %}
{% for interface in minigraph_lo_interfaces %}
{% if interface['addr'] is defined and interface['addr']|ipv6 %}
{% if lo_ipv6_addrs.append(interface['addr']) %}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% if lo_ipv6_addrs|length > 0 %}
route-map RM_SET_SRC6 permit 10
set src {{ lo_ipv6_addrs[0] }}
!
{% endif %}
ip protocol bgp route-map RM_SET_SRC
!
{% if lo_ipv6_addrs|length > 0 %}
ipv6 protocol bgp route-map RM_SET_SRC6
!
{% endif %}
{% endblock source_loopback %}
!
{% block logging %}
log syslog informational
log facility local4
{% endblock logging %}
!

View File

@ -8,7 +8,10 @@ debs/
COPY python-wheels /python-wheels COPY python-wheels /python-wheels
RUN apt-get update && apt-get install -y python-pip supervisor libbsd0 libevent-2.0-5 libjansson4 libwrap0 libxml2 libpci3 libperl5.20 RUN apt-get update && apt-get install -y python-pip supervisor libbsd0 libevent-2.0-5 libjansson4 libwrap0 libxml2 libpci3 libperl5.20
# Dependencies for sonic-cfggen
RUN apt-get install -y python-lxml python-jinja2 python-netaddr python-ipaddr python-yaml
## Pre-install the fundamental packages ## Pre-install the fundamental packages
## Install Python SSWSDK ## Install Python SSWSDK
@ -27,5 +30,8 @@ RUN pip install /python-wheels/sswsdk-2.0.1-py2-none-any.whl && \
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY reconfigure.sh /opt/reconfigure.sh COPY reconfigure.sh /opt/reconfigure.sh
COPY ["config.sh", "/usr/bin/"]
COPY ["lldpd.conf.j2", "/etc/swss/lldp/"]
COPY ["lldpd", "/etc/default/"]
ENTRYPOINT ["/usr/bin/supervisord"] ENTRYPOINT /usr/bin/config.sh && /usr/bin/supervisord

View File

@ -0,0 +1,4 @@
#!/bin/bash
sonic-cfggen -m /etc/sonic/minigraph.xml -t /etc/swss/lldp/lldpd.conf.j2 >/etc/lldpd.conf

View File

@ -0,0 +1,6 @@
###############################################################################
# Managed by sonic-cfggen
###############################################################################
# Uncomment to start SNMP subagent and enable CDP, SONMP and EDP protocol
DAEMON_ARGS=""

View File

@ -0,0 +1,3 @@
{% for member in alias_map %}
configure ports {{member['sonic']}} lldp portidsubtype local {{member['origin']}}
{% endfor %}

View File

@ -1,16 +0,0 @@
FROM docker-base
## Pre-install the fundamental packages
## Clean up
RUN apt-get update && \
apt-get -y install \
smartmontools \
sensord \
&& \
apt-get clean -y && apt-get autoclean -y && apt-get autoremove -y
ENTRYPOINT service rsyslog start \
&& service lm-sensors start \
&& service smartmontools start \
&& service sensord start \
&& /bin/bash

View File

@ -0,0 +1,28 @@
FROM docker-base
RUN apt-get update
RUN apt-get install -y smartmontools sensord
# Dependencies for sonic-cfggen
RUN apt-get install -y python-lxml python-jinja2 python-netaddr python-ipaddr python-yaml
COPY debs/ debs
RUN dpkg -i \
{% for deb in docker_fpm_debs.split(' ') -%}
debs/{{ deb }}{{' '}}
{%- endfor %}
## Clean up
RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y
RUN rm -rf /debs
COPY ["config.sh", "/usr/bin/"]
ENTRYPOINT /usr/bin/config.sh \
&& service rsyslog start \
&& service lm-sensors start \
&& service smartmontools start \
&& service sensord start \
&& /bin/bash

View File

@ -0,0 +1,7 @@
#!/bin/bash
mkdir -p /etc/sensors.d
hwsku=`sonic-cfggen -m /etc/sonic/minigraph.xml -v minigraph_hwsku`
/bin/cp -rf /usr/share/sonic/$hwsku/sensors.conf /etc/sensors.d/

View File

@ -17,6 +17,9 @@ ENV PYTHONOPTIMIZE 1
## Clean up ## Clean up
RUN apt-get update && apt-get install -y libmysqlclient-dev libmysqld-dev libperl-dev libpci-dev libpci3 libsensors4 libsensors4-dev libwrap0-dev RUN apt-get update && apt-get install -y libmysqlclient-dev libmysqld-dev libperl-dev libpci-dev libpci3 libsensors4 libsensors4-dev libwrap0-dev
# Dependencies for sonic-cfggen
RUN apt-get install -y python-lxml python-jinja2 python-netaddr python-ipaddr python-yaml
RUN dpkg -i \ RUN dpkg -i \
{% for deb in docker_snmp_sv2_debs.split(' ') -%} {% for deb in docker_snmp_sv2_debs.split(' ') -%}
debs/{{ deb }}{{' '}} debs/{{ deb }}{{' '}}
@ -44,8 +47,11 @@ RUN apt-get -y install build-essential wget libssl-dev openssl supervisor && \
rm -rf ~/.cache rm -rf ~/.cache
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY ["*.j2", "/etc/swss/snmp/"]
COPY ["snmpd", "/etc/default/"]
COPY ["config.sh", "/usr/bin/"]
## Although exposing ports is not need for host net mode, keep it for possible bridge mode ## Although exposing ports is not need for host net mode, keep it for possible bridge mode
EXPOSE 161/udp 162/udp EXPOSE 161/udp 162/udp
ENTRYPOINT ["/usr/bin/supervisord"] ENTRYPOINT /usr/bin/config.sh && /usr/bin/supervisord

View File

@ -0,0 +1,13 @@
#!/bin/bash
#sysDescription is currently mounted, uncomment this line and provide version.yml instead if use copying instead of mounting
#sonic-cfggen -m /etc/sonic/minigraph.xml -y /etc/sonic/version.yml -t /etc/swss/snmp/sysDescription.j2 >/etc/ssw/sysDescription
mkdir -p /etc/snmp
sonic-cfggen -m /etc/sonic/minigraph.xml -y /etc/sonic/snmp.yml -t /etc/swss/snmp/snmpd.conf.j2 >/etc/snmp/snmpd.conf
hwsku=`sonic-cfggen -m /etc/sonic/minigraph.xml -v minigraph_hwsku`
/bin/cp -rf /usr/share/sonic/$hwsku/alias_map.json /etc/snmp/

View File

@ -0,0 +1,11 @@
# This file controls the activity of snmpd
# Don't load any MIBs by default.
# You might comment this lines once you have the MIBs downloaded.
export MIBS=
# snmpd control (yes means start daemon).
SNMPDRUN=yes
# snmpd options (use syslog, close stdin/out/err).
SNMPDOPTS='-LS4d -Lf /dev/null -u snmp -g snmp -I -smux,mteTrigger,mteTriggerConf,ifTable,ifXTable -p /run/snmpd.pid'

View File

@ -0,0 +1,127 @@
###############################################################################
# Managed by Ansible
# file: ansible/roles/acs/templates/snmpd.conf.j2
###############################################################################
#
# EXAMPLE.conf:
# An example configuration file for configuring the Net-SNMP agent ('snmpd')
# See the 'snmpd.conf(5)' man page for details
#
# Some entries are deliberately commented out, and will need to be explicitly activated
#
###############################################################################
#
# AGENT BEHAVIOUR
#
# Listen for connections on localhost, loopback ip and mgmt (eth0) ip
agentAddress udp:127.0.0.1:161
agentAddress udp:{{ minigraph_mgmt_interface.addr }}:161
{% for minigraph_lo_interface in minigraph_lo_interfaces %}
# TODO: only support ipv4 lo addresses, add ipv6 support later
{% if minigraph_lo_interface.addr | ipv4 %}
agentAddress udp:{{ minigraph_lo_interface.addr }}:161
{% endif %}
{% endfor %}
###############################################################################
#
# ACCESS CONTROL
#
# system + hrSystem groups only
view systemonly included .1.3.6.1.2.1.1
view systemonly included .1.3.6.1.2.1.25.1
# Default access to basic system info
rocommunity {{ snmp_rocommunity }}
###############################################################################
#
# SYSTEM INFORMATION
#
# Note that setting these values here, results in the corresponding MIB objects being 'read-only'
# See snmpd.conf(5) for more details
sysLocation {{ snmp_location }}
sysContact Azure Cloud Switch vteam <linuxnetdev@microsoft.com>
# Application + End-to-End layers
sysServices 72
#
# Process Monitoring
#
# todo: should we enable snmp based monitoring of sswsyncd and other processes?
# At least one 'sendmail' process, but no more than 10
#proc sendmail 10 1
# Walk the UCD-SNMP-MIB::prTable to see the resulting output
# Note that this table will be empty if there are no "proc" entries in the snmpd.conf file
#
# Disk Monitoring
#
# 10MBs required on root disk, 5% free on /var, 10% free on all other disks
disk / 10000
disk /var 5%
includeAllDisks 10%
# Walk the UCD-SNMP-MIB::dskTable to see the resulting output
# Note that this table will be empty if there are no "disk" entries in the snmpd.conf file
#
# System Load
#
# Unacceptable 1-, 5-, and 15-minute load averages
load 12 10 5
# Walk the UCD-SNMP-MIB::laTable to see the resulting output
# Note that this table *will* be populated, even without a "load" entry in the snmpd.conf file
###############################################################################
#
# ACTIVE MONITORING
#
# Note: disabled snmp traps due to side effect of causing snmpd to listen on all ports (0.0.0.0)
#
# send SNMPv1 traps
#trapsink localhost public
# send SNMPv2c traps
#trap2sink localhost public
# send SNMPv2c INFORMs
#informsink localhost public
# Note that you typically only want *one* of these three lines
# Uncommenting two (or all three) will result in multiple copies of each notification.
#
# Event MIB - automatically generate alerts
#
# Remember to activate the 'createUser' lines above
#iquerySecName internalUser
#rouser internalUser
# generate traps on UCD error conditions
#defaultMonitors yes
#note, this release of snmpd does not support linkUpDownNotifications
# generate traps on linkUp/Down
#linkUpDownNotifications yes
#
# AgentX Sub-agents
#
# Run as an AgentX master agent
master agentx
#
# SysDescription pass-through
#
pass -p 10 .1.3.6.1.2.1.1.1 /usr/share/snmp/sysDescr_pass.py

View File

@ -0,0 +1 @@
SONiC Software Version: {{ sonic_baseimage_version}}.SONiC.{{ sonic_version }} - HwSku: {{ minigraph_hwsku }}

View File

@ -2,6 +2,10 @@ FROM docker-base
RUN apt-get update && apt-get install -f -y libdbus-1-3 libdaemon0 libjansson4 RUN apt-get update && apt-get install -f -y libdbus-1-3 libdaemon0 libjansson4
# Dependencies for sonic-cfggen
RUN apt-get install -y python-lxml python-jinja2 python-netaddr python-ipaddr python-yaml
COPY \ COPY \
{% for deb in docker_teamd_debs.split(' ') -%} {% for deb in docker_teamd_debs.split(' ') -%}
debs/{{ deb }}{{' '}} debs/{{ deb }}{{' '}}
@ -13,10 +17,10 @@ RUN dpkg -i \
debs/{{ deb }}{{' '}} debs/{{ deb }}{{' '}}
{%- endfor %} {%- endfor %}
COPY start.sh /usr/bin/start.sh COPY ["start.sh", "config.sh", "/usr/bin/"]
COPY ["teamd.j2", "/etc/swss/teamd/"]
RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y
RUN rm -rf /debs RUN rm -rf /debs
ENTRYPOINT ["/bin/bash"] ENTRYPOINT /usr/bin/config.sh && /usr/bin/start.sh
CMD ["/usr/bin/start.sh"]

8
dockers/docker-teamd/config.sh Executable file
View File

@ -0,0 +1,8 @@
#!/bin/bash
mkdir -p /etc/teamd
for pc in `sonic-cfggen -m /etc/sonic/minigraph.xml --var-keys minigraph_portchannel_interfaces`; do
sonic-cfggen -m /etc/sonic/minigraph.xml -a '{"pc":"'$pc'"}' -t /etc/swss/teamd/teamd.j2 >/etc/teamd/$pc.conf
done

View File

@ -0,0 +1,19 @@
{
"device": "{{ pc }}",
"runner": {
"name": "lacp",
"active": true,
"min_ports": 2,
"tx_hash": ["eth", "ipv4", "ipv6"]
},
"link_watch": {
"name": "ethtool"
},
"ports": {
{% for member in minigraph_portchannel_interfaces[pc] %}
"{{member}}": {}{% if not loop.last %},{% endif %}
{% endfor %}
}
}

View File

@ -2,6 +2,6 @@
DOCKER_FPM = docker-fpm.gz DOCKER_FPM = docker-fpm.gz
$(DOCKER_FPM)_PATH = $(DOCKERS_PATH)/docker-fpm $(DOCKER_FPM)_PATH = $(DOCKERS_PATH)/docker-fpm
$(DOCKER_FPM)_DEPENDS += $(QUAGGA) $(SWSS) $(DOCKER_FPM)_DEPENDS += $(QUAGGA) $(SWSS) $(SONIC_CONFIG_ENGINE)
$(DOCKER_FPM)_LOAD_DOCKERS += $(DOCKER_BASE) $(DOCKER_FPM)_LOAD_DOCKERS += $(DOCKER_BASE)
SONIC_DOCKER_IMAGES += $(DOCKER_FPM) SONIC_DOCKER_IMAGES += $(DOCKER_FPM)

View File

@ -2,7 +2,7 @@
DOCKER_LLDP_SV2 = docker-lldp-sv2.gz DOCKER_LLDP_SV2 = docker-lldp-sv2.gz
$(DOCKER_LLDP_SV2)_PATH = $(DOCKERS_PATH)/docker-lldp-sv2 $(DOCKER_LLDP_SV2)_PATH = $(DOCKERS_PATH)/docker-lldp-sv2
$(DOCKER_LLDP_SV2)_DEPENDS += $(LLDPD) $(DOCKER_LLDP_SV2)_DEPENDS += $(LLDPD) $(SONIC_CONFIG_ENGINE)
$(DOCKER_LLDP_SV2)_PYTHON_WHEELS += $(DBSYNCD_PY2) $(DOCKER_LLDP_SV2)_PYTHON_WHEELS += $(DBSYNCD_PY2)
$(DOCKER_LLDP_SV2)_LOAD_DOCKERS += $(DOCKER_BASE) $(DOCKER_LLDP_SV2)_LOAD_DOCKERS += $(DOCKER_BASE)
SONIC_DOCKER_IMAGES += $(DOCKER_LLDP_SV2) SONIC_DOCKER_IMAGES += $(DOCKER_LLDP_SV2)

View File

@ -2,6 +2,7 @@
DOCKER_PLATFORM_MONITOR = docker-platform-monitor.gz DOCKER_PLATFORM_MONITOR = docker-platform-monitor.gz
$(DOCKER_PLATFORM_MONITOR)_PATH = $(DOCKERS_PATH)/docker-platform-monitor $(DOCKER_PLATFORM_MONITOR)_PATH = $(DOCKERS_PATH)/docker-platform-monitor
$(DOCKER_PLATFORM_MONITOR)_DEPENDS += $(SONIC_CONFIG_ENGINE)
$(DOCKER_PLATFORM_MONITOR)_LOAD_DOCKERS = $(DOCKER_BASE) $(DOCKER_PLATFORM_MONITOR)_LOAD_DOCKERS = $(DOCKER_BASE)
SONIC_SIMPLE_DOCKER_IMAGES += $(DOCKER_PLATFORM_MONITOR) SONIC_DOCKER_IMAGES += $(DOCKER_PLATFORM_MONITOR)

View File

@ -2,7 +2,7 @@
DOCKER_SNMP_SV2 = docker-snmp-sv2.gz DOCKER_SNMP_SV2 = docker-snmp-sv2.gz
$(DOCKER_SNMP_SV2)_PATH = $(DOCKERS_PATH)/docker-snmp-sv2 $(DOCKER_SNMP_SV2)_PATH = $(DOCKERS_PATH)/docker-snmp-sv2
$(DOCKER_SNMP_SV2)_DEPENDS += $(SNMP) $(SNMPD) $(DOCKER_SNMP_SV2)_DEPENDS += $(SNMP) $(SNMPD) $(SONIC_CONFIG_ENGINE)
$(DOCKER_SNMP_SV2)_PYTHON_WHEELS += $(ASYNCSNMP_PY3) $(DOCKER_SNMP_SV2)_PYTHON_WHEELS += $(ASYNCSNMP_PY3)
$(DOCKER_SNMP_SV2)_LOAD_DOCKERS += $(DOCKER_BASE) $(DOCKER_SNMP_SV2)_LOAD_DOCKERS += $(DOCKER_BASE)
SONIC_DOCKER_IMAGES += $(DOCKER_SNMP_SV2) SONIC_DOCKER_IMAGES += $(DOCKER_SNMP_SV2)

View File

@ -2,6 +2,6 @@
DOCKER_TEAMD = docker-teamd.gz DOCKER_TEAMD = docker-teamd.gz
$(DOCKER_TEAMD)_PATH = $(DOCKERS_PATH)/docker-teamd $(DOCKER_TEAMD)_PATH = $(DOCKERS_PATH)/docker-teamd
$(DOCKER_TEAMD)_DEPENDS += $(SWSS) $(LIBTEAMDCT) $(LIBTEAM_UTILS) $(DOCKER_TEAMD)_DEPENDS += $(SWSS) $(LIBTEAMDCT) $(LIBTEAM_UTILS) $(SONIC_CONFIG_ENGINE)
$(DOCKER_TEAMD)_LOAD_DOCKERS += $(DOCKER_BASE) $(DOCKER_TEAMD)_LOAD_DOCKERS += $(DOCKER_BASE)
SONIC_DOCKER_IMAGES += $(DOCKER_TEAMD) SONIC_DOCKER_IMAGES += $(DOCKER_TEAMD)

View File

@ -1,5 +1,5 @@
# sonic-config-engine package # sonic-config-engine package
SONIC_CONFIG_ENGINE = sonic-config-engine_1.0-1_all.deb SONIC_CONFIG_ENGINE = python-sonic-config-engine_1.0-1_all.deb
$(SONIC_CONFIG_ENGINE)_SRC_PATH = $(SRC_PATH)/sonic-config-engine $(SONIC_CONFIG_ENGINE)_SRC_PATH = $(SRC_PATH)/sonic-config-engine
SONIC_PYTHON_STDEB_DEBS += $(SONIC_CONFIG_ENGINE) SONIC_PYTHON_STDEB_DEBS += $(SONIC_CONFIG_ENGINE)

View File

@ -0,0 +1 @@
recursive-include platform *.json *.ini *.conf

View File

@ -169,12 +169,12 @@ def parse_dpg(dpg, hname):
intfs.append(intf) intfs.append(intf)
pcintfs = child.find(str(QName(ns, "PortChannelInterfaces"))) pcintfs = child.find(str(QName(ns, "PortChannelInterfaces")))
pc_intfs = [] pc_intfs = {}
for pcintf in pcintfs.findall(str(QName(ns, "PortChannel"))): for pcintf in pcintfs.findall(str(QName(ns, "PortChannel"))):
pcintfname = pcintf.find(str(QName(ns, "Name"))).text pcintfname = pcintf.find(str(QName(ns, "Name"))).text
pcintfmbr = pcintf.find(str(QName(ns, "AttachTo"))).text pcintfmbr = pcintf.find(str(QName(ns, "AttachTo"))).text
pcmbr_list = pcintfmbr.split(';', 1) pcmbr_list = pcintfmbr.split(';', 1)
pc_intfs.append({'name': pcintfname, 'members': pcmbr_list}) pc_intfs[pcintfname]=pcmbr_list
lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces"))) lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces")))
lo_intfs = [] lo_intfs = []
@ -209,7 +209,7 @@ def parse_dpg(dpg, hname):
vintfname = vintf.find(str(QName(ns, "Name"))).text vintfname = vintf.find(str(QName(ns, "Name"))).text
vlanid = vintf.find(str(QName(ns, "VlanID"))).text vlanid = vintf.find(str(QName(ns, "VlanID"))).text
vintfmbr = vintf.find(str(QName(ns, "AttachTo"))).text vintfmbr = vintf.find(str(QName(ns, "AttachTo"))).text
vmbr_list = vintfmbr.split(';')) vmbr_list = vintfmbr.split(';')
vlan_attributes = {'name': vintfname, 'members': vmbr_list, 'vlanid': vlanid} vlan_attributes = {'name': vintfname, 'members': vmbr_list, 'vlanid': vlanid}
for addrtuple in vlan_map.get(vintfname, []): for addrtuple in vlan_map.get(vintfname, []):
vlan_attributes.update(addrtuple) vlan_attributes.update(addrtuple)
@ -285,6 +285,17 @@ def get_mgmt_info(devices, dev, port):
return ret_val return ret_val
def get_alias_map_list(hwsku):
alias_map_json = os.path.join('/usr/share/sonic', hwsku, 'alias_map.json')
if not os.path.isfile(alias_map_json):
return None
with open(alias_map_json) as data:
alias_map_dict = json.load(data)
alias_map_list = []
for k,v in alias_map_dict.items():
alias_map_list.append({'sonic': k, 'origin': v})
return alias_map_list
def parse_xml(filename): def parse_xml(filename):
root = ET.parse(filename).getroot() root = ET.parse(filename).getroot()
mini_graph_path = filename mini_graph_path = filename
@ -312,14 +323,10 @@ def parse_xml(filename):
hostname = child.text hostname = child.text
# port_alias_map maps ngs port name to sonic port name # port_alias_map maps ngs port name to sonic port name
if hwsku == "Force10-S6000": alias_map_list = get_alias_map_list(hwsku)
for i in range(0, 128, 4): if alias_map_list != None:
port_alias_map["fortyGigE0/%d" % i] = "Ethernet%d" % i for item in alias_map_list:
elif hwsku == "Arista-7050-QX32": port_alias_map[item['origin']] = item['sonic']
for i in range(1, 25):
port_alias_map["Ethernet%d/1" % i] = "Ethernet%d" % ((i - 1) * 4)
for i in range(25, 33):
port_alias_map["Ethernet%d" % i] = "Ethernet%d" % ((i - 1) * 4)
for child in root: for child in root:
if child.tag == str(QName(ns, "DpgDec")): if child.tag == str(QName(ns, "DpgDec")):
@ -340,9 +347,9 @@ def parse_xml(filename):
vlan['members'] = " ".join(vlan['members']) vlan['members'] = " ".join(vlan['members'])
# Replace port with alias in port channel interfaces members # Replace port with alias in port channel interfaces members
for pc in pc_intfs: for pc in pc_intfs.keys():
for i,member in enumerate(pc['members']): for i,member in enumerate(pc_intfs[pc]):
pc['members'][i] = port_alias_map[member] pc_intfs[pc][i] = port_alias_map[member]
Tree = lambda: defaultdict(Tree) Tree = lambda: defaultdict(Tree)
@ -367,6 +374,7 @@ def parse_xml(filename):
results['minigraph_console'] = get_console_info(devices, console_dev, console_port) results['minigraph_console'] = get_console_info(devices, console_dev, console_port)
results['minigraph_mgmt'] = get_mgmt_info(devices, mgmt_dev, mgmt_port) results['minigraph_mgmt'] = get_mgmt_info(devices, mgmt_dev, mgmt_port)
results['inventory_hostname'] = hostname results['inventory_hostname'] = hostname
results['alias_map'] = alias_map_list
return results return results

View File

@ -0,0 +1,34 @@
{
"Ethernet8": "Ethernet8",
"Ethernet0": "Ethernet0",
"Ethernet4": "Ethernet4",
"Ethernet108": "Ethernet108",
"Ethernet100": "Ethernet100",
"Ethernet104": "Ethernet104",
"Ethernet96": "Ethernet96",
"Ethernet124": "Ethernet124",
"Ethernet120": "Ethernet120",
"Ethernet92": "Ethernet92",
"Ethernet28": "Ethernet28",
"Ethernet52": "Ethernet52",
"Ethernet56": "Ethernet56",
"Ethernet76": "Ethernet76",
"Ethernet72": "Ethernet72",
"Ethernet32": "Ethernet32",
"Ethernet16": "Ethernet16",
"Ethernet36": "Ethernet36",
"Ethernet12": "Ethernet12",
"Ethernet88": "Ethernet88",
"Ethernet24": "Ethernet24",
"Ethernet116": "Ethernet116",
"Ethernet80": "Ethernet80",
"Ethernet112": "Ethernet112",
"Ethernet84": "Ethernet84",
"Ethernet48": "Ethernet48",
"Ethernet44": "Ethernet44",
"Ethernet40": "Ethernet40",
"Ethernet64": "Ethernet64",
"Ethernet60": "Ethernet60",
"Ethernet20": "Ethernet20",
"Ethernet68": "Ethernet68"
}

View File

@ -0,0 +1,33 @@
# alias lanes
Ethernet0 0,1,2,3
Ethernet4 4,5,6,7
Ethernet8 8,9,10,11
Ethernet12 12,13,14,15
Ethernet16 16,17,18,19
Ethernet20 20,21,22,23
Ethernet24 24,25,26,27
Ethernet28 28,29,30,31
Ethernet32 32,33,34,35
Ethernet36 36,37,38,39
Ethernet40 40,41,42,43
Ethernet44 44,45,46,47
Ethernet48 48,49,50,51
Ethernet52 52,53,54,55
Ethernet56 56,57,58,59
Ethernet60 60,61,62,63
Ethernet64 64,65,66,67
Ethernet68 68,69,70,71
Ethernet72 72,73,74,75
Ethernet76 76,77,78,79
Ethernet80 80,81,82,83
Ethernet84 84,85,86,87
Ethernet88 88,89,90,91
Ethernet92 92,93,94,95
Ethernet96 96,97,98,99
Ethernet100 100,101,102,103
Ethernet104 104,105,106,107
Ethernet108 108,109,110,111
Ethernet112 112,113,114,115
Ethernet116 116,117,118,119
Ethernet120 120,121,122,123
Ethernet124 124,125,126,127

View File

@ -0,0 +1,21 @@
bus "i2c-7" "i2c-1-mux (chan_id 5)"
chip "lm75-i2c-7-4a"
label temp1 "Ambient Port Temp"
bus "i2c-5" "i2c-1-mux (chan_id 3)"
chip "ucd9200-i2c-5-27"
label in1 "UCD1 vin"
label in2 "ASIC 3.3 vout"
label in3 "ASIC 1.2 vout"
label temp1 "UCD1 Temp"
label temp2 "UCD1 Temp2"
chip "ucd9200-i2c-5-41"
label in1 "UCD2 vin"
label in2 "ASIC Vcore vout"
label temp1 "UCD2 Temp1"
label temp2 "UCD2 Temp2"
bus "i2c-17" "i2c-1-mux (chan_id 7)"
chip "lm75-i2c-17-49"
label temp1 "Ambient Board Temp"

View File

@ -0,0 +1,34 @@
{
"Ethernet8": "fortyGigE0/8",
"Ethernet0": "fortyGigE0/0",
"Ethernet4": "fortyGigE0/4",
"Ethernet108": "fortyGigE0/108",
"Ethernet100": "fortyGigE0/100",
"Ethernet104": "fortyGigE0/104",
"Ethernet96": "fortyGigE0/96",
"Ethernet124": "fortyGigE0/124",
"Ethernet120": "fortyGigE0/120",
"Ethernet92": "fortyGigE0/92",
"Ethernet28": "fortyGigE0/28",
"Ethernet52": "fortyGigE0/52",
"Ethernet56": "fortyGigE0/56",
"Ethernet76": "fortyGigE0/76",
"Ethernet72": "fortyGigE0/72",
"Ethernet32": "fortyGigE0/32",
"Ethernet16": "fortyGigE0/16",
"Ethernet36": "fortyGigE0/36",
"Ethernet12": "fortyGigE0/12",
"Ethernet88": "fortyGigE0/88",
"Ethernet24": "fortyGigE0/24",
"Ethernet116": "fortyGigE0/116",
"Ethernet80": "fortyGigE0/80",
"Ethernet112": "fortyGigE0/112",
"Ethernet84": "fortyGigE0/84",
"Ethernet48": "fortyGigE0/48",
"Ethernet44": "fortyGigE0/44",
"Ethernet40": "fortyGigE0/40",
"Ethernet64": "fortyGigE0/64",
"Ethernet60": "fortyGigE0/60",
"Ethernet20": "fortyGigE0/20",
"Ethernet68": "fortyGigE0/68"
}

View File

@ -0,0 +1,33 @@
# alias lanes
Ethernet0 29,30,31,32
Ethernet4 25,26,27,28
Ethernet8 37,38,39,40
Ethernet12 33,34,35,36
Ethernet16 41,42,43,44
Ethernet20 45,46,47,48
Ethernet24 5,6,7,8
Ethernet28 1,2,3,4
Ethernet32 9,10,11,12
Ethernet36 13,14,15,16
Ethernet40 21,22,23,24
Ethernet44 17,18,19,20
Ethernet48 49,50,51,52
Ethernet52 53,54,55,56
Ethernet56 61,62,63,64
Ethernet60 57,58,59,60
Ethernet64 65,66,67,68
Ethernet68 69,70,71,72
Ethernet72 77,78,79,80
Ethernet76 73,74,75,76
Ethernet80 105,106,107,108
Ethernet84 109,110,111,112
Ethernet88 117,118,119,120
Ethernet92 113,114,115,116
Ethernet96 121,122,123,124
Ethernet100 125,126,127,128
Ethernet104 85,86,87,88
Ethernet108 81,82,83,84
Ethernet112 89,90,91,92
Ethernet116 93,94,95,96
Ethernet120 97,98,99,100
Ethernet124 101,102,103,104

View File

@ -0,0 +1,57 @@
# libsensors configuration file
# --------------------------------------------------
#
# tmp75-i2c-11-4c has sensors close to Networking ASIC.
# tmp75-i2c-11-4d has sensors close to NIC.
# tmp75-i2c-11-4e is an ambient temperature sensor.
chip "tmp75-*"
set temp1_max 50
set temp1_max_hyst 25
# emc1403-i2c-10-4d has following temperature sensors:
# temp1: CPU0 external Temp Sensor
# temp2: CPU1 external Temp Sensor
# temp3: CPU Internal DTS (Internal die, max of all die readings)
chip "emc1403-*"
set temp1_crit 85
set temp1_max 50
set temp2_crit 85
set temp2_max 50
set temp3_crit 85
set temp3_max 50
chip "max6620-i2c-*-2a"
ignore fan3
ignore fan4
chip "w83627dhg-*"
label in0 "VCore 1"
label in1 "VCore 2"
set in0_min 0
set in0_max 1.74
set in1_min 0
set in1_max 1.74
ignore fan1
ignore fan2
ignore fan3
ignore fan4
ignore fan5
ignore in4
ignore in5
ignore in6
ignore temp1
ignore temp2
ignore temp3
ignore cpu0_vid
ignore intrusion0
chip "jc42-*"
set temp1_max 50
set temp1_crit 85
chip "dni_dps460-*"
set temp1_max 50
set temp2_max 50

View File

@ -1,6 +1,20 @@
#!/usr/bin/env python #!/usr/bin/env python
from setuptools import setup from setuptools import setup
import os.path
def get_platform_file_list():
data_files = []
repo_path = os.path.abspath(os.path.dirname(__file__))
data_path = os.path.join(repo_path, 'platform')
platforms = os.listdir(data_path)
for platform in platforms:
data_files.append( (os.path.join('/usr/share/sonic', platform),
['platform/' + platform + '/alias_map.json',
'platform/' + platform + '/port_config.ini',
'platform/' + platform + '/sensors.conf']
))
return data_files
setup(name='sonic-config-engine', setup(name='sonic-config-engine',
version='1.0', version='1.0',
@ -10,5 +24,6 @@ setup(name='sonic-config-engine',
url='https://github.com/Azure/sonic-buildimage', url='https://github.com/Azure/sonic-buildimage',
py_modules=['minigraph'], py_modules=['minigraph'],
scripts=['sonic-cfggen'], scripts=['sonic-cfggen'],
install_requires=['lxml', 'jinja2', 'netaddr', 'ipaddr', 'yaml'], data_files=get_platform_file_list(),
install_requires=['lxml', 'jinja2', 'netaddr', 'ipaddr', 'pyyaml'],
) )

View File

@ -6,6 +6,7 @@ import argparse
import yaml import yaml
import jinja2 import jinja2
import netaddr import netaddr
import json
from minigraph import parse_xml from minigraph import parse_xml
@ -36,27 +37,51 @@ def is_ipv6(value):
def main(): def main():
parser=argparse.ArgumentParser(description="Render configuration file from minigraph data and jinja2 template.") parser=argparse.ArgumentParser(description="Render configuration file from minigraph data and jinja2 template.")
parser.add_argument("template") parser.add_argument("-m", "--minigraph", help="minigraph xml file")
parser.add_argument("-m", "--minigraph", required=True, help="minigraph xml file") parser.add_argument("-y", "--yaml", help="yaml file that contains addtional variables")
parser.add_argument("-v", "--var-file", help="yaml file that contains addtional variables") parser.add_argument("-a", "--additional-data", help="addition data, in json string")
group = parser.add_mutually_exclusive_group()
group.add_argument("-t", "--template", help="render the data with the template file")
group.add_argument("-v", "--var", help="print the value of a variable")
group.add_argument("--var-json", help="print the value of a variable, in json format")
group.add_argument("--var-keys", help="print all keys of a map variable")
group.add_argument("--print-data", help="print all data", action='store_true')
args = parser.parse_args() args = parser.parse_args()
minigraph = args.minigraph data = {}
template_file = os.path.abspath(args.template)
data = parse_xml(minigraph)
if args.var_file != None: if args.minigraph != None:
with open(args.var_file, 'r') as stream: minigraph = args.minigraph
additional_data = yaml.load(stream) data.update(parse_xml(minigraph))
if args.yaml != None:
with open(args.yaml, 'r') as stream:
additional_data = yaml.load(stream)
data.update(additional_data) data.update(additional_data)
env = jinja2.Environment(loader=jinja2.FileSystemLoader('/'), trim_blocks=True) if args.additional_data != None:
env.filters['ipv4'] = is_ipv4 data.update(json.loads(args.additional_data))
env.filters['ipv6'] = is_ipv6
template = env.get_template(template_file)
print template.render(data) if args.template != None:
template_file = os.path.abspath(args.template)
env = jinja2.Environment(loader=jinja2.FileSystemLoader('/'), trim_blocks=True)
env.filters['ipv4'] = is_ipv4
env.filters['ipv6'] = is_ipv6
template = env.get_template(template_file)
print template.render(data)
if args.var != None:
print data[args.var]
if args.var_json != None:
print json.dumps(data[args.var_json])
if args.var_keys != None:
for key in data[args.var_keys].keys():
print key
if args.print_data:
print data
if __name__ == "__main__": if __name__ == "__main__":
main() main()