#!/bin/bash function getMountPoint() { echo $1 | python -c "import sys, json, os; mnts = [x for x in json.load(sys.stdin)[0]['Mounts'] if x['Destination'] == '/usr/share/sonic/hwsku']; print '' if len(mnts) == 0 else os.path.basename(mnts[0]['Source'])" 2>/dev/null } function updateHostName() { HOSTS=/etc/hosts HOSTS_TMP=/etc/hosts.tmp EXEC="docker exec -i {{docker_container_name}} bash -c" NEW_HOSTNAME="$1" HOSTNAME=`$EXEC "hostname"` if ! [[ $HOSTNAME =~ ^[a-zA-Z0-9.\-]*$ ]]; then HOSTNAME=`hostname` fi # copy HOSTS to HOSTS_TMP $EXEC "cp $HOSTS $HOSTS_TMP" # remove entry with hostname $EXEC "sed -i \"/$HOSTNAME$/d\" $HOSTS_TMP" # add entry with new hostname $EXEC "echo -e \"127.0.0.1\t$NEW_HOSTNAME\" >> $HOSTS_TMP" echo "Set hostname in {{docker_container_name}} container" $EXEC "hostname '$NEW_HOSTNAME'" $EXEC "cat $HOSTS_TMP > $HOSTS" $EXEC "rm -f $HOSTS_TMP" } function getBootType() { # same code snippet in files/scripts/syncd.sh case "$(cat /proc/cmdline)" in *SONIC_BOOT_TYPE=warm*) TYPE='warm' ;; *SONIC_BOOT_TYPE=fastfast*) TYPE='fastfast' ;; *SONIC_BOOT_TYPE=fast*|*fast-reboot*) TYPE='fast' ;; *) TYPE='cold' esac echo "${TYPE}" } function preStartAction() { {%- if docker_container_name == "database" %} WARM_DIR=/host/warmboot if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then # Load redis content from /host/warmboot/dump.rdb docker cp $WARM_DIR/dump.rdb database:/var/lib/redis/dump.rdb else # Create an emtpy file and overwrite any RDB if already there echo -n > /tmp/dump.rdb docker cp /tmp/dump.rdb database:/var/lib/redis/ fi {%- elif docker_container_name == "snmp" %} docker exec -i database redis-cli -n 6 HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) vrfenabled=`/usr/bin/redis-cli -n 4 hget "MGMT_VRF_CONFIG|vrf_global" mgmtVrfEnabled` v1SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" DestIp` v1SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" DestPort` v1Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" vrf` v1Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" Community` v2SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" DestIp` v2SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" DestPort` v2Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" vrf` v2Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" Community` v3SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" DestIp` v3SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" DestPort` v3Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" vrf` v3Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" Community` if [ "${v1SnmpTrapIp}" != "" ] then if [ "${v1Vrf}" != "None" ] then sed -i "s/v1_trap_dest:.*/v1_trap_dest: ${v1SnmpTrapIp}:${v1SnmpTrapPort}%${v1Vrf} ${v1Comm}/" "/etc/sonic/snmp.yml" else sed -i "s/v1_trap_dest:.*/v1_trap_dest: ${v1SnmpTrapIp}:${v1SnmpTrapPort} ${v1Comm}/" "/etc/sonic/snmp.yml" fi else sed -i "s/v1_trap_dest:.*/v1_trap_dest: NotConfigured/" "/etc/sonic/snmp.yml" fi if [ "${v2SnmpTrapIp}" != "" ] then if [ "${v2Vrf}" != "None" ] then sed -i "s/v2_trap_dest:.*/v2_trap_dest: ${v2SnmpTrapIp}:${v2SnmpTrapPort}%${v2Vrf} ${v2Comm}/" "/etc/sonic/snmp.yml" else sed -i "s/v2_trap_dest:.*/v2_trap_dest: ${v2SnmpTrapIp}:${v2SnmpTrapPort} ${v2Comm}/" "/etc/sonic/snmp.yml" fi else sed -i "s/v2_trap_dest:.*/v2_trap_dest: NotConfigured/" "/etc/sonic/snmp.yml" fi if [ "${v3SnmpTrapIp}" != "" ] then if [ "${v3Vrf}" != "None" ] then sed -i "s/v3_trap_dest:.*/v3_trap_dest: ${v3SnmpTrapIp}:${v3SnmpTrapPort}%${v3Vrf} ${v3Comm}/" "/etc/sonic/snmp.yml" else sed -i "s/v3_trap_dest:.*/v3_trap_dest: ${v3SnmpTrapIp}:${v3SnmpTrapPort} ${v3Comm}/" "/etc/sonic/snmp.yml" fi else sed -i "s/v3_trap_dest:.*/v3_trap_dest: NotConfigured/" "/etc/sonic/snmp.yml" fi echo -n "" > /tmp/snmpagentaddr.yml keys=`/usr/bin/redis-cli -n 4 keys "SNMP_AGENT_ADDRESS_CONFIG|*"` count=1 for key in $keys;do ip=`echo $key|cut -d "|" -f2` echo -n "snmp_agent_address_$count: $ip" >> /tmp/snmpagentaddr.yml port=`echo $key|cut -d "|" -f3` if [ -n "$port" ]; then echo -n ":$port" >> /tmp/snmpagentaddr.yml fi vrf=`echo $key|cut -d "|" -f4` if [ -n "$vrf" ]; then echo -n "%$vrf" >> /tmp/snmpagentaddr.yml fi echo "" >> /tmp/snmpagentaddr.yml count=$((count+1)) done sed -i '/snmp_agent_address_*/d' /etc/sonic/snmp.yml cat /tmp/snmpagentaddr.yml >> /etc/sonic/snmp.yml {%- else %} : # nothing {%- endif %} } function postStartAction() { {%- if docker_container_name == "database" %} # Wait until redis starts /usr/bin/docker exec database ping_pong_db_insts if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then rm -f $WARM_DIR/dump.rdb else # If there is a config db dump file, load it if [ -r /etc/sonic/config_db.json ]; then sonic-cfggen -j /etc/sonic/config_db.json --write-to-db fi if [[ "$BOOT_TYPE" == "fast" ]]; then # set the key to expire in 3 minutes redis-cli -n 6 SET "FAST_REBOOT|system" "1" "EX" "180" fi redis-cli -n 4 SET "CONFIG_DB_INITIALIZED" "1" fi if [[ -x /usr/bin/db_migrator.py ]]; then # Migrate the DB to the latest schema version if needed /usr/bin/db_migrator.py -o migrate fi {%- elif docker_container_name == "swss" %} docker exec swss rm -f /ready # remove cruft if [[ "$BOOT_TYPE" == "fast" ]] && [[ -d /host/fast-reboot ]]; then test -e /host/fast-reboot/fdb.json && docker cp /host/fast-reboot/fdb.json swss:/ test -e /host/fast-reboot/arp.json && docker cp /host/fast-reboot/arp.json swss:/ test -e /host/fast-reboot/default_routes.json && docker cp /host/fast-reboot/default_routes.json swss:/ rm -fr /host/fast-reboot fi docker exec swss touch /ready # signal swssconfig.sh to go {%- elif docker_container_name == "pmon" %} DEVPATH="/usr/share/sonic/device" REBOOT="platform_reboot" PSENSOR="/usr/local/bin/platform_sensors.py" if [ -d ${DEVPATH}/${PLATFORM} ] && [ -f $PSENSOR ]; then exist=`docker exec -i pmon ls /usr/bin/platform_sensors.py "$@" 2>/dev/null` if [ -z "$exist" ]; then docker cp $PSENSOR pmon:/usr/bin/ fi fi {%- else %} : # nothing {%- endif %} } start() { # Obtain boot type from kernel arguments BOOT_TYPE=`getBootType` # Obtain our platform as we will mount directories with these names in each docker PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` {%- if docker_container_name == "database" %} # Don't mount HWSKU in {{docker_container_name}} container. HWSKU="" {%- else %} # Obtain our HWSKU as we will mount directories with these names in each docker HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` HOSTNAME=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hostname"]'` {%- endif %} if [ -z "$HOSTNAME" ] || ! [[ $HOSTNAME =~ ^[a-zA-Z0-9.\-]*$ ]]; then HOSTNAME=`hostname` fi DOCKERCHECK=`docker inspect --type container {{docker_container_name}} 2>/dev/null` if [ "$?" -eq "0" ]; then {%- if docker_container_name == "database" %} DOCKERMOUNT="" {%- else %} DOCKERMOUNT=`getMountPoint "$DOCKERCHECK"` {%- endif %} if [ x"$DOCKERMOUNT" == x"$HWSKU" ]; then {%- if docker_container_name == "database" %} echo "Starting existing {{docker_container_name}} container" {%- else %} echo "Starting existing {{docker_container_name}} container with HWSKU $HWSKU" {%- endif %} preStartAction docker start {{docker_container_name}} CURRENT_HOSTNAME="$(docker exec {{docker_container_name}} hostname)" if [ x"$HOSTNAME" != x"$CURRENT_HOSTNAME" ]; then updateHostName "$HOSTNAME" fi postStartAction exit $? fi # docker created with a different HWSKU, remove and recreate echo "Removing obsolete {{docker_container_name}} container with HWSKU $DOCKERMOUNT" docker rm -f {{docker_container_name}} fi {%- if docker_container_name == "database" %} echo "Creating new {{docker_container_name}} container" # if database_config exists in old_config, use it; otherwise use the default one in new image if [ -f /etc/sonic/old_config/database_config.json ]; then echo "Use database_config.json from old system..." mv /etc/sonic/old_config/database_config.json /etc/sonic/ fi {%- else %} echo "Creating new {{docker_container_name}} container with HWSKU $HWSKU" {%- endif %} {%- if sonic_asic_platform == "mellanox" %} # TODO: Mellanox will remove the --tmpfs exception after SDK socket path changed in new SDK version {%- endif %} docker create {{docker_image_run_opt}} \ {%- if install_debug_image == "y" %} -v /src:/src:ro -v /debug:/debug:rw \ {%- endif %} {%- if '--log-driver=json-file' in docker_image_run_opt or '--log-driver' not in docker_image_run_opt %} --log-opt max-size=2M --log-opt max-file=5 \ {%- endif %} {%- if sonic_asic_platform == "mellanox" %} {%- if docker_container_name == "syncd" %} -v /var/log/mellanox/sniffer:/var/log/mellanox/sniffer:rw \ -v mlnx_sdk_socket:/tmp \ -v /dev/shm:/dev/shm:rw \ {%- elif docker_container_name == "pmon" %} -v /var/run/hw-management:/var/run/hw-management:rw \ -v mlnx_sdk_socket:/tmp \ -v /dev/shm:/dev/shm:rw \ {%- else %} --tmpfs /tmp \ {%- endif %} {%- endif %} -v /var/run/redis:/var/run/redis:rw \ -v /usr/share/sonic/device/$PLATFORM:/usr/share/sonic/platform:ro \ {%- if docker_container_name != "database" %} -v /usr/share/sonic/device/$PLATFORM/$HWSKU:/usr/share/sonic/hwsku:ro \ {%- endif %} {%- if sonic_asic_platform != "mellanox" %} --tmpfs /tmp \ {%- endif %} --tmpfs /var/tmp \ --hostname "$HOSTNAME" \ --name={{docker_container_name}} {{docker_image_name}}:latest || { echo "Failed to docker run" >&1 exit 4 } preStartAction docker start {{docker_container_name}} postStartAction } wait() { docker wait {{docker_container_name}} } stop() { docker stop {{docker_container_name}} } case "$1" in start|wait|stop|updateHostName) cmd=$1 shift $cmd $@ ;; *) echo "Usage: $0 {start|wait|stop|updateHostName new_hostname}" exit 1 ;; esac