Module nodeset
[hide private]
[frames] | no frames]

Source Code for Module nodeset

  1  #!/usr/bin/env python 
  2  # 
  3  # Copyright CEA/DAM/DIF (2008, 2009) 
  4  #  Contributor: Stephane THIELL <stephane.thiell@cea.fr> 
  5  # 
  6  # This file is part of the ClusterShell library. 
  7  # 
  8  # This software is governed by the CeCILL-C license under French law and 
  9  # abiding by the rules of distribution of free software.  You can  use, 
 10  # modify and/ or redistribute the software under the terms of the CeCILL-C 
 11  # license as circulated by CEA, CNRS and INRIA at the following URL 
 12  # "http://www.cecill.info". 
 13  # 
 14  # As a counterpart to the access to the source code and  rights to copy, 
 15  # modify and redistribute granted by the license, users are provided only 
 16  # with a limited warranty  and the software's author,  the holder of the 
 17  # economic rights,  and the successive licensors  have only  limited 
 18  # liability. 
 19  # 
 20  # In this respect, the user's attention is drawn to the risks associated 
 21  # with loading,  using,  modifying and/or developing or reproducing the 
 22  # software by the user in light of its specific status of free software, 
 23  # that may mean  that it is complicated to manipulate,  and  that  also 
 24  # therefore means  that it is reserved for developers  and  experienced 
 25  # professionals having in-depth computer knowledge. Users are therefore 
 26  # encouraged to load and test the software's suitability as regards their 
 27  # requirements in conditions enabling the security of their systems and/or 
 28  # data to be ensured and,  more generally, to use and operate it in the 
 29  # same conditions as regards security. 
 30  # 
 31  # The fact that you are presently reading this means that you have had 
 32  # knowledge of the CeCILL-C license and that you accept its terms. 
 33  # 
 34  # $Id: nodeset.py 233 2010-02-25 16:51:55Z st-cea $ 
 35   
 36  """ 
 37  Usage: nodeset [COMMAND] [OPTIONS] [ns1 [-ixX] ns2|...] 
 38   
 39  Commands: 
 40      --count, -c <nodeset> [nodeset ...] 
 41          Return the number of nodes in nodesets. 
 42      --expand, -e <nodeset> [nodeset ...] 
 43          Expand nodesets to separate nodes. 
 44      --fold, -f <nodeset> [nodeset ...] 
 45          Compact/fold nodesets (or separate nodes) into one nodeset. 
 46  Options: 
 47      --autostep=<number>, -a <number> 
 48          Specify auto step threshold number when folding nodesets. 
 49          If not specified, auto step is disabled. 
 50          Example: autostep=4, "node2 node4 node6" folds in node[2,4,6] 
 51                   autostep=3, "node2 node4 node6" folds in node[2-6/2] 
 52      --help, -h 
 53          This help page. 
 54      --quiet, -q 
 55          Quiet mode, hide any parse error messages (on stderr). 
 56      --rangeset, -R 
 57          Switch to RangeSet instead of NodeSet. Useful when working on 
 58          numerical cluster ranges, eg. 1,5,18-31. 
 59      --separator=<string>, -S <string> 
 60          Use specified separator string when expanding nodesets (default 
 61          is ' '). 
 62      --version, -v 
 63          Show ClusterShell version and exit. 
 64  Operations (default is union): 
 65          The default operation is the union of node or nodeset. 
 66      --exclude=<nodeset>, -x <nodeset> 
 67          Exclude provided node or nodeset. 
 68      --intersection, -i 
 69          Calculate nodesets intersection. 
 70      --xor, -X 
 71          Calculate symmetric difference (XOR) between two nodesets. 
 72  """ 
 73   
 74  import getopt 
 75  import signal 
 76  import sys 
 77   
 78  from ClusterShell.NodeSet import NodeSet, NodeSetParseError 
 79  from ClusterShell.NodeSet import RangeSet, RangeSetParseError 
 80  from ClusterShell import __version__ 
 81   
82 -def process_stdin(xset, autostep):
83 """Process standard input and populate xset.""" 84 for line in sys.stdin.readlines(): 85 # Support multi-lines and multi-nodesets per line 86 line = line[0:line.find('#')].strip() 87 for node in line.split(): 88 xset.update(xset.__class__(node, autostep=autostep))
89
90 -def compute_nodeset(xset, args, autostep):
91 """Apply operations and operands from args on xset, an initial 92 RangeSet or NodeSet.""" 93 class_set = xset.__class__ 94 # Process operations 95 while args: 96 arg = args.pop(0) 97 if arg in ("-i", "--intersection"): 98 xset.intersection_update(class_set(args.pop(0), 99 autostep=autostep)) 100 elif arg in ("-x", "--exclude"): 101 xset.difference_update(class_set(args.pop(0), 102 autostep=autostep)) 103 elif arg in ("-X", "--xor"): 104 xset.symmetric_difference_update(class_set(args.pop(0), 105 autostep=autostep)) 106 elif arg == '-': 107 process_stdin(xset, autostep) 108 else: 109 xset.update(class_set(arg, autostep=autostep)) 110 111 return xset
112
113 -def run_nodeset(args):
114 """ 115 Main script function. 116 """ 117 autostep = None 118 command = None 119 quiet = False 120 class_set = NodeSet 121 separator = ' ' 122 123 # Parse getoptable options 124 try: 125 opts, args = getopt.getopt(args[1:], "a:cefhqvRS:", 126 ["autostep=", "count", "expand", "fold", "help", 127 "quiet", "rangeset", "version", "separator="]) 128 except getopt.error, err: 129 if err.opt in [ "i", "intersection", "x", "exclude", "X", "xor" ]: 130 print >> sys.stderr, "option -%s not allowed here" % err.opt 131 else: 132 print >> sys.stderr, err.msg 133 print >> sys.stderr, "Try `%s -h' for more information." % args[0] 134 sys.exit(2) 135 136 for k, val in opts: 137 if k in ("-a", "--autostep"): 138 try: 139 autostep = int(val) 140 except ValueError, exc: 141 print >> sys.stderr, exc 142 elif k in ("-c", "--count"): 143 command = "count" 144 elif k in ("-e", "--expand"): 145 command = "expand" 146 elif k in ("-f", "--fold"): 147 command = "fold" 148 elif k in ("-h", "--help"): 149 print __doc__ 150 sys.exit(0) 151 elif k in ("-q", "--quiet"): 152 quiet = True 153 elif k in ("-R", "--rangeset"): 154 class_set = RangeSet 155 elif k in ("-S", "--separator"): 156 separator = val 157 elif k in ("-v", "--version"): 158 print __version__ 159 sys.exit(0) 160 161 # Check for command presence 162 if not command: 163 print >> sys.stderr, "ERROR: no command specified." 164 print __doc__ 165 sys.exit(1) 166 167 try: 168 # Instantiate RangeSet or NodeSet object 169 xset = class_set() 170 171 # No need to specify '-' to read stdin if no argument at all 172 if not args: 173 process_stdin(xset, autostep) 174 175 # Finish xset computing from args 176 compute_nodeset(xset, args, autostep) 177 178 # Interprate special characters (may raise SyntaxError) 179 separator = eval('\'%s\'' % separator, {"__builtins__":None}, {}) 180 181 # Display result according to command choice 182 if command == "expand": 183 print separator.join(xset) 184 elif command == "fold": 185 print xset 186 else: 187 print len(xset) 188 189 except (NodeSetParseError, RangeSetParseError), exc: 190 if not quiet: 191 print >> sys.stderr, "%s parse error:" % class_set.__name__, exc 192 sys.exit(1)
193 194 195 if __name__ == '__main__': 196 try: 197 run_nodeset(sys.argv) 198 sys.exit(0) 199 except AssertionError, e: 200 print >> sys.stderr, "ERROR:", e 201 sys.exit(1) 202 except IndexError: 203 print >> sys.stderr, "ERROR: syntax error" 204 sys.exit(1) 205 except SyntaxError: 206 print >> sys.stderr, "ERROR: invalid separator" 207 sys.exit(1) 208 except KeyboardInterrupt: 209 sys.exit(128 + signal.SIGINT) 210