2020# License along with this library; if not, see <https://www.gnu.org/licenses/>.
2121#
2222
23- """ This module contains the NetVMMixin """
23+ """This module contains the NetVMMixin"""
2424import ipaddress
2525import os
2626import re
@@ -341,6 +341,43 @@ def on_domain_started_net(self, event, **kwargs):
341341 except (qubes .exc .QubesException , libvirt .libvirtError ):
342342 vm .log .warning ("Cannot attach network" , exc_info = 1 )
343343
344+ def reset_deferred_netvm (self ):
345+ deferred_from = self .features .get ("deferred-netvm-original" , None )
346+ if deferred_from is None :
347+ return
348+ oldvalue = None
349+ if deferred_from in self .app .domains :
350+ oldvalue = self .app .domains [deferred_from ]
351+ if oldvalue :
352+ self .fire_event (
353+ "property-pre-set:netvm" ,
354+ pre_event = True ,
355+ name = "netvm" ,
356+ newvalue = self .netvm ,
357+ oldvalue = oldvalue ,
358+ )
359+ if self .netvm :
360+ self .fire_event (
361+ "property-set:netvm" ,
362+ name = "netvm" ,
363+ newvalue = self .netvm ,
364+ oldvalue = oldvalue ,
365+ )
366+ del self .features ["deferred-netvm-original" ]
367+
368+ @qubes .events .handler ("domain-unpaused" )
369+ def on_domain_unpaused_net (
370+ self , event , ** kwargs
371+ ): # pylint: disable=unused-argument
372+ """Check for deferred netvm changes in case qube was paused while
373+ changes happened."""
374+ if getattr (self , "is_preload" , False ):
375+ # Networking of preloaded disposable must be done when it is being
376+ # marked as used, so we guarantee that it finishes before the user
377+ # can use the disposable.
378+ return
379+ self .reset_deferred_netvm ()
380+
344381 @qubes .events .handler ("domain-pre-shutdown" )
345382 def on_domain_pre_shutdown (self , event , force = False ):
346383 """Checks before NetVM shutdown if any connected domains are running.
@@ -373,6 +410,12 @@ def attach_network(self):
373410 self .netvm .start ()
374411
375412 self .netvm .set_mapped_ip_info_for_vm (self )
413+
414+ if self .is_paused ():
415+ self .log .warning (
416+ "Deferred attaching libvirt net device because qube is paused"
417+ )
418+ return
376419 self .libvirt_domain .attachDevice (
377420 self .app .env .get_template ("libvirt/devices/net.xml" ).render (vm = self )
378421 )
@@ -387,6 +430,11 @@ def detach_network(self):
387430 self , "netvm should not be {}" .format (self .netvm )
388431 )
389432
433+ if self .is_paused ():
434+ self .log .warning (
435+ "Deferred detaching libvirt net device because qube is paused"
436+ )
437+ return
390438 self .libvirt_domain .detachDevice (
391439 self .app .env .get_template ("libvirt/devices/net.xml" ).render (vm = self )
392440 )
@@ -515,10 +563,18 @@ def on_property_pre_set_netvm(self, event, name, newvalue, oldvalue=None):
515563 ),
516564 )
517565
566+ if self .is_paused ():
567+ if "deferred-netvm-original" not in self .features :
568+ self .features ["deferred-netvm-original" ] = (
569+ oldvalue .name if oldvalue else None
570+ )
571+ return
518572 # don't check oldvalue, because it's missing if it was default
519- if self .netvm is not None :
520- if self .is_running () and self .netvm .is_running ():
521- self .detach_network ()
573+ if self .netvm is None :
574+ return
575+ if not (self .is_running () and self .netvm .is_running ()):
576+ return
577+ self .detach_network ()
522578
523579 @qubes .events .handler ("property-set:netvm" )
524580 def on_property_set_netvm (self , event , name , newvalue , oldvalue = None ):
@@ -539,7 +595,8 @@ def on_property_set_netvm(self, event, name, newvalue, oldvalue=None):
539595 if self .is_running ():
540596 # refresh IP, DNS etc
541597 self .create_qdb_entries ()
542- self .attach_network ()
598+ if not self .is_paused ():
599+ self .attach_network ()
543600
544601 newvalue .fire_event ("net-domain-connect" , vm = self )
545602
0 commit comments