|
#!/usr/bin/env bash |
|
# will@prime.ms | Updated: 10/31/14 |
|
# usage: ./mkinstance.sh -h |
|
# Based on the Redis 2.8.17-2.el6.remi |
|
# TODO: Add overwrite arg for base conf |
|
# TODO: Grab all replacements for sed from base conf file, currently assumes too many defaults |
|
# TODO: Handle removal if instance was already removed once before |
|
|
|
conf="/etc/redis.conf" |
|
confdir=$(dirname "$conf") |
|
initd="/etc/init.d" |
|
logdir="/var/log/redis" |
|
redis_server="/usr/bin/redis-server" |
|
max=-1 |
|
usage() { |
|
echo "Create new instance for Redis based on $conf"; echo |
|
echo "./mkinstance.sh args" |
|
echo "-i=[001] --instance=[001]" |
|
echo " Specify the instance number" |
|
echo "-a --auto" |
|
echo " Automatically increments the instance" |
|
echo "-d=[path] --datadir=[path]" |
|
echo " Specify data directory for redis" |
|
echo "-v --verbose" |
|
echo " Display generated commands before creating instance" |
|
echo "-r --remove" |
|
echo " Removes the instance (moves data)" |
|
echo "-h --help" |
|
echo " This screen" |
|
} |
|
function coloredEcho(){ |
|
local exp=$1; |
|
local color=$2; |
|
if ! [[ $color =~ ^[0-9]$ ]] ; then |
|
case $(echo "$color" | tr '[:upper:]' '[:lower:]') in |
|
black) color=0 ;; |
|
red) color=1 ;; |
|
green) color=2 ;; |
|
yellow) color=3 ;; |
|
blue) color=4 ;; |
|
magenta) color=5 ;; |
|
cyan) color=6 ;; |
|
white|*) color=7 ;; # white or invalid color |
|
esac |
|
fi |
|
tput setaf $color; |
|
echo "$exp"; |
|
tput sgr0; |
|
} |
|
while [ "$1" != "" ]; do |
|
PARAM=$(echo "$1" | awk -F= '{print $1}') |
|
VALUE=$(echo "$1" | awk -F= '{print $2}') |
|
case $PARAM in |
|
-h | --help) |
|
usage |
|
exit |
|
;; |
|
-i | --instance) |
|
if [ -n "$VALUE" ] ; then |
|
instance=$((10#$VALUE)) |
|
instance=$(printf "%03d" $instance) |
|
else |
|
coloredEcho "ERROR: Missing value for instance" red |
|
usage |
|
exit 1 |
|
fi |
|
;; |
|
-a | --auto) |
|
auto="Y" |
|
;; |
|
-r | --remove) |
|
remove="Y" |
|
;; |
|
-v | --verbose) |
|
verbose="Y" |
|
;; |
|
-d | --datadir) |
|
if [ -n "$VALUE" ] ; then |
|
custom_datadir="$VALUE" |
|
else |
|
coloredEcho "ERROR: Missing value for custom data directory" red |
|
usage |
|
exit 1 |
|
fi |
|
;; |
|
-p | --port) |
|
if [ -n "$VALUE" ] ; then |
|
custom_port="$VALUE" |
|
else |
|
coloredEcho "ERROR: Missing value for custom port" red |
|
usage |
|
exit 1 |
|
fi |
|
;; |
|
*) |
|
coloredEcho "ERROR: unknown parameter \"$PARAM\"" red |
|
usage |
|
exit 1 |
|
;; |
|
esac |
|
shift |
|
done |
|
|
|
#check to make sure redis is installed |
|
if ! [ -f "$redis_server" ] ; then |
|
coloredEcho "ERROR: can't find redis-server, is it installed?" red |
|
echo "I'm looking for it here: $redis_server" |
|
exit 1 |
|
fi |
|
|
|
for file in $confdir/redis-*.conf |
|
do |
|
num=${file:11} |
|
num=${num%.conf} |
|
re='^[0-9]+$' |
|
if ! [[ $num =~ $re ]] ; then |
|
num=0 |
|
fi |
|
[[ $((10#$num)) -gt $((10#$max)) ]] && max=$num |
|
done |
|
if [[ $max == 0 ]] ; then |
|
maxconf="$conf" |
|
coloredEcho "WARNING: No instances!" yellow |
|
else |
|
maxconf="$confdir/redis-$max.conf" |
|
fi |
|
|
|
if [[ $auto == [Y] ]] ; then |
|
instance=$((10#$max + 1)) |
|
instance=$(printf "%03d" $instance) |
|
elif ! [ -n "$instance" ] ; then |
|
coloredEcho "ERROR: instance not set (use --auto or --instance=XXX)" red; echo |
|
usage |
|
exit 1 |
|
fi |
|
|
|
##get defaults |
|
if [ -n "$custom_datadir" ] ; then |
|
if [ -d "$custom_datadir" ] ; then |
|
dir="$(unset CDPATH && cd "$custom_datadir" && pwd)" |
|
new_data_dir="$dir" |
|
else |
|
parent_custom_dir="$(dirname "$custom_datadir")" |
|
parent_custom_base="$(basename "$custom_datadir")" |
|
new_data_dir="$parent_custom_dir/$parent_custom_base" |
|
fi |
|
else |
|
datadir=$(awk '/^[[:blank:]]*dir/ { print $2 }' "$conf") #get datadir of base install |
|
new_data_dir="$(dirname "$datadir")" |
|
fi |
|
|
|
port=$(awk '/^[[:blank:]]*port/ { print $2 }' "$conf") #get port to replace |
|
if [ -n "$custom_port" ] ; then |
|
newport="$custom_port" |
|
else |
|
newport=$(awk '/^[[:blank:]]*port/ { print $2 }' "$maxconf") #needs to get last port used |
|
((newport+=1)) |
|
fi |
|
|
|
if [ -n "$remove" ] && [ -n "$instance" ] && [ -z "$auto" ]; then |
|
conf="$confdir/redis-$instance.conf" |
|
if [ -f "$conf" ] ; then |
|
confdir=$(dirname "$conf") |
|
datadir=$(awk '/^[[:blank:]]*dir/ { print $2 }' "$conf") #get datadir of instance |
|
if [ -d "$datadir" ] ; then |
|
new_data_dir="$(dirname "$datadir")" |
|
echo; echo; |
|
echo "##########################################" |
|
echo "## PENDING REMOVAL OF INSTANCE ##" |
|
echo "##########################################" |
|
echo; echo; |
|
echo "Moving: $datadir --> $new_data_dir/redis-archive/$instance/" |
|
echo "Moving: $confdir/redis-$instance.conf --> $new_data_dir/redis-archive/$instance/$instance.conf" |
|
echo "Moving: $initd/redis-$instance --> $new_data_dir/redis-archive/$instance/$instance.init" |
|
echo; echo; |
|
read -p "Remove $instance? [y/N]: " -n 1 -r; echo |
|
if [[ $REPLY =~ ^[Yy]$ ]] ; then |
|
echo "Stopping redis-$instance service & removing chkconfig" |
|
service "redis-$instance" stop |
|
chkconfig --del "redis-$instance" |
|
echo "Moving files of $instance" |
|
mkdir -p "$new_data_dir/redis-archive/$instance/" |
|
mv "$datadir" "$new_data_dir/redis-archive/$instance/" |
|
mv "$confdir/redis-$instance.conf" "$new_data_dir/redis-archive/$instance/$instance.conf" |
|
mv "$initd/redis-$instance" "$new_data_dir/redis-archive/$instance/$instance.init" |
|
coloredEcho "Done." green; echo |
|
exit |
|
else |
|
echo 'CANCELED... No changes made.' |
|
exit 1 |
|
fi |
|
else |
|
coloredEcho "ERROR: Couldn't find data dir for instance $instance" red |
|
echo "You should manually remove this instance" |
|
echo; coloredEcho "This is what we would have run:" green; echo; |
|
echo "service redis-$instance stop" |
|
echo "chkconfig --del redis-$instance" |
|
echo "mkdir -p $new_data_dir/redis-archive/$instance/" |
|
coloredEcho "mv $datadir $new_data_dir/redis-archive/$instance/" red |
|
echo "mv $confdir/redis-$instance.conf" "$new_data_dir/redis-archive/$instance/$instance.conf" |
|
echo "mv $initd/redis-$instance" "$new_data_dir/redis-archive/$instance/$instance.init" |
|
echo; |
|
exit 1 |
|
fi |
|
else |
|
echo "ERROR: Couldn't find conf file for instance $instance" |
|
exit 1 |
|
fi |
|
elif [ -n "$remove" ] && [ -z "$auto" ]; then |
|
coloredEcho "Error: You must can't use --auto when using --remove" red |
|
exit 1 |
|
fi |
|
|
|
if [ -f "$confdir/redis-$instance.conf" ] ; then |
|
echo "$confdir/redis-$instance.conf exists." |
|
exit |
|
fi |
|
|
|
echo; echo; |
|
coloredEcho "##########################################" cyan |
|
coloredEcho "## PENDING CONFIGURATION SETTINGS ##" cyan |
|
coloredEcho "##########################################" cyan |
|
echo; echo; |
|
echo "Max instance conf file found = $maxconf" |
|
echo "New instance conf = $confdir/redis-$instance.conf" |
|
echo "Sub Dir for data $new_data_dir" |
|
echo "New Data Dir $new_data_dir/redis-$instance/" |
|
echo "New Port $newport" |
|
echo; echo; |
|
read -p "Is the configuration correct? [y/N]: " -n 1 -r; echo |
|
if ! [[ $REPLY =~ ^[Yy]$ ]] ; then |
|
coloredEcho 'CANCELED... No changes made.' red |
|
exit 1 |
|
fi |
|
#commands to run |
|
if [ -n "$verbose" ] ; then |
|
echo; echo; |
|
coloredEcho "##########################################" green |
|
coloredEcho "## RUNNING THE FOLLOWING COMMANDS ##" green |
|
coloredEcho "##########################################" green |
|
echo; echo; |
|
echo "cp $conf $confdir/redis-$instance.conf" |
|
echo "mkdir -p $new_data_dir/redis-$instance" |
|
echo "chown redis $new_data_dir/redis-$instance" |
|
echo "cp $initd/redis $initd/redis-$instance" |
|
echo "sed -i -e 's/#.*$//' -e '/^$/d' \"$confdir/redis-$instance.conf\"" |
|
echo "sed -i \"s,/var/run/redis.pid,/var/run/redis-$instance.pid,\" \"$confdir/redis-$instance.conf\"" |
|
echo "sed -i \"s,$datadir,$new_data_dir/redis-$instance/,\" \"$confdir/redis-$instance.conf\"" |
|
echo "sed -i \"s,port $port,port $newport,\" \"$confdir/redis-$instance.conf\"" |
|
echo "sed -i \"s,logfile $logdir/redis.log,logfile $logdir/redis-$instance.log,\" \"$confdir/redis-$instance.conf\"" |
|
echo "sed -i \"s,name=\"redis-server\",name=\"redis-$instance\",\" \"$initd/redis-$instance\"" |
|
echo "sed -i \"s,exec=\"/usr/bin/\$name\",exec=\"/usr/bin/redis-server\",\" \"$initd/redis-$instance\"" |
|
echo "sed -i \"s,pidfile=\"/var/run/redis/redis.pid\",pidfile=\"/var/run/redis/redis-$instance.pid\",\" \"$initd/redis-$instance\"" |
|
echo "sed -i \"s,REDIS_CONFIG=\"$confdir/redis.conf\",REDIS_CONFIG=\"$confdir/redis-$instance.conf\",\" \"$initd/redis-$instance\"" |
|
echo "sed -i \"s,lockfile=/var/lock/subsys/redis,lockfile=/var/lock/subsys/redis-$instance,\" \"$initd/redis-$instance\"" |
|
echo "sed -i \"s,'&& \$shut','',\" \"$initd/redis-$instance\"" |
|
echo; echo; |
|
read -p "Does this look correct? [y/N]: " -n 1 -r; echo |
|
if ! [[ $REPLY =~ ^[Yy]$ ]] ; then |
|
coloredEcho 'CANCELED... No changes made.' red |
|
exit 1 |
|
fi |
|
fi |
|
#copy files |
|
echo "Copying $conf to $confdir/redis-$instance.conf" |
|
cp "$conf" "$confdir/redis-$instance.conf" |
|
|
|
echo "Making directories for new instance $instance" |
|
mkdir -p "$new_data_dir/redis-$instance" |
|
chown redis "$new_data_dir/redis-$instance" |
|
cp "$initd/redis" "$initd/redis-$instance" |
|
|
|
echo "Erasing comments and blank lines from conf" |
|
sed -i -e 's/#.*$//' -e '/^$/d' "$confdir/redis-$instance.conf" |
|
|
|
echo "Replacing conf values for $instance" |
|
sed -i "s,/var/run/redis.pid,/var/run/redis-$instance.pid," "$confdir/redis-$instance.conf" |
|
sed -i "s,$datadir,$new_data_dir/redis-$instance/," "$confdir/redis-$instance.conf" |
|
sed -i "s,port $port,port $newport," "$confdir/redis-$instance.conf" |
|
sed -i "s,logfile $logdir/redis.log,logfile $logdir/redis-$instance.log," "$confdir/redis-$instance.conf" |
|
sed -i "s,name=\"redis-server\",name=\"redis-$instance\"," "$initd/redis-$instance" |
|
sed -i "s,exec=\"/usr/bin/\$name\",exec=\"/usr/bin/redis-server\"," "$initd/redis-$instance" |
|
sed -i "s,pidfile=\"/var/run/redis/redis.pid\",pidfile=\"/var/run/redis/redis-$instance.pid\"," "$initd/redis-$instance" |
|
sed -i "s,REDIS_CONFIG=\"$confdir/redis.conf\",REDIS_CONFIG=\"$confdir/redis-$instance.conf\"," "$initd/redis-$instance" |
|
sed -i "s,lockfile=/var/lock/subsys/redis,lockfile=/var/lock/subsys/redis-$instance," "$initd/redis-$instance" |
|
sed -i s,'&& $shut','', "$initd/redis-$instance" #remove the second $shut which would shutdown the default redis server |
|
|
|
coloredEcho "Finished!" green; echo; |
|
|
|
read -p "Show Diff? [y/N]: " -n 1 -r; echo |
|
if [[ $REPLY =~ ^[Yy]$ ]] ; then |
|
diff -u "$conf" "$confdir/redis-$instance.conf"; echo |
|
diff -u "$initd/redis" "$initd/redis-$instance"; echo |
|
else |
|
coloredEcho 'Show diff with:' yellow |
|
echo "diff -u $conf $confdir/redis-$instance.conf" |
|
echo "diff -u $initd/redis $initd/redis-$instance"; echo |
|
fi |
|
|
|
read -p "Start new instance? [y/N]: " -n 1 -r; echo |
|
if [[ $REPLY =~ ^[Yy]$ ]] ; then |
|
service "redis-$instance" start |
|
service "redis-$instance" status; echo |
|
else |
|
coloredEcho 'Instance not started' yellow |
|
echo 'Start it with:' |
|
echo "service redis-$instance start"; echo |
|
fi |
|
|
|
read -p "Start on boot? [y/N]: " -n 1 -r; echo |
|
if [[ $REPLY =~ ^[Yy]$ ]] ; then |
|
chkconfig --level 3 "redis-$instance" on |
|
coloredEcho 'Instance will start on boot' green; echo |
|
else |
|
coloredEcho 'Instance wont start on boot' yellow |
|
echo 'Enable it with:' |
|
echo "chkconfig --level 3 redis-$instance on"; echo |
|
fi |
|
|
|
coloredEcho "New files/folders created for this instance:" cyan |
|
echo "$new_data_dir/redis-$instance/" |
|
echo "$confdir/redis-$instance.conf" |
|
echo "$initd/redis-$instance" |
|
echo |
|
|
|
exit |