1#!/bin/sh 2 3# Copyright 2011 Dvir Volk <dvirsk at gmail dot com>. All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions are met: 7# 8# 1. Redistributions of source code must retain the above copyright notice, 9# this list of conditions and the following disclaimer. 10# 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 16# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 17# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 18# EVENT SHALL Dvir Volk OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 19# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 20# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 21# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 22# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 23# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 24# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25# 26################################################################################ 27# 28# Service installer for redis server, runs interactively by default. 29# 30# To run this script non-interactively (for automation/provisioning purposes), 31# feed the variables into the script. Any missing variables will be prompted! 32# Tip: Environment variables also support command substitution (see REDIS_EXECUTABLE) 33# 34# Example: 35# 36# sudo REDIS_PORT=1234 \ 37# REDIS_CONFIG_FILE=/etc/redis/1234.conf \ 38# REDIS_LOG_FILE=/var/log/redis_1234.log \ 39# REDIS_DATA_DIR=/var/lib/redis/1234 \ 40# REDIS_EXECUTABLE=`command -v redis-server` ./utils/install_server.sh 41# 42# This generates a redis config file and an /etc/init.d script, and installs them. 43# 44# /!\ This script should be run as root 45# 46################################################################################ 47 48die () { 49 echo "ERROR: $1. Aborting!" 50 exit 1 51} 52 53 54#Absolute path to this script 55SCRIPT=$(readlink -f $0) 56#Absolute path this script is in 57SCRIPTPATH=$(dirname $SCRIPT) 58 59#Initial defaults 60_REDIS_PORT=6379 61_MANUAL_EXECUTION=false 62 63echo "Welcome to the redis service installer" 64echo "This script will help you easily set up a running redis server" 65echo 66 67#check for root user 68if [ "$(id -u)" -ne 0 ] ; then 69 echo "You must run this script as root. Sorry!" 70 exit 1 71fi 72 73if ! echo $REDIS_PORT | egrep -q '^[0-9]+$' ; then 74 _MANUAL_EXECUTION=true 75 #Read the redis port 76 read -p "Please select the redis port for this instance: [$_REDIS_PORT] " REDIS_PORT 77 if ! echo $REDIS_PORT | egrep -q '^[0-9]+$' ; then 78 echo "Selecting default: $_REDIS_PORT" 79 REDIS_PORT=$_REDIS_PORT 80 fi 81fi 82 83if [ -z "$REDIS_CONFIG_FILE" ] ; then 84 _MANUAL_EXECUTION=true 85 #read the redis config file 86 _REDIS_CONFIG_FILE="/etc/redis/$REDIS_PORT.conf" 87 read -p "Please select the redis config file name [$_REDIS_CONFIG_FILE] " REDIS_CONFIG_FILE 88 if [ -z "$REDIS_CONFIG_FILE" ] ; then 89 REDIS_CONFIG_FILE=$_REDIS_CONFIG_FILE 90 echo "Selected default - $REDIS_CONFIG_FILE" 91 fi 92fi 93 94if [ -z "$REDIS_LOG_FILE" ] ; then 95 _MANUAL_EXECUTION=true 96 #read the redis log file path 97 _REDIS_LOG_FILE="/var/log/redis_$REDIS_PORT.log" 98 read -p "Please select the redis log file name [$_REDIS_LOG_FILE] " REDIS_LOG_FILE 99 if [ -z "$REDIS_LOG_FILE" ] ; then 100 REDIS_LOG_FILE=$_REDIS_LOG_FILE 101 echo "Selected default - $REDIS_LOG_FILE" 102 fi 103fi 104 105if [ -z "$REDIS_DATA_DIR" ] ; then 106 _MANUAL_EXECUTION=true 107 #get the redis data directory 108 _REDIS_DATA_DIR="/var/lib/redis/$REDIS_PORT" 109 read -p "Please select the data directory for this instance [$_REDIS_DATA_DIR] " REDIS_DATA_DIR 110 if [ -z "$REDIS_DATA_DIR" ] ; then 111 REDIS_DATA_DIR=$_REDIS_DATA_DIR 112 echo "Selected default - $REDIS_DATA_DIR" 113 fi 114fi 115 116if [ ! -x "$REDIS_EXECUTABLE" ] ; then 117 _MANUAL_EXECUTION=true 118 #get the redis executable path 119 _REDIS_EXECUTABLE=`command -v redis-server` 120 read -p "Please select the redis executable path [$_REDIS_EXECUTABLE] " REDIS_EXECUTABLE 121 if [ ! -x "$REDIS_EXECUTABLE" ] ; then 122 REDIS_EXECUTABLE=$_REDIS_EXECUTABLE 123 124 if [ ! -x "$REDIS_EXECUTABLE" ] ; then 125 echo "Mmmmm... it seems like you don't have a redis executable. Did you run make install yet?" 126 exit 1 127 fi 128 fi 129fi 130 131#check the default for redis cli 132CLI_EXEC=`command -v redis-cli` 133if [ -z "$CLI_EXEC" ] ; then 134 CLI_EXEC=`dirname $REDIS_EXECUTABLE`"/redis-cli" 135fi 136 137echo "Selected config:" 138 139echo "Port : $REDIS_PORT" 140echo "Config file : $REDIS_CONFIG_FILE" 141echo "Log file : $REDIS_LOG_FILE" 142echo "Data dir : $REDIS_DATA_DIR" 143echo "Executable : $REDIS_EXECUTABLE" 144echo "Cli Executable : $CLI_EXEC" 145 146if $_MANUAL_EXECUTION == true ; then 147 read -p "Is this ok? Then press ENTER to go on or Ctrl-C to abort." _UNUSED_ 148fi 149 150mkdir -p `dirname "$REDIS_CONFIG_FILE"` || die "Could not create redis config directory" 151mkdir -p `dirname "$REDIS_LOG_FILE"` || die "Could not create redis log dir" 152mkdir -p "$REDIS_DATA_DIR" || die "Could not create redis data directory" 153 154#render the templates 155TMP_FILE="/tmp/${REDIS_PORT}.conf" 156DEFAULT_CONFIG="${SCRIPTPATH}/../redis.conf" 157INIT_TPL_FILE="${SCRIPTPATH}/redis_init_script.tpl" 158INIT_SCRIPT_DEST="/etc/init.d/redis_${REDIS_PORT}" 159PIDFILE="/var/run/redis_${REDIS_PORT}.pid" 160 161if [ ! -f "$DEFAULT_CONFIG" ]; then 162 echo "Mmmmm... the default config is missing. Did you switch to the utils directory?" 163 exit 1 164fi 165 166#Generate config file from the default config file as template 167#changing only the stuff we're controlling from this script 168echo "## Generated by install_server.sh ##" > $TMP_FILE 169 170read -r SED_EXPR <<-EOF 171s#^port .\+#port ${REDIS_PORT}#; \ 172s#^logfile .\+#logfile ${REDIS_LOG_FILE}#; \ 173s#^dir .\+#dir ${REDIS_DATA_DIR}#; \ 174s#^pidfile .\+#pidfile ${PIDFILE}#; \ 175s#^daemonize no#daemonize yes#; 176EOF 177sed "$SED_EXPR" $DEFAULT_CONFIG >> $TMP_FILE 178 179#cat $TPL_FILE | while read line; do eval "echo \"$line\"" >> $TMP_FILE; done 180cp $TMP_FILE $REDIS_CONFIG_FILE || die "Could not write redis config file $REDIS_CONFIG_FILE" 181 182#Generate sample script from template file 183rm -f $TMP_FILE 184 185#we hard code the configs here to avoid issues with templates containing env vars 186#kinda lame but works! 187REDIS_INIT_HEADER=\ 188"#!/bin/sh\n 189#Configurations injected by install_server below....\n\n 190EXEC=$REDIS_EXECUTABLE\n 191CLIEXEC=$CLI_EXEC\n 192PIDFILE=\"$PIDFILE\"\n 193CONF=\"$REDIS_CONFIG_FILE\"\n\n 194REDISPORT=\"$REDIS_PORT\"\n\n 195###############\n\n" 196 197REDIS_CHKCONFIG_INFO=\ 198"# REDHAT chkconfig header\n\n 199# chkconfig: - 58 74\n 200# description: redis_${REDIS_PORT} is the redis daemon.\n 201### BEGIN INIT INFO\n 202# Provides: redis_6379\n 203# Required-Start: \$network \$local_fs \$remote_fs\n 204# Required-Stop: \$network \$local_fs \$remote_fs\n 205# Default-Start: 2 3 4 5\n 206# Default-Stop: 0 1 6\n 207# Should-Start: \$syslog \$named\n 208# Should-Stop: \$syslog \$named\n 209# Short-Description: start and stop redis_${REDIS_PORT}\n 210# Description: Redis daemon\n 211### END INIT INFO\n\n" 212 213if command -v chkconfig >/dev/null; then 214 #if we're a box with chkconfig on it we want to include info for chkconfig 215 echo "$REDIS_INIT_HEADER" "$REDIS_CHKCONFIG_INFO" > $TMP_FILE && cat $INIT_TPL_FILE >> $TMP_FILE || die "Could not write init script to $TMP_FILE" 216else 217 #combine the header and the template (which is actually a static footer) 218 echo "$REDIS_INIT_HEADER" > $TMP_FILE && cat $INIT_TPL_FILE >> $TMP_FILE || die "Could not write init script to $TMP_FILE" 219fi 220 221### 222# Generate sample script from template file 223# - No need to check which system we are on. The init info are comments and 224# do not interfere with update_rc.d systems. Additionally: 225# Ubuntu/debian by default does not come with chkconfig, but does issue a 226# warning if init info is not available. 227 228cat > ${TMP_FILE} <<EOT 229#!/bin/sh 230#Configurations injected by install_server below.... 231 232EXEC=$REDIS_EXECUTABLE 233CLIEXEC=$CLI_EXEC 234PIDFILE=$PIDFILE 235CONF="$REDIS_CONFIG_FILE" 236REDISPORT="$REDIS_PORT" 237############### 238# SysV Init Information 239# chkconfig: - 58 74 240# description: redis_${REDIS_PORT} is the redis daemon. 241### BEGIN INIT INFO 242# Provides: redis_${REDIS_PORT} 243# Required-Start: \$network \$local_fs \$remote_fs 244# Required-Stop: \$network \$local_fs \$remote_fs 245# Default-Start: 2 3 4 5 246# Default-Stop: 0 1 6 247# Should-Start: \$syslog \$named 248# Should-Stop: \$syslog \$named 249# Short-Description: start and stop redis_${REDIS_PORT} 250# Description: Redis daemon 251### END INIT INFO 252 253EOT 254cat ${INIT_TPL_FILE} >> ${TMP_FILE} 255 256#copy to /etc/init.d 257cp $TMP_FILE $INIT_SCRIPT_DEST && \ 258 chmod +x $INIT_SCRIPT_DEST || die "Could not copy redis init script to $INIT_SCRIPT_DEST" 259echo "Copied $TMP_FILE => $INIT_SCRIPT_DEST" 260 261#Install the service 262echo "Installing service..." 263if command -v chkconfig >/dev/null 2>&1; then 264 # we're chkconfig, so lets add to chkconfig and put in runlevel 345 265 chkconfig --add redis_${REDIS_PORT} && echo "Successfully added to chkconfig!" 266 chkconfig --level 345 redis_${REDIS_PORT} on && echo "Successfully added to runlevels 345!" 267elif command -v update-rc.d >/dev/null 2>&1; then 268 #if we're not a chkconfig box assume we're able to use update-rc.d 269 update-rc.d redis_${REDIS_PORT} defaults && echo "Success!" 270else 271 echo "No supported init tool found." 272fi 273 274/etc/init.d/redis_$REDIS_PORT start || die "Failed starting service..." 275 276#tada 277echo "Installation successful!" 278exit 0 279