Autotest (autotest.kernel.org) is beggining to leverage Cobbler to auto install host systems. It happens to be valuable to our project to be able to determine the power status of systems, so that we can better determine if the systems are unresponsive or shut off.
This patch was tested using only APC power switches. Behavior and command output is expected to be the same on other fencing agents. The API call return values are probably the big disruption point comparing it to the other power related calls. I find the proposal (on this patch) to provide more clear and meaninful information, but I do acknowledge it's disruptive. Feedback welcome. Signed-off-by: Cleber Rosa <cr...@redhat.com> --- cobbler/action_power.py | 15 ++++++++++++++- cobbler/api.py | 9 +++++++++ cobbler/cli.py | 4 ++-- cobbler/remote.py | 6 ++++-- 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/cobbler/action_power.py b/cobbler/action_power.py index 8c3083b..dc48da9 100644 --- a/cobbler/action_power.py +++ b/cobbler/action_power.py @@ -30,6 +30,7 @@ import os import os.path import traceback import time +import re import utils import func_utils @@ -108,8 +109,20 @@ class PowerTool: # Try the power command 5 times before giving up. # Some power switches are flakey for x in range(0,5): - rc = utils.subprocess_call(self.logger, cmd, shell=False) + output, rc = utils.subprocess_sp(self.logger, cmd, shell=False) if rc == 0: + # If the desired state is actually a query for the status + # return different information than command return code + if desired_state == 'status': + match = re.match('(^Status:\s)(ON|OFF)', output) + if match: + power_status = match.groups()[1] + if power_status == 'ON': + return True + else: + return False + utils.die(self.logger,"command succeeded (rc=%s), but output ('%s') was not understood" % (rc, output)) + return None break else: time.sleep(2) diff --git a/cobbler/api.py b/cobbler/api.py index cb94995..3a1c5a4 100644 --- a/cobbler/api.py +++ b/cobbler/api.py @@ -921,6 +921,15 @@ class BootAPI: time.sleep(5) return self.power_on(system, user, password, logger=logger) + def power_status(self, system, user=None, password=None, logger=None): + """ + Returns the power status for a system that has power management configured. + + @return: 0 the system is powered on, False if it's not or None on error + """ + return action_power.PowerTool(self._config, system, self, user, password, logger = logger).power("status") + + # ========================================================================== def clear_logs(self, system, logger=None): diff --git a/cobbler/cli.py b/cobbler/cli.py index 3b3efa7..99da153 100755 --- a/cobbler/cli.py +++ b/cobbler/cli.py @@ -42,7 +42,7 @@ import item_file OBJECT_ACTIONS = { "distro" : "add copy edit find list remove rename report".split(" "), "profile" : "add copy dumpvars edit find getks list remove rename report".split(" "), - "system" : "add copy dumpvars edit find getks list remove rename report poweron poweroff reboot".split(" "), + "system" : "add copy dumpvars edit find getks list remove rename report poweron poweroff powerstatus reboot".split(" "), "image" : "add copy edit find list remove rename report".split(" "), "repo" : "add copy edit find list remove rename report".split(" "), "mgmtclass" : "add copy edit find list remove rename report".split(" "), @@ -295,7 +295,7 @@ class BootCLI: keys.sort() for x in keys: print "%s : %s" % (x, data[x]) - elif object_action in [ "poweron", "poweroff", "reboot" ]: + elif object_action in [ "poweron", "poweroff", "powerstatus", "reboot" ]: power={} power["power"] = object_action.replace("power","") power["systems"] = [options.name] diff --git a/cobbler/remote.py b/cobbler/remote.py index f88451e..88523e1 100644 --- a/cobbler/remote.py +++ b/cobbler/remote.py @@ -1862,7 +1862,7 @@ class CobblerXMLRPCInterface: """ Internal implementation used by background_power, do not call directly if possible. - Allows poweron/poweroff/reboot of a system specified by object_id. + Allows poweron/poweroff/powerstatus/reboot of a system specified by object_id. """ obj = self.__get_object(object_id) self.check_access(token, "power_system", obj) @@ -1870,10 +1870,12 @@ class CobblerXMLRPCInterface: rc=self.api.power_on(obj, user=None, password=None, logger=logger) elif power=="off": rc=self.api.power_off(obj, user=None, password=None, logger=logger) + elif power=="status": + rc=self.api.power_status(obj, user=None, password=None, logger=logger) elif power=="reboot": rc=self.api.reboot(obj, user=None, password=None, logger=logger) else: - utils.die(self.logger, "invalid power mode '%s', expected on/off/reboot" % power) + utils.die(self.logger, "invalid power mode '%s', expected on/off/status/reboot" % power) return rc def get_config_data(self,hostname): -- 1.7.1 _______________________________________________ cobbler-devel mailing list cobbler-devel@lists.fedorahosted.org https://fedorahosted.org/mailman/listinfo/cobbler-devel