diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2013-05-09 18:09:52 +0000 |
---|---|---|
committer | <> | 2013-06-05 18:25:08 +0000 |
commit | 7e1dea01472ce20c90dd69f11e6c07df9f1d6847 (patch) | |
tree | 51f11e81e42ba5d1b2e91b06a52bef5b45b0e460 /cxmanage/commands | |
download | cxmanage-tarball-7e1dea01472ce20c90dd69f11e6c07df9f1d6847.tar.gz |
Imported from /home/lorry/working-area/delta_cxmanage-tarball/cxmanage-0.8.2.tar.gz.HEADcxmanage-0.8.2masterbaserock/morph
Diffstat (limited to 'cxmanage/commands')
-rw-r--r-- | cxmanage/commands/__init__.py | 29 | ||||
-rw-r--r-- | cxmanage/commands/config.py | 94 | ||||
-rw-r--r-- | cxmanage/commands/fabric.py | 80 | ||||
-rw-r--r-- | cxmanage/commands/fw.py | 164 | ||||
-rw-r--r-- | cxmanage/commands/info.py | 103 | ||||
-rw-r--r-- | cxmanage/commands/ipdiscover.py | 56 | ||||
-rw-r--r-- | cxmanage/commands/ipmitool.py | 60 | ||||
-rw-r--r-- | cxmanage/commands/mc.py | 47 | ||||
-rw-r--r-- | cxmanage/commands/power.py | 110 | ||||
-rw-r--r-- | cxmanage/commands/sensor.py | 83 |
10 files changed, 826 insertions, 0 deletions
diff --git a/cxmanage/commands/__init__.py b/cxmanage/commands/__init__.py new file mode 100644 index 0000000..2160043 --- /dev/null +++ b/cxmanage/commands/__init__.py @@ -0,0 +1,29 @@ +# Copyright (c) 2012, Calxeda Inc. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of Calxeda Inc. nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. diff --git a/cxmanage/commands/config.py b/cxmanage/commands/config.py new file mode 100644 index 0000000..ca80928 --- /dev/null +++ b/cxmanage/commands/config.py @@ -0,0 +1,94 @@ +# Copyright (c) 2012, Calxeda Inc. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of Calxeda Inc. nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. + +from cxmanage import get_tftp, get_nodes, get_node_strings, run_command + +from cxmanage_api.ubootenv import UbootEnv, validate_boot_args + + +def config_reset_command(args): + """reset to factory default settings""" + tftp = get_tftp(args) + nodes = get_nodes(args, tftp, verify_prompt=True) + + if not args.quiet: + print "Sending config reset command..." + + results, errors = run_command(args, nodes, "config_reset") + + if not args.quiet and not errors: + print "Command completed successfully.\n" + + return len(errors) > 0 + + +def config_boot_command(args): + """set A9 boot order""" + if args.boot_order == ['status']: + return config_boot_status_command(args) + + validate_boot_args(args.boot_order) + + tftp = get_tftp(args) + nodes = get_nodes(args, tftp) + + if not args.quiet: + print "Setting boot order..." + + results, errors = run_command(args, nodes, "set_boot_order", + args.boot_order) + + if not args.quiet and not errors: + print "Command completed successfully.\n" + + return len(errors) > 0 + + +def config_boot_status_command(args): + tftp = get_tftp(args) + nodes = get_nodes(args, tftp) + + if not args.quiet: + print "Getting boot order..." + results, errors = run_command(args, nodes, "get_boot_order") + + # Print results + if results: + node_strings = get_node_strings(args, results, justify=True) + print "Boot order" + for node in nodes: + if node in results: + print "%s: %s" % (node_strings[node], ",".join(results[node])) + print + + if not args.quiet and errors: + print "Some errors occured during the command.\n" + + return len(errors) > 0 diff --git a/cxmanage/commands/fabric.py b/cxmanage/commands/fabric.py new file mode 100644 index 0000000..3bf84c2 --- /dev/null +++ b/cxmanage/commands/fabric.py @@ -0,0 +1,80 @@ +# Copyright (c) 2012, Calxeda Inc. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of Calxeda Inc. nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. + +from cxmanage import get_tftp, get_nodes, run_command + + +def ipinfo_command(args): + """get ip info from a cluster or host""" + args.all_nodes = False + + tftp = get_tftp(args) + nodes = get_nodes(args, tftp) + + if not args.quiet: + print "Getting IP addresses..." + + results, errors = run_command(args, nodes, "get_fabric_ipinfo") + + for node in nodes: + if node in results: + print 'IP info from %s' % node.ip_address + for node_id, node_address in results[node].iteritems(): + print 'Node %i: %s' % (node_id, node_address) + print + + return 0 + + +def macaddrs_command(args): + """get mac addresses from a cluster or host""" + args.all_nodes = False + + tftp = get_tftp(args) + nodes = get_nodes(args, tftp) + + if not args.quiet: + print "Getting MAC addresses..." + results, errors = run_command(args, nodes, "get_fabric_macaddrs") + + for node in nodes: + if node in results: + print "MAC addresses from %s" % node.ip_address + for node_id in results[node]: + for port in results[node][node_id]: + for mac_address in results[node][node_id][port]: + print "Node %i, Port %i: %s" % (node_id, port, + mac_address) + print + + if not args.quiet and errors: + print "Some errors occured during the command.\n" + + return len(errors) == 0 diff --git a/cxmanage/commands/fw.py b/cxmanage/commands/fw.py new file mode 100644 index 0000000..87f810b --- /dev/null +++ b/cxmanage/commands/fw.py @@ -0,0 +1,164 @@ +# Copyright (c) 2012, Calxeda Inc. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of Calxeda Inc. nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. + +from pkg_resources import parse_version + +from cxmanage import get_tftp, get_nodes, get_node_strings, run_command, \ + prompt_yes + +from cxmanage_api.image import Image +from cxmanage_api.firmware_package import FirmwarePackage + + +def fwupdate_command(args): + """update firmware on a cluster or host""" + def do_update(): + """ Do a single firmware check+update. Returns True on failure. """ + if not args.force: + if not args.quiet: + print "Checking hosts..." + + results, errors = run_command(args, nodes, "_check_firmware", + package, args.partition, args.priority) + if errors: + print "ERROR: Firmware update aborted." + return True + + if not args.quiet: + print "Updating firmware..." + + results, errors = run_command(args, nodes, "update_firmware", package, + args.partition, args.priority) + if errors: + print "ERROR: Firmware update failed." + return True + + return False + + def do_reset(): + """ Reset and wait. Returns True on failure. """ + if not args.quiet: + print "Checking ECME versions..." + + results, errors = run_command(args, nodes, "get_versions") + if errors: + print "ERROR: MC reset aborted. Backup partitions not updated." + return True + + for result in results.values(): + version = result.ecme_version.lstrip("v") + if parse_version(version) < parse_version("1.2.0"): + print "ERROR: MC reset is unsafe on ECME version v%s" % version + print "Please power cycle the system and start a new fwupdate." + return True + + if not args.quiet: + print "Resetting nodes..." + + results, errors = run_command(args, nodes, "mc_reset", True) + if errors: + print "ERROR: MC reset failed. Backup partitions not updated." + return True + + return False + + if args.image_type == "PACKAGE": + package = FirmwarePackage(args.filename) + else: + try: + simg = None + if args.force_simg: + simg = False + elif args.skip_simg: + simg = True + + image = Image(args.filename, args.image_type, simg, args.daddr, + args.skip_crc32, args.fw_version) + package = FirmwarePackage() + package.images.append(image) + except ValueError as e: + print "ERROR: %s" % e + return True + + if not args.all_nodes: + if args.force: + print 'WARNING: Updating firmware without --all-nodes is dangerous.' + else: + if not prompt_yes( + 'WARNING: Updating firmware without --all-nodes is dangerous. Continue?'): + return 1 + + tftp = get_tftp(args) + nodes = get_nodes(args, tftp, verify_prompt=True) + + errors = do_update() + + if args.full and not errors: + errors = do_reset() + if not errors: + errors = do_update() + + if not args.quiet and not errors: + print "Command completed successfully.\n" + + return errors + + +def fwinfo_command(args): + """print firmware info""" + tftp = get_tftp(args) + nodes = get_nodes(args, tftp) + + if not args.quiet: + print "Getting firmware info..." + + results, errors = run_command(args, nodes, "get_firmware_info") + + node_strings = get_node_strings(args, results, justify=False) + for node in nodes: + if node in results: + print "[ Firmware info for %s ]" % node_strings[node] + + for partition in results[node]: + print "Partition : %s" % partition.partition + print "Type : %s" % partition.type + print "Offset : %s" % partition.offset + print "Size : %s" % partition.size + print "Priority : %s" % partition.priority + print "Daddr : %s" % partition.daddr + print "Flags : %s" % partition.flags + print "Version : %s" % partition.version + print "In Use : %s" % partition.in_use + print + + if not args.quiet and errors: + print "Some errors occured during the command.\n" + + return len(errors) > 0 diff --git a/cxmanage/commands/info.py b/cxmanage/commands/info.py new file mode 100644 index 0000000..d002906 --- /dev/null +++ b/cxmanage/commands/info.py @@ -0,0 +1,103 @@ +# Copyright (c) 2012, Calxeda Inc. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of Calxeda Inc. nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. + +from cxmanage import get_tftp, get_nodes, get_node_strings, run_command + + +def info_command(args): + """print info from a cluster or host""" + if args.info_type in [None, 'basic']: + return info_basic_command(args) + elif args.info_type == 'ubootenv': + return info_ubootenv_command(args) + + +def info_basic_command(args): + """Print basic info""" + components = [ + ("ecme_version", "ECME version"), + ("cdb_version", "CDB version"), + ("stage2_version", "Stage2boot version"), + ("bootlog_version", "Bootlog version"), + ("a9boot_version", "A9boot version"), + ("uboot_version", "Uboot version"), + ("ubootenv_version", "Ubootenv version"), + ("dtb_version", "DTB version") + ] + + tftp = get_tftp(args) + nodes = get_nodes(args, tftp) + + if not args.quiet: + print "Getting info..." + results, errors = run_command(args, nodes, "get_versions") + + # Print results + node_strings = get_node_strings(args, results, justify=False) + for node in nodes: + if node in results: + result = results[node] + print "[ Info from %s ]" % node_strings[node] + print "Hardware version : %s" % result.hardware_version + print "Firmware version : %s" % result.firmware_version + for var, string in components: + if hasattr(result, var): + version = getattr(result, var) + print "%s: %s" % (string.ljust(19), version) + print + + if not args.quiet and errors: + print "Some errors occured during the command.\n" + + return len(errors) > 0 + + +def info_ubootenv_command(args): + tftp = get_tftp(args) + nodes = get_nodes(args, tftp) + + if not args.quiet: + print "Getting u-boot environment..." + results, errors = run_command(args, nodes, "get_ubootenv") + + # Print results + node_strings = get_node_strings(args, results, justify=False) + for node in nodes: + if node in results: + ubootenv = results[node] + print "[ U-Boot Environment from %s ]" % node_strings[node] + for variable in ubootenv.variables: + print "%s=%s" % (variable, ubootenv.variables[variable]) + print + + if not args.quiet and errors: + print "Some errors occured during the command.\n" + + return len(errors) > 0 diff --git a/cxmanage/commands/ipdiscover.py b/cxmanage/commands/ipdiscover.py new file mode 100644 index 0000000..f619d16 --- /dev/null +++ b/cxmanage/commands/ipdiscover.py @@ -0,0 +1,56 @@ +# Copyright (c) 2012, Calxeda Inc. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of Calxeda Inc. nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. + +from cxmanage import get_tftp, get_nodes, get_node_strings, run_command + + +def ipdiscover_command(args): + """discover server IP addresses""" + tftp = get_tftp(args) + nodes = get_nodes(args, tftp) + + if not args.quiet: + print 'Getting server-side IP addresses...' + + results, errors = run_command(args, nodes, 'get_server_ip', args.interface, + args.ipv6, args.server_user, args.server_password, args.aggressive) + + if results: + node_strings = get_node_strings(args, results, justify=True) + print 'IP addresses (ECME, Server)' + for node in nodes: + if node in results: + print '%s: %s' % (node_strings[node], results[node]) + print + + if not args.quiet and errors: + print 'Some errors occurred during the command.' + + return len(errors) > 0 diff --git a/cxmanage/commands/ipmitool.py b/cxmanage/commands/ipmitool.py new file mode 100644 index 0000000..f8baf80 --- /dev/null +++ b/cxmanage/commands/ipmitool.py @@ -0,0 +1,60 @@ +# Copyright (c) 2012, Calxeda Inc. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of Calxeda Inc. nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. + +from cxmanage import get_tftp, get_nodes, get_node_strings, run_command + + +def ipmitool_command(args): + """run arbitrary ipmitool command""" + if args.lanplus: + ipmitool_args = ['-I', 'lanplus'] + args.ipmitool_args + else: + ipmitool_args = args.ipmitool_args + + tftp = get_tftp(args) + nodes = get_nodes(args, tftp) + + if not args.quiet: + print "Running IPMItool command..." + results, errors = run_command(args, nodes, "ipmitool_command", + ipmitool_args) + + # Print results + node_strings = get_node_strings(args, results, justify=False) + for node in nodes: + if node in results and results[node] != "": + print "[ IPMItool output from %s ]" % node_strings[node] + print results[node] + print + + if not args.quiet and errors: + print "Some errors occured during the command.\n" + + return len(errors) > 0 diff --git a/cxmanage/commands/mc.py b/cxmanage/commands/mc.py new file mode 100644 index 0000000..2573540 --- /dev/null +++ b/cxmanage/commands/mc.py @@ -0,0 +1,47 @@ +# Copyright (c) 2012, Calxeda Inc. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of Calxeda Inc. nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. + +from cxmanage import get_tftp, get_nodes, run_command + + +def mcreset_command(args): + """reset the management controllers of a cluster or host""" + tftp = get_tftp(args) + nodes = get_nodes(args, tftp) + + if not args.quiet: + print 'Sending MC reset command...' + + results, errors = run_command(args, nodes, 'mc_reset') + + if not args.quiet and not errors: + print 'Command completed successfully.\n' + + return len(errors) > 0 diff --git a/cxmanage/commands/power.py b/cxmanage/commands/power.py new file mode 100644 index 0000000..b5b6015 --- /dev/null +++ b/cxmanage/commands/power.py @@ -0,0 +1,110 @@ +# Copyright (c) 2012, Calxeda Inc. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of Calxeda Inc. nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. + +from cxmanage import get_tftp, get_nodes, get_node_strings, run_command + + +def power_command(args): + """change the power state of a cluster or host""" + tftp = get_tftp(args) + nodes = get_nodes(args, tftp) + + if not args.quiet: + print 'Sending power %s command...' % args.power_mode + + results, errors = run_command(args, nodes, 'set_power', args.power_mode) + + if not args.quiet and not errors: + print 'Command completed successfully.\n' + + return len(errors) > 0 + + +def power_status_command(args): + tftp = get_tftp(args) + nodes = get_nodes(args, tftp) + + if not args.quiet: + print 'Getting power status...' + results, errors = run_command(args, nodes, 'get_power') + + # Print results + if results: + node_strings = get_node_strings(args, results, justify=True) + print 'Power status' + for node in nodes: + if node in results: + result = 'on' if results[node] else 'off' + print '%s: %s' % (node_strings[node], result) + print + + if not args.quiet and errors: + print 'Some errors occured during the command.\n' + + return len(errors) > 0 + + +def power_policy_command(args): + tftp = get_tftp(args) + nodes = get_nodes(args, tftp) + + if not args.quiet: + print 'Setting power policy to %s...' % args.policy + + results, errors = run_command(args, nodes, 'set_power_policy', + args.policy) + + if not args.quiet and not errors: + print 'Command completed successfully.\n' + + return len(errors) > 0 + + +def power_policy_status_command(args): + tftp = get_tftp(args) + nodes = get_nodes(args, tftp) + + if not args.quiet: + print 'Getting power policy status...' + results, errors = run_command(args, nodes, 'get_power_policy') + + # Print results + if results: + node_strings = get_node_strings(args, results, justify=True) + print 'Power policy status' + for node in nodes: + if node in results: + print '%s: %s' % (node_strings[node], results[node]) + print + + if not args.quiet and errors: + print 'Some errors occured during the command.\n' + + return len(errors) > 0 diff --git a/cxmanage/commands/sensor.py b/cxmanage/commands/sensor.py new file mode 100644 index 0000000..c3fed32 --- /dev/null +++ b/cxmanage/commands/sensor.py @@ -0,0 +1,83 @@ +# Copyright (c) 2012, Calxeda Inc. +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of Calxeda Inc. nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. + +from cxmanage import get_tftp, get_nodes, get_node_strings, run_command + + +def sensor_command(args): + """read sensor values from a cluster or host""" + tftp = get_tftp(args) + nodes = get_nodes(args, tftp) + + if not args.quiet: + print "Getting sensor readings..." + results, errors = run_command(args, nodes, "get_sensors", + args.sensor_name) + + sensors = {} + for node in nodes: + if node in results: + for sensor_name, sensor in results[node].iteritems(): + if not sensor_name in sensors: + sensors[sensor_name] = [] + + reading = sensor.sensor_reading.replace("(+/- 0) ", "") + try: + value = float(reading.split()[0]) + suffix = reading.lstrip("%f " % value) + sensors[sensor_name].append((node, value, suffix)) + except ValueError: + sensors[sensor_name].append((node, reading, "")) + + node_strings = get_node_strings(args, results, justify=True) + jsize = len(node_strings.itervalues().next()) + for sensor_name, readings in sensors.iteritems(): + print sensor_name + + for node, reading, suffix in readings: + print "%s: %.2f %s" % (node_strings[node], reading, suffix) + + try: + if all(suffix == x[2] for x in readings): + minimum = min(x[1] for x in readings) + maximum = max(x[1] for x in readings) + average = sum(x[1] for x in readings) / len(readings) + print "%s: %.2f %s" % ("Minimum".ljust(jsize), minimum, suffix) + print "%s: %.2f %s" % ("Maximum".ljust(jsize), maximum, suffix) + print "%s: %.2f %s" % ("Average".ljust(jsize), average, suffix) + except ValueError: + pass + + print + + if not args.quiet and errors: + print "Some errors occured during the command.\n" + + return len(errors) > 0 |