def external_program_check(to_check=frozenset([PSQL_BIN, LZOP_BIN, PV_BIN])): """ Validates the existence and basic working-ness of other programs Implemented because it is easy to get confusing error output when one does not install a dependency because of the fork-worker model that is both necessary for throughput and makes more obscure the cause of failures. This is intended to be a time and frustration saving measure. This problem has confused The Author in practice when switching rapidly between machines. """ could_not_run = [] error_msgs = [] def psql_err_handler(popen): assert popen.returncode != 0 error_msgs.append( textwrap.fill("Could not get a connection to the database: " "note that superuser access is required") ) # Bogus error message that is re-caught and re-raised raise Exception("INTERNAL: Had problems running psql " "from external_program_check") with open(os.devnull, "w") as nullf: for program in to_check: try: if program is PSQL_BIN: psql_csv_run("SELECT 1", error_handler=psql_err_handler) else: if program is PV_BIN: extra_args = ["--quiet"] else: extra_args = [] proc = popen_sp([program] + extra_args, stdout=nullf, stderr=nullf, stdin=subprocess.PIPE) # Close stdin for processes that default to # reading from the pipe; the programs WAL-E uses # of this kind will terminate in this case. proc.stdin.close() proc.wait() except EnvironmentError: could_not_run.append(program) if could_not_run: error_msgs.append("Could not run the following programs, are they installed? " + ", ".join(could_not_run)) if error_msgs: raise UserException("could not run one or more external programs WAL-E depends upon", "\n".join(error_msgs)) return None
def external_program_check(to_check=frozenset([PSQL_BIN, LZOP_BIN, PV_BIN])): """ Validates the existence and basic working-ness of other programs Implemented because it is easy to get confusing error output when one does not install a dependency because of the fork-worker model that is both necessary for throughput and makes more obscure the cause of failures. This is intended to be a time and frustration saving measure. This problem has confused The Author in practice when switching rapidly between machines. """ could_not_run = [] error_msgs = [] def psql_err_handler(popen): assert popen.returncode != 0 error_msgs.append( textwrap.fill('Could not get a connection to the database: ' 'note that superuser access is required')) # Bogus error message that is re-caught and re-raised raise EnvironmentError('INTERNAL: Had problems running psql ' 'from external_program_check') with open(os.devnull, 'w') as nullf: for program in to_check: try: if program is PSQL_BIN: psql_csv_run('SELECT 1', error_handler=psql_err_handler) else: if program is PV_BIN: extra_args = ['--quiet'] else: extra_args = [] proc = popen_sp([program] + extra_args, stdout=nullf, stderr=nullf, stdin=subprocess.PIPE) # Close stdin for processes that default to # reading from the pipe; the programs WAL-E uses # of this kind will terminate in this case. proc.stdin.close() proc.wait() except EnvironmentError: could_not_run.append(program) if could_not_run: error_msgs.append( 'Could not run the following programs, are they installed? ' + ', '.join(could_not_run)) if error_msgs: raise UserException( 'could not run one or more external programs WAL-E depends upon', '\n'.join(error_msgs)) return None