root.py 3.26 KB
Newer Older
Oliver Smith's avatar
Oliver Smith committed
1
"""
Oliver Smith's avatar
Oliver Smith committed
2
Copyright 2019 Oliver Smith
Oliver Smith's avatar
Oliver Smith committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

This file is part of pmbootstrap.

pmbootstrap is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

pmbootstrap is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with pmbootstrap.  If not, see <http://www.gnu.org/licenses/>.
"""
import os
import shutil

import pmb.config
import pmb.chroot
import pmb.chroot.binfmt
import pmb.helpers.run
26
import pmb.helpers.run_core
Oliver Smith's avatar
Oliver Smith committed
27 28


29 30 31 32 33 34
def executables_absolute_path():
    """
    Get the absolute paths to the sh and chroot executables.
    """
    ret = {}
    for binary in ["sh", "chroot"]:
35
        path = shutil.which(binary, path=pmb.config.chroot_host_path)
36 37 38 39 40 41 42
        if not path:
            raise RuntimeError("Could not find the '" + binary +
                               "' executable. Make sure, that it is in" " your current user's PATH.")
        ret[binary] = path
    return ret


43 44
def root(args, cmd, suffix="native", working_dir="/", output="log",
         output_return=False, check=None, env={}, auto_init=True):
Oliver Smith's avatar
Oliver Smith committed
45 46 47
    """
    Run a command inside a chroot as root.

48 49
    :param env: dict of environment variables to be passed to the command, e.g.
                {"JOBS": "5"}
50 51 52 53
    :param auto_init: automatically initialize the chroot

    See pmb.helpers.run_core.core() for a detailed description of all other
    arguments and the return value.
Oliver Smith's avatar
Oliver Smith committed
54
    """
55
    # Initialize chroot
Oliver Smith's avatar
Oliver Smith committed
56 57 58
    chroot = args.work + "/chroot_" + suffix
    if not auto_init and not os.path.islink(chroot + "/bin/sh"):
        raise RuntimeError("Chroot does not exist: " + chroot)
59 60
    if auto_init:
        pmb.chroot.init(args, suffix)
Oliver Smith's avatar
Oliver Smith committed
61

62 63 64 65
    # Readable log message (without all the escaping)
    msg = "(" + suffix + ") % "
    for key, value in env.items():
        msg += key + "=" + value + " "
Oliver Smith's avatar
Oliver Smith committed
66
    if working_dir != "/":
67 68 69 70 71 72
        msg += "cd " + working_dir + "; "
    msg += " ".join(cmd)

    # Merge env with defaults into env_all
    env_all = {"CHARSET": "UTF-8",
               "HISTFILE": "~/.ash_history",
73
               "HOME": "/root",
74 75 76 77 78
               "PATH": pmb.config.chroot_path,
               "SHELL": "/bin/ash",
               "TERM": "xterm"}
    for key, value in env.items():
        env_all[key] = value
Oliver Smith's avatar
Oliver Smith committed
79

80 81 82 83 84 85 86 87 88
    # Build the command in steps and run it, e.g.:
    # cmd: ["echo", "test"]
    # cmd_chroot: ["/sbin/chroot", "/..._native", "/bin/sh", "-c", "echo test"]
    # cmd_sudo: ["sudo", "env", "-i", "sh", "-c", "PATH=... /sbin/chroot ..."]
    executables = executables_absolute_path()
    cmd_chroot = [executables["chroot"], chroot, "/bin/sh", "-c",
                  pmb.helpers.run.flat_cmd(cmd, working_dir)]
    cmd_sudo = ["sudo", "env", "-i", executables["sh"], "-c",
                pmb.helpers.run.flat_cmd(cmd_chroot, env=env_all)]
89 90 91
    kill_as_root = output in ["log", "stdout"]
    return pmb.helpers.run_core.core(args, msg, cmd_sudo, None, output,
                                     output_return, check, kill_as_root)