aboutsummaryrefslogtreecommitdiff
#!/bin/sh

BOOT_WAIT_DEFAULT=25
# set GO_PLAY_KIDS to no to have a longer sequence of tests
GO_PLAY_KIDS=no

YESCOUNT=0
NOCOUNT=0

function testcount()
{
    test $1 = $2 && echo SUCCESS || echo FAILED
    test $1 = $2 && YESCOUNT=$(($YESCOUNT + 1)) || NOCOUNT=$(($NOCOUNT + 1))
}

function dirtyssh()
{
    ssh -q \
        -o UserKnownHostsFile=/dev/null \
        -o StrictHostKeyChecking=no \
        -p $1 \
        root@localhost \
        "$2"
}

function herd_service_status()
{
    echo "herd status of $2 on ${VM[$1]}:"
    dirtyssh ${PORT[$1]} "herd status $2"
    echo
}

function herd_test_service_status()
{
    echo "Test if the $2 service is $3 on ${VM[$1]}."
    RESULT=$(herd_service_status $1 $2 | awk -- '/It is '$3'/ {print $3}')
    testcount ${RESULT} $3
    echo
}

function test_forward()
{
    echo "From ${VM[$1]}, take reverse port forward opened by
${VM[$2]} to connect to ${VM[$3]} through
sshd of ${VM[$4]}."
    EXITHOST=reset
    EXITHOST=$(dirtyssh \
                   ${PORT[$1]} \
                   "ssh -q \\
                        -o UserKnownHostsFile=/dev/null \\
                        -o StrictHostKeyChecking=no \\
                        -p $5 \\
                        root@$6 \\
                        hostname")
    echo "Hostname at forward exit: ${EXITHOST}, expected: ${VM[$3]}"
    testcount ${EXITHOST} ${VM[$3]}
}

echo "*** DEFINING VM INSTANCIATION ARRAYS"
echo

I=0
SSHD_WILD=$I

VM[$I]=sshd-wild
echo "* VM: ${VM[$I]}"
EXTRA_SERVICES[$I]=""
PORT[$I]=$((10022+$I))
EXTRAPORT_HOST[$I]=$((${PORT[$I]}+1000))
EXTRAPORT_VM[$I]=$((${PORT[$I]}+2000))
ULTIMAPORT_HOST[$I]=$((${PORT[$I]}+3000))
ULTIMAPORT_VM[$I]=$((${PORT[$I]}+4000))
echo

I=$(($I+1))
SSHD_REMOTE=$I

VM[$I]=sshd-remote
echo "* VM: ${VM[$I]}"
ALLOW_GATEWAY[$I]="yes"
EXTRA_SERVICES[$I]=""
PORT[$I]=$((10022+$I))
EXTRAPORT_HOST[$I]=$((${PORT[$I]}+1000))
EXTRAPORT_VM[$I]=$((${PORT[$I]}+2000))
ULTIMAPORT_HOST[$I]=$((${PORT[$I]}+3000))
ULTIMAPORT_VM[$I]=$((${PORT[$I]}+4000))
EXTRA_SERVICES[$I]=""
echo

I=$(($I+1))
SSHD_SOCKS=$I

VM[$I]=sshd-socks
echo "* VM: ${VM[$I]}"
ALLOW_GATEWAY[$I]="yes"
BOOT_WAIT[$I]=25
EXTRA_SERVICES[$I]=""
PORT[$I]=$((10022+$I))
EXTRAPORT_HOST[$I]=$((${PORT[$I]}+1000))
EXTRAPORT_VM[$I]=$((${PORT[$I]}+2000))
ULTIMAPORT_HOST[$I]=$((${PORT[$I]}+3000))
ULTIMAPORT_VM[$I]=$((${PORT[$I]}+4000))
echo

I=$(($I+1))
WHISPERS=$I

VM[$I]=whispers
echo "* VM: ${VM[$I]}"
EXTRA_SERVICES[$I]=""
PORT[$I]=$((10022+$I))
EXTRAPORT_HOST[$I]=$((${PORT[$I]}+1000))
EXTRAPORT_VM[$I]=$((${PORT[$I]}+2000))
ULTIMAPORT_HOST[$I]=$((${PORT[$I]}+3000))
ULTIMAPORT_VM[$I]=$((${PORT[$I]}+4000))
EXTRA_SERVICES[$I]="
           (service
            whispers-service-type
            (whispers-configuration
             (lieutenants
              (list
               (service
                whispers-service-type
                (whispers-configuration
                 (name 'bare)
                 (lieutenants
                  (list
                   (service
                    persistent-ssh-service-type
                    (ssh-connection-configuration
                     (require-networking? #f)
                     (socks-proxy-config
                      (socks-proxy-configuration
                       (use-proxy? #t)
                       (dynamic-forward
                        (ssh-connection-configuration
                         (require-networking? #f)
                         (sshd-host \"10.0.2.2\")
                         (sshd-port ${PORT[$SSHD_SOCKS]})
                          (forwards
                           (list (dynamic-forward-configuration)))))))
                     (sshd-host \"10.0.2.2\")
                     (sshd-port ${PORT[$SSHD_REMOTE]})
                     (forwards
                      (list (reverse-port-forward-configuration
                             (entry-port ${EXTRAPORT_VM[$SSHD_REMOTE]})
                             (forward-host \"10.0.2.2\")
                             (exit-port ${PORT[$SSHD_WILD]}))))))
                   (service
                    whispers-service-type
                    (whispers-configuration
                     (name 'burr)
                     (user \"whispers\")
                     (group \"whispers\")))
                   (service
                    whispers-service-type
                    (whispers-configuration
                     (name 'bear)
                     (user \"whispers\")
                     (group \"whispers\")
                     (lieutenants
                      (list
                       (service
                        whispers-service-type
                        (whispers-configuration
                         (name 'bearable)
                         (user \"whispers\")
                         (group \"whispers\")))
                       (service
                        whispers-service-type
                        (whispers-configuration
                         (name 'bore)
                         (user \"whispers\")
                         (group \"whispers\")
                         (extend-user? #t)
                         (extend-group? #t)))))))))))))))"
echo

for I in ${!PORT[@]}
do
    EXTRACONTENT[$I]=""
    if [ -v ALLOW_TUNDEV[$I] ]
    then
        EXTRACONTENT[$I]="
                     (extra-content \"
PermitTunnel=point-to-point\")"
    fi
    GATEWAY[$I]=""
    if [ -v ALLOW_GATEWAY[$I] ]
    then
        GATEWAY[$I]="
                     (gateway-ports? #t)"
    fi
    WAIT[$I]=$BOOT_WAIT_DEFAULT
    if [ -v BOOT_WAIT[$I] ]
    then
        WAIT[$I]=${BOOT_WAIT[$I]}
    fi
done
echo

echo "*** CONCATENATING SYSTEM CONFIGURATIONS"
echo
for I in ${!PORT[@]}
do
    echo "* VM: ${VM[$I]}"
    echo "(use-modules (guix records)
                   (gnu)
                   (whispers services whispers)
                   (whispers services ssh-tunneler))
(use-service-modules networking ssh desktop)
(use-package-modules ssh lsof)

(operating-system
  (host-name \"${VM[$I]}\")
  (timezone \"Asia/Shanghai\")
  (locale \"en_US.utf8\")

  (bootloader (bootloader-configuration
                (bootloader grub-bootloader)
                (targets '(\"/dev/sda\"))))

  (file-systems (cons (file-system
                        (device (file-system-label \"root\"))
                        (mount-point \"/\")
                        (type \"ext4\"))
                      %base-file-systems))

  (users %base-user-accounts)

  (packages (append (list lsof)
                    %base-packages))

  (services
    (append
     (list (service dhcp-client-service-type)
           (service openssh-service-type
                    (openssh-configuration
                     (permit-root-login #t)
                     (allow-empty-passwords? #t)
                     (openssh openssh-sans-x)
                     (port-number 22)${GATEWAY[$I]}${EXTRACONTENT[$I]}))${EXTRA_SERVICES[$I]})
     %base-services)))" > /tmp/${VM[$I]}.scm
    echo
done
echo

echo "*** INSTANCIATING VMs"
echo
for I in ${!PORT[@]}
do
    echo "* VM: ${VM[$I]}"
    VMRUN[$I]=$(guix system vm /tmp/${VM[$I]}.scm)
    echo
done
echo

echo "*** SILENTLY BOOTING VMs..."
echo
for I in ${!PORT[@]}
do
    NICSTANCE=-"nic user,model=virtio-net-pci,hostfwd=tcp::${PORT[$I]}-:22,hostfwd=tcp::${EXTRAPORT_HOST[$I]}-:${EXTRAPORT_VM[$I]},hostfwd=tcp::${ULTIMAPORT_HOST[$I]}-:${ULTIMAPORT_VM[$I]}"
        echo "* VM: ${VM[$I]}"
        ${VMRUN[$I]} \
            $NICSTANCE \
            -display none &
        sleep ${WAIT[$I]}
    echo
done
echo

echo "*** SETTING PASSWORDLESS LOGIN FOR WHISPERS USERS..."
echo
echo "* VM: ${VM[$WHISPERS]}"
dirtyssh ${PORT[$CLIENT01]} 'passwd -d whispers'
echo
echo

echo "*** REPORTING SHEPHERD STATUS"
echo
for I in ${!PORT[@]}
do
    echo "* VM: ${VM[$I]}"
    dirtyssh ${PORT[$I]} 'herd status'
    echo
done
echo

echo "*** REPORTING NETWORK INTERFACES"
echo
for I in ${!PORT[@]}
do
    echo "* VM: ${VM[$I]}"
    dirtyssh ${PORT[$I]} 'ip addr show'
    echo
done
echo

echo "*** REPORTING ROUTES"
echo
for I in ${!PORT[@]}
do
    echo "* VM: ${VM[$I]}"
    dirtyssh ${PORT[$I]} 'ip route'
    echo
done
echo

function full_tests()
{
    herd_service_status $WHISPERS whispers
    herd_test_service_status $WHISPERS whispers running
}

if [[ foo$GO_PLAY_KIDS == foono ]]
then
    full_tests
    echo
fi

echo "*** TESTS SUMMARRY"
echo
echo Successes: $YESCOUNT
echo Failures: $NOCOUNT
echo
echo

echo "You can ssh into the VMs from another terminal of this host"
for I in ${!PORT[@]}
do
    echo "* VM: ${VM[$I]}, port: ${PORT[$I]}"
done
echo
read -n 1 -r -s -p "When done playing, press any key to halt the VMs..."
echo
echo

echo "*** HALTING VMs"
echo
for I in ${!PORT[@]}
do
    echo "* VM: ${VM[$I]}"
    dirtyssh ${PORT[$I]} halt
    echo
done