Friday, October 7, 2011

finding broken symlinks

Bash snippet for finding broken symlinks.

Shamelessly stolen from here.


find . -type l | (while read FN ; do test -e "$FN" || ls -ld "$FN"; done)

Friday, September 23, 2011

chkconfig-compatible unicorn script



For posterity, here is a chkconfig-compatible init script for unicorn.

Adapted from here.


#!/bin/sh
# chkconfig: 2345 85 15
# description: init.d script for single or multiple unicorn installations. Expects at least one .conf file in /etc/unicorn
# processname: unicorn
#
## A sample /etc/unicorn/my_app.conf
##
## RAILS_ENV=production
## RAILS_ROOT=/var/apps/www/my_app/current
#
# This configures a unicorn master for your app at /var/apps/www/my_app/current running in
# production mode. It will read config/unicorn.rb for further set up.
#
# You should ensure different ports or sockets are set in each config/unicorn.rb if
# you are running more than one master concurrently.
#
# If you call this script without any config parameters, it will attempt to run the
# init command for all your unicorn configurations listed in /etc/unicorn/*.conf
#
# /etc/init.d/unicorn start # starts all unicorns
#
# If you specify a particular config, it will only operate on that one
#
# /etc/init.d/unicorn start /etc/unicorn/my_app.conf

set -e

sig () {
  test -s "$PID" && kill -$1 `cat "$PID"`
}

oldsig () {
  test -s "$OLD_PID" && kill -$1 `cat "$OLD_PID"`
}

cmd () {

  case $1 in
    start)
      sig 0 && echo >&2 "Already running" && exit 0
      echo "Starting"
      $CMD
      ;;
    stop)
      sig QUIT && echo "Stopping" && exit 0
      echo >&2 "Not running"
      ;;
    force-stop)
      sig TERM && echo "Forcing a stop" && exit 0
      echo >&2 "Not running"
      ;;
    restart|reload)
      sig USR2 && sleep 5 && oldsig QUIT && echo "Killing old master" `cat $OLD_PID` && exit 0
      echo >&2 "Couldn't reload, starting '$CMD' instead"
      $CMD
      ;;
    upgrade)
      sig USR2 && echo Upgraded && exit 0
      echo >&2 "Couldn't upgrade, starting '$CMD' instead"
      $CMD
      ;;
    rotate)
            sig USR1 && echo rotated logs OK && exit 0
            echo >&2 "Couldn't rotate logs" && exit 1
            ;;
    *)
      echo >&2 "Usage: $0 "
      exit 1
      ;;
    esac
}

setup () {

  echo -n "$RAILS_ROOT: "
  cd $RAILS_ROOT || exit 1
  export PID=$RAILS_ROOT/tmp/pids/unicorn.pid
  export OLD_PID="$PID.oldbin"

  CMD="unicorn_rails --config-file config/unicorn.rb --env $RAILS_ENV --daemonize"
}

start_stop () {
  
  # either run the start/stop/reload/etc command for every config under /etc/unicorn
  # or just do it for a specific one

  # $1 contains the start/stop/etc command
  # $2 if it exists, should be the specific config we want to act on
  if [ $2 ]; then
    . $2
    setup
    cmd $1
  else
for CONFIG in /etc/unicorn/*.conf; do
      # import the variables
      . $CONFIG
      setup

      # run the start/stop/etc command
      cmd $1
    done
fi
}

ARGS="$1 $2"
start_stop $ARGS

chkconfig-compatible nginx init script



For posterity, here is a chkconfig-compatible init script for nginx.



#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig:   - 85 15
# description:  Nginx is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 proxy server
# processname: nginx
# config:      /opt/nginx/conf/nginx.conf
# config:      /etc/sysconfig/nginx
# pidfile:     /var/run/nginx.pid

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0

nginx="/opt/nginx/sbin/nginx"
prog=$(basename $nginx)

NGINX_CONF_FILE="/opt/nginx/conf/nginx.conf"

[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx

lockfile=/var/lock/subsys/nginx

start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}

stop() {
    echo -n $"Stopping $prog: "
    killproc $prog
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}

restart() {
    configtest_q || configtest || return 6
    stop
    start
}

reload() {
    configtest_q || configtest || return 6
    echo -n $"Reloading $prog: "
    killproc $nginx -HUP
    echo
}

configtest() {
  $nginx -t -c $NGINX_CONF_FILE
}

configtest_q() {
    configtest >/dev/null 2>&1
}

rh_status() {
    status $prog
}

rh_status_q() {
    rh_status >/dev/null 2>&1
}

# Upgrade the binary with no downtime.
upgrade() {
    local pidfile="/var/run/${prog}.pid"
    local oldbin_pidfile="${pidfile}.oldbin"

    configtest_q || configtest || return 6
    echo -n $"Staring new master $prog: "
    killproc $nginx -USR2
    retval=$?
    echo 
    sleep 1
    if [[ -f ${oldbin_pidfile} && -f ${pidfile} ]];  then
        echo -n $"Graceful shutdown of old $prog: "
        killproc -p ${oldbin_pidfile} -QUIT
        retval=$?
        echo 
        return 0
    else
        echo $"Something bad happened, manual intervention required, maybe restart?"
        return 1
    fi
}

case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart|configtest)
        $1
        ;;
    force-reload|upgrade) 
        rh_status_q || exit 7
        upgrade
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    status|status_q)
        rh_$1
        ;;
    condrestart|try-restart)
        rh_status_q || exit 7
        restart
	    ;;
    *)
        echo $"Usage: $0 {start|stop|reload|configtest|status|force-reload|upgrade|restart}"
        exit 2
esac

Tuesday, August 2, 2011

the only problem i've ever had with tinydns

On occasion tinydns can become completely unresponsive. Every time this has happened to me, this has been because it can not log. This is easily diagnosed via netstat.


vietnam ~ # netstat -tlundp | grep -i tinydns
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
udp 128372 0 192.168.1.4:53 0.0.0.0:* 16073/tinydns


Any significant, constantly increasing number under Recv-Q usually indicates this problem.

The problem is solved easily enough, assuming a standard install of tinydns/daemontools.

vietnam ~ # svc -u /service/tinydns/log

Friday, June 24, 2011

chkconfig-compatible init script for daemontools



For posterity, here is a chkconfig-compatible init script for daemontools / svscan

Adapted from here.


#!/bin/sh
#
# svscan This shell script takes care of starting and stopping
# svscan (the supervise scan program)
#
# chkconfig: 2345 11 88
# description: svscan starts and monitors a collection of services.
# processname: svscan
# config: /service

# Source function library.
. /etc/rc.d/init.d/functions

PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin

case "$1" in

start)
echo -n "Starting svscan: "
if [ -f /var/run/svscan.pid ]; then
if ps h `cat /var/run/svscan.pid` >/dev/null; then
echo svscan already started
exit 0
fi
fi
cd /service
for service in *; do
touch "$service"/down "$service"/log/down >/dev/null 2>&1
done
env - PATH="$PATH" svscan &
echo $! > /var/run/svscan.pid
echo svscan
;;

stop)
echo -n "Stopping svscan: "
killproc svscan
echo

cd /service
for service in *; do
echo -n "Stopping service $service: "
if svok "$service"; then
svc -dx "$service"
echo stopped.
else
echo already stopped.
fi
if [ -d "$service/log" ]; then
echo -n "Stopping service $service/log: "
if svok "$service/log"; then
svc -dx "$service/log"
echo stopped.
else
echo already stopped.
fi
fi
done
;;

restart)
$0 stop
sleep 1
$0 start
;;

status)
status svscan
;;

*)
echo "Usage: svscan {start|stop|status|restart}" 1>&2
;;

esac