#!/bin/bash -ef

po_domain="alterator-mkve"

alterator_api_version=1
. alterator-sh-functions

# action write {{{
stopped()
{
    local state

    if ! state="$(mkve info "$in_machine" --state | cut -d: -f1)"; then
        write_error "`_ "mkve failed"`"
        return 1
    fi

    [ "$state" = "5" ]
}

set_password()
{
    if ! stopped "$in_machine"; then
        write_error "`_ "you must stop machine at first"`"
        return
    fi

    local mnt
    if ! mnt="$(mktemp -d 2>&1)"; then
        write_error "`_ "mktemp failed:"` $mnt"
        return
    fi

    local err img="/var/lib/mkve/machines/$in_machine/root.img"
    if ! err=$(mount -o loop "$img" "$mnt" 2>&1); then
        write_error "`_ "can't mount"` $img to $mnt: $err"
        return
    fi

    if ! err=$(printf "root:%s\n" "$in_password" | chroot "$mnt" chpasswd 2>&1); then
        write_error "`_ "chpasswd failed: "` $err"
        umount "$mnt"
        rmdir "$mnt"
        return
    fi

    if ! err=$(umount "$mnt" 2>&1); then
        write_error "`_ "can't umount"` $mnt: $err"
        rmdir "$mnt"
        return
    fi

    if ! err=$(rmdir "$mnt" 2>&1); then
        write_error "`_ "can't remove dir"` $mnt: $err"
        return
    fi

    write_error "`_ "password successfully set"`"
}

action_write()
{
    case ${in__objects} in
        password) set_password ;;
        reset) write_error "`_ "Reset to defaults values"`" ;;
    esac
}
# }}}
# action read {{{

read_ip()
{
    # XXX: I think, that there is only one network interface, but it can be false in common case
    local descr="/etc/libvirt/qemu/$in_machine.xml"
    local mac=$(sed --silent -e "s/\s\+<mac address='\(.*\)'.*\$/\1/p" "$descr")
    mac=$(printf '%s' "$mac" | sed -e 's/0\(.\)\(:\|$\)/\1\2/g')
    local bridge=$(sed --silent -e "s/\s\+<source bridge='\(.*\)'.*\$/\1/p" "$descr")
    [ -n "$mac" -a -n "$bridge" ] || return

    local arpwatch_db="/var/lib/arpwatch/arp.dat.$bridge"
    [ -f "$arpwatch_db" ] || arpwatch_db="/var/lib/arpwatch/arp.dat"

    local arppid="$(pgrep arpwatch)"
    [ -z "$arppid" ] || kill -s SIGALRM $arppid
    local ip="$(grep "$mac" "$arpwatch_db" | tail -1 | cut -f2)"
    printf '%s' "$ip"
}

action_read()
{
    case ${in__objects} in
        ip)
            local ip="$(read_ip)"
            [ -n "$ip" ] || ip="`_ "not found"`"
            write_string_param 'ip' "$ip"
            ;;
    esac
}

# }}}

on_message()
{
    set | egrep '^in_'; echo

    case "$in_action" in
        list)        write_nop          ;;
        write)       action_write       ;;
        read)        action_read        ;;
        type)        write_nop          ;;
        *)           write_bool 'false' ;;
    esac
}

message_loop

# vim:fdm=marker et sw=4 ts=4
