mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-26 07:22:20 +00:00
Merge pull request #93 from jodh-intel/add-data-collection-script
scripts: Add data collection script
This commit is contained in:
commit
adf7b536cb
17
.github/ISSUE_TEMPLATE.md
vendored
Normal file
17
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
# Description of problem
|
||||
|
||||
(replace this text with the list of steps you followed)
|
||||
|
||||
# Expected result
|
||||
|
||||
(replace this text with an explanation of what you thought would happen)
|
||||
|
||||
# Actual result
|
||||
|
||||
(replace this text with details of what actually happened)
|
||||
|
||||
---
|
||||
|
||||
(replace this text with the output of the `kata-collect-data.sh` script, after
|
||||
you have reviewed its content to ensure it does not contain any private
|
||||
information).
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
/build-runv
|
||||
/kata-runtime
|
||||
/data/kata-collect-data.sh
|
||||
|
11
Makefile
11
Makefile
@ -64,6 +64,13 @@ LIBEXECDIR := $(PREFIX)/libexec
|
||||
SHAREDIR := $(PREFIX)/share
|
||||
DEFAULTSDIR := $(SHAREDIR)/defaults
|
||||
|
||||
COLLECT_SCRIPT = data/kata-collect-data.sh
|
||||
COLLECT_SCRIPT_SRC = $(COLLECT_SCRIPT).in
|
||||
|
||||
GENERATED_FILES += $(COLLECT_SCRIPT)
|
||||
SCRIPTS += $(COLLECT_SCRIPT)
|
||||
SCRIPTS_DIR := $(BINDIR)
|
||||
|
||||
PKGDATADIR := $(SHAREDIR)/$(PROJECT_DIR)
|
||||
PKGLIBDIR := $(LOCALSTATEDIR)/lib/$(PROJECT_DIR)
|
||||
PKGRUNDIR := $(LOCALSTATEDIR)/run/$(PROJECT_DIR)
|
||||
@ -124,8 +131,6 @@ DESTSYSCONFIG := $(abspath $(DESTSYSCONFDIR)/$(CONFIG_FILE))
|
||||
|
||||
DESTSHAREDIR := $(DESTDIR)/$(SHAREDIR)
|
||||
|
||||
SCRIPTS_DIR := $(BINDIR)
|
||||
|
||||
# list of variables the user may wish to override
|
||||
USER_VARS += ARCH
|
||||
USER_VARS += BINDIR
|
||||
@ -380,7 +385,7 @@ install-scripts:
|
||||
$(foreach f,$(SCRIPTS),$(call INSTALL_EXEC,$f,$(SCRIPTS_DIR)))
|
||||
|
||||
clean:
|
||||
$(QUIET_CLEAN)rm -f $(TARGET) $(CONFIG) $(GENERATED_GO_FILES) $(GENERATED_FILES)
|
||||
$(QUIET_CLEAN)rm -f $(TARGET) $(CONFIG) $(GENERATED_GO_FILES) $(GENERATED_FILES) $(COLLECT_SCRIPT)
|
||||
|
||||
show-usage: show-header
|
||||
@printf "• Overview:\n"
|
||||
|
561
data/kata-collect-data.sh.in
Normal file
561
data/kata-collect-data.sh.in
Normal file
@ -0,0 +1,561 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2017-2018 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
script_name=${0##*/}
|
||||
runtime_name="@RUNTIME_NAME@"
|
||||
runtime=$(command -v "$runtime_name" 2>/dev/null)
|
||||
issue_url="@PROJECT_BUG_URL@"
|
||||
script_version="@VERSION@ (commit @COMMIT@)"
|
||||
|
||||
typeset -r unknown="unknown"
|
||||
|
||||
# Maximum number of errors to show for a single system component
|
||||
# (such as runtime or proxy).
|
||||
PROBLEM_LIMIT=${PROBLEM_LIMIT:-50}
|
||||
|
||||
# List of patterns used to detect problems in logfiles.
|
||||
problem_pattern="("
|
||||
problem_pattern+="\<abort|"
|
||||
problem_pattern+="\<bug\>|"
|
||||
problem_pattern+="\<cannot\>|"
|
||||
problem_pattern+="\<catastrophic|"
|
||||
problem_pattern+="\<could not\>|"
|
||||
problem_pattern+="\<couldn\'t\>|"
|
||||
problem_pattern+="\<critical|"
|
||||
problem_pattern+="\<die\>|"
|
||||
problem_pattern+="\<died\>|"
|
||||
problem_pattern+="\<does.*not.*exist\>|"
|
||||
problem_pattern+="\<dying\>|"
|
||||
problem_pattern+="\<empty\>|"
|
||||
problem_pattern+="\<erroneous|"
|
||||
problem_pattern+="\<error|"
|
||||
problem_pattern+="\<expected\>|"
|
||||
problem_pattern+="\<fail|"
|
||||
problem_pattern+="\<fatal|"
|
||||
problem_pattern+="\<impossible\>|"
|
||||
problem_pattern+="\<impossibly\>|"
|
||||
problem_pattern+="\<incorrect|"
|
||||
problem_pattern+="\<invalid\>|"
|
||||
problem_pattern+="\<level=\"*error\"* |"
|
||||
problem_pattern+="\<level=\"*fatal\"* |"
|
||||
problem_pattern+="\<level=\"*panic\"* |"
|
||||
problem_pattern+="\<level=\"*warning\"* |"
|
||||
problem_pattern+="\<missing\>|"
|
||||
problem_pattern+="\<need\>|"
|
||||
problem_pattern+="\<no.*such.*file\>|"
|
||||
problem_pattern+="\<not.*found\>|"
|
||||
problem_pattern+="\<not.*supported\>|"
|
||||
problem_pattern+="\<too many\>|"
|
||||
problem_pattern+="\<unable\>|"
|
||||
problem_pattern+="\<unavailable\>|"
|
||||
problem_pattern+="\<unexpected|"
|
||||
problem_pattern+="\<unknown\>|"
|
||||
problem_pattern+="\<urgent|"
|
||||
problem_pattern+="\<warn\>|"
|
||||
problem_pattern+="\<warning\>|"
|
||||
problem_pattern+="\<wrong\>"
|
||||
problem_pattern+=")"
|
||||
|
||||
# List of patterns used to exclude messages that are not problems
|
||||
problem_exclude_pattern="("
|
||||
problem_exclude_pattern+="\<launching .* with:"
|
||||
problem_exclude_pattern+=")"
|
||||
|
||||
usage()
|
||||
{
|
||||
cat <<EOT
|
||||
Usage: $script_name [options]
|
||||
|
||||
Summary: Collect data about an installation of @PROJECT_NAME@.
|
||||
|
||||
Description: Run this script as root to obtain a markdown-formatted summary
|
||||
of the environment of the @PROJECT_NAME@ installation. The output of this script
|
||||
can be pasted directly into a github issue at the address below:
|
||||
|
||||
$issue_url
|
||||
|
||||
Options:
|
||||
|
||||
-h | --help : show this usage summary.
|
||||
-v | --version : show program version.
|
||||
|
||||
EOT
|
||||
}
|
||||
|
||||
version()
|
||||
{
|
||||
cat <<EOT
|
||||
$script_name version $script_version
|
||||
EOT
|
||||
}
|
||||
|
||||
die()
|
||||
{
|
||||
local msg="$*"
|
||||
echo >&2 "ERROR: $script_name: $msg"
|
||||
exit 1
|
||||
}
|
||||
|
||||
msg()
|
||||
{
|
||||
local msg="$*"
|
||||
echo "$msg"
|
||||
}
|
||||
|
||||
heading()
|
||||
{
|
||||
local name="$*"
|
||||
echo -e "\n# $name\n"
|
||||
}
|
||||
|
||||
subheading()
|
||||
{
|
||||
local name="$*"
|
||||
echo -e "\n## $name\n"
|
||||
}
|
||||
|
||||
separator()
|
||||
{
|
||||
echo -e '\n---\n'
|
||||
}
|
||||
|
||||
have_cmd()
|
||||
{
|
||||
local cmd="$1"
|
||||
|
||||
command -v "$cmd" &>/dev/null
|
||||
local ret=$?
|
||||
|
||||
if [ $ret -eq 0 ]; then
|
||||
msg "Have \`$cmd\`"
|
||||
else
|
||||
msg "No \`$cmd\`"
|
||||
fi
|
||||
|
||||
[ $ret -eq 0 ]
|
||||
}
|
||||
|
||||
show_quoted_text()
|
||||
{
|
||||
local text="$*"
|
||||
|
||||
echo "\`\`\`"
|
||||
echo "$text"
|
||||
echo "\`\`\`"
|
||||
}
|
||||
|
||||
run_cmd_and_show_quoted_output()
|
||||
{
|
||||
local cmd="$*"
|
||||
|
||||
local output
|
||||
|
||||
msg "Output of \"\`$cmd\`\":"
|
||||
output=$(eval "$cmd" 2>&1)
|
||||
show_quoted_text "$output"
|
||||
}
|
||||
|
||||
show_runtime_configs()
|
||||
{
|
||||
local configs config
|
||||
|
||||
heading "Runtime config files"
|
||||
|
||||
configs=$($runtime --@PROJECT_TYPE@-show-default-config-paths)
|
||||
if [ $? -ne 0 ]; then
|
||||
version=$($runtime --version|tr '\n' ' ')
|
||||
die "failed to check config files - runtime is probably too old ($version)"
|
||||
fi
|
||||
|
||||
subheading "Runtime default config files"
|
||||
|
||||
show_quoted_text "$configs"
|
||||
|
||||
# add in the standard defaults for good measure "just in case"
|
||||
configs+=" /etc/@PROJECT_TAG@/configuration.toml"
|
||||
configs+=" /usr/share/defaults/@PROJECT_TAG@/configuration.toml"
|
||||
configs+=" @DESTCONFIG@"
|
||||
configs+=" @DESTSYSCONFIG@"
|
||||
|
||||
# create a unique list of config files
|
||||
configs=$(echo $configs|tr ' ' '\n'|sort -u)
|
||||
|
||||
subheading "Runtime config file contents"
|
||||
|
||||
for config in $configs; do
|
||||
if [ -e "$config" ]; then
|
||||
run_cmd_and_show_quoted_output "cat \"$config\""
|
||||
else
|
||||
msg "Config file \`$config\` not found"
|
||||
fi
|
||||
done
|
||||
|
||||
separator
|
||||
}
|
||||
|
||||
show_log_details()
|
||||
{
|
||||
heading "Logfiles"
|
||||
|
||||
show_runtime_log_details
|
||||
show_proxy_log_details
|
||||
show_shim_log_details
|
||||
|
||||
separator
|
||||
}
|
||||
|
||||
show_runtime_log_details()
|
||||
{
|
||||
subheading "Runtime logs"
|
||||
|
||||
find_system_journal_problems "runtime" "@RUNTIME_NAME@" ""
|
||||
}
|
||||
|
||||
find_system_journal_problems()
|
||||
{
|
||||
local name="$1"
|
||||
local program="$2"
|
||||
local unit="$3"
|
||||
|
||||
# select by identifier
|
||||
local selector="-t"
|
||||
|
||||
local data_source="system journal"
|
||||
|
||||
local problems=$(journalctl -q -o cat -a "$selector" "$program" |\
|
||||
grep "time=" |\
|
||||
egrep -i "$problem_pattern" |\
|
||||
egrep -iv "$problem_exclude_pattern" |\
|
||||
tail -n ${PROBLEM_LIMIT})
|
||||
|
||||
if [ -n "$problems" ]; then
|
||||
msg "Recent $name problems found in $data_source:"
|
||||
show_quoted_text "$problems"
|
||||
else
|
||||
msg "No recent $name problems found in $data_source."
|
||||
fi
|
||||
}
|
||||
|
||||
show_proxy_log_details()
|
||||
{
|
||||
subheading "Proxy logs"
|
||||
|
||||
find_system_journal_problems "proxy" "@PROJECT_TYPE@-proxy" ""
|
||||
}
|
||||
|
||||
show_shim_log_details()
|
||||
{
|
||||
subheading "Shim logs"
|
||||
|
||||
find_system_journal_problems "shim" "@PROJECT_TYPE@-shim" ""
|
||||
}
|
||||
|
||||
show_package_versions()
|
||||
{
|
||||
heading "Packages"
|
||||
|
||||
local pattern="("
|
||||
local project
|
||||
|
||||
# CC 2.x runtime. This shouldn't be installed but let's check anyway
|
||||
pattern+="cc-oci-runtime"
|
||||
|
||||
# core components
|
||||
for project in @PROJECT_TYPE@
|
||||
do
|
||||
pattern+="|${project}-proxy"
|
||||
pattern+="|${project}-runtime"
|
||||
pattern+="|${project}-shim"
|
||||
done
|
||||
|
||||
# assets
|
||||
pattern+="|clear-containers-image"
|
||||
pattern+="|linux-container"
|
||||
|
||||
# optimised hypervisor
|
||||
pattern+="|qemu-lite"
|
||||
|
||||
# default distro hypervisor
|
||||
pattern+="|qemu-system-x86"
|
||||
|
||||
pattern+=")"
|
||||
|
||||
if have_cmd "dpkg"; then
|
||||
run_cmd_and_show_quoted_output "dpkg -l|egrep \"$pattern\""
|
||||
fi
|
||||
|
||||
if have_cmd "rpm"; then
|
||||
run_cmd_and_show_quoted_output "rpm -qa|egrep \"$pattern\""
|
||||
fi
|
||||
|
||||
separator
|
||||
}
|
||||
|
||||
show_container_mgr_details()
|
||||
{
|
||||
heading "Container manager details"
|
||||
|
||||
if have_cmd "docker"; then
|
||||
subheading "Docker"
|
||||
run_cmd_and_show_quoted_output "docker version"
|
||||
run_cmd_and_show_quoted_output "docker info"
|
||||
run_cmd_and_show_quoted_output "systemctl show docker"
|
||||
fi
|
||||
|
||||
if have_cmd "kubectl"; then
|
||||
subheading "Kubernetes"
|
||||
run_cmd_and_show_quoted_output "kubectl version"
|
||||
run_cmd_and_show_quoted_output "kubectl config view"
|
||||
run_cmd_and_show_quoted_output "systemctl show kubelet"
|
||||
|
||||
if have_cmd "crio"; then
|
||||
run_cmd_and_show_quoted_output "crio --version"
|
||||
run_cmd_and_show_quoted_output "systemctl show crio"
|
||||
fi
|
||||
fi
|
||||
|
||||
separator
|
||||
}
|
||||
|
||||
show_meta()
|
||||
{
|
||||
local date
|
||||
|
||||
heading "Meta details"
|
||||
|
||||
date=$(date '+%Y-%m-%d.%H:%M:%S.%N%z')
|
||||
msg "Running \`$script_name\` version \`$script_version\` at \`$date\`."
|
||||
|
||||
separator
|
||||
}
|
||||
|
||||
show_runtime()
|
||||
{
|
||||
local cmd
|
||||
|
||||
msg "Runtime is \`$runtime\`."
|
||||
|
||||
cmd="@PROJECT_TYPE@-env"
|
||||
heading "\`$cmd\`"
|
||||
run_cmd_and_show_quoted_output "$runtime $cmd"
|
||||
|
||||
separator
|
||||
}
|
||||
|
||||
# Parameter 1: Path to disk image file.
|
||||
# Returns: Agent version string, or "$unknown" on error.
|
||||
get_agent_version()
|
||||
{
|
||||
local img="$1"
|
||||
|
||||
[ -z "$img" ] && { echo "$unknown"; return;}
|
||||
[ -e "$img" ] || { echo "$unknown"; return;}
|
||||
|
||||
local loop_device
|
||||
local partition_path
|
||||
local partitions
|
||||
local partition
|
||||
local count
|
||||
local mountpoint
|
||||
local version
|
||||
local expected
|
||||
|
||||
loop_device=$(loopmount_image "$img")
|
||||
if [ -z "$loop_device" ]; then
|
||||
echo "$unknown"
|
||||
return
|
||||
fi
|
||||
|
||||
partitions=$(get_partitions "$loop_device")
|
||||
count=$(echo "$partitions"|wc -l)
|
||||
|
||||
expected=1
|
||||
|
||||
if [ "$count" -ne "$expected" ]; then
|
||||
release_device "$loop_device"
|
||||
echo "$unknown"
|
||||
return
|
||||
fi
|
||||
|
||||
partition="$partitions"
|
||||
|
||||
partition_path="/dev/${partition}"
|
||||
if [ ! -e "$partition_path" ]; then
|
||||
release_device "$loop_device"
|
||||
echo "$unknown"
|
||||
return
|
||||
fi
|
||||
|
||||
mountpoint=$(mount_partition "$partition_path")
|
||||
|
||||
agent="/bin/@PROJECT_TYPE@-agent"
|
||||
|
||||
version=$(chroot "$mountpoint" "$agent" --version 2>/dev/null)
|
||||
|
||||
unmount_partition "$mountpoint"
|
||||
release_device "$loop_device"
|
||||
|
||||
[ -z "$version" ] && version="$unknown"
|
||||
|
||||
echo "$version"
|
||||
}
|
||||
|
||||
# Returns: Full path to the image file.
|
||||
get_image_file()
|
||||
{
|
||||
local cmd="@PROJECT_TYPE@-env"
|
||||
local cmdline="$runtime $cmd"
|
||||
|
||||
image=$(eval "$cmdline" 2>/dev/null |\
|
||||
grep -A 1 '^\[Image\]' |\
|
||||
egrep "\<Path\> =" |\
|
||||
awk '{print $3}' |\
|
||||
tr -d '"')
|
||||
|
||||
echo "$image"
|
||||
}
|
||||
|
||||
# Parameter 1: Path to disk image file.
|
||||
# Returns: Path to loop device.
|
||||
loopmount_image()
|
||||
{
|
||||
local img="$1"
|
||||
[ -n "$img" ] || die "need image file"
|
||||
|
||||
local device_path
|
||||
|
||||
losetup -fP "$img"
|
||||
|
||||
device_path=$(losetup -j "$img" |\
|
||||
cut -d: -f1 |\
|
||||
sort -k1,1 |\
|
||||
tail -1)
|
||||
|
||||
echo "$device_path"
|
||||
}
|
||||
|
||||
# Parameter 1: Path to loop device.
|
||||
# Returns: Partition names.
|
||||
get_partitions()
|
||||
{
|
||||
local device_path="$1"
|
||||
[ -n "$device_path" ] || die "need device path"
|
||||
|
||||
local device
|
||||
local partitions
|
||||
|
||||
device=${device_path/\/dev\//}
|
||||
|
||||
partitions=$(lsblk -nli -o NAME "${device_path}" |\
|
||||
grep -v "^${device}$")
|
||||
|
||||
echo "$partitions"
|
||||
}
|
||||
|
||||
# Parameter 1: Path to disk partition device.
|
||||
# Returns: Mountpoint.
|
||||
mount_partition()
|
||||
{
|
||||
local partition="$1"
|
||||
[ -n "$partition" ] || die "need partition"
|
||||
[ -e "$partition" ] || die "partition does not exist: $partition"
|
||||
|
||||
local mountpoint
|
||||
|
||||
mountpoint=$(mktemp -d)
|
||||
|
||||
mount -oro,noload "$partition" "$mountpoint"
|
||||
|
||||
echo "$mountpoint"
|
||||
}
|
||||
|
||||
# Parameter 1: Mountpoint.
|
||||
unmount_partition()
|
||||
{
|
||||
local mountpoint="$1"
|
||||
[ -n "$mountpoint" ] || die "need mountpoint"
|
||||
[ -n "$mountpoint" ] || die "mountpoint does not exist: $mountpoint"
|
||||
|
||||
umount "$mountpoint"
|
||||
}
|
||||
|
||||
# Parameter 1: Loop device path.
|
||||
release_device()
|
||||
{
|
||||
local device="$1"
|
||||
[ -n "$device" ] || die "need device"
|
||||
[ -e "$device" ] || die "device does not exist: $device"
|
||||
|
||||
losetup -d "$device"
|
||||
}
|
||||
|
||||
show_agent_version()
|
||||
{
|
||||
local image
|
||||
local version
|
||||
|
||||
image=$(get_image_file)
|
||||
version=$(get_agent_version "$image")
|
||||
|
||||
heading "Agent"
|
||||
|
||||
msg "version:"
|
||||
|
||||
show_quoted_text "$version"
|
||||
|
||||
separator
|
||||
}
|
||||
|
||||
main()
|
||||
{
|
||||
args=$(getopt \
|
||||
-n "$script_name" \
|
||||
-a \
|
||||
--options="dhv" \
|
||||
--longoptions="debug help version" \
|
||||
-- "$@")
|
||||
|
||||
eval set -- "$args"
|
||||
[ $? -ne 0 ] && { usage && exit 1; }
|
||||
[ $# -eq 0 ] && { usage && exit 0; }
|
||||
|
||||
while [ $# -gt 1 ]
|
||||
do
|
||||
case "$1" in
|
||||
-d|--debug)
|
||||
set -x
|
||||
;;
|
||||
|
||||
-h|--help)
|
||||
usage && exit 0
|
||||
;;
|
||||
|
||||
-v|--version)
|
||||
version && exit 0
|
||||
;;
|
||||
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
[ $(id -u) -eq 0 ] || die "Need to run as root"
|
||||
[ -n "$runtime" ] || die "cannot find runtime '$runtime_name'"
|
||||
|
||||
show_meta
|
||||
show_runtime
|
||||
show_runtime_configs
|
||||
show_agent_version
|
||||
show_log_details
|
||||
show_container_mgr_details
|
||||
show_package_versions
|
||||
}
|
||||
|
||||
main "$@"
|
Loading…
Reference in New Issue
Block a user