pmbootstrap: kill process if silent for 5 minutes (rewrite logging)

This commit is contained in:
Oliver Smith 2018-07-14 01:13:28 +00:00
parent a9f149153a
commit 8268dc0e3d
31 changed files with 544 additions and 192 deletions

View file

@ -17,75 +17,7 @@ You should have received a copy of the GNU General Public License
along with pmbootstrap. If not, see <http://www.gnu.org/licenses/>.
"""
import shlex
import subprocess
import logging
import os
def core(args, cmd, log_message, log, return_stdout, check=True,
working_dir=None, background=False):
"""
Run the command and write the output to the log.
:param cmd: command as list, e.g. ["echo", "string with spaces"]
:param log_message: simplified and more readable form of the command, e.g.
"(native) % echo test" instead of the full command with
entering the chroot and more escaping
:param log: * True: write stdout and stderr of the running process into
the log file (read with "pmbootstrap log").
* False: redirect stdout and stderr to pmbootstrap stdout
:param return_stdout: write stdout to a buffer and return it as string when
the command is through
:param check: raise an exception, when the command fails
:param working_dir: path in host system where the command should run
:param background: run the process in the background and return the process
handler
:returns: * stdout when return_stdout is True
* process handler when background is True
* None otherwise
"""
logging.debug(log_message)
logging.verbose("run: " + str(cmd))
if working_dir:
working_dir_old = os.getcwd()
os.chdir(working_dir)
ret = None
if background:
if log:
ret = subprocess.Popen(cmd, stdout=args.logfd, stderr=args.logfd)
else:
ret = subprocess.Popen(cmd)
logging.debug("Started process in background with PID " + str(ret.pid))
else:
try:
if log:
if return_stdout:
ret = subprocess.check_output(cmd).decode("utf-8")
args.logfd.write(ret)
else:
subprocess.check_call(cmd, stdout=args.logfd,
stderr=args.logfd)
args.logfd.flush()
else:
logging.debug("*** output passed to pmbootstrap stdout, not" +
" to this log ***")
subprocess.check_call(cmd)
except subprocess.CalledProcessError as exc:
if check:
if log:
logging.debug("^" * 70)
logging.info("NOTE: The failed command's output is above"
" the ^^^ line in the logfile: " + args.log)
raise RuntimeError("Command failed: " + log_message) from exc
else:
pass
if working_dir:
os.chdir(working_dir_old)
return ret
import pmb.helpers.run_core
def flat_cmd(cmd, working_dir=None, env={}):
@ -117,24 +49,16 @@ def flat_cmd(cmd, working_dir=None, env={}):
return ret
def user(args, cmd, log=True, working_dir=None, return_stdout=False,
check=True, background=False, env={}):
def user(args, cmd, working_dir=None, output="log", output_return=False,
check=None, env={}, kill_as_root=False):
"""
Run a command on the host system as user.
:param cmd: command as list, e.g. ["echo", "string with spaces"]
:param log: when set to true, redirect all output to the logfile
:param working_dir: path in host system where the command should run
:param return_stdout: write stdout to a buffer and return it as string when
the command is through
:param check: raise an exception, when the command fails
:param background: run the process in the background and return the process
handler
:param env: dict of environment variables to be passed to the command, e.g.
{"JOBS": "5"}
:returns: * stdout when return_stdout is True
* process handler when background is True
* None otherwise
See pmb.helpers.run_core.core() for a detailed description of all other
arguments and the return value.
"""
# Readable log message (without all the escaping)
msg = "% "
@ -147,18 +71,23 @@ def user(args, cmd, log=True, working_dir=None, return_stdout=False,
# Add environment variables and run
if env:
cmd = ["sh", "-c", flat_cmd(cmd, env=env)]
return core(args, cmd, msg, log, return_stdout, check, working_dir,
background)
return pmb.helpers.run_core.core(args, msg, cmd, working_dir, output,
output_return, check, kill_as_root)
def root(args, cmd, log=True, working_dir=None, return_stdout=False,
check=True, background=False, env={}):
def root(args, cmd, working_dir=None, output="log", output_return=False,
check=None, env={}):
"""
Run a command on the host system as root, with sudo.
NOTE: See user() above for parameter descriptions.
:param env: dict of environment variables to be passed to the command, e.g.
{"JOBS": "5"}
See pmb.helpers.run_core.core() for a detailed description of all other
arguments and the return value.
"""
if env:
cmd = ["sh", "-c", flat_cmd(cmd, env=env)]
cmd = ["sudo"] + cmd
return user(args, cmd, log, working_dir, return_stdout, check, background)
return user(args, cmd, working_dir, output, output_return, check, env,
True)