Hacked By AnonymousFox
# Copyright (C) 2017 Canonical Ltd.
#
# This file is part of cloud-init. See LICENSE file for license information.
"""Cloud-init apport interface"""
import json
import os
from cloudinit.cmd.devel import read_cfg_paths
from cloudinit.cmd.devel.logs import (
INSTALLER_APPORT_FILES,
INSTALLER_APPORT_SENSITIVE_FILES,
)
try:
from apport.hookutils import (
attach_file,
attach_file_if_exists,
attach_root_command_outputs,
root_command_output,
)
has_apport = True
except ImportError:
has_apport = False
KNOWN_CLOUD_NAMES = [
"AliYun",
"AltCloud",
"Akamai",
"Amazon - Ec2",
"Azure",
"Bigstep",
"Brightbox",
"CloudSigma",
"CloudStack",
"DigitalOcean",
"E24Cloud",
"GCE - Google Compute Engine",
"Huawei Cloud",
"Exoscale",
"Hetzner Cloud",
"NWCS",
"IBM - (aka SoftLayer or BlueMix)",
"LXD",
"MAAS",
"NoCloud",
"OpenNebula",
"OpenStack",
"Oracle",
"OVF",
"RbxCloud - (HyperOne, Rootbox, Rubikon)",
"OpenTelekomCloud",
"SAP Converged Cloud",
"Scaleway",
"SmartOS",
"UpCloud",
"VMware",
"Vultr",
"ZStack",
"Outscale",
"Other",
]
# Potentially clear text collected logs
CLOUDINIT_LOG = "/var/log/cloud-init.log"
CLOUDINIT_OUTPUT_LOG = "/var/log/cloud-init-output.log"
def _get_user_data_file() -> str:
paths = read_cfg_paths()
return paths.get_ipath_cur("userdata_raw")
def attach_cloud_init_logs(report, ui=None):
"""Attach cloud-init logs and tarfile from 'cloud-init collect-logs'."""
attach_root_command_outputs(
report,
{
"cloud-init-log-warnings": (
'egrep -i "warn|error" /var/log/cloud-init.log'
),
"cloud-init-output.log.txt": "cat /var/log/cloud-init-output.log",
},
)
root_command_output(
["cloud-init", "collect-logs", "-t", "/tmp/cloud-init-logs.tgz"]
)
attach_file(report, "/tmp/cloud-init-logs.tgz", "logs.tgz")
def attach_hwinfo(report, ui=None):
"""Optionally attach hardware info from lshw."""
prompt = (
"Your device details (lshw) may be useful to developers when"
" addressing this bug, but gathering it requires admin privileges."
" Would you like to include this info?"
)
if ui and ui.yesno(prompt):
attach_root_command_outputs(report, {"lshw.txt": "lshw"})
def attach_cloud_info(report, ui=None):
"""Prompt for cloud details if instance-data unavailable.
When we have valid _get_instance_data, apport/generic-hooks/cloud_init.py
provides CloudName, CloudID, CloudPlatform and CloudSubPlatform.
Apport/generic-hooks are delivered by cloud-init's downstream branches
ubuntu/(devel|kinetic|jammy|focal|bionic) so they will not be represented
in upstream main.
In absence of viable instance-data.json format, prompt for the cloud below.
"""
if ui:
paths = read_cfg_paths()
try:
with open(paths.get_runpath("instance_data")) as file:
instance_data = json.load(file)
assert instance_data.get("v1", {}).get("cloud_name")
return # Valid instance-data means generic-hooks will report
except (IOError, json.decoder.JSONDecodeError, AssertionError):
pass
# No valid /run/cloud/instance-data.json on system. Prompt for cloud.
prompt = "Is this machine running in a cloud environment?"
response = ui.yesno(prompt)
if response is None:
raise StopIteration # User cancelled
if response:
prompt = (
"Please select the cloud vendor or environment in which"
" this instance is running"
)
response = ui.choice(prompt, KNOWN_CLOUD_NAMES)
if response:
report["CloudName"] = KNOWN_CLOUD_NAMES[response[0]]
else:
report["CloudName"] = "None"
def attach_installer_files(report, ui=None):
"""Attach any subiquity installer logs config.
To support decoupling apport integration from installer config/logs,
we eventually want to either source this function or APPORT_FILES
attribute from subiquity and/or ubuntu-desktop-installer package-hooks
python modules.
"""
for apport_file in INSTALLER_APPORT_FILES:
realpath = os.path.realpath(apport_file.path)
attach_file_if_exists(report, realpath, apport_file.label)
def attach_ubuntu_pro_info(report, ui=None):
"""Attach ubuntu pro logs and tag if keys present in user-data."""
realpath = os.path.realpath("/var/log/ubuntu-advantage.log")
attach_file_if_exists(report, realpath)
if os.path.exists(realpath):
report.setdefault("Tags", "")
if report["Tags"]:
report["Tags"] += " "
report["Tags"] += "ubuntu-pro"
def attach_user_data(report, ui=None):
"""Optionally provide user-data if desired."""
if ui:
user_data_file = _get_user_data_file()
prompt = (
"Your user-data, cloud-config or autoinstall files can optionally "
" be provided from {0} and could be useful to developers when"
" addressing this bug. Do you wish to attach user-data to this"
" bug?".format(user_data_file)
)
response = ui.yesno(prompt)
if response is None:
raise StopIteration # User cancelled
if response:
realpath = os.path.realpath(user_data_file)
attach_file(report, realpath, "user_data.txt")
for apport_file in INSTALLER_APPORT_SENSITIVE_FILES:
realpath = os.path.realpath(apport_file.path)
attach_file_if_exists(report, realpath, apport_file.label)
def add_bug_tags(report):
"""Add any appropriate tags to the bug."""
new_tags = []
if report.get("CurtinError"):
new_tags.append("curtin")
if report.get("SubiquityLog"):
new_tags.append("subiquity")
if "JournalErrors" in report.keys():
errors = report["JournalErrors"]
if "Breaking ordering cycle" in errors:
new_tags.append("systemd-ordering")
if report.get("UdiLog"):
new_tags.append("ubuntu-desktop-installer")
if new_tags:
report.setdefault("Tags", "")
if report["Tags"]:
report["Tags"] += " "
report["Tags"] += " ".join(new_tags)
def add_info(report, ui):
"""This is an entry point to run cloud-init's apport functionality.
Distros which want apport support will have a cloud-init package-hook at
/usr/share/apport/package-hooks/cloud-init.py which defines an add_info
function and returns the result of cloudinit.apport.add_info(report, ui).
"""
if not has_apport:
raise RuntimeError(
"No apport imports discovered. Apport functionality disabled"
)
attach_cloud_init_logs(report, ui)
attach_hwinfo(report, ui)
attach_cloud_info(report, ui)
attach_user_data(report, ui)
attach_installer_files(report, ui)
attach_ubuntu_pro_info(report, ui)
add_bug_tags(report)
return True
Hacked By AnonymousFox1.0, Coded By AnonymousFox