sonic-buildimage/files/build_templates/docker_image_ctl.j2
Stephen Sun 7d0570c517
[Mellanox]Take advantage of sdk variable to customize the location where sdk_socket exists. (#4223)
Take advantage of an SDK environment variable to customize the location where sdk_socket exists.
In the latest SDK sdk_socket has been moved from /tmp to /var/run which is a better place to contain this kind of file.
However, this prevents the subdirs under /var/run from being mapped to different volumes. To resolve this, we take advantage of an SDK variable to designate the location of sdk_socket.
This requires every process that requires to access sdk_socket have this environment variable defined. However, to define environment variable for each process is less scalable. We take advantage of the docker scope environment variable to avoid that.
It depends on PR 4227
2020-03-09 12:36:56 -07:00

261 lines
9.1 KiB
Django/Jinja

#!/bin/bash
# single instance containers are still supported (even though it might not look like it)
# if no instance number is passed to this script, $DEV will simply be unset, resulting in docker
# commands being sent to the base container name. E.g. `docker start database$DEV` simply starts
# the container `database` if no instance number is passed since `$DEV` is not defined
{%- if docker_container_name == "database" %}
link_namespace() {
# Makes namespace of a docker container available in
# /var/run/netns so it can be managed with iproute2
mkdir -p /var/run/netns
PID="$(docker inspect -f {{"'{{.State.Pid}}'"}} "{{docker_container_name}}$DEV")"
if `ip netns | grep --quiet -w "{{docker_container_name}}$DEV"`; then # namespace exists
if [ $(readlink -f /var/run/netns/$NET_NS$DEV) = $(readlink -f /proc/$PID/ns/net) ]; then # namespace is correctly linked
return 0
else # if it's incorrectly linked remove it
ip netns delete "{{docker_container_name}}$DEV"
fi
fi
ln -s /proc/$PID/ns/net /var/run/netns/$NET_NS$DEV
}
{%- endif %}
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 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" %}
sonic-db-cli STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s)
{%- else %}
: # nothing
{%- endif %}
}
function postStartAction()
{
{%- if docker_container_name == "database" %}
if [ "$DEV" ]; then
link_namespace $DEV
fi
# 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.json dump file, load it.
if [ -r /etc/sonic/config_db.json ]; then
if [ -r /etc/sonic/init_cfg.json ]; then
sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db.json --write-to-db
else
sonic-cfggen -j /etc/sonic/config_db.json --write-to-db
fi
fi
if [[ "$BOOT_TYPE" == "fast" ]]; then
# set the key to expire in 3 minutes
sonic-db-cli STATE_DB SET "FAST_REBOOT|system" "1" "EX" "180"
fi
sonic-db-cli CONFIG_DB 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"]'`
{%- endif %}
DOCKERCHECK=`docker inspect --type container {{docker_container_name}}$DEV 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}}$DEV container"
{%- else %}
echo "Starting existing {{docker_container_name}}$DEV container with HWSKU $HWSKU"
{%- endif %}
preStartAction
docker start {{docker_container_name}}$DEV
postStartAction
exit $?
fi
# docker created with a different HWSKU, remove and recreate
echo "Removing obsolete {{docker_container_name}}$DEV container with HWSKU $DOCKERMOUNT"
docker rm -f {{docker_container_name}}$DEV
fi
{%- if docker_container_name == "database" %}
echo "Creating new {{docker_container_name}}$DEV 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}}$DEV container with HWSKU $HWSKU"
{%- endif %}
if [ -z "$DEV" ]; then
NET="host"
else
{%- if docker_container_name == "database" %}
NET="bridge"
{%- else %}
NET="container:database$DEV"
{%- endif %}
fi
{%- 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}} \
--net=$NET \
--uts=host \{# W/A: this should be set per-docker, for those dockers which really need host's UTS namespace #}
{%- 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:/var/run/sx_sdk \
-v mlnx_sdk_ready:/tmp \
-v /dev/shm:/dev/shm:rw \
-e SX_API_SOCKET_FILE=/var/run/sx_sdk/sx_api.sock \
{%- elif docker_container_name == "pmon" %}
-v /var/run/hw-management:/var/run/hw-management:rw \
-v mlnx_sdk_socket:/var/run/sx_sdk \
-v mlnx_sdk_ready:/tmp \
-e SX_API_SOCKET_FILE=/var/run/sx_sdk/sx_api.sock \
-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 \
--name={{docker_container_name}}$DEV {{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}}$DEV
}
stop() {
docker stop {{docker_container_name}}$DEV
{%- if docker_container_name == "database" %}
ip netns delete "$NET_NS$DEV"
{%- endif %}
}
OP=$1
DEV=$2 # namespace/device number to operate on
NET_NS="asic" #name of the network namespace
case "$1" in
start|wait|stop)
$1
;;
*)
echo "Usage: $0 {start namespace(optional)|wait namespace(optional)|stop namespace(optional)}"
exit 1
;;
esac