#!/usr/bin/perl -w
# written 2015 by Bernhard M. Wiedemann
# usage: novncviewer $INSTANCEID
#
# this is is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2

use strict;
use FindBin;

my $vncviewer = $ENV{VNCVIEWER} || "gvncviewer";
if(!$ENV{OS_AUTH_URL}) {
        die "you need to source openrc.sh to have OS_AUTH_URL OS_USERNAME OS_PASSWORD OS_TENANT_NAME variables setup\n"
}

sub find_free_port()
{
    #check for used ports in netstat -tln
    open(my $fd, "<", "/proc/net/tcp6") or die $!;
    my %usedport;
    while(<$fd>) {
        m/^\s*\d+: [0-9A-F]+:([0-9A-F]+) [0-9A-F]+:[0-9A-F]+ 0A / or next;
	my $port = hex($1);
	$usedport{$port}=1;
    }
    for my $p (5900..5999) {
        return $p unless $usedport{$p};
    }
}

my $id = $ENV{INSTANCEID}||shift;
if(!$id) {
    die "usage: $0 INSTANCEID\n"
}

$_ = `nova get-vnc-console $id novnc`;
die "cannot get novnc URL from nova: $_" unless m{https?://[^ ]*};
my $url = $&;

my $port = find_free_port();
my $pid = fork();
die unless defined $pid;
if($pid) {
    $port -= 5900;
    sleep 1;
    system($vncviewer, "localhost:$port");
    kill 'TERM', $pid;
} else {
    exec("$FindBin::Bin/wsconnectionproxy.pl", "--to", $url, "--port", $port);
}

