[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [OSSTEST PATCH 3/4] dhcp leases: Introduce new client/server leases query mechanism



From: osstest service user <osstest@xxxxxxxxxxxxxxxxxxxxxx>

osstest needs to know (from the DHCP server) what addresses its guests
have.  Until now, the only way to do this has been to read the DHCP
server's leases file - if necessary, fetching the leases file from the
server.

Of course the size of the leases file is proportional to the size of
the installation, as is the number of simultaneous test jobs.  So the
overall impact of this is O(n^2); currently, the leases file in
Massachusetts is about 300kby and is being fetched fairly frequently.

So, we provide an alternative arrangement.

The ISC DHCP server does not support a standard way of querying it
about leases (eg, SNMP).  It does support an ISC protocol called
"OMAPI".

We don't want to have each osstest test job talk to the DHCP server
via OMAPI because this would involve giving them a password to the
DHCP server.  So we need to provide, effectively, a proxy daemon.

The available OMAPI client libraries are synchronous; the best
available library is written in Python.  We could write the whole
daemon in Python but that would involve doing our own select and line
buffering/reassembly, reimplementing command parsing, etc. - which we
already have implementations of in tcl/daemonlib.tcl.

So we provide, instead:

 * A Python program `ms-leases-omapiproxy' which speaks OMAPI to the
   DHCP server, and a simple synchronous query protocol on its
   stdin/stdout.  OMAPI authentication is based on a shared secret; to
   avoid duplicating it any more than necessary, ms-leases-omapiproxy
   half-arsedly parses the relevant DHCP server config fragment.

 * A Tcl daemon `ms-leasesdaemon' which multiplexes the multiple
   clients, and issues queries to the Python program.  It speaks
   a protocol similar to the other Tcl daemons.

 * A client implementation in Osstest/DhcpWatch/leasesdaemon.pm which
   can be requested by per-host configuration, as the DHCP lease
   method.

Like with the `leases' access method, the hostname of the DHCP server
must be specified in the host property.  The Tcl daemon binds to *, so
does not need to know its hostname.  So the config has only the port,
and the on-DHCP-server settings.

Signed-off-by: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
---
 Osstest.pm                        |  4 ++
 Osstest/DhcpWatch/leasesdaemon.pm | 98 +++++++++++++++++++++++++++++++++++++++
 ms-leases-omapiproxy              | 43 +++++++++++++++++
 ms-leasesdaemon                   | 51 ++++++++++++++++++++
 4 files changed, 196 insertions(+)
 create mode 100644 Osstest/DhcpWatch/leasesdaemon.pm
 create mode 100755 ms-leases-omapiproxy
 create mode 100755 ms-leasesdaemon

diff --git a/Osstest.pm b/Osstest.pm
index a78728c..9fdefde 100644
--- a/Osstest.pm
+++ b/Osstest.pm
@@ -104,6 +104,10 @@ our %c = qw(
     HostnameSortSwapWords 0
 
     Timezone UTC
+
+    DhcpServerOmapiKeyFile /etc/dhcp/osstest-omapi-key
+    DhcpServerOmapiPort 7991
+    LeasesDaemonPort 4033
 );
 
 $c{$_}='' foreach qw(
diff --git a/Osstest/DhcpWatch/leasesdaemon.pm 
b/Osstest/DhcpWatch/leasesdaemon.pm
new file mode 100644
index 0000000..9148880
--- /dev/null
+++ b/Osstest/DhcpWatch/leasesdaemon.pm
@@ -0,0 +1,98 @@
+# This is part of "osstest", an automated testing framework for Xen.
+# Copyright (C) 2009-2013 Citrix Inc.
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+# 
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+package Osstest::DhcpWatch::leasesdaemon;
+
+use strict;
+use warnings;
+
+use POSIX;
+use IO::File;
+use IO::Socket;
+
+use Osstest;
+use Osstest::TestSupport;
+
+BEGIN {
+    use Exporter ();
+    our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
+    $VERSION     = 1.00;
+    @ISA         = qw(Exporter);
+    @EXPORT      = qw();
+    %EXPORT_TAGS = ( );
+
+    @EXPORT_OK   = qw();
+}
+
+sub new {
+    my ($class, $ho, $meth, $source) = @_;
+    my $mo;
+    if ($source =~ m/:(?=[^:]*)$/) {
+       $mo = {
+            Host => $`,
+            Port => $',
+        };
+    } else {
+       $mo = {
+            Host => $source,
+            Port => $c{LeasesDaemonPort},
+        };
+    }
+    return bless $mo, $class;
+}
+
+sub check_ip ($$) {
+    my ($mo, $gho) = @_;
+
+    my $may_retry = 1;
+    while ($may_retry) {
+        my $rv;
+        eval {
+            my $lserv = $mo->{Conn};
+            if (!$lserv) {
+                logm("leasesdaemon: $gho->{Name}:".
+                     " connecting to $mo->{Host}:$mo->{Port}");
+                $may_retry = 0;
+                $lserv = tcpconnect($mo->{Host}, $mo->{Port});
+                $lserv->autoflush(1);
+                $_ = <$lserv>;
+                defined && m/^OK ms-leasesdaemon\s/ or die "$_ ?";
+                $mo->{Conn} = $lserv;
+            }
+            print $lserv "ether-ip4 $gho->{Ether}\n";
+            $_ = <$lserv>;
+            if (m/^\d+\.\d+\.\d+\.\d+$/) {
+                $gho->{Ip} = $&;
+                report_once($gho, 'leasesdaemon::check_ip', 
+                            "guest $gho->{Name}: $gho->{Ether} $gho->{Ip}");
+                $rv = undef;
+            } elsif (m/^none$/) {
+                $rv = 'no lease';
+            } else {
+                die "got $_ !";
+            }
+        };
+        if (!length $@) {
+            return $rv;
+        }
+        $may_retry = 0;
+        delete $mo->{Conn};
+    }
+    return "error talking to ms-leasesdaemon: $@";
+}
+
+1;
diff --git a/ms-leases-omapiproxy b/ms-leases-omapiproxy
new file mode 100755
index 0000000..a302a85
--- /dev/null
+++ b/ms-leases-omapiproxy
@@ -0,0 +1,43 @@
+#!/usr/bin/python -u
+
+import sys
+import os
+import pypureomapi
+import re as regexp
+
+def getkey(filename):
+    global key_name
+    global secret_key
+
+    kn_re = regexp.compile(r'''\s*key\s+(\w+)\s*\{$''')
+    sk_re = regexp.compile(r'''\s*secret\s*(['"])(.*)\1\s*\;\s*$''')
+    f = open(filename)
+    for l in f:
+        m = kn_re.match(l)
+        if m: key_name = m.group(1)
+        m = sk_re.match(l)
+        if m: secret_key = m.group(2)
+
+    key_name
+    secret_key
+
+def connect(port):
+    global om
+    om = pypureomapi.Omapi('localhost', 7911, key_name, secret_key)
+
+def iterate():
+    while True:
+        l = sys.stdin.readline()
+        if not l: break
+
+        mac = l.rstrip()
+        try:
+            ip = om.lookup_ip(mac)
+        except pypureomapi.OmapiErrorNotFound:
+            ip = 'none'
+        print('%s %s' % (mac, ip))
+
+getkey(sys.argv[2])
+connect(int(sys.argv[1]))
+print('OK')
+iterate()
diff --git a/ms-leasesdaemon b/ms-leasesdaemon
new file mode 100755
index 0000000..e72596c
--- /dev/null
+++ b/ms-leasesdaemon
@@ -0,0 +1,51 @@
+#!/usr/bin/tclsh8.5
+# -*- Tcl -*- 
+# usage: ./ms-ownerdaemon  ... | logger
+
+# This is part of "osstest", an automated testing framework for Xen.
+# Copyright (C) 2009-2013 Citrix Inc.
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+# 
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+source ./tcl/daemonlib.tcl
+
+proc chan-destroy-stuff {chan} { }
+
+proc cmd/ether-ip4 {chan desc mac} {
+    global omclichan
+    if {![regexp {^(?:[0-9a-f]{2}:){5}[0-9a-f]{2}$} $mac mac]} {
+        chan-error $chan "bad mac address"
+        return
+    }
+    puts-chan $omclichan "$mac"
+    set l [must-gets-chan $omclichan "^$mac "]
+    puts-chan $chan [lindex $l 1]
+}
+
+proc banner {chan} {
+    return "OK ms-leasesdaemon"
+}
+
+main-daemon Leases {
+    global c omclichan chandesc
+
+    set cmd [list ./ms-leases-omapiproxy \
+                 $c(DhcpServerOmapiPort) $c(DhcpServerOmapiKeyFile) \
+                 2>@ stderr]
+    set omclichan [open |$cmd r+]
+    fconfigure $omclichan -buffering line -translation lf
+    set chandesc($omclichan) omcli
+    must-gets-chan $omclichan {^OK}
+}
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.