@@ -227,9 +227,31 @@ def __init__(self, vm):
227227 self .icon = getattr (vm , 'icon' , 'appvm-black' )
228228 self .auto_cleanup = getattr (vm , 'auto_cleanup' , False )
229229
230+ self .available = None
230231 self .state = {'power' : "" , 'outdated' : "" }
231232 self .updateable = getattr (vm , 'updateable' , False )
232- self .update (True )
233+ self .update (update_size_on_disk = True , update_availability = True )
234+
235+ def check_availability_state (self ):
236+ for volume in self .vm .volumes .values ():
237+ if volume .ephemeral :
238+ continue
239+ if volume .pool not in self .vm .app .pools :
240+ return False
241+ if volume .source is not None :
242+ if volume .source not in (
243+ pool_volume .vid
244+ for pool in self .vm .app .pools .values ()
245+ for pool_volume in pool .volumes
246+ ):
247+ return False
248+ elif volume .vid != "" :
249+ if volume .vid not in (
250+ pool_volume .vid
251+ for pool_volume in self .vm .app .pools [volume .pool ].volumes
252+ ):
253+ return False
254+ return True
233255
234256 def update_power_state (self ):
235257 try :
@@ -267,10 +289,15 @@ def update_power_state(self):
267289 except exc .QubesDaemonAccessError :
268290 pass
269291
270- def update (self , update_size_on_disk = False , event = None ):
292+ def update (self ,
293+ update_size_on_disk = False ,
294+ update_availability = False ,
295+ event = None
296+ ):
271297 """
272298 Update VmInfo
273299 :param update_size_on_disk: should disk utilization be updated?
300+ :param update_availability: should disk volume availability be updated?
274301 :param event: name of the event that caused the update, to avoid
275302 updating unnecessary properties; if event is none, update everything
276303 :return: None
@@ -341,6 +368,9 @@ def update(self, update_size_on_disk=False, event=None):
341368 self .disk_float = None
342369 self .disk = None
343370
371+ if self .vm .klass != 'AdminVM' and update_availability :
372+ self .available = self .check_availability_state ()
373+
344374 if self .vm .klass != 'AdminVM' :
345375 self .virt_mode = getattr (self .vm , 'virt_mode' , None )
346376 else :
@@ -691,6 +721,10 @@ def filterAcceptsRow(self, sourceRow, sourceParent):
691721 if not self .window .show_internal_action .isChecked () and vm .internal :
692722 return False
693723
724+ if not self .window .show_unavailable_pool_action .isChecked () and \
725+ not vm .available :
726+ return False
727+
694728 if self .window .show_user .isChecked () \
695729 and vm .klass in ['AppVM' , 'StandaloneVM' ] \
696730 and not getattr (vm .vm , 'template_for_dispvms' , False ) \
@@ -800,6 +834,11 @@ def __init__(self, qt_app, qubes_app, dispatcher, _parent=None):
800834 self .show_internal_action .setCheckable (True )
801835 self .show_internal_action .toggled .connect (self .invalidate )
802836
837+ self .show_unavailable_pool_action = self .menu_view .addAction (
838+ self .tr ('Show qubes stored on unavailable storage pools' ))
839+ self .show_unavailable_pool_action .setCheckable (True )
840+ self .show_unavailable_pool_action .toggled .connect (self .invalidate )
841+
803842 self .menu_view .addSeparator ()
804843 self .menu_view .addAction (self .action_toolbar )
805844 self .menu_view .addAction (self .action_menubar )
@@ -892,15 +931,27 @@ def __init__(self, qt_app, qubes_app, dispatcher, _parent=None):
892931 self .size_on_disk_timer .setInterval (1000 * 60 * 5 ) # every 5 mins
893932 self .size_on_disk_timer .start ()
894933
934+ self .volumes_available_timer = QTimer ()
935+ self .volumes_available_timer .timeout .connect (
936+ self .update_halted_availability
937+ )
938+ self .volumes_available_timer .setInterval (
939+ 1000 * 60 * 5
940+ ) # every 5 minutes
941+ self .volumes_available_timer .start ()
942+
895943 self .new_qube = QProcess ()
896944
897945 def eventFilter (self , _object , event ):
898- ''' refresh disk usage every 60s if focused & every 5m in background '''
946+ ''' refresh disk info every 60s if focused & every 5m in background '''
899947 if event .type () == QEvent .Type .WindowActivate :
900948 self .update_running_size ()
949+ self .update_halted_availability ()
901950 self .size_on_disk_timer .setInterval (1000 * 60 )
951+ self .volumes_available_timer .setInterval (1000 * 60 )
902952 elif event .type () == QEvent .Type .WindowDeactivate :
903953 self .size_on_disk_timer .setInterval (1000 * 60 * 5 )
954+ self .volumes_available_timer .setInterval (1000 * 60 * 5 )
904955 return False
905956
906957 def scroll_to_top (self ):
@@ -1018,6 +1069,8 @@ def save_showing(self):
10181069 self .show_standalone .isChecked ())
10191070 self .manager_settings .setValue ('show/internal' ,
10201071 self .show_internal_action .isChecked ())
1072+ self .manager_settings .setValue ('show/unavailable_pool' ,
1073+ self .show_unavailable_pool_action .isChecked ())
10211074 self .manager_settings .setValue ('show/user' ,
10221075 self .show_user .isChecked ())
10231076 self .manager_settings .setValue ('show/all' ,
@@ -1139,6 +1192,14 @@ def update_running_size(self, *_args):
11391192 self .qubes_cache .get_vm (qid = vm .qid ).update (
11401193 update_size_on_disk = True , event = 'disk_size' )
11411194
1195+ def update_halted_availability (self , * _args ):
1196+ if not self .show_unavailable_pool_action .isChecked ():
1197+ for vm in self .qubes_app .domains :
1198+ if not vm .is_running ():
1199+ self .qubes_cache .get_vm (qid = vm .qid ).update (
1200+ update_availability = True , event = 'volume_availability' )
1201+ self .invalidate ()
1202+
11421203 def on_domain_added (self , _submitter , _event , vm , ** _kwargs ):
11431204 try :
11441205 domain = self .qubes_app .domains [vm ]
@@ -1258,6 +1319,9 @@ def load_manager_settings(self):
12581319
12591320 self .show_internal_action .setChecked (self .manager_settings .value (
12601321 'show/internal' , "false" ) == "true" )
1322+ self .show_unavailable_pool_action .setChecked (
1323+ self .manager_settings .value (
1324+ 'show/unavailable_pool' , "false" ) == "true" )
12611325 # load last window size
12621326 self .resize (self .manager_settings .value ("window_size" ,
12631327 QSize (1100 , 600 )))
0 commit comments