Skip to content

Commit

Permalink
Add events for virt.instance.query, including status change (#14970)
Browse files Browse the repository at this point in the history
  • Loading branch information
william-gr authored Nov 18, 2024
1 parent b2d3a9c commit ff029ac
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/middlewared/middlewared/plugins/virt/instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class Config:
cli_namespace = 'virt.instance'
entry = VirtInstanceEntry
role_prefix = 'VIRT_INSTANCE'
event_register = True

@filterable
async def query(self, filters, options):
Expand Down
20 changes: 20 additions & 0 deletions src/middlewared/middlewared/plugins/virt/websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,26 @@ async def _run_impl(self):
self._incoming[data['metadata']['id']].append(data)
for i in self._waiters[data['metadata']['id']]:
i.set()
if data['metadata'].get('class') == 'task':
if data['metadata'].get('description') in (
'Starting instance',
'Stopping instance',
) and data['metadata']['status_code'] == 200:
for instance in data['metadata']['resources']['instances']:
instance_id = instance.replace('/1.0/instances/', '')
self.middleware.send_event(
'virt.instance.query',
'CHANGED',
id=instance_id,
fields={
'status': (
'RUNNING'
if data['metadata']['description'] == 'Starting instance'
else
'STOPPED'
),
},
)
case 'logging':
if data['metadata']['message'] == 'Instance agent started':
self.middleware.send_event(
Expand Down
28 changes: 20 additions & 8 deletions tests/api2/test_virt_002_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,26 @@ def test_virt_instance_update():


def test_virt_instance_stop():
# Stop only one of them so the others are stopped during delete
assert ssh(f'incus list {INS2_NAME} -f json| jq ".[].status"').strip() == '"Running"'
instance = call('virt.instance.query', [['id', '=', INS2_NAME]], {'get': True})
assert instance['status'] == 'RUNNING'
call('virt.instance.stop', INS2_NAME, {'force': True}, job=True)
instance = call('virt.instance.query', [['id', '=', INS2_NAME]], {'get': True})
assert instance['status'] == 'STOPPED'
assert ssh(f'incus list {INS2_NAME} -f json| jq ".[].status"').strip() == '"Stopped"'
wait_status_event = Event()

def wait_status(event_type, **kwargs):
if kwargs['collection'] == 'virt.instance.query' and kwargs['id'] == INS2_NAME:
fields = kwargs.get('fields')
if fields and fields.get('status') == 'STOPPED':
wait_status_event.set()

with client() as c:
c.subscribe('virt.instance.query', wait_status, sync=True)

# Stop only one of them so the others are stopped during delete
assert ssh(f'incus list {INS2_NAME} -f json| jq ".[].status"').strip() == '"Running"'
instance = c.call('virt.instance.query', [['id', '=', INS2_NAME]], {'get': True})
assert instance['status'] == 'RUNNING'
call('virt.instance.stop', INS2_NAME, {'force': True}, job=True)
instance = c.call('virt.instance.query', [['id', '=', INS2_NAME]], {'get': True})
assert instance['status'] == 'STOPPED'
assert wait_status_event.wait(timeout=1)
assert ssh(f'incus list {INS2_NAME} -f json| jq ".[].status"').strip() == '"Stopped"'


def test_virt_instance_restart():
Expand Down

0 comments on commit ff029ac

Please sign in to comment.