768beb79e1
this is the first step to moving different databases tables into different database instances in this PR, only handle multiple database instances creation based on user configuration at /etc/sonic/database_config.json we keep current method to create single database instance if no extra/new DATABASE configuration exist in database_config.json file. if user try to configure more db instances at database_config.json , we create those new db instances along with the original db instance existing today. The configuration is as below, later we can add more db related information if needed: { ... "DATABASE": { "redis-db-01" : { "port" : "6380", "database": ["APPL_DB", "STATE_DB"] }, "redis-db-02" : { "port" : "6381", "database":["ASIC_DB"] }, } ... } The detail description is at design doc at Azure/SONiC#271 The main idea is : when database.sh started, we check the configuration and generate corresponding scripts. rc.local service handle old_config copy when loading new images, there is no dependency between rc.local and database service today, for safety and make sure the copy operation are done before database try to read it, we make database service run after rc.local Then database docker started, we check the configuration and generate corresponding scripts/.conf in database docker as well. based on those conf, we create databases instances as required. at last, we ping_pong check database are up and continue Signed-off-by: Dong Zhang d.zhang@alibaba-inc.com
233 lines
7.7 KiB
Django/Jinja
233 lines
7.7 KiB
Django/Jinja
#!/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
|
|
{%- 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
|
|
|
|
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
|
|
{%- elif docker_container_name == "snmp" %}
|
|
docker exec -i database redis-cli -n 6 HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s)
|
|
{%- 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}}
|
|
updateHostName "$HOSTNAME"
|
|
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
|