1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
# Copyright (C) 2017 Canonical Ltd.
#
# This file is part of cloud-init. See LICENSE file for license information.
'''Cloud-init apport interface'''
try:
from apport.hookutils import (
attach_file, attach_root_command_outputs, root_command_output)
has_apport = True
except ImportError:
has_apport = False
KNOWN_CLOUD_NAMES = [
'AliYun',
'AltCloud',
'Amazon - Ec2',
'Azure',
'Bigstep',
'Brightbox',
'CloudSigma',
'CloudStack',
'DigitalOcean',
'E24Cloud',
'GCE - Google Compute Engine',
'Exoscale',
'Hetzner Cloud',
'IBM - (aka SoftLayer or BlueMix)',
'LXD',
'MAAS',
'NoCloud',
'OpenNebula',
'OpenStack',
'Oracle',
'OVF',
'OpenTelekomCloud',
'Scaleway',
'SmartOS',
'VMware',
'ZStack',
'Other']
# Potentially clear text collected logs
CLOUDINIT_LOG = '/var/log/cloud-init.log'
CLOUDINIT_OUTPUT_LOG = '/var/log/cloud-init-output.log'
USER_DATA_FILE = '/var/lib/cloud/instance/user-data.txt' # Optional
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 available.'''
if ui:
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_user_data(report, ui=None):
'''Optionally provide user-data if desired.'''
if ui:
prompt = (
'Your user-data or cloud-config file 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:
attach_file(report, USER_DATA_FILE, 'user_data.txt')
def add_bug_tags(report):
'''Add any appropriate tags to the bug.'''
if 'JournalErrors' in report.keys():
errors = report['JournalErrors']
if 'Breaking ordering cycle' in errors:
report['Tags'] = 'systemd-ordering'
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)
add_bug_tags(report)
return True
# vi: ts=4 expandtab
|