Releases: GSI-HPC/go-nodeset
Release list
v1.0.1
A patch release with three fixes. Each corrects behaviour that contradicted the documentation of v1.0.0, and each makes some expressions that v1.0.0 accepted an error or name other hosts. A fix is a patch release (decision 10), so the section on upgrading names every such change, for a program to tell whether it is affected. No exported identifier was added, removed or changed, and String, Hostlist and Expand write any given set as v1.0.0 did.
Fixes
- A range needs both its bounds (#10, #11). v1.0.0 read a range with a dash and no last bound as its first bound alone:
exe[1-]wasexe1, andexe[1-,5]wasexe[1,5]. That is whatexe[1-$N]leaves behind whenNis empty or unset, so a command meant for many hosts ran onexe1alone. ClusterShell 1.10.1 rejects such a range, and the language reference of v1.0.0 did not list it among the differences. It is now an error:in "exe[1-]": the range "1-" has no last bound. @*and@source:*over aMapResolverevaluate each group on its own (#12, #13).MapResolver.Alljoined the expressions of a source's groups with commas into one expression, which is evaluated left to right, so the!,&or^of one group applied to every group before it. Witha: exe1andb: exe[2-4]!exe1,@*namedexe[2-4]where@a,@bnamedexe[1-4], against the doc comments ofResolver.AllandMapResolver.All, which promise every host the source knows and the union of its groups.Allnow refers to such a group as@source:group, which the parser evaluates on its own, and@*namesexe[1-4]. ClusterShell 1.10.1 also joins the groups of a source without anallgroup into one expression, and the notes of v1.0.0 said thatMapResolverresolves@*as ClusterShell does. Here the package now departs from it (decision 11).- A group whose brackets do not balance is evaluated on its own too. v1.0.0 wrote it into the join as it was, so it took the comma and the next group into its range: with
a: exe[1andb: 3],@*namedexe[1,3], although each group alone is an error.Allnow refers to such a group as well, and@*is an error, as each group is. ClusterShell's fallback namesexe[1,3]too (decision 12).
Upgrading from v1.0.0
Any expression not covered here names the same hosts as in v1.0.0.
- A range without its last bound is an error wherever it is written.
exe[1-]andexe[1-/1]wereexe1,exe[01-]wasexe01,exe[1-,5]andexe[5,1-]wereexe[1,5], anda[1-]b[2-3]wasa1b[2-3].Parse,ParseWithandAddreturn the error, andMustParsepanics.Contains("exe[1-]")andCanonical("exe[1-]"), which foundexe1, now report that the set does not hold it. A group whose expression holds such a range makes every reference to it an error,@*over its source included.exe[1-/2]was an error already, and only its message changed.StringandHostlistalways write both bounds, so whatever v1.0.0 printed parses as it did.
The other two fixes concern a program only if it uses @*, @source:* or MapResolver.All over a MapResolver source in which a group holds !, & or ^, or a bracket that does not balance. To tell what changes for such a source, parse @source:g for each such group g. If one is an error, @source:* is now an error too. Otherwise @source:* now names those groups and the expressions of the others together, unless one of the errors below applies or the groups together exceed the limits.
- Where the
MapResolveritself resolves whatAllreturns,@*can only gain hosts, unless it is now an error. Withbatch: exe[1-100],drained: exe[5,7]andup: @batch!@drained,@*wasexe[1-4,6,8-100]and is nowexe[1-100], so a program that acts on@*now reaches the drained hosts too. Combined with another setX,X!@*can remove more hosts andX&@*keep more. - Where one host is spelled with different padding in different groups,
@*can print and list it in another spelling. Witha: exe1,b: exe[2-4]!exe1andc: exe01,@*wasexe[01,2-4]and is nowexe[1-4], andExpandandCanonicalgiveexe1where they gaveexe01. MapResolver.Allreturns another expression for such a source. Witha: exe1andb: exe[2-4]!exe1in the sourcelocal,All("local")wasexe1,exe[2-4]!exe1and is nowexe1,@local:b. Witha: exe[1andb: 3]it wasexe[1,3]and is now@local:a,@local:b. A program that stores or compares that string, or hands it to another tool, sees the difference. A source whose groups hold no operator but the union and balance their brackets gets the same expression as before.All, and with it@*and@source:*, is an error when it has to refer to a group whose name is empty or*, or holds whitespace of any kind, a comma,!,&,^or a bracket, or to a group of a source whose name holds one of those or a colon, since such a reference might not read back as that group. The error quotes the reference. This includes sources v1.0.0 answered right: with the one groupmy group: exe[1-4]!exe2,@*wasexe[1,3-4]and is now an error.- A group that
Allrefers to is evaluated one level of nesting deeper. A chain of group references that@*or@source:*resolved in v1.0.0 at the sixteenth level now fails withgroup references nested more than 16 levels deep. - A custom
ResolverwhoseAllcallsMapResolver.Allnow receives, in itsResolve, the referencesAllreturns and the bare references inside the groups they name, both with theMapResolver's own source name. It has to answer for that source as theMapResolverdoes, or@*leaves those groups out or fails. A resolver whose ownAlljoins the expressions of several groups has the bug that this release fixes inMapResolver, and the doc comment ofResolver.Allnow says so. - ClusterShell names the same hosts for such a source when it is given what
Allreturns as theallgroup of a source of the same name, apart from the differences and limits the language reference lists and group names it reads otherwise, such as one beginning with@.
v1.0.0 is not retracted. Upgrading is recommended, above all for a program that builds expressions from variables or user input.
Requirements
Go 1.26 or newer.
v1.0.0
The first release of go-nodeset: ClusterShell node sets for Go, in one package that needs nothing but the standard library. It parses, folds and expands ranges, steps and names with several numbers, applies the set operators , ! & ^, and resolves @group references through a resolver of your own. It names the same hosts as ClusterShell 1.10.1, folds them alike and lists them in the same order, apart from the differences below.
The engine was written as the nodeset package of clusterctl and shipped there first.
Stability
From this release on, a minor or patch release does not break the exported API, the hosts an expression names, or the output of String, Hostlist and Expand (decision 10). The text of errors, speed and memory are not covered.
What it does
Parse,ParseWithandMustParseread an expression;NewandAddbuild a set.Stringfolds a set as ClusterShell does, including names with several numbers;Hostlistwrites one that Slurm accepts;Expandlists the hosts in ClusterShell's order.Union,Intersection,Difference,SymmetricDifference,Split,Contains,Canonical,Len,Clone.Resolver, the optionalListerandMapResolverresolve groups as ClusterShell does,@source:groupand@*included.WithAutostepfolds arithmetic progressions as ClusterShell's autostep does.- Sets keep their ranges:
r[1-1000]n[1-1000]is held as two ranges rather than a million hosts, and is listed host by host only when an operator has to combine it with hosts it does not hold.
Differences from ClusterShell
A few expressions are read differently, on purpose: padding is not part of a host's identity (exe1,exe01 is one host), adjacent numeric parts, names beginning with - and exe[1-2-3] are errors, whitespace unions, and an empty operand names nothing. Where one pattern holds numbers of different widths, the folded output may order them differently: ClusterShell prints exe[3,01-02], go-nodeset exe[01-02,3]. doc/language.md lists every difference.
An expression may name at most 1,048,576 hosts, and a bracket may hold at most as many elements, so that a typo such as exe[1-100000000] is refused rather than exhausting memory (limits). ClusterShell has no such limit.
Requirements
Go 1.26 or newer.