sonic-buildimage/files/image_config/reset-factory/reset-factory
Mohammedz93 28b9299445
Support Reset factory (#14105)
#### Why I did it
Support reset factory in Sonic OS
[Reset Factory HLD](https://github.com/sonic-net/SONiC/pull/1231)
[Sonic-mgmt tests](https://github.com/sonic-net/sonic-mgmt/pull/7652)

#### How I did it
- Added new script "/usr/bin/reset-factory"
   * It generates a new config_db.json files with factory configurations
   * It clears system files and logs
   * It removes all docker containers on system except database
   * It clears non-default users and restores default users password
- Dump the default users info to a new file during build "/etc/sonic/default_users.json"
- Supported new type "Keep-basic" in "config-setup factory"
- Add new conf file for config-setup "/etc/config-setup/config-setup.conf

#### How to verify it
- Run reset-factory script with all types: < none | keep-all-config | only-config | keep-basic >
- Run config-setup factory with parameters < none | keep-basic >

#### Description for the changelog
Support reset factory in Sonic OS

#### Ensure to add label/tag for the feature raised. example - PR#2174 under sonic-utilities repo. where, Generic Config and Update feature has been labelled as GCU.
2023-07-11 16:14:17 -07:00

198 lines
6.2 KiB
Bash
Executable File

#!/bin/bash
###########################################################################
# SONIC Factory reset script #
# /usr/bin/reset-factory #
# This script is used to reset the system to factory settings. #
# It creates factory default configuration and save it to config_db.json. #
# Also, it clear logs, tech-support, reboot-cause files, warmboot files, #
# docker containers non-default users, users history files and #
# home directories. #
###########################################################################
# Initialize constants
CONFIG_DB_JSON=/etc/sonic/config_db.json
DEFAULT_USERS_FILE=/etc/sonic/default_users.json
PERMLOG=/var/log/systemlog
SONIC_VERSION=$(sonic-cfggen -y /etc/sonic/sonic_version.yml -v build_version)
SONIC_OVERLAY_UPPERDIR="/host/image-$SONIC_VERSION/rw/etc/sonic"
SERVICES_STOPPED=0
trap "error_cleanup" HUP INT QUIT PIPE TERM
# Command usage and help
usage()
{
cat << EOF
Usage: reset-factory < keep-all-config | only-config | keep-basic >
Create factory default configuration and save it to
to ${CONFIG_DB_JSON}.
Clears logs, system files and reboot the system.
Default - Reset configurations to factory default. Logs and files will be deleted.
keep-all-config - Preserves all configurations after boot. Logs and files will be deleted.
only-config - Reset configurations to factory default. Logs and files will be preserved.
keep-basic - Preserves basic configurations only after boot. Logs and files will be deleted.
EOF
}
run_reboot()
{
reboot
# If for any reason we reach this code, then force reboot
rc=$?
if [ $rc -ne 0 ]; then
# Force reboot
reboot -f
fi
}
error_cleanup()
{
if [ ! -z "${TEMP_CFG}" ]; then
# Recover config_db.json file
mv ${TEMP_CFG} ${CONFIG_DB_JSON}
fi
if [ $SERVICES_STOPPED -eq 0 ]; then
ERRMSG="reset-factory: halted with error before stopping critical services; exiting"
logger $ERRMSG
echo $ERRMSG
exit 1
else
ERRMSG="reset-factory: halted with error after stopping critical services; rebooting"
logger $ERRMSG
echo $ERRMSG
run_reboot
fi
}
# Restore original /etc/sonic folder by clearing the folder in overlayfs upperdir
clear_sonic_dir()
{
EXCLUDE_LIST="${CONFIG_DB_JSON}\|/etc/sonic/sonic-environment"
find $SONIC_OVERLAY_UPPERDIR -type f | grep -ve ${EXCLUDE_LIST} | xargs rm -rf
# remount root
mount -o remount /
}
# Get list of defaults users names and passwords from DEFAULT_USERS_FILE
# Delete non-default users and restore default password of default users
reset_users()
{
if [ ! -f "${DEFAULT_USERS_FILE}" ]; then
echo "Error: Failed to get default users information"
return
fi
# Get default user accounts
default_users=$(jq -r '. | keys[]' $DEFAULT_USERS_FILE)
EXCLUDE_LIST=$(echo $default_users | tr ' ' '|')
# Get non-default user accounts
other_users=$(getent passwd | awk -F: '($3>=1000 && $3<=60000) {print $1}' | grep -E -v $EXCLUDE_LIST)
echo "Remove non-default users"
for user in ${other_users[@]}
do
# avoid printing home directory and mail spool errors
userdel -rf $user 2> /dev/null
done
echo "Restore default users passwords"
for user in ${default_users[@]}
do
# Restore default password
user_pass=$(jq -r '.[$user].password' --arg user "${user}" $DEFAULT_USERS_FILE)
echo "$user:$user_pass" | chpasswd -e
# Check if we need to expire password
expire=$(jq -r '.[$user].expire' --arg user "${user}" $DEFAULT_USERS_FILE)
[ "${expire}" == "true" ] && passwd -e ${user}
done
}
# Only root can run reset factory
if [ $UID != 0 ]; then
echo "You must be root to reset system to factory settings"
exit 1
fi
CMD=$1
FACTORY_TYPE=
if [ "$CMD" = "keep-all-config" ] || [ "$CMD" = "only-config" ] || \
[ "$CMD" = "keep-basic" ] || [ -z "$CMD" ]; then
FACTORY_TYPE=$CMD
else
usage
exit 1
fi
SERVICES_STOPPED=1
echo "Stop critical services"
monit unmonitor container_checker
systemctl stop sonic.target --job-mode replace-irreversibly
rc=$?
if [ $rc -ne 0 ]; then
error_cleanup
fi
DATE=$(date "+%Y/%m/%d %H:%M:%S")
HOSTNAME=$(hostname | sed 's/\./ /' | awk '{print $1}')
printf "%s %s reset-factory: resetting system to factory defaults\n" "$DATE" "$HOSTNAME" >> $PERMLOG
# Backup and delete config_db.json
TEMP_CFG="/tmp/temp_config_db.$$"
cp ${CONFIG_DB_JSON} ${TEMP_CFG}
if [ "$FACTORY_TYPE" != "keep-basic" ] && [ "$FACTORY_TYPE" != "keep-all-config" ]; then
rm -f ${CONFIG_DB_JSON}
fi
echo "Call config-setup factory"
config-setup factory $FACTORY_TYPE
rc=$?
if [ $rc -ne 0 ]; then
error_cleanup
fi
if [ "$FACTORY_TYPE" != "only-config" ]; then
if [ "$FACTORY_TYPE" != "keep-basic" ]; then
# Delete non-default users and restore default users passwords
reset_users
echo "Delete bash, python and vim history files"
find /home /root -type f -name ".bash_history" -o -name ".python_history" -o -name ".viminfo" | xargs rm -rf
echo "Delete any non-dotfiles in users home directories"
find /home/ /root -type f ! -iname ".*" -delete
fi
echo "Remove all docker containers except the database"
database_pattern=($(docker ps -a -q -f "name=database" | paste -sd '|' -))
docker rm -f $(docker ps -a -q | egrep -v ${database_pattern}) > /dev/null
echo "Clear sonic directory"
clear_sonic_dir
echo "Clear warmboot folder"
find /host/warmboot/ -type f -delete
echo "Delete reboot-cause files and symlinks"
find /host/reboot-cause/ -type l,f -delete
echo "Delete tech-support files"
rm -rf /var/dump/*
echo "Delete logs files"
find /var/log/ -type f ! -iname "wtmp" ! -iname "btmp" ! -iname "lastlog" ! -iname "systemlog" -delete
# Clear wtmp, utmp and lastlog files
rm -rf /var/log/btmp.*
cat /dev/null > /var/log/btmp
rm -rf /var/log/wtmp.*
cat /dev/null > /var/log/wtmp
rm -rf /var/log/lastlog.*
cat /dev/null > /var/log/lastlog
fi
run_reboot