@@ -38,17 +38,19 @@ def hostlist_expression(hosts):
38
38
E.g. with an inventory containing:
39
39
40
40
[compute]
41
- dev-foo-0 ansible_host=localhost
42
- dev-foo-3 ansible_host=localhost
41
+ dev-foo-00 ansible_host=localhost
42
+ dev-foo-3 ansible_host=localhost
43
43
my-random-host
44
- dev-foo-4 ansible_host=localhost
45
- dev-foo-5 ansible_host=localhost
46
- dev-compute-0 ansible_host=localhost
47
- dev-compute-1 ansible_host=localhost
44
+ dev-foo-04 ansible_host=localhost
45
+ dev-foo-05 ansible_host=localhost
46
+ dev-compute-000 ansible_host=localhost
47
+ dev-compute-001 ansible_host=localhost
48
48
49
49
Then "{{ groups[compute] | hostlist_expression }}" will return:
50
50
51
- ["dev-foo-[0,3-5]", "dev-compute-[0-1]", "my-random-host"]
51
+ ['dev-foo-[00,04-05,3]', 'dev-compute-[000-001]', 'my-random-host']
52
+
53
+ NB: This does not guranteed to return parts in the same order as `scontrol hostlist`, but its output should return the same hosts when passed to `scontrol hostnames`.
52
54
"""
53
55
54
56
results = {}
@@ -58,19 +60,23 @@ def hostlist_expression(hosts):
58
60
if m :
59
61
prefix , suffix = m .groups ()
60
62
r = results .setdefault (prefix , [])
61
- r .append (int ( suffix ) )
63
+ r .append (suffix )
62
64
else :
63
65
unmatchable .append (v )
64
66
return ['{}[{}]' .format (k , _group_numbers (v )) for k , v in results .items ()] + unmatchable
65
67
66
68
def _group_numbers (numbers ):
67
69
units = []
68
- prev = min (numbers )
69
- for v in sorted (numbers ):
70
+ ints = [int (n ) for n in numbers ]
71
+ lengths = [len (n ) for n in numbers ]
72
+ # sort numbers by int value and length:
73
+ ints , lengths , numbers = zip (* sorted (zip (ints , lengths , numbers )))
74
+ prev = min (ints )
75
+ for i , v in enumerate (sorted (ints )):
70
76
if v == prev + 1 :
71
- units [- 1 ].append (v )
77
+ units [- 1 ].append (numbers [ i ] )
72
78
else :
73
- units .append ([v ])
79
+ units .append ([numbers [ i ] ])
74
80
prev = v
75
81
return ',' .join (['{}-{}' .format (u [0 ], u [- 1 ]) if len (u ) > 1 else str (u [0 ]) for u in units ])
76
82
0 commit comments