terom@583: #!/bin/bash terom@575: ## vim: set ft=sh : terom@575: # terom@575: # Operations on zonefiles/hosts/whatever terom@575: terom@605: function link { terom@608: local out="$1" terom@608: local tgt="$2" terom@585: terom@608: if check_link "$out" "$tgt"; then terom@585: log_update "Linking $out -> $tgt..." terom@585: terom@608: do_link "$out" "$tgt" terom@585: terom@585: else terom@585: log_skip "Linking $out -> $tgt: not changed" terom@585: fi terom@585: } terom@585: terom@605: function copy { terom@608: local out="$1" terom@608: local src="$2" terom@587: terom@608: if check_update "$out" "$src"; then terom@587: log_update "Copying $out <- $src..." terom@587: terom@608: do_update "$out" \ terom@608: cat "$src" terom@587: else terom@587: log_skip "Copying $out <- $src: not changed" terom@587: fi terom@587: } terom@585: terom@589: ## Run check-command on given file, outputting results: terom@589: # terom@605: # check $src $cmd $args... terom@589: # terom@605: function check { terom@608: local src="$1"; shift terom@608: local cmd="$1"; shift terom@589: terom@608: if cmd_test "$cmd" -q "$@"; then terom@589: log_skip "Check $src: OK" terom@589: terom@589: else terom@589: log_error " Check $src: Failed" terom@589: terom@608: indent " " "$cmd" "$@" terom@589: terom@589: exit 1 terom@589: fi terom@589: } terom@589: terom@605: ## Generate forward zone from hosts hosts using pvl.hosts-dns: terom@575: # terom@607: # update_hosts_forward out/hosts/$hosts $hosts in/hosts/$hosts terom@605: function update_hosts_forward { terom@608: local out="$1"; shift terom@608: local domain="$1"; shift terom@615: terom@616: if check_update "$out" "$@"; then terom@616: log_update "Generating forward hosts zone $out @ $domain <- $@..." terom@605: terom@608: do_update "$out" $OPT/bin/pvl.hosts-dns \ terom@607: --hosts-charset=$CHARSET \ terom@608: --forward-zone="$domain" \ terom@616: "$@" terom@605: else terom@616: log_skip "Generating forward hosts $out <- $@: not changed" terom@605: fi terom@605: } terom@575: terom@605: function update_hosts_dhcp { terom@607: local out=$1; shift terom@607: local src=$1; shift terom@605: terom@607: if check_update $out $src "$@"; then terom@605: log_update "Generating DHCP hosts $out <- $src..." terom@605: terom@607: do_update $out $OPT/bin/pvl.hosts-dhcp \ terom@607: --hosts-charset=$CHARSET \ terom@607: $src "$@" terom@575: else terom@605: log_skip "Generating DHCP hosts $out <- $src: not changed" terom@575: fi terom@575: } terom@575: terom@607: ## Generate reverse zone from hosts hosts using pvl.hosts-dns: terom@607: # terom@607: # update_hosts_reverse out/hosts/$reverse $reverse in/hosts/$hosts terom@607: function update_hosts_reverse { terom@608: local out="$1"; shift terom@608: local reverse="$1"; shift terom@607: terom@616: if check_update "$out" "$@"; then terom@616: log_update "Generating reverse hosts zone $out <- $@..." terom@607: terom@608: do_update "$out" $OPT/bin/pvl.hosts-dns \ terom@607: --hosts-charset=$CHARSET \ terom@608: --reverse-zone="$reverse" \ terom@616: "$@" terom@607: else terom@616: log_skip "Generating reverse hosts $out <- $@: not changed" terom@607: fi terom@607: } terom@607: terom@584: ## Update .serial number: terom@584: # terom@618: # do_update_serial .../serials/$zone $serial terom@584: # terom@584: function do_update_serial { terom@618: local dst="$1" terom@618: local serial="$2" terom@584: terom@618: echo $serial > $dst terom@584: } terom@584: terom@584: terom@605: ## Generate new serial for zone using pvl.dns-serial, if the zone data has changed: terom@575: # terom@618: # update_serial .../serials/$zone $serial $deps... terom@575: # terom@575: # Supports SERIAL_FORCE/NOOP. terom@575: # Updates $SERIALS/$zone.serial. terom@575: function update_serial { terom@618: local dst="$1"; shift terom@608: local serial="$1"; shift terom@618: terom@618: local old=$(test -e "$dst" && cat "$dst" || echo '') terom@575: terom@575: # test terom@575: if [ $SERIAL_FORCE ]; then terom@618: log_force "Updating $dst: $old <- $serial: forced" terom@575: terom@618: do_update_serial "$dst" "$serial" terom@575: terom@618: elif ! check_update "$dst" "$@"; then terom@618: log_skip "Updating $dst: $old <- $serial: not changed" terom@575: terom@575: elif [ $SERIAL_NOOP ]; then terom@618: log_noop "Updating $dst: $old <- $serial: skipped" terom@575: terom@575: else terom@618: log_update "Updating $dst: $old <- $serial" terom@575: terom@618: do_update_serial "$dst" "$serial" terom@575: fi terom@575: } terom@575: terom@608: ## Generate zone file from source using pvl.dns-zone: terom@575: # terom@608: # update_zone out/zones/$zone in/zones/$zone var/serials/$zone terom@608: function update_zone { terom@618: local out="$1"; shift terom@618: local src="$1"; shift terom@618: local serial="$1"; shift terom@611: local serial_opt= terom@611: terom@611: if [ -n "$serial" -a -f "$serial" ]; then terom@611: serial_opt="--serial=$(cat "$serial")" terom@611: elif [ $SERIAL_NOOP ]; then terom@611: warn "$out: noop'd serial, omitting" terom@611: else terom@611: fail "$out: missing serial: $serial" terom@611: fi terom@575: terom@618: if check_update "$out" "$src" "$serial" "$@"; then terom@575: log_update "Generating $out <- $src..." terom@575: terom@608: do_update "$out" $OPT/bin/pvl.dns-zone "$src" \ terom@613: --include-path=$SRV/var/zones \ terom@611: $serial_opt terom@575: else terom@575: log_skip "Generating $out <- $src: not changed" terom@575: fi terom@575: } terom@575: terom@614: ## Generate dhcp confs from source using pvl.dhcp-conf: terom@614: function update_dhcp_conf { terom@614: local out="$1" terom@614: local src="$2" terom@614: terom@614: if check_update "$out" "$src"; then terom@614: log_update "Generating $out <- $src..." terom@614: terom@614: do_update "$out" $OPT/bin/pvl.dhcp-conf "$src" \ terom@614: --include-path=$SRV/var/dhcp terom@614: else terom@614: log_skip "Generating $out <- $src: not changed" terom@614: fi terom@614: } terom@614: terom@605: ## Test hosts zone for validity using pvl.hosts-check: terom@575: # terom@605: # check_hosts .../hosts terom@575: function check_hosts { terom@575: local hosts=$1; shift 1 terom@605: terom@605: # TODO terom@605: check $hosts \ terom@605: $OPT/bin/pvl.hosts-check $hosts terom@575: } terom@575: terom@575: ## Test zone file for validity using named-checkzone: terom@575: # terom@605: # check_zone ..../$zone $origin terom@575: function check_zone { terom@605: local zone=$1 terom@605: local origin=$2 terom@575: terom@613: log_check "Checking $zone @ $origin..." terom@613: terom@605: # checkzone is very specific about the order of arguments, -q must be first terom@605: check $zone $NAMED_CHECKZONE $origin $zone terom@575: } terom@575: terom@585: ## Test DHCP configuration for validity using dhcpd -t: terom@585: # terom@585: # check_dhcp [$conf] terom@585: # terom@585: # Defaults to the global $DHCPD_CONF. terom@585: # Fails if the check fails. terom@585: function check_dhcp { terom@585: local conf=${1:-$DHCPD_CONF} terom@613: terom@613: log_check "Checking DHCP $conf..." terom@585: terom@591: if [ ! -e $DHCPD ]; then terom@591: log_warn "check_dhcp: dhcpd not installed, skipping: $conf" terom@591: return 0 terom@591: fi terom@591: terom@605: check $conf \ terom@589: $DHCPD -cf $conf -t terom@585: } terom@585: terom@586: ## Test DHCP configuration of given settings/dhcp using check_dhcp $DHCP_DATA/$host.conf: terom@585: # terom@586: # check_dhcp_conf $conf terom@586: # terom@586: function check_dhcp_conf { terom@589: local conf=$1; terom@585: terom@586: check_dhcp $DHCP_DATA/$conf.conf terom@585: } terom@585: terom@605: ### Deploy terom@617: # set by do_reload_zone if zone data has actually been reloaded terom@617: RELOAD_ZONES= terom@617: terom@605: ## Run rndc reload terom@589: function do_reload_zones { terom@582: # run terom@582: indent " rndc: " \ terom@582: $RNDC reload terom@589: terom@589: # set flag terom@589: RELOAD_ZONES=y terom@582: } terom@582: terom@575: ## Load update zonefiles into bind: terom@575: # terom@584: # reload_zones terom@575: # terom@575: # Invokes `rndc reload`, showing its output. terom@584: function reload_zones { terom@575: local msg="Reload zones" terom@575: terom@584: if [ $RELOAD_FORCE ]; then terom@582: log_force "$msg..." terom@582: terom@589: do_reload_zones terom@582: terom@584: elif [ $RELOAD_NOOP ]; then terom@582: log_noop "$msg: skipped" terom@575: terom@591: elif [ ! -e $RNDC ]; then terom@591: log_warn "reload_zones: rndc not installed, skipping" terom@591: terom@591: elif [ ! -e $RNDC_KEY ]; then terom@591: log_warn " $msg: rndc: key not found: $RNDC_KEY" terom@591: terom@575: elif [ ! -r $RNDC_KEY ]; then terom@575: log_error " $msg: rndc: permission denied: $RNDC_KEY" terom@575: terom@582: return 1 terom@582: terom@575: else terom@575: log_update "$msg..." terom@575: terom@575: # run terom@589: do_reload_zones terom@589: fi terom@589: } terom@589: terom@589: ## Reload DHCP by restarting it, if running: terom@589: # terom@589: # do_reload_dhcp terom@589: # terom@589: # Does NOT restart dhcp if it is not running (status). terom@589: function do_reload_dhcp { terom@589: if cmd_test $DHCPD_INIT status >/dev/null; then terom@589: cmd $DHCPD_INIT restart terom@589: else terom@589: log_warn "dhcpd not running; did not restart" terom@589: fi terom@589: } terom@589: terom@589: ## Reload dhcp hosts terom@589: # terom@589: # reload_dhcp terom@589: # terom@589: # noop's if we haven't reloaded zones terom@589: function reload_dhcp { terom@589: local msg="Reload DHCP hosts" terom@589: terom@589: if [ $RELOAD_FORCE ]; then terom@589: log_force "$msg..." terom@589: terom@589: do_reload_dhcp terom@589: terom@589: elif [ $RELOAD_NOOP ]; then terom@589: log_noop "$msg: skipped" terom@591: terom@591: elif [ ! -e $DHCPD ]; then terom@591: log_warn "reload_dhcp: dhcpd not installed, skipping: $conf" terom@591: terom@589: else terom@589: log_update "$msg..." terom@589: terom@589: # run terom@589: do_reload_dhcp terom@575: fi terom@575: } terom@584: terom@605: ### Commit terom@605: ## Commit changes to version control: terom@575: # terom@619: # update_commit .../etc "commit message" terom@575: # terom@605: # Invokes `hg commit`, first showing the diff. terom@618: function update_commit { terom@619: local repo="$1" terom@575: local commit_msg="$COMMIT_MSG" terom@575: terom@605: local msg="Commit changes" terom@575: terom@575: # operate? terom@575: if [ $COMMIT_FORCE ]; then terom@618: log_force "$msg: $commit_msg" terom@575: terom@619: [ $LOG_DIFF ] && indent " " hg_diff $repo terom@575: terom@619: hg_commit "$repo" "$commit_msg" terom@619: terom@619: elif ! hg_modified "$repo"; then terom@612: log_warn "$msg: no changes" terom@575: terom@575: elif [ $COMMIT_SKIP ]; then terom@575: log_noop "$msg: skipped" terom@580: terom@580: # still show diff, though terom@619: [ $LOG_DIFF ] && indent " " hg_diff "$repo" terom@575: else terom@618: log_update "$msg: $commit_msg" terom@575: terom@619: [ $LOG_DIFF ] && indent " " hg_diff $repo terom@619: terom@619: hg_commit "$repo" "$commit_msg" terom@575: fi terom@575: }