Thursday 26 September 2013

BASH completion example

Since sometimes we forget (or can't be bothered) with doing a --help or doing a man <command> having bash completion is great.

in this example, I am using a script that I've made which is a simple script that has the following commands.

vm.sh --help
create [servername] If option=console, then display console immediately
destroy [servername] Delete a VM
list-vol List all disks for all VMs
list-vm List VMs and status
console [servername] Access console of server
vnc [servername] List VNC port for VM
reset [servername] Restart VM

With bash completion, after typing the command (vm.sh) and pressing tab it will automatically show the commands create destroy list-vol list-vm console vnc reset

Then after the command, pressing tab will output the list of all servers available.

# bash completion for vm.sh
# pks - 20130926
# Now with extra flash bastard bits

# Press tab to view list of available servers after the command


_vm.sh ()   #  By convention, the function name
{           #+ starts with an underscore.
  local cmd_="$1##*/}"
  # word that is being completed
  local word=${COMP_WORDS[COMP_CWORD]}
  # entire line being completed
  local line=${COMP_LINE}
  # exclusion pattern
  local xpat='|*mqueue*'
  _get_comp_words_by_ref -n : cur prev
  # previous command
  prev="${COMP_WORDS[COMP_CWORD-1]}"

  COMPREPLY=()   # Array variable storing the possible completions.
  case "$prev" in
    create|destroy|console|vnc|reset)
    servers=`vm.sh list-vm | awk '{print $2}' | grep web | xargs -n1`
    COMPREPLY=( $( compgen -W '$servers' -- "$cur" ) )
    return 0
    ;;

  esac
  case "$word" in
    *)
    COMPREPLY=( $( compgen -W 'create destroy list-vol list-vm console \
                               vnc reset' -- $cur ) );;
  esac

  return 0
}

_complete ()
{

  COMPREPLY=
}
complete -F _vm.sh vm.sh


# Local variables:
# mode: shell-script
# sh-basic-offset: 4
# sh-indent-comment: t
# indent-tabs-mode: nil
# End:
# ex: ts=4 sw=4 et filetype=sh

To break it down,
$word contains the current command
$prev contains the previous command, so if it is selected, what the next command can be e.g. in this case
if prev=console then the next command can be <servername>

Wednesday 18 September 2013

Auto creating DNS entries in bind

So I virtualised the entire London web server infrastructure (140+ servers) and I've just come back from Santa Clara where I was sent to virtualise the infrastructure there (140+ servers).

One of the most useful things I've learned in doing these projects is that creating DNS entries can be a pain. You can obviously do this via a VIM macro (copy paste, add one to a number, repeat), but you can also do it via bind itself. It can auto generate the DNS entries for you.

For example in our db.sv1.vm.prod zone file:
$GENERATE 1-140 web${0,3,d} A 10.10.0.$
Generates the DNS entries
web001
web002
web003
...
web140
So this works for our test web servers too:

$GENERATE 1-14 testweb${0,2,d) A 10.10.7.$
generates DNS entries
testweb01
testweb02
testweb03
...
testweb14