lib/update.operations
author Tero Marttila <terom@paivola.fi>
Tue, 20 Mar 2012 14:30:16 +0200
changeset 57 d83a5e9be193
parent 52 b68b8615c512
child 59 b0c761c4d5f8
permissions -rw-r--r--
update: use hg diff --stat for .serials
## vim: set ft=sh :
#
# Operations on zonefiles/hosts/whatever

## Hosts
## Update hosts from verbatim from input zone data:
#
#   copy_hosts      $ZONES/$zone    $DATA/$base
#
# Writes updated zone to $zone, deps on $base.
function copy_hosts {
    local zone=$1
    local base=$2

    if check_update $zone $base; then
        log_update "Copying hosts $zone <- $base..."

        do_update $zone \
            cat $ROOT/$base
    else
        log_skip "Copying hosts $zone <- $base: not changed"
    fi
}

## Generate hosts from input zone data using $BIN/process-zone:
#
#   update_hosts    $ZONES/$zone    $DATA/$base
#
# Writes process-zone'd data to $zone, deps on $base.
function update_hosts {
    local zone=$1; shift
    local base=$1; shift

    if check_update $zone $base; then
        log_update "Generating hosts $zone <- $base..."

        do_update $zone \
            $BIN/process-zone $PROCESS_ARGS $ROOT/$base "$@"
    else
        log_skip "Generating hosts $zone <- $base: not changed"
    fi
}

## Generate new serial for zone using $BIN/update-serial, if the zone data has changed:
#
#   update_serial   $zone   $deps...
#
# Supports SERIAL_FORCE/NOOP.
# Updates $SERIALS/$zone.serial.
function update_serial {
    local zone=$1; shift
    
    local serial=$SERIALS/$zone.serial

    # test
    if [ $SERIAL_FORCE ]; then
        log_force "Updating $serial: forced"

        do_update_serial $serial

    elif ! check_update $serial "$@"; then
        log_skip "Updating $serial: not changed"

    elif [ $SERIAL_NOOP ]; then
        log_noop "Updating $serial: skipped"

    else
        log_update "Updating $serial..."

        do_update_serial $serial
    fi
}

## Link serial for zone from given base-zone:
#
#   link_serial $zone $base
function link_serial {
    local zone=$1
    local base=$2

    local lnk=$SERIALS/$zone.serial
    local tgt=$SERIALS/$base.serial

    if check_link $lnk $tgt; then
        log_update "Linking $lnk -> $tgt..."

        do_link $lnk $tgt

    else
        log_skip "Linking $lnk -> $tgt: not changed"
    fi
}

## Update zone file verbatim from source:
#
#   copy_zone   $view   $zone   [$base]
#
# Copies changed $DATA/$base zone data to $ZONES/$view/$zone.
function copy_zone {
    local view=$1
    local zone=$2
    local base=${3:-$zone}

    local out=$ZONES/$view/$zone
    local src=$DATA/$base

    if check_update $out $src; then
        log_update "Copying $out <- $src..."

        do_update $out \
            cat $ROOT/$src
    else
        log_skip "Copying $out <- $src: not changed"
    fi
}

## Expand zone file from source using $BIN/expand-zone:
#
#   update_zone $view   $zone   [$base]
#
# Processed $DATA/$base zone data through $BIN/expand-zone, writing output to $ZONES/$view/$zone.
function update_zone {
    local view=$1
    local zone=$2
    local base=${3:-$zone}

    local out=$ZONES/$view/$zone
    local src=$DATA/$base.zone
    local lnk=$ZONES/$base

    local serial=$SERIALS/$base.serial

    if check_update $out $src $serial; then
        log_update "Generating $out <- $src..." 

        do_update $out \
            $BIN/expand-zone $ROOT/$src \
                --serial $ROOT/$serial              \
                --expand zones=$(abspath $ZONES)    \
                --expand view=$view
    else
        log_skip "Generating $out <- $src: not changed" 
    fi
}

## Link zone file to ues given shared zone.
#
#   link_zone   $view   $zone   [$base]
#
# Looks for shared zone at:
#   $ZONES/$view/$base
#   $ZONES/common/$base
function link_zone {
    local view=$1
    local zone=$2
    local base=${3:-$zone}

    local out=$ZONES/$view/$zone
    local tgt=$(choose_link $out $ZONES/$view/$base $ZONES/common/$base)

    if check_link $out $tgt; then
        log_update "Linking $out -> $tgt..."

        do_link $out $tgt

    else
        log_skip "Linking $out -> $tgt: not changed"
    fi
}

## Test hosts zone for validity:
#
#   check_hosts     $DATA/$hosts    --check-exempt ...
#
# Fails if the check fails.
function check_hosts {
    local hosts=$1; shift 1

    local cmd=($BIN/process-zone $PROCESS_ARGS $ROOT/$hosts --check-hosts "$@")

    if "${cmd[@]}" -q; then
        log_skip "Check $hosts: OK"
    else
        log_error "  Check $hosts: Failed"

        indent "    " "${cmd[@]}"

        exit 1
    fi
}

## Test zone file for validity using named-checkzone:
#
#   check_zone      $view       $zone       $origin
#
# Uses the zonefile at $ZONES/$view/$zone, loading it with given initial $ORIGIN.
# Fails if the check fails.
function check_zone {
    local view=$1
    local zone=$2
    local origin=$3

    local src=$ZONES/$view/$zone

    local cmd=($NAMED_CHECKZONE $origin $ROOT/$src)

    # test
    # XXX: checkzone is very specific about the order of arguments, -q must be first
    if $NAMED_CHECKZONE -q $origin $ROOT/$src; then
        log_skip "Check $src ($origin): OK"
    else
        log_error "  Check $src ($origin): Failed:"

        indent "    " "${cmd[@]}"
        
        exit 1
    fi
}

## Load update zonefiles into bind:
#
#   deploy_zones    
#
# Invokes `rndc reload`, showing its output.
function deploy_zones {
    local msg="Reload zones"

    if [ $DEPLOY_SKIP ]; then
        log_skip    "$msg: skipped"
    
    elif [ ! -r $RNDC_KEY ]; then
        log_error   "  $msg: rndc: permission denied: $RNDC_KEY"

    else
        log_update  "$msg..."

        # run
        indent "        rndc: " \
            $RNDC reload
    fi
}
## Commit changes in $DATA to version control:
#
#   commit_data
#
# Invokes `hg commit` in the $REPO, first showing the diff.
function commit_data {
    local repo=$REPO
    local commit_msg="$COMMIT_MSG"

    local msg="Commit changes in $repo"

    # operate?
    if [ $COMMIT_FORCE ]; then
        log_force   "$msg..."

        do_commit "$commit_msg"

    elif ! hg_modified; then
        log_skip    "$msg: no changes"

    elif [ $COMMIT_SKIP ]; then
        log_noop    "$msg: skipped"
        
        # still show diff, though
        [ $LOG_DIFF ] && indent "    " hg_diff
    else
        log_update  "$msg..."

        do_commit "$commit_msg"
    fi
}