factor out utils.void_coros_maybe()
This commit is contained in:
		
							parent
							
								
									fe97a15d11
								
							
						
					
					
						commit
						5b52d23478
					
				@ -507,16 +507,8 @@ class Storage:
 | 
			
		||||
    def create(self):
 | 
			
		||||
        ''' Creates volumes on disk '''
 | 
			
		||||
        old_umask = os.umask(0o002)
 | 
			
		||||
 | 
			
		||||
        coros = []
 | 
			
		||||
        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)
 | 
			
		||||
 | 
			
		||||
        yield from qubes.utils.void_coros_maybe(
 | 
			
		||||
            vol.create() for vol in self.vm.volumes.values())
 | 
			
		||||
        os.umask(old_umask)
 | 
			
		||||
 | 
			
		||||
    @asyncio.coroutine
 | 
			
		||||
@ -544,8 +536,9 @@ class Storage:
 | 
			
		||||
 | 
			
		||||
        self.vm.volumes = {}
 | 
			
		||||
        with VmCreationManager(self.vm):
 | 
			
		||||
            yield from _wait_and_reraise([self.clone_volume(src_vm, vol_name)
 | 
			
		||||
                for vol_name in self.vm.volume_config.keys()])
 | 
			
		||||
            yield from qubes.utils.void_coros_maybe(
 | 
			
		||||
                self.clone_volume(src_vm, vol_name)
 | 
			
		||||
                for vol_name in self.vm.volume_config.keys())
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def outdated_volumes(self):
 | 
			
		||||
@ -571,12 +564,8 @@ class Storage:
 | 
			
		||||
            raise qubes.exc.QubesVMError(
 | 
			
		||||
                self.vm,
 | 
			
		||||
                'VM directory does not exist: {}'.format(self.vm.dir_path))
 | 
			
		||||
        futures = []
 | 
			
		||||
        for volume in self.vm.volumes.values():
 | 
			
		||||
            ret = volume.verify()
 | 
			
		||||
            if asyncio.iscoroutine(ret):
 | 
			
		||||
                futures.append(ret)
 | 
			
		||||
        yield from _wait_and_reraise(futures)
 | 
			
		||||
        yield from qubes.utils.void_coros_maybe(
 | 
			
		||||
            vol.verify() for vol in self.vm.volumes.values())
 | 
			
		||||
        self.vm.fire_event('domain-verify-files')
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
@ -586,42 +575,29 @@ class Storage:
 | 
			
		||||
 | 
			
		||||
            Errors on removal are catched and logged.
 | 
			
		||||
        '''
 | 
			
		||||
        futures = []
 | 
			
		||||
        for name, volume in self.vm.volumes.items():
 | 
			
		||||
            self.log.info('Removing volume %s: %s' % (name, volume.vid))
 | 
			
		||||
        results = []
 | 
			
		||||
        for vol in self.vm.volumes.values():
 | 
			
		||||
            self.log.info('Removing volume %s: %s' % (vol.name, vol.vid))
 | 
			
		||||
            try:
 | 
			
		||||
                ret = volume.remove()
 | 
			
		||||
                if asyncio.iscoroutine(ret):
 | 
			
		||||
                    futures.append(ret)
 | 
			
		||||
                results.append(vol.remove())
 | 
			
		||||
            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:
 | 
			
		||||
            yield from _wait_and_reraise(futures)
 | 
			
		||||
            yield from qubes.utils.void_coros_maybe(results)
 | 
			
		||||
        except (IOError, OSError) as e:
 | 
			
		||||
            self.vm.log.exception("Failed to remove some volume", e)
 | 
			
		||||
 | 
			
		||||
    @asyncio.coroutine
 | 
			
		||||
    def start(self):
 | 
			
		||||
        ''' Execute the start method on each volume '''
 | 
			
		||||
        futures = []
 | 
			
		||||
        for volume in self.vm.volumes.values():
 | 
			
		||||
            ret = volume.start()
 | 
			
		||||
            if asyncio.iscoroutine(ret):
 | 
			
		||||
                futures.append(ret)
 | 
			
		||||
 | 
			
		||||
        yield from _wait_and_reraise(futures)
 | 
			
		||||
        yield from qubes.utils.void_coros_maybe(
 | 
			
		||||
            vol.start() for vol in self.vm.volumes.values())
 | 
			
		||||
 | 
			
		||||
    @asyncio.coroutine
 | 
			
		||||
    def stop(self):
 | 
			
		||||
        ''' Execute the stop method on each volume '''
 | 
			
		||||
        futures = []
 | 
			
		||||
        for volume in self.vm.volumes.values():
 | 
			
		||||
            ret = volume.stop()
 | 
			
		||||
            if asyncio.iscoroutine(ret):
 | 
			
		||||
                futures.append(ret)
 | 
			
		||||
 | 
			
		||||
        yield from _wait_and_reraise(futures)
 | 
			
		||||
        yield from qubes.utils.void_coros_maybe(
 | 
			
		||||
            vol.stop() for vol in self.vm.volumes.values())
 | 
			
		||||
 | 
			
		||||
    def unused_frontend(self):
 | 
			
		||||
        ''' Find an unused device name '''
 | 
			
		||||
@ -826,14 +802,6 @@ class Pool:
 | 
			
		||||
        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):
 | 
			
		||||
    ''' Helper function to convert types to appropriate strings
 | 
			
		||||
    '''  # FIXME: find another solution for serializing basic types
 | 
			
		||||
 | 
			
		||||
@ -190,3 +190,16 @@ def coro_maybe(value):
 | 
			
		||||
    if asyncio.iscoroutine(value):
 | 
			
		||||
        return (yield from 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