Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion qubesadmin/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,12 @@ def __getitem__(self, item):
# done by 'item not in self' check above, unless blind_mode is
# enabled
klass = None
state = None
if self._vm_list and item in self._vm_list:
klass = self._vm_list[item]['class']
self._vm_objects[item] = cls(self.app, item, klass=klass)
state = self._vm_list[item]['state']
self._vm_objects[item] = cls(self.app, item,
klass=klass, state=state)
return self._vm_objects[item]

def __contains__(self, item):
Expand Down
38 changes: 22 additions & 16 deletions qubesadmin/vm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class QubesVM(qubesadmin.base.PropertyHolder):

firewall = None

def __init__(self, app, name, klass=None):
def __init__(self, app, name, klass=None, state=None):
super(QubesVM, self).__init__(app, 'admin.vm.property.', name)
self._volumes = None
self._klass = klass
Expand All @@ -55,6 +55,11 @@ def __init__(self, app, name, klass=None):
self.features = qubesadmin.features.Features(self)
self.devices = qubesadmin.devices.DeviceManager(self)
self.firewall = qubesadmin.firewall.Firewall(self)
self._state = state

def clear_cache(self):
self._state = None
super(QubesVM, self).clear_cache()

@property
def name(self):
Expand Down Expand Up @@ -138,7 +143,7 @@ def unpause(self):
'''
self.qubesd_call(self._method_dest, 'admin.vm.Unpause')

def get_power_state(self):
def get_power_state(self, force=False):
'''Return power state description string.

Return value may be one of those:
Expand Down Expand Up @@ -168,20 +173,21 @@ def get_power_state(self):

'''

try:
vm_list_info = [line
for line in self.qubesd_call(
self._method_dest, 'admin.vm.List', None, None
).decode('ascii').split('\n')
if line.startswith(self._method_dest+' ')]
except qubesadmin.exc.QubesDaemonNoResponseError:
return 'NA'
assert len(vm_list_info) == 1
# name class=... state=... other=...
# NOTE: when querying dom0, we get whole list
vm_state = vm_list_info[0].strip().partition('state=')[2].split(' ')[0]
return vm_state

if not self._state or force:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ouch, this will break all the long-running processes using vm.is_running() or such. One example is qvm-shutdown --wait. IMO caching of VM state should be opt-in, not opt-out.

try:
vm_list_info = [line
for line in self.qubesd_call(
self._method_dest, 'admin.vm.List', None, None
).decode('ascii').split('\n')
if line.startswith(self._method_dest+' ')]
except qubesadmin.exc.QubesDaemonNoResponseError:
return 'NA'
assert len(vm_list_info) == 1
# name class=... state=... other=...
# NOTE: when querying dom0, we get whole list
self._state = (vm_list_info[0].strip().partition('state=')[2]
.split(' ')[0])
return self._state

def is_halted(self):
''' Check whether this domain's state is 'Halted'
Expand Down