Skip to content

Commit 5f6d24d

Browse files
committed
Stop conversion of domains list to set
It loses the input order the user intended.
1 parent 2a30a33 commit 5f6d24d

2 files changed

Lines changed: 32 additions & 5 deletions

File tree

qubesadmin/tests/tools/init.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,26 @@ def test_105_set_prop_positional(self):
149149
args = parser.parse_args(['testvalue'])
150150
self.assertIn(
151151
('testprop', 'testvalue'), args.properties.items())
152+
153+
154+
class TC_02_QubesArgumentParser(qubesadmin.tests.QubesTestCase):
155+
def test_000_domain_preserve_order(self):
156+
self.app.expected_calls[('dom0', 'admin.vm.List', None, None)] = (
157+
b'0\x00some-vm class=AppVM state=Running\n'
158+
b'some-a class=AppVM state=Halted\n'
159+
b'some-b class=AppVM state=Paused\n'
160+
)
161+
162+
parser = qubesadmin.tools.QubesArgumentParser(vmname_nargs="+")
163+
wanted_args = ["some-vm", "some-a", "some-vm"]
164+
args = parser.parse_args(wanted_args, app=self.app)
165+
self.assertEqual(
166+
["some-a", "some-b", "some-vm"],
167+
[qube.name for qube in self.app.domains],
168+
"app namespace must have domains in alphabetical order",
169+
)
170+
self.assertEqual(
171+
["some-vm", "some-a"],
172+
[qube.name for qube in args.domains],
173+
"args namespace must have domains in input order",
174+
)

qubesadmin/tools/__init__.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -191,14 +191,18 @@ def parse_qubes_app(self, parser, namespace):
191191
except KeyError:
192192
parser.error('no such domain: {!r}'.format(vm_name))
193193
else:
194-
destinations = set()
194+
destinations = []
195195
for destination in getattr(namespace, self.dest):
196196
if any(wildcard in destination for wildcard in '*?[!]'):
197-
for domain in app.domains:
197+
for domain in [
198+
qube
199+
for qube in app.domains
200+
if qube.name not in destinations
201+
]:
198202
if fnmatch.fnmatch(domain.name, destination):
199-
destinations.add(domain.name)
200-
else:
201-
destinations.add(destination)
203+
destinations.append(domain.name)
204+
elif destination not in destinations:
205+
destinations.append(destination)
202206

203207
for vm_name in destinations:
204208
try:

0 commit comments

Comments
 (0)