From: Brian Flowers Date: Tue, 24 May 2016 01:23:30 +0000 (-0400) Subject: Initial code commit; still a work in progress X-Git-Url: http://git.slightlycyberpunk.com%2C%20git.slightlycyberpunk.com/git/?a=commitdiff_plain;h=9d2383e70b3df4a6be1756d23c130479162f60c8;p=bdsm.git Initial code commit; still a work in progress --- 9d2383e70b3df4a6be1756d23c130479162f60c8 diff --git a/README b/README new file mode 100644 index 0000000..b5b07b6 --- /dev/null +++ b/README @@ -0,0 +1,29 @@ +bdsm +A Slightly Cyberpunk project +[git|www].slightlycyberpunk.com + +bdsm is the Bash Daemon for System Monitoring, a truly agentless system monitoring and administration tool for Linux and Unix systems. + +0) PREREQUISITES + +a) A GNU system +b) bash +c) vmstat + +1) INSTALLATION INSTRUCTIONS + +Create a new user named bdsm and clone the repository into this user's home directory. + +2) CONFIGURATION + +Login as the bdsm user + +Configure your infrastructure with: +~/bdsm.sh configure + +Then deploy the required components to all downstream hosts with: +~/bdsm.sh deploy + +3) USAGE + +Execute ~/bdsm.sh help for usage information \ No newline at end of file diff --git a/bdsm.conf b/bdsm.conf new file mode 100644 index 0000000..f7ecb56 --- /dev/null +++ b/bdsm.conf @@ -0,0 +1,4 @@ +generic:bdsm +{ + vmstat(5); +} diff --git a/bdsm.d/df.generic b/bdsm.d/df.generic new file mode 100644 index 0000000..09648de --- /dev/null +++ b/bdsm.d/df.generic @@ -0,0 +1,139 @@ +#!/bin/bash +################################################################################ +# +# df.generic +# Bash Daemon for System Monitoring +# Generic df plugin for monitoring disk utilization +# +# +# +# +############################################################################### + +# TRAP UNKNOWN ERRORS +############################################################################### +trap failure SIGTERM SIGINT SIGFPE + +failure() +{ + error "Something has gone SERIOUSLY wrong! (Received signal $?)" + return 255 +} + +error() +{ + printf "\e[41m" 1>&2 + printf "ERROR: $1" 1>&2 + printf "\e[0m\n" 1>&2 +} + +# VARIABLES +############################################################################### +SCRIPT=$0 +HOSTNAME=$2 +DELAY=$3 +LABEL=$4 +PATH=$5 +OUTPATH=/home/bdsm/out.fifo + +# MAIN FUNCTIONS +############################################################################### +help() +{ + echo "Generic df disk utilization monitoring" + echo "USAGE: $0 [FUNCTION] [HOSTNAME] [DELAY]" + echo "FUNCTION -- start/stop/status/help" + echo "HOSTNAME -- the hostname to monitor" + echo "::DELAY -- seconds between measurements" + echo "::LABEL -- label for this drive" + echo "::DRIVE -- filesystem path to monitor" + exit 0 +} + +start() +{ + running=`ssh $HOSTNAME "cat /home/bdsm/.df.pid | \ + xargs ps -T | \ + grep -v PID | \ + wc -l"` 2>/dev/null + + if [ $running -eq 0 ] || [ $running -gt 5 ]; then + # Check if df is installed + installed=`ssh -q $HOSTNAME "df > /dev/null 2>&1; echo $?"` + if [ ! $installed ]; then + echo "" > $OUTPATH + return 1 + fi + + ssh -q $HOSTNAME <> $OUTPATH + sleep $DELAY + done & +EOF + ssh -q $HOSTNAME "ps aux | \ + grep bdsm | \ + grep df | \ + grep -v grep | \ + awk '{print \$2}' \ + > /home/bdsm/.df.pid &" + else + echo "Already Running" + fi +} + +stop() +{ + ssh $HOSTNAME "kill `cat /home/bdsm/.df.pid`" + ssh $HOSTNAME "rm /home/bdsm/.df.pid" +} + +status() +{ + running=`ssh $HOSTNAME "cat /home/bdsm/.df.pid | \ + xargs ps -T | \ + grep -v PID | \ + wc -l"` + + if [ $running -eq 0 ]; then + echo "OFF" + else + echo "ON" + fi +} + +# UTILITY FUNCTIONS +############################################################################### + +formatConfig() +{ + # Reformat config file to be more machine-readable + # Removes whitespace and adds semicolons after property values + cat /home/bdsm/bdsm.conf | tr '\n' ' ' | sed 's/}/}\ + /g' | sed 's/^;*//g' | sed "s/[[:space:]]//g"| \ + sed 's/;\([{}]\)/\1/g' | sed 's/\([{}]\);/\1/g' \ + > /home/bdsm/.bdsm.conf.tmp +} + +# SCRIPT START +############################################################################### + +# Get a list of configured hosts +hosts=$(cat /home/bdsm/.bdsm.conf.tmp | cut -d'{' -f1) + +if [ -z $1 ]; then + help +elif [ $1 == "start" ]; then + formatConfig + start +elif [ $1 == "stop" ]; then + formatConfig + stop +elif [ $1 == "status" ]; then + formatConfig + status +elif [ $1 == "help" ]; then + help +fi diff --git a/bdsm.d/template.generic b/bdsm.d/template.generic new file mode 100644 index 0000000..e1fb372 --- /dev/null +++ b/bdsm.d/template.generic @@ -0,0 +1,109 @@ +#!/bin/bash +################################################################################ +# +# template.generic +# Bash Daemon for System Monitoring +# Generic plugin template +# +############################################################################### + +# TRAP UNKNOWN ERRORS +############################################################################### +trap failure SIGTERM SIGINT SIGFPE + +failure() +{ + error "Something has gone SERIOUSLY wrong! (Received signal $?)" + return 255 +} + +error() +{ + printf "\e[41m" 1>&2 + printf "ERROR: $1" 1>&2 + printf "\e[0m\n" 1>&2 +} + +# VARIABLES +############################################################################### +SCRIPT=$0 +HOSTNAME=$2 + +# FIFO pipe to be used for output +OUTPATH=/home/bdsm/out.fifo + +# Optional Parameters +PARAM1=$3 +PARAM2=$4 + +# MAIN FUNCTIONS +############################################################################### +help() +{ + # Print usage information + # Formatting is important here, as this is processed by bdsm.sh! + # First two parameters should be function and hostname + # Other parameters are optional and will be stored in bdsm.conf + # Any parameters to be stored in BSDM.conf should output as: + # ::[PARAM NAME] -- [PARAM DESCRIPTION] + # Parameters NOT stored in bsfc.conf must NOT start with ::! + echo "PLUGIN DESCRIPTION GOES HERE" + echo "USAGE: $0 [FUNCTION] [HOSTNAME] [PARAMETER 1] [PARAMETER 2]" + echo "FUNCTION -- start, stop, status or help" + echo "HOSTNAME -- host to run the monitor on" + echo "::PARAM1 -- description of the first parameter" + echo "::PARAM2 -- description of the second parameter" + exit 0 +} + +start() +{ + # Start the monitor and write output to $OUTPATH + # Output should be pipe-delimited + # One line per attribute + # Format: + # $TIMESTAMP|$HOST|$ATTRIBUTE|$VALUE + # + # TIMESTAMP format is date +%s + # HOSTNAME is a global variable + # ATTRIBUTE is a string describing what is being measure + # ex. "CPU-SY" for system CPU utilization + # VALUE is the value measured (ie, percentage) + # : Don't include units -- ie, 59 not 59% + # : UP/DOWN/??? for service up/down checks + # : If those don't make sense, use whatever does, but keep it concise! +} + +stop() +{ + # Stop the monitor +} + +status() +{ + # Check if the monitor is running and echo ON or OFF +} + +# SCRIPT START +############################################################################### + +# Reformat config file to be more machine-readable +# Removes whitespace and adds semicolons after property values +cat /home/bdsm/bdsm.conf | sed "s/[[:space:]]//g" | tr '\n' ' ' | sed 's/}/}\ + /g' | sed 's/^;*//g' | sed 's/;\([{}]\)/\1/g' | sed 's/\([{}]\);/\1/g' \ + > /home/bdsm/.bdsm.conf.tmp + +# Get a list of configured hosts +hosts=$(cat /home/bdsm/.bdsm.conf.tmp | cut -d'{' -f1) + +if [ -z $1 ]; then + help +elif [ $1 == "start" ]; then + start +elif [ $1 == "stop" ]; then + stop +elif [ $1 == "status" ]; then + status +elif [ $1 == "help" ]; then + help +fi diff --git a/bdsm.d/vmstat.generic b/bdsm.d/vmstat.generic new file mode 100755 index 0000000..e34a079 --- /dev/null +++ b/bdsm.d/vmstat.generic @@ -0,0 +1,172 @@ +#!/bin/bash +################################################################################ +# +# vmstat.generic +# Bash Daemon for System Monitoring +# Generic vmstat plugin +# +# +# +# +############################################################################### + +# TRAP UNKNOWN ERRORS +############################################################################### +trap failure SIGTERM SIGINT SIGFPE + +failure() +{ + error "Something has gone SERIOUSLY wrong! (Received signal $?)" + return 255 +} + +error() +{ + printf "\e[41m" 1>&2 + printf "ERROR: $1" 1>&2 + printf "\e[0m\n" 1>&2 +} + +# VARIABLES +############################################################################### +SCRIPT=$0 +HOSTNAME=$2 +DELAY=$3 +OUTPATH=/home/bdsm/out.fifo + +# MAIN FUNCTIONS +############################################################################### +help() +{ + echo "Generic vmstat monitoring" + echo "USAGE: $0 [FUNCTION] [HOSTNAME] [DELAY]" + echo "FUNCTION -- start/stop/status/help" + echo "HOSTNAME -- the hostname to monitor" + echo "::DELAY -- seconds between measurements" + exit 0 +} + +start() +{ + running=`ssh $HOSTNAME "cat /home/bdsm/.vmstat.pid | \ + xargs ps -T | \ + grep -v PID | \ + wc -l"` 2>/dev/null + + if [ $running -eq 0 ] || [ $running -gt 5 ]; then + # Check if vmstat is installed + installed=`ssh -q $HOSTNAME "vmstat > /dev/null 2>&1; echo $?"` + if [ ! $installed ]; then + echo "" > $OUTPATH + return 1 + fi + + # Check what options vmstat supports + if [ `ssh -q $HOSTNAME "vmstat -n >/dev/null 2>&1; echo $?"` ]; then + vmopt="-n" + else + vmopt="" + fi + + # Check what options awk supports + if [ ! -z `ssh $HOSTNAME "echo | awk -W interactive '{print 1}' 2>&1 >/dev/null"` ]; then + awkopt="" + else + awkopt="-W interactive" + fi + + ssh -q $HOSTNAME < uscol) + sycol=i + if(\$i == "wa" && i > uscol) + wacol=i + if(\$i == "id" && i > uscol) + idcol=i + } + } + !/[a-z-]/ { + "date '+%s'" | getline ts + if(uscol != 99 && uscol != 0) + print ts,host,"CPU-US",\$uscol + if(sycol != 0) + print ts,host,"CPU-SY",\$sycol + if(wacol != 0) + print ts,host,"CPU-WA",\$wacol + if(idcol != 0) + print ts,host,"CPU-ID",\$idcol + close("date '+%s'") + }' >> $OUTPATH & +EOF + ssh -q $HOSTNAME "ps aux | \ + grep bdsm | \ + grep vmstat | \ + grep -v grep | \ + awk '{print \$2}' \ + > /home/bdsm/.vmstat.pid &" + else + echo "Already Running" + fi +} + +stop() +{ + ssh $HOSTNAME "kill `cat /home/bdsm/.vmstat.pid`" + ssh $HOSTNAME "rm /home/bdsm/.vmstat.pid" +} + +status() +{ + running=`ssh $HOSTNAME "cat /home/bdsm/.vmstat.pid | \ + xargs ps -T | \ + grep -v PID | \ + wc -l"` + + if [ $running -eq 0 ]; then + echo "OFF" + else + echo "ON" + fi +} + +# UTILITY FUNCTIONS +############################################################################### + +formatConfig() +{ + # Reformat config file to be more machine-readable + # Removes whitespace and adds semicolons after property values + cat /home/bdsm/bdsm.conf | tr '\n' ' ' | sed 's/}/}\ + /g' | sed 's/^;*//g' | sed "s/[[:space:]]//g"| \ + sed 's/;\([{}]\)/\1/g' | sed 's/\([{}]\);/\1/g' \ + > /home/bdsm/.bdsm.conf.tmp +} + +# SCRIPT START +############################################################################### + +# Get a list of configured hosts +hosts=$(cat /home/bdsm/.bdsm.conf.tmp | cut -d'{' -f1) + +if [ -z $1 ]; then + help +elif [ $1 == "start" ]; then + formatConfig + start +elif [ $1 == "stop" ]; then + formatConfig + stop +elif [ $1 == "status" ]; then + formatConfig + status +elif [ $1 == "help" ]; then + help +fi diff --git a/bdsm.sh b/bdsm.sh new file mode 100755 index 0000000..c2b4622 --- /dev/null +++ b/bdsm.sh @@ -0,0 +1,425 @@ +#!/bin/bash +################################################################################ +# +# bdsm.sh +# Bash Daemon for System Monitoring +# +# TODO: +# 1) Fully shakeout configure +# 2) Finish Deploy +# ) Plugins: +# 3) iostat +# 4) ram +# 5) disk utilization +# +############################################################################### + +# TRAP UNKNOWN ERRORS +############################################################################### + +trap failure SIGFPE SIGHUP SIGABRT SIGALRM SIGQUIT +trap term SIGTERM SIGINT + +term() +{ + echo + echo + error "BDSM TERMINATED." + exit 1 +} + +failure() +{ + echo + echo + error "Something has gone SERIOUSLY wrong! (Received signal $?)" + exit 255 +} + +# UTILITY FUNCTIONS +############################################################################### +error() +{ + printf "\e[41m" 1>&2 + printf "ERROR: $1" 1>&2 + printf "\e[0m\n" 1>&2 +} + +warn() +{ + printf "\e[30;43m" 1>&2 + printf "WARNING: $1" 1>&2 + printf "\e[0m\n" 1>&2 + +} + +header() +{ + echo + printf "\e[44m" 1>&2 + printf " $1" 1>&2 + printf "\e[0m\n" 1>&2 +} + +option() +{ + printf "\e[36m" 1>&2 + printf " $1" 1>&2 + printf "\e[0m\n" 1>&2 +} + +prompt() +{ + read -t .25 -n 1000 discard &2 + printf "\r$1" 1>&2 + printf "\e[0;0m " 1>&2 +} + +info() +{ + printf "\e[33m" + printf "INFO: $1" + printf "\e[0m\n" +} + +selector() +{ + prmpt=${1} + shift + + argarr=( "$@" ) + i=0 + while [ ! -z "$1" ]; do + option "$i. $1" + i=`expr $i + 1` + shift + done + + selection=-1 + while [ "$selection" -lt 0 ] || \ + [ "$selection" -gt $i ] || \ + [ "`echo $selection | sed 's/[^0-9]//g'`" != "$selection" ]; do + prompt "$prmpt: " + read selection + done + + echo ${argarr[$selection]} +} + +confirm() +{ + prmpt=${1} + + prompt "CONFIRM: $prmpt Y/[N]" + read selection + if [ "$selection" == "Y" ] || [ "$selection" == "y" ]; then + echo 0 + else + echo 1 + fi +} + +# ACTION FUNCTIONS +############################################################################### + +help() +{ + echo + echo "Bash Daemon for System Monitoring (bdsm.sh)" + echo "USAGE: $0 [start|stop|status|deploy|configure|help]" + echo + echo "If this is your first time executing $0, start with:" + echo " $0 configure" + echo + echo "Once configuration is complete, you must deploy with:" + echo " $0 deploy" + echo + echo "During deployment you may be asked for the root password" + echo " for these systems. This is required for configuring user" + echo " setup. To avoid this, create a user 'bdsm' on the remote" + echo " server and configure passwordless SSH access to this user." + echo " This user will need very limited permissions." + echo + echo " After deployment is completed, you can start, check, or stop:" + echo " $0 start" + echo " $0 status" + echo " $0 stop" + echo + echo "Returns:" + echo " 0: Success!" + echo " 1: PEBKAC" + echo " 2: Could not connect to remote host" + echo " 255: You're on your own. Good luck!" +} + +start() +{ + i=0 + while [ $i -lt ${#hosts[@]} ]; do + type=`echo ${hosts[$i]} | cut -d':' -f1` + host=`echo ${hosts[$i]} | cut -d':' -f2-` + info "Starting $type monitors on $host..." + functions=`cat /home/bdsm/.bdsm.conf.tmp | grep "$type:$host" | sed 's/.*{\(.*\)}.*/\1/'` + + j=0 + echo $functions | tr ';' '\n' | sed 's/[(),]/ /g' | while read line; do + command=`echo $line | cut -d' ' -f1` + args="`echo $line | cut -d' ' -f2-`" + if [ -f /home/bdsm/bdsm.d/$command.$type ]; then + /home/bdsm/bdsm.d/$command.$type start $host $args + elif [ -f /home/bdsm/bdsm.d/$command.$type ]; then + /home/bdsm/bdsm.d/$command.generic start $host $args + else + error "Could not find plugin for $command on $type:$host!" + fi + done + + ssh $host "cat /home/bdsm/out.fifo" > /home/bdsm/in.fifo & + echo $! > /home/bdsm/pids/$host.in + + i=`expr $i + 1` + done +} + +stop() +{ + i=0 + while [ $i -lt ${#hosts[@]} ]; do + type=`echo ${hosts[$i]} | cut -d':' -f1` + host=`echo ${hosts[$i]} | cut -d':' -f2-` + info "Stopping $type monitors on $host..." + functions=`cat /home/bdsm/.bdsm.conf.tmp | grep "$type:$host" | sed 's/.*{\(.*\)}.*/\1/'` + + j=0 + echo $functions | tr ';' '\n' | sed 's/[(),]/ /g' | while read line; do + command=`echo $line | cut -d' ' -f1` + args="`echo $line | cut -d' ' -f2-`" + if [ -f /home/bdsm/bdsm.d/$command.$type ]; then + /home/bdsm/bdsm.d/$command.$type stop $host $args + elif [ -f /home/bdsm/bdsm.d/$command.$type ]; then + /home/bdsm/bdsm.d/$command.generic stop $host $args + else + error "Could not find plugin for $command on $type:$host!" + fi + done + + kill `cat /home/bdsm/pids/$host.in` 2>/dev/null + rm /home/bdsm/pids/$host.in + + i=`expr $i + 1` + done +} + +status() +{ + i=0 + while [ $i -lt ${#hosts[@]} ]; do + type=`echo ${hosts[$i]} | cut -d':' -f1` + host=`echo ${hosts[$i]} | cut -d':' -f2-` + info "Stopping $type monitors on $host..." + functions=`cat /home/bdsm/.bdsm.conf.tmp | grep "$type:$host" | sed 's/.*{\(.*\)}.*/\1/'` + + j=0 + echo $functions | tr ';' '\n' | sed 's/[(),]/ /g' | while read line; do + command=`echo $line | cut -d' ' -f1` + prefix="$type:$host|$command|" + if [ -f /home/bdsm/bdsm.d/$command.$type ]; then + /home/bdsm/bdsm.d/$command.$type status $host | sed "s/^/$prefix/g" + elif [ -f /home/bdsm/bdsm.d/$command.$type ]; then + /home/bdsm/bdsm.d/$command.generic status $host | sed "s/^/$prefix/g" + else + error "Could not find plugin for $command on $type:$host!" + fi + done + + pid=`cat /home/bdsm/pids/$host.in` + if [ ! -f /home/bdsm/pids/$host.in ]; then + echo "$type:$host:MONITOR|???" + elif [ `ps -p $pid | wc -l` -ge 2 ]; then + echo "$type:$host:MONITOR|UP" + else + echo "$type:$host:MONITOR|DOWN" + fi + + i=`expr $i + 1` + done +} + +configure() +{ + configured=0 + if [ -f /home/bdsm/bdsm.conf ]; then + prompt "Configuration already exists! [K]eep, [U]pdate, or [D]elete?" + read selection + if [ $selection == "K" ]; then + info "Proceeding with existing configuration..." + configured=1 + elif [ $selection == "U" ]; then + info "Updating existing configuration..." + elif [ $selection == "D" ]; then + info "Purging existing configuration..." + rm /home/bdsm/bdsm.conf + touch /home/bdsm/bdsm.conf + else + error "Invalid selection." + return 1 + fi + else + touch /home/bdsm/bdsm.conf + fi + + while [ $configured -ne 1 ]; do + # Prompt which host to configure + header "Select a host to configure:" + + host=`selector "Select a host" $hosts "New..." "Done"` + if [ "$host" == "New..." ]; then + host="" + elif [ "$host" == "Done" ]; then + configured=1 + break + else + type=`echo $host | cut -d':' -f1` + host=`echo $host | cut -d':' -f2-` + fi + while [ -z $host ]; do + header "Configure a new host" + + types=$(ls /home/bdsm/bdsm.d/ | cut -d'.' -f2 | sort -u) + type=`selector "Host type" $types` + + prompt "Hostname: " + read host + + if [ `confirm "Confirm creation of $type:$host?"` -eq 0 ]; then + echo "$host{}" >> /home/bdsm/.bdsm.conf.tmp + else + host="" + fi + done + + header "Configuring $host" + availServices=$(ls /home/bdsm/bdsm.d | cut -d'.' -f1 | sort -u) + services=$(cat /home/bdsm/.bdsm.conf.tmp | grep ":$host{" | \ + sed 's/.*{\(.*\)}/\1/g' | tr ';' ' ') + service=`selector "Select a service to configure" $services "Add a service..." "Done"` + + if [ "$service" == "Add a service..." ]; then + header "Add a new service" + service=`selector "Service type: " $availServices` + elif [ "$service" == "Done" ]; then + continue + fi + + header "Configuring $service" + if [ `confirm "Disable $service?"` -eq 0 ]; then + # TODO + # This may need fixed + # TODO + cat /home/bdsm/.bdsm.conf.tmp | \ + sed 's/\(.*:$host{.*\)$service;\(.*\)/\1\2/g' \ + > /home/bdsm/.bdsm.conf.tmp2 + mv /home/bdsm/.bdsm.conf.tmp2 /home/bdsm/.bdsm.conf.tmp + else + header "Reconfiguring $service" + svc=`echo $service | sed 's/(.*)$//g'` + if [ -f /home/bdsm/bdsm.d/$svc.$type ]; then + serviceFile="$svc.$type" + elif [ -f /home/bdsm/bdsm.d/$svc.generic ]; then + serviceFile="$svc.generic" + else + error "$service plugin not found!" + fi + + max=`echo $params | wc -l` + newservice=`echo $service | cut -d'(' -f1`"(" + i=1 + while [ $i -le $max ]; do + param="`/home/bdsm/bdsm.d/$serviceFile help | grep "^::" | sed -n ${i}p`" + paramName="`echo ${param} | sed 's/^::\(.*\) *--.*/\1/g'`" + paramDesc="`echo ${param} | sed 's/^.*--\(.*\)/\1/g'`" + prompt "$paramName: " + read param + newservice=${newservice}${param}"," + i=`expr $i + 1` + done + newservice=`echo $newservice | sed 's/,$/)/g'` + fi + + # TODO + # Validate removal/replacement of old service + # TODO + curHost="`cat /home/bdsm/.bdsm.conf.tmp | grep ":$host{"`" + curHost=`echo $curHost | sed "s/$service;//g" | sed "s/}\$/$newservice;}/g"` + cat /home/bdsm/.bdsm.conf.tmp | \ + grep -v ":$host{" \ + > /home/bdsm/.bdsm.conf.tmp2 + echo $curHost >> /home/bdsm/.bdsm.conf.tmp2 + mv /home/bdsm/.bdsm.conf.tmp2 /home/bdsm/.bdsm.conf.tmp + # Reload the hosts list + hosts=$(cat /home/bdsm/.bdsm.conf.tmp | cut -d'{' -f1) + done + + # Convert config back to a more readable format + cat /home/bdsm/.bdsm.conf.tmp | sed 's/{/\ + {\ + /g' | sed 's/;/;\ + /g' | sed 's/}/}\ + /g' > /home/bdsm/bdsm.conf + rm /home/bdsm/.bdsm.conf.tmp + + info "Configuration complete!" + info "Don't forget to DEPLOY these changes!" + exit 0 +} + +deploy() +{ + i=0 + while [ $i -lt ${#hosts[@]} ]; do + type=`echo ${hosts[$i]} | cut -d':' -f1` + host=`echo ${hosts[$i]} | cut -d':' -f2-` + info "Deploying on $host..." + + ssh -q bdsm@$host + ret=$? + if [ ! $ret ]; then + info "Passwordless SSH not configured. Creating bdsm user as root..." + ssh root@$host "useradd --home-dir /home/bdsm bdsm" + + info "Logging in as bdsm user to transfer SSH key..." + cat /home/bdsm/.ssh/id_rsa.pub | ssh bdsm@$host 'cat >> ~/.ssh/authorized_keys' + fi + + ssh bdsm@$host "mkfifo /home/bdsm/out.fifo" + done +} + +# SCRIPT START +############################################################################### + +# Reformat config file to be more machine-readable +# Removes whitespace and adds semicolons after property values +cat /home/bdsm/bdsm.conf | tr '\n' ' ' | sed "s/[[:space:]]//g" | sed 's/}/}\ +/g' | sed 's/^;*//g' | sed 's/\([{}]\);/\1/g' \ +> /home/bdsm/.bdsm.conf.tmp + +# Get a list of configured hosts +hosts=$(cat /home/bdsm/.bdsm.conf.tmp | cut -d'{' -f1) + +if [ -z $1 ]; then + help +elif [ $1 == "start" ]; then + start +elif [ $1 == "stop" ]; then + stop +elif [ $1 == "status" ]; then + status +elif [ $1 == "configure" ]; then + configure +elif [ $1 == "deploy" ]; then + deploy +else + help +fi \ No newline at end of file