terom@60: #!/bin/bash terom@52: ## vim: set ft=sh : terom@52: # terom@52: # Operations on zonefiles/hosts/whatever terom@52: terom@52: ## Hosts terom@52: ## Update hosts from verbatim from input zone data: terom@52: # terom@52: # copy_hosts $ZONES/$zone $DATA/$base terom@52: # terom@52: # Writes updated zone to $zone, deps on $base. terom@52: function copy_hosts { terom@52: local zone=$1 terom@52: local base=$2 terom@52: terom@52: if check_update $zone $base; then terom@52: log_update "Copying hosts $zone <- $base..." terom@52: terom@52: do_update $zone \ terom@52: cat $ROOT/$base terom@52: else terom@52: log_skip "Copying hosts $zone <- $base: not changed" terom@52: fi terom@52: } terom@52: terom@52: ## Generate hosts from input zone data using $BIN/process-zone: terom@52: # terom@52: # update_hosts $ZONES/$zone $DATA/$base terom@52: # terom@52: # Writes process-zone'd data to $zone, deps on $base. terom@52: function update_hosts { terom@52: local zone=$1; shift terom@52: local base=$1; shift terom@52: terom@52: if check_update $zone $base; then terom@52: log_update "Generating hosts $zone <- $base..." terom@52: terom@52: do_update $zone \ terom@52: $BIN/process-zone $PROCESS_ARGS $ROOT/$base "$@" terom@52: else terom@52: log_skip "Generating hosts $zone <- $base: not changed" terom@52: fi terom@52: } terom@52: terom@61: ## Update .serial number: terom@61: # terom@61: # do_update_serial $serial terom@61: # terom@61: # Shows old/new serial on debug. terom@61: function do_update_serial { terom@61: local serial=$1 terom@61: terom@61: # read terom@61: local old=$(test -e $ROOT/$serial && cat $ROOT/$serial || echo '') terom@61: terom@61: terom@61: cmd $BIN/update-serial $ROOT/$serial terom@61: terom@61: # read terom@61: local new=$(cat $ROOT/$serial) terom@61: terom@61: debug " $old -> $new" terom@61: } terom@61: terom@61: terom@52: ## Generate new serial for zone using $BIN/update-serial, if the zone data has changed: terom@52: # terom@52: # update_serial $zone $deps... terom@52: # terom@52: # Supports SERIAL_FORCE/NOOP. terom@52: # Updates $SERIALS/$zone.serial. terom@52: function update_serial { terom@52: local zone=$1; shift terom@52: terom@52: local serial=$SERIALS/$zone.serial terom@52: terom@52: # test terom@52: if [ $SERIAL_FORCE ]; then terom@52: log_force "Updating $serial: forced" terom@52: terom@52: do_update_serial $serial terom@52: terom@52: elif ! check_update $serial "$@"; then terom@52: log_skip "Updating $serial: not changed" terom@52: terom@52: elif [ $SERIAL_NOOP ]; then terom@52: log_noop "Updating $serial: skipped" terom@52: terom@52: else terom@52: log_update "Updating $serial..." terom@52: terom@52: do_update_serial $serial terom@52: fi terom@52: } terom@52: terom@52: ## Link serial for zone from given base-zone: terom@52: # terom@52: # link_serial $zone $base terom@52: function link_serial { terom@52: local zone=$1 terom@52: local base=$2 terom@52: terom@52: local lnk=$SERIALS/$zone.serial terom@52: local tgt=$SERIALS/$base.serial terom@52: terom@52: if check_link $lnk $tgt; then terom@52: log_update "Linking $lnk -> $tgt..." terom@52: terom@52: do_link $lnk $tgt terom@52: terom@52: else terom@52: log_skip "Linking $lnk -> $tgt: not changed" terom@52: fi terom@52: } terom@52: terom@52: ## Update zone file verbatim from source: terom@52: # terom@52: # copy_zone $view $zone [$base] terom@52: # terom@52: # Copies changed $DATA/$base zone data to $ZONES/$view/$zone. terom@52: function copy_zone { terom@52: local view=$1 terom@52: local zone=$2 terom@52: local base=${3:-$zone} terom@52: terom@52: local out=$ZONES/$view/$zone terom@52: local src=$DATA/$base terom@52: terom@52: if check_update $out $src; then terom@52: log_update "Copying $out <- $src..." terom@52: terom@52: do_update $out \ terom@52: cat $ROOT/$src terom@52: else terom@52: log_skip "Copying $out <- $src: not changed" terom@52: fi terom@52: } terom@52: terom@52: ## Expand zone file from source using $BIN/expand-zone: terom@52: # terom@52: # update_zone $view $zone [$base] terom@52: # terom@52: # Processed $DATA/$base zone data through $BIN/expand-zone, writing output to $ZONES/$view/$zone. terom@52: function update_zone { terom@52: local view=$1 terom@52: local zone=$2 terom@52: local base=${3:-$zone} terom@52: terom@52: local out=$ZONES/$view/$zone terom@52: local src=$DATA/$base.zone terom@52: local lnk=$ZONES/$base terom@52: terom@52: local serial=$SERIALS/$base.serial terom@52: terom@52: if check_update $out $src $serial; then terom@52: log_update "Generating $out <- $src..." terom@52: terom@52: do_update $out \ terom@52: $BIN/expand-zone $ROOT/$src \ terom@52: --serial $ROOT/$serial \ terom@52: --expand zones=$(abspath $ZONES) \ terom@52: --expand view=$view terom@52: else terom@52: log_skip "Generating $out <- $src: not changed" terom@52: fi terom@52: } terom@52: terom@52: ## Link zone file to ues given shared zone. terom@52: # terom@52: # link_zone $view $zone [$base] terom@52: # terom@52: # Looks for shared zone at: terom@52: # $ZONES/$view/$base terom@52: # $ZONES/common/$base terom@52: function link_zone { terom@52: local view=$1 terom@52: local zone=$2 terom@52: local base=${3:-$zone} terom@52: terom@52: local out=$ZONES/$view/$zone terom@52: local tgt=$(choose_link $out $ZONES/$view/$base $ZONES/common/$base) terom@52: terom@52: if check_link $out $tgt; then terom@52: log_update "Linking $out -> $tgt..." terom@52: terom@52: do_link $out $tgt terom@52: terom@52: else terom@52: log_skip "Linking $out -> $tgt: not changed" terom@52: fi terom@52: } terom@52: terom@52: ## Test hosts zone for validity: terom@52: # terom@52: # check_hosts $DATA/$hosts --check-exempt ... terom@52: # terom@52: # Fails if the check fails. terom@52: function check_hosts { terom@52: local hosts=$1; shift 1 terom@52: terom@52: local cmd=($BIN/process-zone $PROCESS_ARGS $ROOT/$hosts --check-hosts "$@") terom@52: terom@52: if "${cmd[@]}" -q; then terom@52: log_skip "Check $hosts: OK" terom@52: else terom@52: log_error " Check $hosts: Failed" terom@52: terom@52: indent " " "${cmd[@]}" terom@52: terom@52: exit 1 terom@52: fi terom@52: } terom@52: terom@52: ## Test zone file for validity using named-checkzone: terom@52: # terom@52: # check_zone $view $zone $origin terom@52: # terom@52: # Uses the zonefile at $ZONES/$view/$zone, loading it with given initial $ORIGIN. terom@52: # Fails if the check fails. terom@52: function check_zone { terom@52: local view=$1 terom@52: local zone=$2 terom@52: local origin=$3 terom@52: terom@52: local src=$ZONES/$view/$zone terom@52: terom@52: local cmd=($NAMED_CHECKZONE $origin $ROOT/$src) terom@52: terom@52: # test terom@52: # XXX: checkzone is very specific about the order of arguments, -q must be first terom@52: if $NAMED_CHECKZONE -q $origin $ROOT/$src; then terom@52: log_skip "Check $src ($origin): OK" terom@52: else terom@52: log_error " Check $src ($origin): Failed:" terom@52: terom@52: indent " " "${cmd[@]}" terom@52: terom@52: exit 1 terom@52: fi terom@52: } terom@52: terom@59: # Run rndc reload terom@59: function do_reload { terom@59: # run terom@59: indent " rndc: " \ terom@59: $RNDC reload terom@59: } terom@59: terom@52: ## Load update zonefiles into bind: terom@52: # terom@61: # reload_zones terom@52: # terom@52: # Invokes `rndc reload`, showing its output. terom@61: function reload_zones { terom@52: local msg="Reload zones" terom@52: terom@61: if [ $RELOAD_FORCE ]; then terom@59: log_force "$msg..." terom@59: terom@59: do_reload terom@59: terom@61: elif [ $RELOAD_NOOP ]; then terom@59: log_noop "$msg: skipped" terom@52: terom@52: elif [ ! -r $RNDC_KEY ]; then terom@52: log_error " $msg: rndc: permission denied: $RNDC_KEY" terom@52: terom@59: return 1 terom@59: terom@52: else terom@52: log_update "$msg..." terom@52: terom@52: # run terom@59: do_reload terom@52: fi terom@52: } terom@61: terom@61: ## Perform `hg commit` for $DATA terom@61: function do_commit { terom@61: local msg=$1 terom@61: terom@61: [ $LOG_DIFF ] && indent " " hg_diff terom@61: terom@61: hg_commit "$msg" terom@61: } terom@61: terom@61: terom@52: ## Commit changes in $DATA to version control: terom@52: # terom@52: # commit_data terom@52: # terom@52: # Invokes `hg commit` in the $REPO, first showing the diff. terom@52: function commit_data { terom@52: local repo=$REPO terom@52: local commit_msg="$COMMIT_MSG" terom@52: terom@52: local msg="Commit changes in $repo" terom@52: terom@52: # operate? terom@52: if [ $COMMIT_FORCE ]; then terom@52: log_force "$msg..." terom@52: terom@52: do_commit "$commit_msg" terom@52: terom@52: elif ! hg_modified; then terom@52: log_skip "$msg: no changes" terom@52: terom@52: elif [ $COMMIT_SKIP ]; then terom@52: log_noop "$msg: skipped" terom@57: terom@57: # still show diff, though terom@57: [ $LOG_DIFF ] && indent " " hg_diff terom@52: else terom@52: log_update "$msg..." terom@52: terom@52: do_commit "$commit_msg" terom@52: fi terom@52: } terom@52: