diff --git a/README b/README index 329eb1cb..b7a12b82 100644 --- a/README +++ b/README @@ -130,7 +130,7 @@ it the proper way for a production system, we have a script doing this for Ubuntu and Debian systems: % cd utils - % ./install_server + % ./install_server.sh The script will ask you a few questions and will setup everything you need to run Redis properly as a background daemon that will start again on diff --git a/utils/install_server.sh b/utils/install_server.sh index c5ca944e..15b60a08 100755 --- a/utils/install_server.sh +++ b/utils/install_server.sh @@ -30,46 +30,48 @@ # this scripts should be run as root die () { - echo "ERROR: $1. Aborting!" + echo "ERROR: $1. Aborting!" exit 1 } + +#Absolute path to this script +SCRIPT=$(readlink -f $0) +#Absolute path this script is in +SCRIPTPATH=$(dirname $SCRIPT) + #Initial defaults _REDIS_PORT=6379 echo "Welcome to the redis service installer" -echo "This script will help you easily set up a running redis server +echo "This script will help you easily set up a running redis server" +echo -" - -#check for root user TODO: replace this with a call to "id" -if [ `whoami` != "root" ] ; then +#check for root user +if [ "$(id -u)" -ne 0 ] ; then echo "You must run this script as root. Sorry!" exit 1 fi - #Read the redis port -read -p "Please select the redis port for this instance: [$_REDIS_PORT] " REDIS_PORT -if [ ! `echo $REDIS_PORT | egrep "^[0-9]+\$"` ] ; then +read -p "Please select the redis port for this instance: [$_REDIS_PORT] " REDIS_PORT +if ! echo $REDIS_PORT | egrep -q '^[0-9]+$' ; then echo "Selecting default: $_REDIS_PORT" - REDIS_PORT=$_REDIS_PORT + REDIS_PORT=$_REDIS_PORT fi #read the redis config file _REDIS_CONFIG_FILE="/etc/redis/$REDIS_PORT.conf" read -p "Please select the redis config file name [$_REDIS_CONFIG_FILE] " REDIS_CONFIG_FILE -if [ !"$REDIS_CONFIG_FILE" ] ; then +if [ -z "$REDIS_CONFIG_FILE" ] ; then REDIS_CONFIG_FILE=$_REDIS_CONFIG_FILE echo "Selected default - $REDIS_CONFIG_FILE" fi -#try and create it -mkdir -p `dirname "$REDIS_CONFIG_FILE"` || die "Could not create redis config directory" #read the redis log file path _REDIS_LOG_FILE="/var/log/redis_$REDIS_PORT.log" read -p "Please select the redis log file name [$_REDIS_LOG_FILE] " REDIS_LOG_FILE -if [ !"$REDIS_LOG_FILE" ] ; then +if [ -z "$REDIS_LOG_FILE" ] ; then REDIS_LOG_FILE=$_REDIS_LOG_FILE echo "Selected default - $REDIS_LOG_FILE" fi @@ -78,55 +80,71 @@ fi #get the redis data directory _REDIS_DATA_DIR="/var/lib/redis/$REDIS_PORT" read -p "Please select the data directory for this instance [$_REDIS_DATA_DIR] " REDIS_DATA_DIR -if [ !"$REDIS_DATA_DIR" ] ; then +if [ -z "$REDIS_DATA_DIR" ] ; then REDIS_DATA_DIR=$_REDIS_DATA_DIR echo "Selected default - $REDIS_DATA_DIR" fi -mkdir -p $REDIS_DATA_DIR || die "Could not create redis data directory" #get the redis executable path -_REDIS_EXECUTABLE=`which redis-server` +_REDIS_EXECUTABLE=`command -v redis-server` read -p "Please select the redis executable path [$_REDIS_EXECUTABLE] " REDIS_EXECUTABLE -if [ ! -f "$REDIS_EXECUTABLE" ] ; then +if [ ! -x "$REDIS_EXECUTABLE" ] ; then REDIS_EXECUTABLE=$_REDIS_EXECUTABLE - - if [ ! -f "$REDIS_EXECUTABLE" ] ; then + + if [ ! -x "$REDIS_EXECUTABLE" ] ; then echo "Mmmmm... it seems like you don't have a redis executable. Did you run make install yet?" exit 1 fi - fi - -#render the tmplates -TMP_FILE="/tmp/$REDIS_PORT.conf" -DEFAULT_CONFIG="../redis.conf" -INIT_TPL_FILE="./redis_init_script.tpl" -INIT_SCRIPT_DEST="/etc/init.d/redis_$REDIS_PORT" -PIDFILE="/var/run/redis_$REDIS_PORT.pid" - - - #check the default for redis cli -CLI_EXEC=`which redis-cli` -if [ ! "$CLI_EXEC" ] ; then +CLI_EXEC=`command -v redis-cli` +if [ -z "$CLI_EXEC" ] ; then CLI_EXEC=`dirname $REDIS_EXECUTABLE`"/redis-cli" fi +echo "Selected config:" + +echo "Port : $REDIS_PORT" +echo "Config file : $REDIS_CONFIG_FILE" +echo "Log file : $REDIS_LOG_FILE" +echo "Data dir : $REDIS_DATA_DIR" +echo "Executable : $REDIS_EXECUTABLE" +echo "Cli Executable : $CLI_EXEC" + +read -p "Is this ok? Then press ENTER to go on or Ctrl-C to abort." _UNUSED_ + +mkdir -p `dirname "$REDIS_CONFIG_FILE"` || die "Could not create redis config directory" +mkdir -p `dirname "$REDIS_LOG_FILE"` || die "Could not create redis log dir" +mkdir -p "$REDIS_DATA_DIR" || die "Could not create redis data directory" + +#render the templates +TMP_FILE="/tmp/${REDIS_PORT}.conf" +DEFAULT_CONFIG="${SCRIPTPATH}/../redis.conf" +INIT_TPL_FILE="${SCRIPTPATH}/redis_init_script.tpl" +INIT_SCRIPT_DEST="/etc/init.d/redis_${REDIS_PORT}" +PIDFILE="/var/run/redis_${REDIS_PORT}.pid" + +if [ ! -f "$DEFAULT_CONFIG" ]; then + echo "Mmmmm... the default config is missing. Did you switch to the utils directory?" + exit 1 +fi + #Generate config file from the default config file as template #changing only the stuff we're controlling from this script echo "## Generated by install_server.sh ##" > $TMP_FILE -SED_EXPR="s#^port [0-9]{4}\$#port ${REDIS_PORT}#;\ -s#^logfile .+\$#logfile ${REDIS_LOG_FILE}#;\ -s#^dir .+\$#dir ${REDIS_DATA_DIR}#;\ -s#^pidfile .+\$#pidfile ${PIDFILE}#;\ -s#^daemonize no\$#daemonize yes#;" -echo $SED_EXPR +read -r SED_EXPR <<-EOF +s#^port [0-9]{4}\$#port ${REDIS_PORT}#; \ +s#^logfile .+\$#logfile ${REDIS_LOG_FILE}#; \ +s#^dir .+\$#dir ${REDIS_DATA_DIR}#; \ +s#^pidfile .+\$#pidfile ${PIDFILE}#; \ +s#^daemonize no\$#daemonize yes#; +EOF sed -r "$SED_EXPR" $DEFAULT_CONFIG >> $TMP_FILE #cat $TPL_FILE | while read line; do eval "echo \"$line\"" >> $TMP_FILE; done -cp -f $TMP_FILE $REDIS_CONFIG_FILE || exit 1 +cp $TMP_FILE $REDIS_CONFIG_FILE || die "Could not write redis config file $REDIS_CONFIG_FILE" #Generate sample script from template file rm -f $TMP_FILE @@ -138,7 +156,7 @@ REDIS_INIT_HEADER=\ #Configurations injected by install_server below....\n\n EXEC=$REDIS_EXECUTABLE\n CLIEXEC=$CLI_EXEC\n -PIDFILE=$PIDFILE\n +PIDFILE=\"$PIDFILE\"\n CONF=\"$REDIS_CONFIG_FILE\"\n\n REDISPORT=\"$REDIS_PORT\"\n\n ###############\n\n" @@ -146,45 +164,82 @@ REDISPORT=\"$REDIS_PORT\"\n\n REDIS_CHKCONFIG_INFO=\ "# REDHAT chkconfig header\n\n # chkconfig: - 58 74\n -# description: redis_6379 is the redis daemon.\n +# description: redis_${REDIS_PORT} is the redis daemon.\n ### BEGIN INIT INFO\n # Provides: redis_6379\n -# Required-Start: $network $local_fs $remote_fs\n -# Required-Stop: $network $local_fs $remote_fs\n +# Required-Start: \$network \$local_fs \$remote_fs\n +# Required-Stop: \$network \$local_fs \$remote_fs\n # Default-Start: 2 3 4 5\n # Default-Stop: 0 1 6\n -# Should-Start: $syslog $named\n -# Should-Stop: $syslog $named\n -# Short-Description: start and stop redis_6379\n +# Should-Start: \$syslog \$named\n +# Should-Stop: \$syslog \$named\n +# Short-Description: start and stop redis_${REDIS_PORT}\n # Description: Redis daemon\n ### END INIT INFO\n\n" -if [ !`which chkconfig` ] ; then - #combine the header and the template (which is actually a static footer) - echo $REDIS_INIT_HEADER > $TMP_FILE && cat $INIT_TPL_FILE >> $TMP_FILE || die "Could not write init script to $TMP_FILE" -else +if command -v chkconfig >/dev/null; then #if we're a box with chkconfig on it we want to include info for chkconfig - echo -e $REDIS_INIT_HEADER $REDIS_CHKCONFIG_INFO > $TMP_FILE && cat $INIT_TPL_FILE >> $TMP_FILE || die "Could not write init script to $TMP_FILE" + echo "$REDIS_INIT_HEADER" "$REDIS_CHKCONFIG_INFO" > $TMP_FILE && cat $INIT_TPL_FILE >> $TMP_FILE || die "Could not write init script to $TMP_FILE" +else + #combine the header and the template (which is actually a static footer) + echo "$REDIS_INIT_HEADER" > $TMP_FILE && cat $INIT_TPL_FILE >> $TMP_FILE || die "Could not write init script to $TMP_FILE" fi +### +# Generate sample script from template file +# - No need to check which system we are on. The init info are comments and +# do not interfere with update_rc.d systems. Additionally: +# Ubuntu/debian by default does not come with chkconfig, but does issue a +# warning if init info is not available. + +cat > ${TMP_FILE} <> ${TMP_FILE} + #copy to /etc/init.d -cp -f $TMP_FILE $INIT_SCRIPT_DEST && chmod +x $INIT_SCRIPT_DEST || die "Could not copy redis init script to $INIT_SCRIPT_DEST" +cp $TMP_FILE $INIT_SCRIPT_DEST && \ + chmod +x $INIT_SCRIPT_DEST || die "Could not copy redis init script to $INIT_SCRIPT_DEST" echo "Copied $TMP_FILE => $INIT_SCRIPT_DEST" #Install the service echo "Installing service..." -if [ !`which chkconfig` ] ; then - #if we're not a chkconfig box assume we're able to use update-rc.d - update-rc.d redis_$REDIS_PORT defaults && echo "Success!" -else +if command -v chkconfig >/dev/null 2>&1; then # we're chkconfig, so lets add to chkconfig and put in runlevel 345 - chkconfig --add redis_$REDIS_PORT && echo "Successfully added to chkconfig!" - chkconfig --level 345 redis_$REDIS_PORT on && echo "Successfully added to runlevels 345!" + chkconfig --add redis_${REDIS_PORT} && echo "Successfully added to chkconfig!" + chkconfig --level 345 redis_${REDIS_PORT} on && echo "Successfully added to runlevels 345!" +elif command -v update-rc.d >/dev/null 2>&1; then + #if we're not a chkconfig box assume we're able to use update-rc.d + update-rc.d redis_${REDIS_PORT} defaults && echo "Success!" +else + echo "No supported init tool found." fi - + /etc/init.d/redis_$REDIS_PORT start || die "Failed starting service..." #tada echo "Installation successful!" exit 0 - diff --git a/utils/redis_init_script.tpl b/utils/redis_init_script.tpl index e2af1fe7..d6508631 100755 --- a/utils/redis_init_script.tpl +++ b/utils/redis_init_script.tpl @@ -3,29 +3,41 @@ case "$1" in start) if [ -f $PIDFILE ] then - echo "$PIDFILE exists, process is already running or crashed" + echo "$PIDFILE exists, process is already running or crashed" else - echo "Starting Redis server..." - $EXEC $CONF + echo "Starting Redis server..." + $EXEC $CONF fi ;; stop) if [ ! -f $PIDFILE ] then - echo "$PIDFILE does not exist, process is not running" + echo "$PIDFILE does not exist, process is not running" else - PID=$(cat $PIDFILE) - echo "Stopping ..." - $CLIEXEC -p $REDISPORT shutdown - while [ -x /proc/${PID} ] - do - echo "Waiting for Redis to shutdown ..." - sleep 1 - done - echo "Redis stopped" + PID=$(cat $PIDFILE) + echo "Stopping ..." + $CLIEXEC -p $REDISPORT shutdown + while [ -x /proc/${PID} ] + do + echo "Waiting for Redis to shutdown ..." + sleep 1 + done + echo "Redis stopped" fi ;; + status) + if [ ! -f $PIDFILE ] + then + echo 'Redis is not running' + else + echo "Redis is running ($(<$PIDFILE))" + fi + ;; + restart) + $0 stop + $0 start + ;; *) - echo "Please use start or stop as first argument" + echo "Please use start, stop, restart or status as first argument" ;; esac