--- a/bin/update Thu Mar 15 18:34:57 2012 +0200
+++ b/bin/update Fri Mar 16 13:59:26 2012 +0200
@@ -22,7 +22,15 @@
## options
IS_TTY=
+
+LOG=y
+LOG_INFO=
+LOG_DEBUG=
+LOG_CMD=
+
UPDATE_FORCE=
+UPDATE_NOOP=
+UPDATE_DIFF=
SERIAL_NOUPDATE=
function help_args {
@@ -32,7 +40,15 @@
Usage: $prog [options]
-h display this help text
+
+ -q quiet
+ -v verbose
+ -D debug
+
+ -d show changes
+
-F force-updates without checking src mtime
+ -n no-op/mock-update; do not actually change anything; implies -S
-S do not update serial
END
}
@@ -40,16 +56,32 @@
function parse_args {
OPTIND=1
- while getopts 'hFS' opt "$@"; do
+ while getopts 'hqvDdFnS' opt "$@"; do
case $opt in
h)
help_args $1
exit 0
;;
+ q) LOG= ;;
+ v) LOG_INFO=y ;;
+ D)
+ LOG_DEBUG=y
+ LOG_CMD=y
+
+ ;;
+
+ d) UPDATE_DIFF=y ;;
F) UPDATE_FORCE=y ;;
S) SERIAL_NOUPDATE=y ;;
-
+
+ n)
+ # implies -S
+ UPDATE_NOOP=y
+ SERIAL_NOUPDATE=y
+ ;;
+
+
?)
die
;;
@@ -78,19 +110,40 @@
}
function log {
- log_msg "$*"
+ [ $LOG ] && log_msg "$*" || true
}
function log_info {
- log_color 36 " $*"
+ [ $LOG_INFO ] && log_color 36 " $*" || true
}
function log_debug {
- log_color 32 " $*"
+ [ $LOG_DEBUG ] && log_color 32 " $*" || true
}
function log_cmd {
- log_color 35 " \$ $*"
+ [ $LOG_CMD ] && log_color 35 " \$ $*" || true
+}
+
+# XXX: broken
+function log_stack {
+ local level=1
+
+ while info=$(caller $level); do
+ echo $info | read line sub file
+
+ log_msg "$file:$lineno $sub()"
+
+ level=$(($level + 1))
+ done
+}
+
+function fail {
+ func=$(caller 1 | cut -d ' ' -f 2)
+
+ log_error "$func: $*"
+
+ exit 2
}
function die {
@@ -113,9 +166,11 @@
}
function indent () {
+ local indent=$1; shift
+
"$@" | (
while read line; do
- echo " $line"
+ echo "$indent$line"
done
) || exit $?
}
@@ -126,49 +181,116 @@
[ -d $ZONES ] || die "Missing zones: $ZONES"
## functions
-function update {
- local dst=$1
- local src=$2
+function check_update {
+ # target
+ local dst=$1; shift
+
+ log_debug "$dst:"
+
+ # need update?
+ local update=
+
+ if [ ! -e $dst ] || [ $UPDATE_FORCE ]; then
+ log_debug " update forced"
+ update=y
+ fi
+
+ # check deps
+ for dep in "$@"; do
+ # don't bother checking if already figured out
+ [ $update ] && continue
+
+ # check
+
+ if [ $dst -ot $dep ]; then
+ log_debug " changed: $dep"
+ update=y
+ fi
+ done
+
+ [ ! $update ] && log_debug " up-to-date"
+
+ # return
+ [ $update ]
+}
+
+function do_update {
+ local dst=$1; shift
local tmp=$dst.new
- shift 2
-
- if [ -z $src ] || [ $UPDATE_FORCE ] || [ $dst -ot $src ]; then
- log_debug "update: $dst <- $src"
- cmd "$@" $src > $tmp
+ log_debug " update: $dst"
+ cmd "$@" > $tmp
- # compare
- if [ -e $dst ]; then
- # terse
- indent diff --unified=1 $dst $tmp
+ # compare
+ if [ -e $dst ] && [ $UPDATE_DIFF ]; then
+ log_debug " changes:"
+
+ # terse
+ indent " " diff --unified=1 $dst $tmp
+ fi
+
+ if [ $UPDATE_NOOP ]; then
+ # cleanup
+ log_debug " no-op:"
+
+ cmd rm $tmp
+ else
+ # commit
+ log_debug " done:"
+
+ cmd mv $tmp $dst
+ fi
+}
+
+function update {
+ local dst=$1; shift;
+
+ local sep=
+ local dep=()
+ local cmd=()
+
+ for arg in "$@"; do
+ if [ $arg == '--' ]; then
+ sep=y
fi
-
- # overwrite
- mv $tmp $dst
- else
- log_debug "$dst <- $src: up-to-date"
- fi
+ if [ $sep ]; then
+ cmd=("${cmd[@]:-}" "$arg")
+ else
+ dep=("${dep[@]:-}" "$arg")
+ fi
+ done
+
+ [ ! $sep ] && fail "Invalid args given: $@"
+
+ check_update $dst "${dep[@]}" && do_update $dst "${cmd[@]}" || true
}
## bin wrappers
function update_serial {
- cmd $UPDATE_SERIAL $*
+ local serial=$1; shift
+ local old=$(cat $serial)
+
+ log_info "Updating serial: $serial"
+
+ cmd $UPDATE_SERIAL $* $serial
+
+ local new=$(cat $serial)
+
+ log_debug " $old -> $new"
}
function expand_zone {
local output=$1; shift
local src=$1; shift
-
- update $output $src $EXPAND_ZONE "$@"
}
function process_zone {
local output=$1; shift
local src=$1; shift
- update $output $src $PROCESS_ZONE $PROCESS_ARGS "$@"
+ check_update $output $src && update $output $PROCESS_ZONE $PROCESS_ARGS "$@" $src
}
## actions
@@ -177,21 +299,38 @@
local part=$2
local name=$zone.zone.$part
+ local src=$SETTINGS/$name
+ local dst=$ZONES/$name
- log_info "Copying zone $zone/$part: zones/$name"
- update $ZONES/$name $SETTINGS/$name cat
+ if check_update $dst $src; then
+ log_info "Copying zone $zone.$part..."
+
+ do_update $output cat $src
+ else
+ log_info "Copying zone $zone.$part: not changed"
+ fi
}
function update_zone {
local zone=$1
+
local name=$zone.zone
- log_info "Generating $zone zone headers: zones/$name"
+ local out=$ZONES/$name
+ local in=$SETTINGS/$zone.zone
+ local serial=$SERIALS/$zone.serial
- expand_zone $ZONES/$name $SETTINGS/$zone.zone \
- --serial $SERIALS/$zone.serial \
- --expand zones=$ROOT/$ZONES
+ if check_update $out $in $serial; then
+ log_info "Generating $zone zone headers..."
+
+ do_update $out \
+ $EXPAND_ZONE $SETTINGS/$zone.zone \
+ --serial $SERIALS/$zone.serial \
+ --expand zones=$ROOT/$ZONES
+ else
+ log_info "Generating $zone zone headers: not changed"
+ fi
}
function update_zone_view {
@@ -200,12 +339,35 @@
local name=$view/$zone.zone
- log_info "Generating $zone:$view zone headers: zones/$name"
+ local out=$ZONES/$name
+ local in=$SETTINGS/$zone.zone
+ local serial=$SERIALS/$zone.serial
- expand_zone $ZONES/$name $SETTINGS/$zone.zone \
- --serial $SERIALS/$zone.serial \
- --expand zones=$ROOT/$ZONES \
- --expand view=$view
+ if check_update $out $in $serial; then
+ log_info "Generating $zone:$view zone headers..."
+
+ do_update $out \
+ $EXPAND_ZONE $SETTINGS/$zone.zone \
+ --serial $SERIALS/$zone.serial \
+ --expand zones=$ROOT/$ZONES \
+ --expand view=$view
+ else
+ log_info "Generating $zone:$view zone headers: not changed"
+ fi
+}
+
+function update_hosts {
+ local dst=$1; shift
+ local src=$1; shift
+
+
+ if check_update $dst $src; then
+ log_info "Generating $dst..."
+
+ do_update $dst $PROCESS_ZONE $PROCESS_ARGS $src "$@"
+ else
+ log_info "Generating $dst: not changed"
+ fi
}
function main {
@@ -214,18 +376,19 @@
parse_args "$@"
+ log "Updating serials..."
+
if [ $SERIAL_NOUPDATE ]; then
- log_debug "skipping serial-update"
+ log_debug "skipping"
else
- log "Updating serials..."
- update_serial $SERIALS/paivola.serial
- update_serial $SERIALS/paivola-reverse.serial
+ 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
- process_zone $ZONES/paivola-reverse.zone.hosts $SETTINGS/paivola.txt --reverse-zone $REVERSE_ZONE --reverse-domain $REVERSE_DOMAIN
+ update_hosts $ZONES/external/paivola.zone.hosts $SETTINGS/paivola.txt --forward-zone
+ update_hosts $ZONES/internal/paivola.zone.hosts $SETTINGS/paivola.txt --forward-zone --forward-txt --forward-mx $FORWARD_MX
+ update_hosts $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
@@ -233,7 +396,7 @@
copy_zone_part paivola internal
copy_zone_part paivola external
- log "Updating zones..."
+ log "Updating zones headers..."
update_zone paivola-reverse
update_zone_view paivola internal
update_zone_view paivola external