bin/update
changeset 7 f4457348faa0
parent 2 aeb106b9487c
child 8 dab145ee3f81
--- a/bin/update	Thu Mar 15 18:34:32 2012 +0200
+++ b/bin/update	Thu Mar 15 18:34:57 2012 +0200
@@ -5,13 +5,14 @@
 
 ROOT=$(pwd)
 
-BIN=$ROOT/bin
+BIN=bin
 PROCESS_ZONE=$BIN/process-zone
 EXPAND_ZONE=$BIN/expand-zone
+UPDATE_SERIAL=$BIN/update-serial
 
-SETTINGS=$ROOT/settings
-ZONES=$ROOT/zones
-SERIALS=$ROOT/serials
+SETTINGS=settings
+ZONES=zones
+SERIALS=serials
 
 PROCESS_ARGS='--input-charset latin-1'
 
@@ -19,59 +20,178 @@
 REVERSE_ZONE=194.197.235
 REVERSE_DOMAIN=paivola.fi
 
-function log {
+## options
+IS_TTY=
+UPDATE_FORCE=
+SERIAL_NOUPDATE=
+
+function help_args {
+    local prog=$1
+
+    cat <<END
+Usage: $prog [options]
+
+    -h      display this help text
+    -F      force-updates without checking src mtime
+    -S      do not update serial
+END
+}
+
+function parse_args {
+    OPTIND=1
+
+    while getopts 'hFS' opt "$@"; do
+        case $opt in
+            h)  
+                help_args $1
+                exit 0
+            ;;
+
+            F)  UPDATE_FORCE=y ;;
+            S)  SERIAL_NOUPDATE=y ;;
+            
+            ?)  
+                die 
+            ;;
+        esac
+
+    done
+}
+
+## lib
+function log_msg {
     echo "$*" >&2
 }
 
+function log_color {
+    local code=$1; shift
+
+    if [ $IS_TTY ]; then
+        echo $'\e[0;'${code}'m'"$*"$'\e[00m' >&2
+    else
+        echo "$*" >&2
+    fi
+}
+
+function log_error {
+    log_color 31 "$*"
+}
+
+function log {
+    log_msg "$*"
+}
+
+function log_info {
+    log_color 36 "  $*"
+}
+
+function log_debug {
+    log_color 32 "    $*"
+}
+
+function log_cmd {
+    log_color 35 "       \$ $*"
+}
+
 function die {
-    log "$*"
+    log_error "$*"
     exit 1
 }
 
-function log_cmd {
+function cmd {
+    log_cmd "$@"
+
+    "$@" || die "Failed"
+}
+
+function run_cmd {
     local msg=$1; shift
 
-    #log ">>>" "$@"
+    log_info "$msg... "
 
-    echo -n "$msg... " >&2
-
-    "$@" && log "OK" >&2 || die "Failed"
+    cmd "$@"
 }
 
+function indent () {
+    "$@" | (
+        while read line; do
+            echo "    $line"
+        done
+    ) || exit $?
+}
+
+## test
 [ -d $SETTINGS ] || die "Missing settings: $SETTINGS"
 [ -d $SERIALS ] || die "Missing serials: $SERIALS"
 [ -d $ZONES ] || die "Missing zones: $ZONES"
 
+## functions
+function update {
+    local dst=$1
+    local src=$2
+    local tmp=$dst.new
+
+    shift 2
+
+    if [ -z $src ] || [ $UPDATE_FORCE ] || [ $dst -ot $src ]; then
+        log_debug "update: $dst <- $src"
+        cmd "$@" $src > $tmp
+
+        # compare
+        if [ -e $dst ]; then
+            # terse
+            indent diff --unified=1 $dst $tmp
+        fi
+        
+        # overwrite
+        mv $tmp $dst
+
+    else
+        log_debug "$dst <- $src: up-to-date"
+    fi
+}
+
+## bin wrappers
+function update_serial {
+    cmd $UPDATE_SERIAL $*
+}
+
 function expand_zone {
     local output=$1; shift
+    local src=$1; shift
 
-    $EXPAND_ZONE -o $output "$@"
+
+    update $output $src $EXPAND_ZONE "$@"
 }
 
 function process_zone {
     local output=$1; shift
+    local src=$1; shift
 
-    $PROCESS_ZONE $PROCESS_ARGS -o $output "$@"
+    update $output $src $PROCESS_ZONE $PROCESS_ARGS "$@"
 }
 
+## actions
 function copy_zone_part {
     local zone=$1
     local part=$2
 
     local name=$zone.zone.$part
 
-    log_cmd "Copying zone $zone/$part: zones/$name"
-    cp $SETTINGS/$name $ZONES/$name
+    log_info "Copying zone $zone/$part: zones/$name"
+
+    update $ZONES/$name $SETTINGS/$name cat
 }
 
 function update_zone {
     local zone=$1
     local name=$zone.zone
 
-    log_cmd "Generating $zone zone headers: zones/$name" \
-        expand_zone     $ZONES/$name    $SETTINGS/$zone.zone   \
-            --serial $SERIALS/$zone.serial --update-serial  \
-            --expand zones=$ZONES
+    log_info "Generating $zone zone headers: zones/$name" 
+
+    expand_zone     $ZONES/$name    $SETTINGS/$zone.zone   \
+        --serial $SERIALS/$zone.serial  \
+        --expand zones=$ROOT/$ZONES
 }
 
 function update_zone_view {
@@ -80,32 +200,43 @@
 
     local name=$view/$zone.zone
 
-    log_cmd "Generating $zone:$view zone headers: zones/$name" \
-        expand_zone     $ZONES/$name    $SETTINGS/$zone.zone   \
-            --serial $SERIALS/$zone.serial --update-serial  \
-            --expand zones=$ZONES   \
-            --expand view=$view
+    log_info "Generating $zone:$view zone headers: zones/$name"
+
+    expand_zone     $ZONES/$name    $SETTINGS/$zone.zone   \
+        --serial $SERIALS/$zone.serial  \
+        --expand zones=$ROOT/$ZONES     \
+        --expand view=$view
 }
 
 function main {
-    log_cmd "Generating external forward zone: zones/external/paivola.zone.hosts" \
-        process_zone    $ZONES/external/paivola.zone.hosts  $SETTINGS/paivola.txt --forward-zone
+    # test tty
+    [ -t 1 ] && IS_TTY=y
 
-    log_cmd "Generating internal forward zone: zones/internal/paivola.zone.hosts" \
+    parse_args "$@"
+
+    if [ $SERIAL_NOUPDATE ]; then
+        log_debug "skipping serial-update"
+    else
+        log "Updating serials..."
+            update_serial   $SERIALS/paivola.serial
+            update_serial   $SERIALS/paivola-reverse.serial
+    fi
+
+    log "Generating host zones..."
+        process_zone    $ZONES/external/paivola.zone.hosts  $SETTINGS/paivola.txt --forward-zone
         process_zone    $ZONES/internal/paivola.zone.hosts  $SETTINGS/paivola.txt --forward-zone --forward-txt --forward-mx $FORWARD_MX
-
-    log_cmd "Generating reverse zones: zones/paivola-reverse.zone.hosts" \
         process_zone    $ZONES/paivola-reverse.zone.hosts   $SETTINGS/paivola.txt --reverse-zone $REVERSE_ZONE --reverse-domain $REVERSE_DOMAIN
 
+    log "Copying zone parts..."
+        copy_zone_part      paivola             auto
+        copy_zone_part      paivola             services
+        copy_zone_part      paivola             internal
+        copy_zone_part      paivola             external
 
-    copy_zone_part      paivola             auto
-    copy_zone_part      paivola             services
-    copy_zone_part      paivola             internal
-    copy_zone_part      paivola             external
-
-    update_zone         paivola-reverse
-    update_zone_view    paivola             internal
-    update_zone_view    paivola             external
+    log "Updating zones..."
+        update_zone         paivola-reverse
+        update_zone_view    paivola             internal
+        update_zone_view    paivola             external
 }
 
-main
+main "$@"