import contextlib import os from six.moves.urllib.error import URLError from six.moves.urllib.request import urlopen from leapp.exceptions import StopActorExecutionError from leapp.libraries.stdlib import CalledProcessError @contextlib.contextmanager def guarded_execution(*guards): try: yield except CalledProcessError as e: # collect output from guards for possible spurious failure guard_errors = [] for guard in guards: err = guard() if err: guard_errors.append(err) details = None if guard_errors: details = { 'hint': 'Possible spurious failure: {cause}'.format(cause=' '.join(guard_errors)) } raise StopActorExecutionError( message=str(e), details=details ) def connection_guard(url='https://example.com'): def closure(): try: urlopen(url) return None except URLError as e: cause = '''Failed to open url '{url}' with error: {error}'''.format(url=url, error=e) return ('There was probably a problem with internet connection ({cause}).' ' Check your connection and try again.'.format(cause=cause)) return closure def space_guard(path='/', min_free_mb=100): def closure(): info = os.statvfs(path) free_mb = (info.f_bavail * info.f_frsize) >> 20 if free_mb >= min_free_mb: return None return ('''Not enough free disk space in '{path}', needed: {min} M, available: {avail} M.''' ' Free more disk space and try again.'.format(path=path, min=min_free_mb, avail=free_mb)) return closure