-
Notifications
You must be signed in to change notification settings - Fork 1
Closed
Labels
pdsh-compatpdsh compatibility mode featurespdsh compatibility mode featuresstatus:reviewUnder reviewUnder reviewtype:enhancementNew feature or requestNew feature or request
Description
Summary
Implement pdsh-style hostlist expression syntax for specifying multiple hosts using range notation. This allows compact specification of host lists like node[01-10] instead of listing each host individually.
Parent Issue
Part of #91 (pdsh compatibility mode) - Phase 3: Hostlist Expression Support
Prerequisites
- Phase 2 Core Infrastructure must be complete
- The hostlist parser can be used in both pdsh compat mode and native bssh mode
Background
pdsh uses a powerful hostlist expression syntax that allows:
- Range expansion:
node[01-05]->node01, node02, node03, node04, node05 - Multiple ranges:
node[1-3,7,9-10]->node1, node2, node3, node7, node9, node10 - Prefix/suffix:
rack[1-2]-node[1-3]-> all combinations - Exclusion:
node[1-10] -x node[3-5] - File input:
^/path/to/hostfile
Proposed Implementation
Hostlist Syntax
hostlist = host_term (',' host_term)*
host_term = prefix range_expr suffix
range_expr = '[' range_list ']'
range_list = range_item (',' range_item)*
range_item = NUMBER | NUMBER '-' NUMBER
prefix = STRING (any characters before '[')
suffix = STRING (any characters after ']', may include nested ranges)
Examples
# Simple range
node[1-5] # -> node1, node2, node3, node4, node5
# Zero-padded range
node[01-05] # -> node01, node02, node03, node04, node05
# Multiple values
node[1,3,5] # -> node1, node3, node5
# Mixed ranges and values
node[1-3,7,9-10] # -> node1, node2, node3, node7, node9, node10
# Multiple range groups
rack[1-2]-node[1-3] # -> rack1-node1, rack1-node2, rack1-node3,
# rack2-node1, rack2-node2, rack2-node3
# With domain suffix
web[1-3].example.com # -> web1.example.com, web2.example.com, web3.example.com
# File input (pdsh style)
^/etc/hosts.cluster # Read hosts from file, one per lineModule Structure
// src/hostlist/mod.rs
pub mod parser;
pub mod expander;
pub fn expand_hostlist(expr: &str) -> Result<Vec<String>, HostlistError>;
pub fn parse_hostfile(path: &Path) -> Result<Vec<String>, HostlistError>;Native bssh -H Option Integration
The hostlist expression syntax will be available in native bssh mode through the -H (hosts) option. This extends the current comma-separated host list syntax to support range expressions.
Current -H Option Syntax
# Current syntax (comma-separated hosts)
bssh -H "user@host1:22,user@host2:22,user@host3:22" "uptime"Extended -H Option Syntax with Range Expansion
# Simple range expansion
bssh -H "node[1-5]" "uptime"
# Expands to: node1, node2, node3, node4, node5
# Zero-padded range
bssh -H "node[01-05]" "uptime"
# Expands to: node01, node02, node03, node04, node05
# With user and port specification
bssh -H "admin@web[1-3].example.com:22" "uptime"
# Expands to: admin@web1.example.com:22, admin@web2.example.com:22, admin@web3.example.com:22
# Multiple ranges in single host pattern
bssh -H "rack[1-2]-node[1-3]" "uptime"
# Expands to: rack1-node1, rack1-node2, rack1-node3, rack2-node1, rack2-node2, rack2-node3
# Multiple host patterns (comma-separated)
bssh -H "web[1-3],db[1-2]" "uptime"
# Expands to: web1, web2, web3, db1, db2
# Complex combination with user/port
bssh -H "admin@app[01-03].prod.example.com:2222,root@db[1-2].prod.example.com" "uptime"
# Expands to: admin@app01.prod.example.com:2222, admin@app02.prod.example.com:2222,
# admin@app03.prod.example.com:2222, root@db1.prod.example.com, root@db2.prod.example.com
# File input
bssh -H "^/etc/cluster/hosts" "uptime"
# Reads hosts from file
# Mixed: explicit hosts and range expressions
bssh -H "gateway,node[1-3],backup" "uptime"
# Expands to: gateway, node1, node2, node3, backup-H Option Parsing Flow
Input: "admin@web[1-3].example.com:22"
↓
Parse user prefix: "admin@"
↓
Parse hostname with range: "web[1-3].example.com"
↓
Expand range: ["web1.example.com", "web2.example.com", "web3.example.com"]
↓
Parse port suffix: ":22"
↓
Output: ["admin@web1.example.com:22", "admin@web2.example.com:22", "admin@web3.example.com:22"]
Integration with Existing -H Features
The range expansion should work seamlessly with existing -H option features:
| Feature | Example | Description |
|---|---|---|
--filter |
bssh -H "node[1-10]" --filter "node[1-5]" |
Expand both, then filter |
--exclude / -x |
bssh -H "node[1-10]" -x "node[3-5]" |
Expand both, then exclude |
| Jump hosts | bssh -H "node[1-3]" -J "bastion" |
Apply jump host to all expanded hosts |
| Output dir | bssh -H "node[1-5]" -o ./results |
Create output files for each expanded host |
Implementation Tasks
- Create
src/hostlist/mod.rsmodule - Implement range parser (
[1-5]syntax) - Implement zero-padding preservation (
[01-05]->01, 02, ...) - Implement comma-separated values (
[1,3,5]) - Implement mixed ranges and values (
[1-3,7,9-10]) - Implement multiple range groups (cartesian product)
- Implement file input with
^filenamesyntax - Integrate with
-Hoption in native mode- Parse user prefix (
user@) before expansion - Parse port suffix (
:port) after expansion - Handle comma-separated host patterns
- Integrate with
--filteroption - Integrate with
--exclude/-xoption
- Parse user prefix (
- Integrate with
-woption in pdsh compat mode - Add comprehensive unit tests
- Add integration tests with actual command execution
- Update documentation
- Update CLI help text with range expansion examples
Acceptance Criteria
-
node[1-5]expands to 5 hosts -
node[01-05]preserves zero-padding -
node[1,3,5]expands to 3 specific hosts -
node[1-3,7]combines ranges and individual values -
rack[1-2]-node[1-3]produces 6 hosts (cartesian product) -
^/path/to/filereads hosts from file -
-H "user@host[1-3]:port"correctly parses user, expands hostname, preserves port -
-H "host[1-3],host[5-7]"expands multiple patterns -
-H "node[1-10]" -x "node[3-5]"correctly excludes expanded range - Invalid syntax produces clear error messages
- Empty ranges are handled gracefully
- Large ranges work efficiently (e.g.,
[1-1000])
Edge Cases to Handle
- Empty brackets:
node[]-> error - Reversed range:
node[5-1]-> error or reverse iteration? - Invalid numbers:
node[a-z]-> error - Unclosed brackets:
node[1-5-> error - Nested brackets:
node[[1-2]]-> error - Overlapping ranges:
node[1-5,3-7]-> deduplicate? - User/port with range:
user@host[1-3]:22-> proper parsing - Range in username:
user[1-3]@host-> should this be supported? - Range in port:
host:22[01-03]-> should this be an error? - IPv6 addresses:
[2001:db8::1]vs range[1-3]-> disambiguation
Technical Considerations
- Consider using
nomorpestfor parsing - Cartesian product can produce large host lists - consider limits
- Zero-padding detection: compare digit counts in range bounds
- User/port parsing must happen before/after range expansion
- IPv6 literal brackets
[...]must not conflict with range brackets
Notes
- This feature can be enabled in native bssh mode too, not just pdsh compat
- Consider making hostlist expansion a reusable library
- The
-Hoption integration makes this feature immediately useful without requiring pdsh compat mode
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
pdsh-compatpdsh compatibility mode featurespdsh compatibility mode featuresstatus:reviewUnder reviewUnder reviewtype:enhancementNew feature or requestNew feature or request