summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Kraft <george.kraft@calxeda.com>2012-08-22 14:11:57 -0500
committerGeorge Kraft <george.kraft@calxeda.com>2012-08-22 14:11:57 -0500
commit349dcfe06e23cde7cf0836c812422fe91d16edef (patch)
tree3941743739c6e7ad346da984f33ac8b5da046366
parent598cd87ceff40263578b3f246f4f59b221a06c7d (diff)
downloadcxmanage-349dcfe06e23cde7cf0836c812422fe91d16edef.tar.gz
When using --all-nodes, obtain IP addresses in parallel.
Getting IP addresses from the fabric can be slow since it has to wait for a TFTP transfer. It's generally not noticable with just a single host, but for multiple fabrics, it can take a while. Getting addresses in parallel should speed things up a bit.
-rw-r--r--cxmanage/controller.py76
-rw-r--r--cxmanage_test/controller_test.py4
-rwxr-xr-xscripts/cxmanage32
3 files changed, 73 insertions, 39 deletions
diff --git a/cxmanage/controller.py b/cxmanage/controller.py
index b47ab0b..c0c054e 100644
--- a/cxmanage/controller.py
+++ b/cxmanage/controller.py
@@ -175,20 +175,32 @@ class Controller:
########################### Targets-specific methods #########################
-
- def add_target(self, address, username, password, all_nodes=False):
- """ Add the target to the list of targets for the group. """
- # Do nothing if the target is already present
+ def add_target(self, address, username, password):
+ """ Add a target to the controller """
for target in self.targets:
if target.address == address:
return
target = self.target_class(address, username, password, self.verbosity)
- if all_nodes:
- for entry in target.get_ipinfo(self.tftp):
- self.add_target(entry[1], username, password)
- else:
- self.targets.append(target)
+ self.targets.append(target)
+
+ def add_fabrics(self, addresses, username, password):
+ """ Add all targets reported by each fabric """
+ targets = [self.target_class(x, username, password, self.verbosity)
+ for x in addresses]
+
+ if self.verbosity >= 1:
+ print "Getting IP addresses..."
+ results, errors = self._run_command(targets, "get_ipinfo", self.tftp)
+
+ for target in targets:
+ if target.address in results:
+ for ipinfo in results[target.address]:
+ self.add_target(ipinfo[1], username, password)
+
+ self._print_errors(targets, errors)
+
+ return len(errors) > 0
def get_addresses_in_range(self, start, end):
""" Return a list of addresses in the given IP range """
@@ -229,6 +241,8 @@ class Controller:
def power_status(self):
""" Retrieve power status from all targets in group """
+ if self.verbosity >= 1:
+ print "Getting power status..."
results, errors = self._run_command(self.targets, "get_power")
# Print results
@@ -244,7 +258,7 @@ class Controller:
print
# Print errors
- self._print_errors(errors)
+ self._print_errors(self.targets, errors)
return len(errors) > 0
@@ -260,6 +274,8 @@ class Controller:
def power_policy_status(self):
""" Get power policy status for all targets """
+ if self.verbosity >= 1:
+ print "Getting power policy status..."
results, errors = self._run_command(self.targets, "get_power_policy")
# Print results
@@ -272,7 +288,7 @@ class Controller:
print
# Print errors
- self._print_errors(errors)
+ self._print_errors(self.targets, errors)
return len(errors) > 0
@@ -299,6 +315,8 @@ class Controller:
def firmware_info(self):
""" Print firmware info for all targets """
+ if self.verbosity >= 1:
+ print "Getting firmware info..."
results, errors = self._run_command(self.targets, "get_firmware_info")
for target in self.targets:
@@ -316,12 +334,14 @@ class Controller:
print "In Use : %s" % partition.in_use
print
- self._print_errors(errors)
+ self._print_errors(self.targets, errors)
return len(errors) > 0
def get_sensors(self, name=""):
""" Get sensor readings from all targets """
+ if self.verbosity >= 1:
+ print "Getting sensor readings..."
results, errors = self._run_command(self.targets, "get_sensors", name)
if len(results) > 0:
@@ -372,12 +392,14 @@ class Controller:
print
- self._print_errors(errors)
+ self._print_errors(self.targets, errors)
return len(errors) > 0
def get_ipinfo(self):
""" Get IP info from all targets """
+ if self.verbosity >= 1:
+ print "Getting IP info..."
results, errors = self._run_command(self.targets, "get_ipinfo",
self.tftp)
@@ -391,12 +413,14 @@ class Controller:
print "Node %i: %s" % entry
print
- self._print_errors(errors)
+ self._print_errors(self.targets, errors)
return len(errors) > 0
def get_macaddrs(self):
""" Get mac addresses from all targets """
+ if self.verbosity >= 1:
+ print "Getting MAC addresses..."
results, errors = self._run_command(self.targets, "get_macaddrs",
self.tftp)
@@ -411,7 +435,7 @@ class Controller:
if target != self.targets[-1] or len(errors) > 0:
print
- self._print_errors(errors)
+ self._print_errors(self.targets, errors)
return len(errors) > 0
@@ -445,6 +469,8 @@ class Controller:
def config_boot_status(self):
""" Get boot order from all targets """
+ if self.verbosity >= 1:
+ print "Getting boot orders..."
results, errors = self._run_command(self.targets, "get_boot_order",
self.tftp)
@@ -458,12 +484,14 @@ class Controller:
print
# Print errors
- self._print_errors(errors)
+ self._print_errors(self.targets, errors)
return len(errors) > 0
def info_basic(self):
""" Get basic SoC info from all targets """
+ if self.verbosity >= 1:
+ print "Getting SoC info..."
results, errors = self._run_command(self.targets, "info_basic")
# Print results
@@ -480,12 +508,14 @@ class Controller:
print
# Print errors
- self._print_errors(errors)
+ self._print_errors(self.targets, errors)
return len(errors) > 0
def info_ubootenv(self):
""" Print u-boot environment for all targets """
+ if self.verbosity >= 1:
+ print "Getting u-boot environments..."
results, errors = self._run_command(self.targets, "get_ubootenv",
self.tftp)
@@ -500,7 +530,7 @@ class Controller:
print
# Print errors
- self._print_errors(errors)
+ self._print_errors(self.targets, errors)
return len(errors) > 0
@@ -514,6 +544,8 @@ class Controller:
def ipmitool_command(self, ipmitool_args):
""" Run an arbitrary ipmitool command on all targets """
+ if self.verbosity >= 1:
+ print "Running IPMItool command..."
results, errors = self._run_command(self.targets, "ipmitool_command",
ipmitool_args)
@@ -526,7 +558,7 @@ class Controller:
print
# Print errors
- self._print_errors(errors)
+ self._print_errors(self.targets, errors)
return len(errors) > 0
@@ -546,7 +578,7 @@ class Controller:
return False
else:
# Print errors
- self._print_errors(errors)
+ self._print_errors(targets, errors)
# Decide whether or not to retry
if retries == None:
@@ -624,11 +656,11 @@ class Controller:
return results, errors
- def _print_errors(self, errors):
+ def _print_errors(self, targets, errors):
""" Print errors if they occured """
if len(errors) > 0:
print "Command failed on these hosts"
- for target in self.targets:
+ for target in targets:
if target.address in errors:
print "%s: %s" % (target.address.ljust(16),
errors[target.address])
diff --git a/cxmanage_test/controller_test.py b/cxmanage_test/controller_test.py
index 2a9296b..5235cdc 100644
--- a/cxmanage_test/controller_test.py
+++ b/cxmanage_test/controller_test.py
@@ -65,7 +65,7 @@ class ControllerTest(unittest.TestCase):
""" Test adding targets with ipinfo """
# Add targets
self.assertEqual(len(self.controller.targets), 0)
- self.controller.add_target(ADDRESSES[0], "admin", "admin", True)
+ self.controller.add_fabrics([ADDRESSES[0]], "admin", "admin")
# Examine targets
self.assertEqual(len(ADDRESSES), len(self.controller.targets))
@@ -99,7 +99,7 @@ class ControllerCommandTest(unittest.TestCase):
# Set up the controller and add targets
self.controller = Controller(max_threads=32,
image_class=DummyImage, target_class=DummyTarget)
- self.controller.add_target(ADDRESSES[0], "admin", "admin", True)
+ self.controller.add_fabrics([ADDRESSES[0]], "admin", "admin")
def test_power(self):
""" Test power command """
diff --git a/scripts/cxmanage b/scripts/cxmanage
index 409d922..b4fac67 100755
--- a/scripts/cxmanage
+++ b/scripts/cxmanage
@@ -38,7 +38,6 @@ import os
import pkgutil
import sys
-from cxmanage import CxmanageError
from cxmanage.controller import Controller
# Load plugins
@@ -300,11 +299,19 @@ def set_tftp(controller, args):
controller.set_internal_tftp_server()
-def add_targets(controller, args, hosts=None):
- """add targets to controller addresses"""
- if hosts == None:
- hosts = args.hostname.split(',')
+def add_targets(controller, args):
+ hosts = parse_hosts(controller, args.hostname.split(','))
+ if args.all_nodes:
+ if controller.add_fabrics(hosts, args.user, args.password):
+ print "ERROR: Failed to get IP addresses. Aborting.\n"
+ sys.exit(1)
+ else:
+ for host in hosts:
+ controller.add_target(host, args.user, args.password)
+def parse_hosts(controller, hosts):
+ """add targets to controller addresses"""
+ results = []
for entry in hosts:
# Check if it's a hostfile
if entry.startswith('hostfile='):
@@ -314,7 +321,7 @@ def add_targets(controller, args, hosts=None):
elements = line.partition('#')[0].split()
for element in elements:
hostfile_entries.extend(element.split(','))
- add_targets(controller, args, hostfile_entries)
+ hosts.extend(parse_hosts(controller, hostfile_entries))
except IOError:
print 'ERROR: %s is not a valid hostfile entry' % entry
sys.exit(1)
@@ -322,17 +329,12 @@ def add_targets(controller, args, hosts=None):
# Not a hostfile, is it an IP range?
try:
start, end = entry.split('-')
- addresses = controller.get_addresses_in_range(start, end)
- add_targets(controller, args, addresses)
+ hosts.extend(controller.get_addresses_in_range(start, end))
except ValueError:
# Not a hostfile or IP range, add it as a regular host
- try:
- controller.add_target(entry, args.user,
- args.password, args.all_nodes)
- except CxmanageError:
- print ("ERROR: Failed to retrieve IP info from %s\n"
- % entry)
- sys.exit(1)
+ results.append(entry)
+
+ return results
def power_command(controller, args):