factor out utils.void_coros_maybe()
This commit is contained in:
		
							parent
							
								
									fe97a15d11
								
							
						
					
					
						commit
						5b52d23478
					
				@ -507,16 +507,8 @@ class Storage:
 | 
				
			|||||||
    def create(self):
 | 
					    def create(self):
 | 
				
			||||||
        ''' Creates volumes on disk '''
 | 
					        ''' Creates volumes on disk '''
 | 
				
			||||||
        old_umask = os.umask(0o002)
 | 
					        old_umask = os.umask(0o002)
 | 
				
			||||||
 | 
					        yield from qubes.utils.void_coros_maybe(
 | 
				
			||||||
        coros = []
 | 
					            vol.create() for vol in self.vm.volumes.values())
 | 
				
			||||||
        for volume in self.vm.volumes.values():
 | 
					 | 
				
			||||||
            # launch the operation, if it's asynchronous, then append to wait
 | 
					 | 
				
			||||||
            #  for them at the end
 | 
					 | 
				
			||||||
            ret = volume.create()
 | 
					 | 
				
			||||||
            if asyncio.iscoroutine(ret):
 | 
					 | 
				
			||||||
                coros.append(ret)
 | 
					 | 
				
			||||||
        yield from _wait_and_reraise(coros)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        os.umask(old_umask)
 | 
					        os.umask(old_umask)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @asyncio.coroutine
 | 
					    @asyncio.coroutine
 | 
				
			||||||
@ -544,8 +536,9 @@ class Storage:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        self.vm.volumes = {}
 | 
					        self.vm.volumes = {}
 | 
				
			||||||
        with VmCreationManager(self.vm):
 | 
					        with VmCreationManager(self.vm):
 | 
				
			||||||
            yield from _wait_and_reraise([self.clone_volume(src_vm, vol_name)
 | 
					            yield from qubes.utils.void_coros_maybe(
 | 
				
			||||||
                for vol_name in self.vm.volume_config.keys()])
 | 
					                self.clone_volume(src_vm, vol_name)
 | 
				
			||||||
 | 
					                for vol_name in self.vm.volume_config.keys())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def outdated_volumes(self):
 | 
					    def outdated_volumes(self):
 | 
				
			||||||
@ -571,12 +564,8 @@ class Storage:
 | 
				
			|||||||
            raise qubes.exc.QubesVMError(
 | 
					            raise qubes.exc.QubesVMError(
 | 
				
			||||||
                self.vm,
 | 
					                self.vm,
 | 
				
			||||||
                'VM directory does not exist: {}'.format(self.vm.dir_path))
 | 
					                'VM directory does not exist: {}'.format(self.vm.dir_path))
 | 
				
			||||||
        futures = []
 | 
					        yield from qubes.utils.void_coros_maybe(
 | 
				
			||||||
        for volume in self.vm.volumes.values():
 | 
					            vol.verify() for vol in self.vm.volumes.values())
 | 
				
			||||||
            ret = volume.verify()
 | 
					 | 
				
			||||||
            if asyncio.iscoroutine(ret):
 | 
					 | 
				
			||||||
                futures.append(ret)
 | 
					 | 
				
			||||||
        yield from _wait_and_reraise(futures)
 | 
					 | 
				
			||||||
        self.vm.fire_event('domain-verify-files')
 | 
					        self.vm.fire_event('domain-verify-files')
 | 
				
			||||||
        return True
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -586,42 +575,29 @@ class Storage:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            Errors on removal are catched and logged.
 | 
					            Errors on removal are catched and logged.
 | 
				
			||||||
        '''
 | 
					        '''
 | 
				
			||||||
        futures = []
 | 
					        results = []
 | 
				
			||||||
        for name, volume in self.vm.volumes.items():
 | 
					        for vol in self.vm.volumes.values():
 | 
				
			||||||
            self.log.info('Removing volume %s: %s' % (name, volume.vid))
 | 
					            self.log.info('Removing volume %s: %s' % (vol.name, vol.vid))
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                ret = volume.remove()
 | 
					                results.append(vol.remove())
 | 
				
			||||||
                if asyncio.iscoroutine(ret):
 | 
					 | 
				
			||||||
                    futures.append(ret)
 | 
					 | 
				
			||||||
            except (IOError, OSError) as e:
 | 
					            except (IOError, OSError) as e:
 | 
				
			||||||
                self.vm.log.exception("Failed to remove volume %s", name, e)
 | 
					                self.vm.log.exception("Failed to remove volume %s", vol.name, e)
 | 
				
			||||||
 | 
					 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            yield from _wait_and_reraise(futures)
 | 
					            yield from qubes.utils.void_coros_maybe(results)
 | 
				
			||||||
        except (IOError, OSError) as e:
 | 
					        except (IOError, OSError) as e:
 | 
				
			||||||
            self.vm.log.exception("Failed to remove some volume", e)
 | 
					            self.vm.log.exception("Failed to remove some volume", e)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @asyncio.coroutine
 | 
					    @asyncio.coroutine
 | 
				
			||||||
    def start(self):
 | 
					    def start(self):
 | 
				
			||||||
        ''' Execute the start method on each volume '''
 | 
					        ''' Execute the start method on each volume '''
 | 
				
			||||||
        futures = []
 | 
					        yield from qubes.utils.void_coros_maybe(
 | 
				
			||||||
        for volume in self.vm.volumes.values():
 | 
					            vol.start() for vol in self.vm.volumes.values())
 | 
				
			||||||
            ret = volume.start()
 | 
					 | 
				
			||||||
            if asyncio.iscoroutine(ret):
 | 
					 | 
				
			||||||
                futures.append(ret)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        yield from _wait_and_reraise(futures)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @asyncio.coroutine
 | 
					    @asyncio.coroutine
 | 
				
			||||||
    def stop(self):
 | 
					    def stop(self):
 | 
				
			||||||
        ''' Execute the stop method on each volume '''
 | 
					        ''' Execute the stop method on each volume '''
 | 
				
			||||||
        futures = []
 | 
					        yield from qubes.utils.void_coros_maybe(
 | 
				
			||||||
        for volume in self.vm.volumes.values():
 | 
					            vol.stop() for vol in self.vm.volumes.values())
 | 
				
			||||||
            ret = volume.stop()
 | 
					 | 
				
			||||||
            if asyncio.iscoroutine(ret):
 | 
					 | 
				
			||||||
                futures.append(ret)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        yield from _wait_and_reraise(futures)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def unused_frontend(self):
 | 
					    def unused_frontend(self):
 | 
				
			||||||
        ''' Find an unused device name '''
 | 
					        ''' Find an unused device name '''
 | 
				
			||||||
@ -826,14 +802,6 @@ class Pool:
 | 
				
			|||||||
        return NotImplementedError(msg)
 | 
					        return NotImplementedError(msg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@asyncio.coroutine
 | 
					 | 
				
			||||||
def _wait_and_reraise(futures):
 | 
					 | 
				
			||||||
    if futures:
 | 
					 | 
				
			||||||
        done, _ = yield from asyncio.wait(futures)
 | 
					 | 
				
			||||||
        for task in done:  # (re-)raise first exception in line
 | 
					 | 
				
			||||||
            task.result()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def _sanitize_config(config):
 | 
					def _sanitize_config(config):
 | 
				
			||||||
    ''' Helper function to convert types to appropriate strings
 | 
					    ''' Helper function to convert types to appropriate strings
 | 
				
			||||||
    '''  # FIXME: find another solution for serializing basic types
 | 
					    '''  # FIXME: find another solution for serializing basic types
 | 
				
			||||||
 | 
				
			|||||||
@ -190,3 +190,16 @@ def coro_maybe(value):
 | 
				
			|||||||
    if asyncio.iscoroutine(value):
 | 
					    if asyncio.iscoroutine(value):
 | 
				
			||||||
        return (yield from value)
 | 
					        return (yield from value)
 | 
				
			||||||
    return value
 | 
					    return value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@asyncio.coroutine
 | 
				
			||||||
 | 
					def void_coros_maybe(values):
 | 
				
			||||||
 | 
					    ''' Ignore elements of the iterable values that are not coroutine
 | 
				
			||||||
 | 
					        objects. Run all coroutine objects to completion, in parallel
 | 
				
			||||||
 | 
					        to each other. If there were exceptions, re-raise the leftmost
 | 
				
			||||||
 | 
					        one (not necessarily chronologically first). Return nothing.
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
 | 
					    coros = [val for val in values if asyncio.iscoroutine(val)]
 | 
				
			||||||
 | 
					    if coros:
 | 
				
			||||||
 | 
					        done, _ = yield from asyncio.wait(coros)
 | 
				
			||||||
 | 
					        for task in done:
 | 
				
			||||||
 | 
					            task.result()  # re-raises exception if task failed
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user