Mega update - includes support for new AP8959 and very old AP9210 pdus, pduclient now includes a delay ability, and the driver plugin mechanism has been totally revamped. Warning this still needs work.
Change-Id: I49b1c24c963ea78ffd5e1667a54309a88b694c01
diff --git a/etc/lavapdu/lavapdu.conf b/etc/lavapdu/lavapdu.conf
index acded88..ae8cbc5 100644
--- a/etc/lavapdu/lavapdu.conf
+++ b/etc/lavapdu/lavapdu.conf
@@ -5,21 +5,28 @@
"dbhost": "127.0.0.1",
"dbuser": "pdudaemon",
"dbpass": "pdudaemon",
- "dbname": "lavapdu"
+ "dbname": "lavapdu",
+ "retries": 3,
+ "logging_level": "DEBUG"
},
"pdus": {
- "pdu14": {
- "driver": "apc9218"
+ "192.168.10.2": {
+ "driver": "apc9210"
},
- "pdu15": {
- "driver": "apc9218"
+ "192.168.10.3": {
+ "driver": "apc7952",
+ "telnetport": 5023
},
- "localhost": {
- "driver": "apc9218"
+ "192.168.10.4": {
+ "driver": "apc7952"
},
- "pdu04": {
- "driver": "blah",
- "snmp": "this"
+ "192.168.10.5": {
+ "driver": "apc8959",
+ "this": "that",
+ "something": "else"
+ },
+ "192.168.25.52": {
+ "driver": "apc7952"
}
}
}
\ No newline at end of file
diff --git a/lavapdu-listen b/lavapdu-listen
index c6a22f0..ec5b00b 100755
--- a/lavapdu-listen
+++ b/lavapdu-listen
@@ -48,18 +48,12 @@
"""
Read settings from config file, to listen to all hosts, hostname should be 0.0.0.0
"""
- settings = {}
+ #settings = {}
print("Reading settings from %s" % conffile)
with open(filename) as stream:
jobdata = stream.read()
json_data = json.loads(jobdata)
- settings['port'] = json_data["daemon"]['port']
- settings['hostname'] = json_data["daemon"]['hostname']
- settings['dbuser'] = json_data["daemon"]['dbuser']
- settings['dbpass'] = json_data["daemon"]['dbpass']
- settings['dbname'] = json_data["daemon"]['dbname']
- settings['dbhost'] = json_data["daemon"]['dbhost']
- return settings
+ return json_data
if __name__ == '__main__':
# instance settings come from django - the coordinator doesn't use django and is
@@ -83,13 +77,14 @@
print "No such directory for specified logfile '%s'" % logfile
open(logfile, 'w').close()
level = logging.DEBUG
- if options.loglevel == "DEBUG":
+ settings = settings["daemon"]
+ if settings["logging_level"] == "DEBUG":
level = logging.DEBUG
- if options.loglevel == "WARNING":
+ if settings["logging_level"] == "WARNING":
level = logging.WARNING
- if options.loglevel == "ERROR":
+ if settings["logging_level"] == "ERROR":
level = logging.ERROR
- if options.loglevel == "INFO":
+ if settings["logging_level"] == "INFO":
level = logging.INFO
client_logger, watched_file_handler = getDaemonLogger(logfile, loglevel=level,
log_format='%(asctime)s:%(levelname)s:%(name)s:%(message)s')
@@ -107,10 +102,7 @@
files_preserve=[watched_file_handler.stream],
stderr=watched_file_handler.stream,
stdout=watched_file_handler.stream)
- starter = {"logging_level": level,
- "settings": settings}
with context:
logging.info("Running LAVA PDU Listener %s %s %d."
% (logfile, settings['hostname'], settings['port']))
- #logging.getLogger().setLevel(options.loglevel)
- ListenerServer(starter).start()
\ No newline at end of file
+ ListenerServer(settings).start()
\ No newline at end of file
diff --git a/lavapdu-runner b/lavapdu-runner
index dadf9f3..b1730ff 100755
--- a/lavapdu-runner
+++ b/lavapdu-runner
@@ -54,15 +54,7 @@
with open(filename) as stream:
jobdata = stream.read()
json_data = json.loads(jobdata)
- settings['port'] = json_data["daemon"]['port']
- settings['hostname'] = json_data["daemon"]['hostname']
- settings['dbuser'] = json_data["daemon"]['dbuser']
- settings['dbpass'] = json_data["daemon"]['dbpass']
- settings['dbname'] = json_data["daemon"]['dbname']
- settings['dbhost'] = json_data["daemon"]['dbhost']
- pdus = json_data["pdus"]
- return (settings, pdus)
-
+ return json_data
if __name__ == '__main__':
# instance settings come from django - the coordinator doesn't use django and is
@@ -70,7 +62,7 @@
pidfile = "/var/run/lavapdu-runner.pid"
logfile = "/var/log/lavapdu-runner.log"
conffile = "/etc/lavapdu/lavapdu.conf"
- settings, pdus = readSettings(conffile)
+ settings = readSettings(conffile)
usage = "Usage: %prog [--logfile] --[loglevel]"
description = "LAVA PDU request listener server, host and port are handled in %s" % conffile
parser = optparse.OptionParser(usage=usage, description=description)
@@ -86,13 +78,14 @@
print "No such directory for specified logfile '%s'" % logfile
open(logfile, 'w').close()
level = logging.DEBUG
- if options.loglevel == "DEBUG":
+ daemon_settings = settings["daemon"]
+ if daemon_settings["logging_level"] == "DEBUG":
level = logging.DEBUG
- if options.loglevel == "WARNING":
+ if daemon_settings["logging_level"] == "WARNING":
level = logging.WARNING
- if options.loglevel == "ERROR":
+ if daemon_settings["logging_level"] == "ERROR":
level = logging.ERROR
- if options.loglevel == "INFO":
+ if daemon_settings["logging_level"] == "INFO":
level = logging.INFO
client_logger, watched_file_handler = getDaemonLogger(logfile, loglevel=level,
log_format='%(asctime)s:%(levelname)s:%(name)s:%(message)s')
@@ -110,11 +103,8 @@
files_preserve=[watched_file_handler.stream],
stderr=watched_file_handler.stream,
stdout=watched_file_handler.stream)
- starter = {"logging_level": level,
- "settings": settings,
- "pdus": pdus}
with context:
logging.info("Running LAVA PDU Runner %s dbhost: %s"
- % (logfile, settings["dbhost"]))
- p = PDURunner(starter)
+ % (logfile, settings["daemon"]["dbhost"]))
+ p = PDURunner(settings)
p.run_me()
diff --git a/lavapdu/__init__.py b/lavapdu/__init__.py
index 6c6aaf6..fe1f8f3 100644
--- a/lavapdu/__init__.py
+++ b/lavapdu/__init__.py
@@ -17,6 +17,3 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
-
-import pdurunner
-import socketserver
\ No newline at end of file
diff --git a/lavapdu/dbhandler.py b/lavapdu/dbhandler.py
index bc89847..09c7058 100644
--- a/lavapdu/dbhandler.py
+++ b/lavapdu/dbhandler.py
@@ -51,7 +51,7 @@
def get_next_job(self):
now = int(time.time())
- row = self.do_sql_with_fetch("select id,hostname,port,request from pdu_queue where exectime < %i order by id asc limit 1" % now)
+ row = self.do_sql_with_fetch("select id,hostname,port,request from pdu_queue where (exectime < %i or exectime is null) order by id asc limit 1" % now)
return row
def close(self):
diff --git a/lavapdu/drivers/__init__.py b/lavapdu/drivers/__init__.py
index 2524629..fe05efd 100644
--- a/lavapdu/drivers/__init__.py
+++ b/lavapdu/drivers/__init__.py
@@ -16,8 +16,4 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-# MA 02110-1301, USA.
-
-#from apc9218 import apc9218
-#from apc7952 import apc7952
-#from apc8959 import apc8959
+# MA 02110-1301, USA.
\ No newline at end of file
diff --git a/lavapdu/drivers/apc7952.py b/lavapdu/drivers/apc7952.py
index 2e4abfb..4b9b234 100644
--- a/lavapdu/drivers/apc7952.py
+++ b/lavapdu/drivers/apc7952.py
@@ -19,11 +19,17 @@
# MA 02110-1301, USA.
import logging
-from apcbase import APCBase
+from lavapdu.drivers.apcbase import APCBase
class APC7952(APCBase):
+ @classmethod
+ def accepts(cls, drivername):
+ if drivername == "apc7952":
+ return True
+ return False
+
def _pdu_logout(self):
self._back_to_main()
logging.debug("Logging out")
diff --git a/lavapdu/drivers/apc8959.py b/lavapdu/drivers/apc8959.py
index f5f64c7..e37559d 100644
--- a/lavapdu/drivers/apc8959.py
+++ b/lavapdu/drivers/apc8959.py
@@ -19,12 +19,21 @@
# MA 02110-1301, USA.
import logging
-from apcbase import APCBase
+from lavapdu.drivers.apcbase import APCBase
class APC8959(APCBase):
pdu_commands = {"off": "olOff", "on": "olOn"}
+# def __init__(self, hostname):
+# super(APC8959, self).__init__(hostname)
+
+ @classmethod
+ def accepts(cls, drivername):
+ if drivername == "apc8959":
+ return True
+ return False
+
def _pdu_logout(self):
logging.debug("logging out")
self.connection.send("\r")
@@ -41,4 +50,5 @@
self._pdu_get_to_prompt()
self.connection.sendline(self.pdu_commands[command] + (" %i" % port_number))
self.connection.expect("E000: Success")
+ self._pdu_get_to_prompt()
logging.debug("done")
\ No newline at end of file
diff --git a/lavapdu/drivers/apc9210.py b/lavapdu/drivers/apc9210.py
new file mode 100644
index 0000000..b86339a
--- /dev/null
+++ b/lavapdu/drivers/apc9210.py
@@ -0,0 +1,59 @@
+#! /usr/bin/python
+
+# Copyright 2013 Linaro Limited
+# Author Matt Hart <matthew.hart@linaro.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+import logging
+from lavapdu.drivers.apc7952 import APC7952
+
+
+class APC9210(APC7952):
+
+ @classmethod
+ def accepts(cls, drivername):
+ if drivername == "apc9210":
+ return True
+ return False
+
+ def _port_interaction(self, command, port_number):
+ print("Attempting command: %s port: %i" % (command, port_number))
+ ### make sure in main menu here
+ self._back_to_main()
+ self.connection.send("\r")
+ self.connection.expect("1- Outlet Manager")
+ self.connection.expect("> ")
+ logging.debug("Entering Outlet Manager")
+ self.connection.send("1\r")
+ self.connection.expect("------- Outlet Manager")
+ logging.debug("Got to Device Manager")
+ self._enter_outlet(port_number, False)
+ self.connection.expect(["1- Control of Outlet", "1- Outlet Control/Configuration"])
+ self.connection.expect("> ")
+ self.connection.send("1\r")
+ self.connection.expect("Turn Outlet On")
+ self.connection.expect("> ")
+ if command == "on":
+ self.connection.send("1\r")
+ self.connection.expect("Turn Outlet On")
+ self._do_it()
+ elif command == "off":
+ self.connection.send("2\r")
+ self.connection.expect("Turn Outlet Off")
+ self._do_it()
+ else:
+ logging.debug("Unknown command!")
\ No newline at end of file
diff --git a/lavapdu/drivers/apc9218.py b/lavapdu/drivers/apc9218.py
index 1dae89a..8535c85 100644
--- a/lavapdu/drivers/apc9218.py
+++ b/lavapdu/drivers/apc9218.py
@@ -19,10 +19,17 @@
# MA 02110-1301, USA.
import logging
-from apc7952 import APC7952
+from lavapdu.drivers.apc7952 import APC7952
+
class APC9218(APC7952):
+ @classmethod
+ def accepts(cls, drivername):
+ if drivername == "apc9218":
+ return True
+ return False
+
def _port_interaction(self, command, port_number):
print("Attempting command: %s port: %i" % (command, port_number))
### make sure in main menu here
diff --git a/lavapdu/drivers/apcbase.py b/lavapdu/drivers/apcbase.py
index d3dca6f..aaa19c5 100644
--- a/lavapdu/drivers/apcbase.py
+++ b/lavapdu/drivers/apcbase.py
@@ -20,37 +20,47 @@
import logging
import pexpect
-from driver import PDUDriver
+from lavapdu.drivers.driver import PDUDriver
import sys
+
class APCBase(PDUDriver):
connection = None
- def __init__(self, pdu_hostname, pdu_telnetport=23):
- self.exec_string = "/usr/bin/telnet %s %d" % (pdu_hostname, pdu_telnetport)
+ def __init__(self, hostname, settings):
+ self.hostname = hostname
+ logging.debug(settings)
+ self.settings = settings
+ telnetport = 23
+ if "telnetport" in settings:
+ telnetport = settings["telnetport"]
+ self.exec_string = "/usr/bin/telnet %s %d" % (hostname, telnetport)
self.get_connection()
- super(APCBase, self).__init__(pdu_hostname)
+ super(APCBase, self).__init__()
- #def port_on(self, port_number):
- # self.port_interaction("on", port_number)
-
- #def port_off(self, port_number):
- # self.port_interaction("off", port_number)
+ @classmethod
+ def accepts(cls, drivername):
+ return False
def port_interaction(self, command, port_number):
logging.debug("Running port_interaction from APCBase")
self._port_interaction(command, port_number)
- self._cleanup()
+ #self._cleanup()
def get_connection(self):
logging.debug("Connecting to APC PDU with: %s" % self.exec_string)
- self.connection = pexpect.spawn(self.exec_string, logfile=sys.stdout)
+ if logging.getLogger().getEffectiveLevel() == logging.DEBUG:
+ self.connection = pexpect.spawn(self.exec_string, logfile=sys.stdout)
+ else:
+ self.connection = pexpect.spawn(self.exec_string)
self._pdu_login("apc","apc")
def _cleanup(self):
self._pdu_logout()
- logging.debug("Closing connection: %s" % self.connection)
- self.connection.close(True)
+
+ def _bombout(self):
+ logging.debug("Bombing out of driver: %s" % self.connection)
+ self.connection.close(force=True)
del(self)
def _pdu_login(self, username, password):
diff --git a/lavapdu/drivers/driver.py b/lavapdu/drivers/driver.py
index 7325473..f93974e 100644
--- a/lavapdu/drivers/driver.py
+++ b/lavapdu/drivers/driver.py
@@ -18,30 +18,48 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
-import time
import logging
+
class PDUDriver(object):
connection = None
hostname = ""
- def __init__(self, pdu_hostname):
- self.hostname = pdu_hostname
- #super(PDUDriver,self).__init__(pdu_hostname)
+ def __init__(self):
+ super(PDUDriver, self).__init__()
+
+ @classmethod
+ def select(cls, drivername):
+ logging.debug("adding PDUDriver subclasses: %s" % cls.__subclasses__())
+ candidates = cls.__subclasses__() # pylint: disable=no-member
+ for subc in cls.__subclasses__():
+ logging.debug("adding %s subclasses: %s" % (subc,subc.__subclasses__()))
+ candidates = candidates + (subc.__subclasses__())
+ for subsubc in subc.__subclasses__():
+ logging.debug("adding %s subclasses: %s" % (subsubc,subsubc.__subclasses__()))
+ candidates = candidates + (subsubc.__subclasses__())
+ logging.debug(candidates)
+ willing = [c for c in candidates if c.accepts(drivername)]
+ if len(willing) == 0:
+ raise NotImplementedError(
+ "No driver accepted the request "
+ "'%s' with the specified job parameters. %s" % (drivername, cls)
+ )
+ logging.debug("%s accepted the request" % willing[0])
+ return willing[0]
def handle(self, request, port_number, delay=0):
- logging.debug("Driving PDU: %s PORT: %s REQUEST: %s (delay %s)" %(self.hostname,port_number,request,delay))
- if request == "reboot":
- self.port_off(port_number)
- time.sleep(delay)
- self.port_on(port_number)
- elif request == "on":
+ logging.debug("Driving PDU hostname: %s PORT: %s REQUEST: %s (delay %s)" %(self.hostname,port_number,request,delay))
+ if request == "on":
self.port_on(port_number)
elif request == "off":
self.port_off(port_number)
else:
logging.debug("Unknown request to handle - oops")
- raise
+ raise NotImplementedError(
+ "Driver doesn't know how to %s " % (request)
+ )
+ self._cleanup()
#def _port_interaction(self, command, port_number):
# super(PDUDriver, self).port_interaction(command,port_number)
diff --git a/lavapdu/drivers/strategies.py b/lavapdu/drivers/strategies.py
new file mode 100644
index 0000000..962eaf3
--- /dev/null
+++ b/lavapdu/drivers/strategies.py
@@ -0,0 +1,24 @@
+#! /usr/bin/python
+
+# Copyright 2013 Linaro Limited
+# Author Matt Hart <matthew.hart@linaro.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+from lavapdu.drivers.apc7952 import APC7952
+from lavapdu.drivers.apc9218 import APC9218
+from lavapdu.drivers.apc8959 import APC8959
+from lavapdu.drivers.apc9210 import APC9210
\ No newline at end of file
diff --git a/lavapdu/engine.py b/lavapdu/engine.py
deleted file mode 100644
index 47c04f7..0000000
--- a/lavapdu/engine.py
+++ /dev/null
@@ -1,50 +0,0 @@
-#! /usr/bin/python
-
-# Copyright 2013 Linaro Limited
-# Author Matt Hart <matthew.hart@linaro.org>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 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 General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-# MA 02110-1301, USA.
-
-import pexpect
-import os
-import logging
-import pkgutil
-import sys
-
-
-class PDUEngine():
- connection = None
- prompt = 0
- driver = None
- firmware_dict = {}
-
- def __init__(self, pdu_hostname):
- pass
-
-if __name__ == "__main__":
- logging.basicConfig(level=logging.DEBUG)
- logging.getLogger().setLevel(logging.DEBUG)
- pe = PDUEngine("pdu01")
- pe.driver.port_off(1)
- pe.driver.port_on(1)
- pe.close()
- pe = PDUEngine("pdu03")
- pe.driver.port_off(3)
- pe.driver.port_on(3)
- pe.close()
-
- #pe = PDUEngine("pdu16")
- #pe.close()
\ No newline at end of file
diff --git a/lavapdu/pdurunner.py b/lavapdu/pdurunner.py
index d31b8fd..de53eef 100644
--- a/lavapdu/pdurunner.py
+++ b/lavapdu/pdurunner.py
@@ -20,17 +20,20 @@
import logging
import time
-from dbhandler import DBHandler
+import json
import traceback
+from lavapdu.dbhandler import DBHandler
+from lavapdu.drivers.driver import PDUDriver
+import lavapdu.drivers.strategies
-class PDURunner():
+class PDURunner(object):
def __init__(self, config):
- logging.basicConfig(level=config["logging_level"])
- logging.getLogger().setLevel(config["logging_level"])
- logging.getLogger().name = "PDURunner"
- self.config = config
self.pdus = config["pdus"]
+ self.settings = config["daemon"]
+ logging.basicConfig(level=self.settings["logging_level"])
+ logging.getLogger().setLevel(self.settings["logging_level"])
+ logging.getLogger().name = "PDURunner"
def get_one(self, db):
job = db.get_next_job()
@@ -44,25 +47,31 @@
logging.debug("Found nothing to do in database")
def driver_from_hostname(self, hostname):
- logging.debug("Trying to find a driver for %s" % hostname)
+ logging.debug("Trying to find a driver for hostname %s" % hostname)
logging.debug(self.pdus)
- driver = self.pdus[hostname]["driver"]
- logging.debug("Driver: %s" % driver)
- module = __import__("drivers.%s" % driver.lower(), fromlist=[driver])
- class_ = getattr(module, driver)
- return class_(hostname)
+ if hostname in self.pdus:
+ drivername = (self.pdus[hostname]["driver"])
+ else:
+ raise NotImplementedError("No configuration available for hostname %s\n"
+ "Is there a section in the lavapdu.conf?" % hostname)
+ logging.debug("Config file wants driver: %s" % drivername)
+ driver = PDUDriver.select(drivername)(hostname, self.pdus[hostname])
+ return driver
def do_job(self, hostname, port, request, delay=0):
- retries = 10
+ retries = self.settings["retries"]
+ driver = False
while retries > 0:
try:
driver = self.driver_from_hostname(hostname)
return driver.handle(request, port, delay)
except Exception as e:
- driver.cleanup()
logging.warn(traceback.format_exc())
logging.warn("Failed to execute job: %s %s %s (attempts left %i) error was %s" %
(hostname, port, request, retries, e.message))
+ if driver:
+ #driver._cleanup()
+ driver._bombout()
time.sleep(5)
retries -= 1
return False
@@ -70,21 +79,20 @@
def run_me(self):
logging.info("Starting up the PDURunner")
while 1:
- db = DBHandler(self.config["settings"])
+ db = DBHandler(self.settings)
self.get_one(db)
db.close()
del(db)
time.sleep(2)
if __name__ == "__main__":
- starter = { "settings": {"dbhost": "127.0.0.1",
- "dbuser": "pdudaemon",
- "dbpass": "pdudaemon",
- "dbname": "lavapdu"},
- "pdus": { "pdu14": { "driver": "APC9218" },"pdu15": {"driver": "APC8959"} },
- "logging_level": logging.DEBUG}
- p = PDURunner(starter)
- p.do_job("pdu15",18,"off",10)
- p.do_job("pdu15",18,"reboot",10)
- p.do_job("pdu15",18,"on",10)
- #p.run_me()
+ settings = {}
+ filename = "/etc/lavapdu/lavapdu.conf"
+ print("Reading settings from %s" % filename)
+ with open(filename) as stream:
+ jobdata = stream.read()
+ json_data = json.loads(jobdata)
+
+ p = PDURunner(json_data)
+ #p.do_job("192.168.10.5",18,"reboot",2)
+ p.run_me()
diff --git a/lavapdu/socketserver.py b/lavapdu/socketserver.py
index 2ba149c..916b02d 100644
--- a/lavapdu/socketserver.py
+++ b/lavapdu/socketserver.py
@@ -22,18 +22,23 @@
import logging
import socket
import time
+import json
from dbhandler import DBHandler
-
class ListenerServer(object):
- def __init__(self, config):
- self.server = TCPServer((config["settings"]["hostname"], config["settings"]["port"]), TCPRequestHandler)
+ def __init__(self, settings):
+ listen_host = settings["hostname"]
+ listen_port = settings["port"]
+
logging.getLogger().name = "ListenerServer"
- logging.getLogger().setLevel(config["logging_level"])
- logging.info("listening on %s:%s" % (config["settings"]["hostname"], config["settings"]["port"]))
- self.server.settings = config["settings"]
- self.db = DBHandler(self.server.settings)
+ logging.getLogger().setLevel(settings["logging_level"])
+ logging.debug("ListenerServer __init__")
+ logging.info("listening on %s:%s" % (listen_host, listen_port))
+
+ self.server = TCPServer((listen_host, listen_port), TCPRequestHandler)
+ self.server.settings = settings
+ self.db = DBHandler(settings)
self.create_db()
self.db.close()
del(self.db)
@@ -58,11 +63,12 @@
#"One instance per connection. Override handle(self) to customize action."
def insert_request(self, data):
logging.getLogger().name = "TCPRequestHandler"
+ logging.getLogger().setLevel(self.server.settings["logging_level"])
array = data.split(" ")
delay = 10
custom_delay = False
now = int(time.time())
- if len(array) < 3:
+ if (len(array) < 3) or (len(array) > 4):
logging.info("Wrong data size")
raise Exception("Unexpected data")
if len(array) == 4:
@@ -87,7 +93,7 @@
def queue_request(self, hostname, port, request, exectime):
db = DBHandler(self.server.settings)
- sql = "insert into pdu_queue (hostname,port,request,exectime)" \
+ sql = "insert into pdu_queue (hostname,port,request,exectime) " \
"values ('%s',%i,'%s',%i)" % (hostname,port,request,exectime)
db.do_sql(sql)
db.close()
@@ -103,7 +109,7 @@
try:
request_host = socket.gethostbyaddr(ip)[0]
except socket.herror as e:
- logging.debug("Unable to resolve: %s error: %s" % (ip,e))
+ #logging.debug("Unable to resolve: %s error: %s" % (ip,e))
request_host = ip
logging.info("Received a request from %s: '%s'" % (request_host, data))
self.insert_request(data)
@@ -123,12 +129,19 @@
logging.basicConfig(level=logging.DEBUG)
logging.getLogger().setLevel(logging.DEBUG)
logging.debug("Executing from __main__")
- starter = {"hostname": "0.0.0.0",
- "port":16421,
- "dbhost":"127.0.0.1",
- "dbuser":"pdudaemon",
- "dbpass":"pdudaemon",
- "dbname":"lavapdu",
- "logging_level": logging.DEBUG}
- ss = ListenerServer(starter)
+ settings = {}
+ filename = "/etc/lavapdu/lavapdu.conf"
+ print("Reading settings from %s" % filename)
+ with open(filename) as stream:
+ jobdata = stream.read()
+ json_data = json.loads(jobdata)
+
+ #starter = {"daemon": {"dbhost":"127.0.0.1",
+ # "dbuser":"pdudaemon",
+ # "dbpass":"pdudaemon",
+ # "dbname":"lavapdu",
+ # "logging_level": logging.DEBUG,
+ # "hostname": "0.0.0.0", "port": 16421}}
+ #ss = ListenerServer(starter)
+ ss = ListenerServer(json_data)
ss.start()
\ No newline at end of file
diff --git a/pduclient b/pduclient
index 3347c60..143da8e 100755
--- a/pduclient
+++ b/pduclient
@@ -26,11 +26,11 @@
description = "LAVA PDU daemon client"
commands = ["reboot", "on", "off"]
parser = optparse.OptionParser(usage=usage, description=description)
- parser.add_option("--daemon", dest="pdudaemonhostname", action="store", type="string", help="LAVAPDU Daemon (ex: control)")
+ parser.add_option("--daemon", dest="pdudaemonhostname", action="store", type="string", help="LAVAPDU Daemon hostname (ex: localhost)")
parser.add_option("--hostname", dest="pduhostname", action="store", type="string", help="PDU Hostname (ex: pdu05)")
parser.add_option("--port", dest="pduportnum", action="store", type="string", help="PDU Portnumber (ex: 04)")
parser.add_option("--command", dest="pducommand", action="store", type="string", help="PDU command (ex: reboot|on|off)")
- parser.add_option("--delay", dest="pdudelay", action="store", type="int", help="Delay before command runs, or between off/on when rebooting")
+ parser.add_option("--delay", dest="pdudelay", action="store", type="int", help="Delay before command runs, or between off/on when rebooting (ex: 5)")
(options, args) = parser.parse_args()
if (not (options.pdudaemonhostname) or not(options.pduhostname) or not (options.pduportnum) or not (options.pducommand)):
print("Missing option, try -h for help")
@@ -38,9 +38,8 @@
if not (options.pducommand in commands):
print("Unknown pdu command: %s" % options.pducommand)
exit(1)
- #print(options)
if options.pdudelay:
- string = ("%s %s %s" % (options.pduhostname, options.pduportnum, options.pducommand, options.pdudelay))
+ string = ("%s %s %s %s" % (options.pduhostname, options.pduportnum, options.pducommand, options.pdudelay))
else:
string = ("%s %s %s" % (options.pduhostname, options.pduportnum, options.pducommand))
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@@ -52,7 +51,7 @@
reply = sock.recv(16384).strip() # limit reply to 16K
sock.close()
except Exception:
- print ("Error sending command, wrong hostname?")
+ print ("Error sending command, wrong daemon hostname?")
exit(1)
if reply == "ack":
print("Command sent successfully.")