+def captureOutput(popen_args, stdin_str=None, *args, **kwargs):
+ """Capture stdout from a command.
+
+ This method will proxy the arguments to subprocess.Popen. It
+ returns the output from the command if the call succeeded and
+ raises an exception if the process returns a non-0 value.
+
+ This is intended to be a variant on the subprocess.check_call
+ function that also allows you access to the output from the
+ command.
+ """
+ if 'stdin' not in kwargs:
+ kwargs['stdin'] = subprocess.PIPE
+ if 'stdout' not in kwargs:
+ kwargs['stdout'] = subprocess.PIPE
+ if 'stderr' not in kwargs:
+ kwargs['stderr'] = subprocess.STDOUT
+ p = subprocess.Popen(popen_args, *args, **kwargs)
+ out, _ = p.communicate(stdin_str)
+ if p.returncode:
+ raise subprocess.CalledProcessError(p.returncode, popen_args, out)
+ return out
+
+#
+# Exceptions.
+#
+
+class InvalidInput(Exception):
+ """Exception for user-provided input is invalid but maybe in good faith.
+
+ This would include setting memory to negative (which might be a
+ typo) but not setting an invalid boot CD (which requires bypassing
+ the select box).
+ """
+ def __init__(self, err_field, err_value, expl=None):
+ Exception.__init__(self, expl)
+ self.err_field = err_field
+ self.err_value = err_value
+
+class CodeError(Exception):
+ """Exception for internal errors or bad faith input."""
+ pass
+