The current run_cmd and run_cmd_qa functions have a very confusing API, and their implementation is ancient (dates back from a time when we still supported Python 2.4).
We should implement a new run function, which supports running both interactive and non-interactive commands, as well as more advanced features like running a command asynchronously, and providing support to drop into an interactive shell when a command failed.