%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /bin/X11/
Upload File :
Create Path :
Current File : //bin/X11/oem-getlogs

#!/usr/bin/python3

"""Get Hardware Enablement related logs"""

# TODO: Address following pylint complaints
# pylint: disable=invalid-name,missing-function-docstring

import gzip
import os
import re
import shutil
import subprocess
import sys
import tempfile
import time
import zipfile
from argparse import ArgumentParser
from glob import glob
from io import BytesIO

import apport
from apport import hookutils
from problem_report import CompressedValue

opt_debug = False


# Apport helper routines
def debug(text):
    if opt_debug:
        print(f"{text}\n")


def attach_command_output(report, command_list, key):
    debug(" ".join(command_list))
    log = hookutils.command_output(command_list)
    if not log or log[:5] == "Error":
        return
    report[key] = log


def attach_pathglob_as_zip(report, pathglob, key, data_filter=None, mode="b"):
    """Use zip file here because tarfile module in linux can't
    properly handle file size 0 with content in /sys directory like
    edid file. zipfile module works fine here. So we use it.

    mode:
         a: for ascii  mode of data
         b: for binary mode of data
    """
    filelist = []
    for pg in pathglob:
        for file in glob(pg):
            filelist.append(file)

    zipf = BytesIO()
    with zipfile.ZipFile(zipf, mode="w", compression=zipfile.ZIP_DEFLATED) as zipobj:
        for f in filelist:
            if opt_debug:
                print(key, f)
            if not os.path.isfile(f):
                if opt_debug:
                    print(f, "is not a file")
                continue
            if mode == "a":
                with open(f, encoding="ascii") as f_fd:
                    data = f_fd.read()
                    if data_filter is None:
                        zipobj.writestr(f, data)
                    else:
                        zipobj.writestr(f, data_filter(data))
            else:
                zipobj.write(f)
    cvalue = CompressedValue()
    cvalue.set_value(zipf.getbuffer())
    report[key + ".zip"] = cvalue


def attach_nvidia_debug_logs(report, keep_locale=False):
    # check if nvidia-bug-report.sh exists
    nv_debug_command = "nvidia-bug-report.sh"

    if shutil.which(nv_debug_command) is None:
        if opt_debug:
            print(nv_debug_command, "does not exist.")
        return

    env = os.environ.copy()
    if not keep_locale:
        env["LC_MESSAGES"] = "C"

    # output result to temp directory
    nv_tempdir = tempfile.mkdtemp()
    nv_debug_file = "nvidia-bug-report"
    nv_debug_fullfile = os.path.join(nv_tempdir, nv_debug_file)
    nv_debug_cmd = [nv_debug_command, "--output-file", nv_debug_fullfile]
    try:
        subprocess.run(
            nv_debug_cmd,
            env=env,
            check=False,
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL,
        )
        nv_debug_fullfile_gz = nv_debug_fullfile + ".gz"
        hookutils.attach_file_if_exists(
            report, nv_debug_fullfile_gz, "nvidia-bug-report.gz"
        )
        os.unlink(nv_debug_fullfile_gz)
        os.rmdir(nv_tempdir)
    except OSError as e:
        print("Error:", str(e))
        print("Fail on cleanup", nv_tempdir, ". Please file a bug for it.")


def dot():
    print(".", end="", flush=True)


def build_packages():
    # related packages
    packages = ["apt", "grub2"]

    # display
    packages.append("xorg")
    packages.append("gnome-shell")

    # audio
    packages.append("alsa-base")

    # hotkey and hotplugs
    packages.append("udev")

    # networking issues
    packages.append("network-manager")

    return packages


def helper_url_credential_filter(string_with_urls):
    return re.sub(r"://\w+?:\w+?@", "://USER:SECRET@", string_with_urls)


def add_info(report):
    # Check if the DCD file is exist in the installer.
    attach_command_output(report, ["ubuntu-report", "show"], "UbuntuReport")
    dot()
    hookutils.attach_file_if_exists(report, "/etc/buildstamp", "BuildStamp")
    dot()
    attach_pathglob_as_zip(
        report,
        ["/sys/firmware/acpi/tables/*", "/sys/firmware/acpi/tables/*/*"],
        "acpitables",
    )
    dot()

    # Basic hardare information
    hookutils.attach_hardware(report)
    dot()
    hookutils.attach_wifi(report)
    dot()

    hwe_system_commands = {
        "lspci--xxxx": ["lspci", "-xxxx"],
        "lshw.json": ["lshw", "-json", "-numeric"],
        "dmidecode": ["dmidecode"],
        "fwupdmgr_get-devices": [
            "fwupdmgr",
            "get-devices",
            "--show-all-devices",
            "--no-unreported-check",
        ],
        "boltctl-list": ["boltctl", "list"],
        "mokutil---sb-state": ["mokutil", "--sb-state"],
        "tlp-stat": ["tlp-stat"],
    }
    for name, command_list in hwe_system_commands.items():
        attach_command_output(report, command_list, name)
        dot()

    # More audio related
    hookutils.attach_alsa(report)
    dot()
    audio_system_commands = {
        "pactl-list": ["pactl", "list"],
        "aplay-l": ["aplay", "-l"],
        "aplay-L": ["aplay", "-L"],
        "arecord-l": ["arecord", "-l"],
        "arecord-L": ["arecord", "-L"],
    }
    for name, command_list in audio_system_commands.items():
        attach_command_output(report, command_list, name)
        dot()
    attach_pathglob_as_zip(
        report,
        [
            "/usr/share/alsa/ucm/*/*",
            "/usr/share/alsa/ucm2/*",
            "/usr/share/alsa/ucm2/*/*",
            "/usr/share/alsa/ucm2/*/*/*",
        ],
        "ALSA-UCM",
    )
    dot()

    # FIXME: should be included in xorg in the future
    gfx_system_commands = {
        "glxinfo": ["glxinfo"],
        "xrandr": ["xrandr"],
        "xinput": ["xinput"],
    }
    for name, command_list in gfx_system_commands.items():
        attach_command_output(report, command_list, name)
        dot()
    attach_pathglob_as_zip(report, ["/sys/devices/*/*/drm/card?/*/edid"], "EDID")
    dot()

    # nvidia-bug-reports.sh
    attach_nvidia_debug_logs(report)
    dot()

    # FIXME: should be included in thermald in the future
    attach_pathglob_as_zip(
        report,
        ["/etc/thermald/*", "/sys/devices/virtual/thermal/*", "/sys/class/thermal/*"],
        "THERMALD",
    )
    dot()

    # all kernel and system messages
    attach_pathglob_as_zip(report, ["/var/log/*", "/var/log/*/*"], "VAR_LOG")
    dot()

    # apt configs
    attach_pathglob_as_zip(
        report,
        [
            "/etc/apt/apt.conf.d/*",
            "/etc/apt/sources.list",
            "/etc/apt/sources.list.d/*.list",
            "/etc/apt/preferences.d/*",
        ],
        "APT_CONFIGS",
        mode="a",
        data_filter=helper_url_credential_filter,
    )
    dot()

    # TODO: debug information for suspend or hibernate

    # packages installed.
    attach_command_output(report, ["dpkg", "-l"], "dpkg-l")
    dot()

    # FIXME: should be included in bluez in the future
    attach_command_output(report, ["hciconfig", "-a"], "hciconfig-a")
    dot()

    # FIXME: should be included in dkms in the future
    attach_command_output(report, ["dkms", "status"], "dkms_status")
    dot()

    # enable when the feature to include data from package hooks exists.
    # packages = build_packages()
    # attach_related_packages(report, packages)


def main():
    parser = ArgumentParser(
        prog="oem-getlogs",
        usage="Useage: sudo -E oem-getlogs [-c CASE_ID]",
        description=__doc__,
    )
    parser.add_argument(
        "-c", "--case-id", help="optional CASE_ID", dest="cid", default=""
    )
    args = parser.parse_args()

    # check if we got root permission
    if os.geteuid() != 0:
        print("Error: you need to run this program as root")
        parser.print_help()
        sys.exit(1)

    print("Start to collect logs: ", end="", flush=True)
    # create report
    report = apport.Report()
    add_info(report)

    # generate filename
    hostname = os.uname()[1]
    date_time = time.strftime("%Y%m%d%H%M%S%z", time.localtime())
    filename_lst = ["oemlogs", hostname]
    if len(args.cid) > 0:
        filename_lst.append(args.cid)
    filename_lst.append(date_time + ".apport.gz")
    filename = "-".join(filename_lst)

    with gzip.open(filename, "wb") as f:
        report.write(f)
    print("\nSaved log to", filename)
    print("The owner of the file is root. You might want to")
    print("    chown [user]:[group]", filename)


if __name__ == "__main__":
    main()

Zerion Mini Shell 1.0