1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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
83 """Process standard input and populate xset."""
84 for line in sys.stdin.readlines():
85
86 line = line[0:line.find('#')].strip()
87 for node in line.split():
88 xset.update(xset.__class__(node, autostep=autostep))
89
91 """Apply operations and operands from args on xset, an initial
92 RangeSet or NodeSet."""
93 class_set = xset.__class__
94
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
114 """
115 Main script function.
116 """
117 autostep = None
118 command = None
119 quiet = False
120 class_set = NodeSet
121 separator = ' '
122
123
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
162 if not command:
163 print >> sys.stderr, "ERROR: no command specified."
164 print __doc__
165 sys.exit(1)
166
167 try:
168
169 xset = class_set()
170
171
172 if not args:
173 process_stdin(xset, autostep)
174
175
176 compute_nodeset(xset, args, autostep)
177
178
179 separator = eval('\'%s\'' % separator, {"__builtins__":None}, {})
180
181
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