debug

package
v1.57.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 17, 2023 License: Apache-2.0 Imports: 21 Imported by: 0

Documentation

Overview

Package debug implements a 'devenv debug' command that allows developers to debug their devenv environment.

Description: This file contains the code for the 'devenv debug export' command. This command is used to export debug information from a devenv instance.

Index

Constants

This section is empty.

Variables

View Source
var ProblemPodCrashLoopBackOff = Problem{
	Resource:         "pod",
	ID:               "PodCrashLoopBackOff",
	ShortDescription: "A pod is in a crash loop backoff state, meaning it is crashing repeatedly",
	Detector: func(ctx context.Context, obj runtime.Object) (string, bool, bool) {
		pod, ok := obj.(*corev1.Pod)
		if !ok {
			return "", false, false
		}

		isCrashLoopBackoff := func(cs *corev1.ContainerStatus) bool {
			return cs.State.Waiting != nil && cs.State.Waiting.Reason == "CrashLoopBackOff"
		}

		for i := range pod.Status.ContainerStatuses {
			cs := &pod.Status.ContainerStatuses[i]
			if isCrashLoopBackoff(cs) {
				return fmt.Sprintf("Container %s in a crash loop backoff state: %v",
					cs.Name, cs.LastTerminationState.Terminated.Message,
				), false, true
			}
		}

		for i := range pod.Status.InitContainerStatuses {
			cs := &pod.Status.InitContainerStatuses[i]
			if isCrashLoopBackoff(cs) {
				return fmt.Sprintf("Init container %s in a crash loop backoff state: %v",
					cs.Name, cs.LastTerminationState.Terminated.Message,
				), false, true
			}
		}

		return "", false, false
	},
}

ProblemPodCrashLoopBackOff is a problem with a pod that is in a crash loop https://github.com/getoutreach/devenv/wiki/PodCrashLoopBackOff

View Source
var ProblemPodImagePullBackOff = Problem{
	Resource:         "pod",
	ID:               "PodImagePullBackOff",
	ShortDescription: "A pod is in a image pull backoff state, meaning it is unable to pull the image",
	Detector: func(ctx context.Context, obj runtime.Object) (string, bool, bool) {
		pod, ok := obj.(*corev1.Pod)
		if !ok {
			return "", false, false
		}

		isImagePullBackOff := func(cs *corev1.ContainerStatus) bool {

			return cs.State.Waiting != nil &&
				(cs.State.Waiting.Reason == "ImagePullBackOff" || cs.State.Waiting.Reason == "ErrImagePull")
		}

		getImageForContainerStatus := func(isInitContainer bool, cs *corev1.ContainerStatus) string {
			sl := pod.Spec.Containers
			if isInitContainer {
				sl = pod.Spec.InitContainers
			}

			var container *corev1.Container
			for i := range sl {
				c := &sl[i]
				if c.Name == cs.Name {
					container = c
					break
				}
			}
			if container == nil {
				return "unknown"
			}

			return container.Image
		}

		for i := range pod.Status.ContainerStatuses {
			cs := &pod.Status.ContainerStatuses[i]
			imageName := getImageForContainerStatus(false, cs)
			if isImagePullBackOff(cs) {
				return fmt.Sprintf("Container %s is failing to pull its image (%s)", cs.Name, imageName), false, true
			}
		}

		for i := range pod.Status.InitContainerStatuses {
			cs := &pod.Status.InitContainerStatuses[i]
			imageName := getImageForContainerStatus(true, cs)
			if isImagePullBackOff(cs) {
				return fmt.Sprintf("Container %s is failing to pull its image (%s)", cs.Name, imageName), false, true
			}
		}

		return "", false, false
	},
}

ProblemPodImagePullBackOff is a problem with a pod that is in a image pull backoff state https://github.com/getoutreach/devenv/wiki/PodImagePullBackOff

View Source
var ProblemPodNotReady = Problem{
	Resource:         "pod",
	ID:               "PodNotReady",
	ShortDescription: "A pod is not ready which can indicate a problem with the pod",
	Detector: func(ctx context.Context, obj runtime.Object) (string, bool, bool) {
		pod, ok := obj.(*corev1.Pod)
		if !ok {
			return "", false, false
		}

		if pod.Status.Phase != corev1.PodRunning {
			return "", false, false
		}

		for i := range pod.Status.ContainerStatuses {
			cs := &pod.Status.ContainerStatuses[i]
			if !cs.Ready {
				return fmt.Sprintf("Container %s is not ready", cs.Name), false, true
			}
		}

		return "", false, false
	},
}

ProblemPodNotReady is a problem with a pod that is not ready https://github.com/getoutreach/devenv/wiki/PodNotReady

View Source
var ProblemPodOOMKilled = Problem{
	Resource:         "pod",
	ID:               "PodOOMKilled",
	ShortDescription: "A pod was killed because it ran out of memory recently",
	Detector: func(ctx context.Context, obj runtime.Object) (string, bool, bool) {
		pod, ok := obj.(*corev1.Pod)
		if !ok {
			return "", false, false
		}

		for i := range pod.Status.ContainerStatuses {
			cs := &pod.Status.ContainerStatuses[i]
			if cs.State.Terminated != nil && cs.State.Terminated.Reason == "OOMKilled" {
				return fmt.Sprintf("Container %s was killed because it ran out of memory", cs.Name), false, true
			}

			if cs.LastTerminationState.Terminated != nil && cs.LastTerminationState.Terminated.Reason == "OOMKilled" {
				return fmt.Sprintf("Container %s was recently killed because it ran out of memory: %s",
					cs.Name,
					cs.LastTerminationState.Terminated.FinishedAt.Time,
				), true, true
			}
		}

		return "", false, false
	},
}

ProblemPodOOMKilled is a problem with a pod that is/was OOM killed https://github.com/getoutreach/devenv/wiki/PodOOMKilled

View Source
var ProblemPodPending = Problem{
	Resource:         "pod",
	ID:               "PodPending",
	ShortDescription: "A pod is pending",
	Detector: func(ctx context.Context, obj runtime.Object) (string, bool, bool) {
		pod, ok := obj.(*corev1.Pod)
		if !ok {
			return "", false, false
		}

		if pod.Status.Phase != corev1.PodPending {
			return "", false, false
		}

		for i := range pod.Status.ContainerStatuses {
			cs := &pod.Status.ContainerStatuses[i]
			if cs.State.Waiting != nil {
				return fmt.Sprintf("Container %s is pending: %s", cs.Name, cs.State.Waiting.Message), false, true
			}
		}

		for i := range pod.Status.InitContainerStatuses {
			cs := &pod.Status.InitContainerStatuses[i]
			if cs.State.Waiting != nil {
				return fmt.Sprintf("Init container %s is pending: %s", cs.Name, cs.State.Waiting.Message), false, true
			}
		}

		return "", false, false
	},
}

PodPending is a problem with a pod that is stuck pending https://github.com/getoutreach/devenv/wiki/PodPending

View Source
var ProblemVaultTokenExpired = Problem{
	Resource:         "vault",
	ID:               "VaultTokenExpired",
	ShortDescription: "Vault token is expired, run `devenv auth refresh` to get a new token",
	Detector: func(ctx context.Context, obj runtime.Object) (string, bool, bool) {
		b, err := box.LoadBox()
		if err != nil {
			return fmt.Sprintf("failed to load box configuration, %s", err), false, true
		}

		if b.DeveloperEnvironmentConfig.VaultConfig.Enabled {

			nullLogger := logrus.New()
			nullLogger.Out = io.Discard
			if err := vault.IsLoggedIn(ctx, nullLogger, b); err != nil {
				return fmt.Sprintf("failed to get vault authentication status, %s", err), false, true
			}
		}

		return "", false, false
	},
}

ProblemVaultTokenExpired is a problem with expired vault token https://github.com/getoutreach/devenv/wiki/ProblemVaultTokenExpired

Functions

func NewCommand

func NewCommand(log *logrus.Logger) *cli.Command

NewCommand creates a new devenv debug command

Types

type Options

type Options struct {
	// contains filtered or unexported fields
}

Options contains options for the devenv debug command

func NewOptions

func NewOptions(log logrus.FieldLogger) *Options

NewOptions contains options for the devenv debug command

func (*Options) Run

func (o *Options) Run(ctx context.Context) error

Run runs the devenv debug command

type Problem

type Problem struct {
	// Resource is a resource of the problem used to group problems together
	Resource string

	// ID is a unique identifier for the problem used to group
	// problems together for different resources.
	ID string

	// ShortDescription is a short description of the problem
	ShortDescription string

	// HelpURL is a URL that can be used to help the user resolve
	// the problem. Defaults to the devenv wki/ID.
	HelpURL string

	// Detector is a function that detects if this problem exists.
	Detector func(context.Context, runtime.Object) (resourceSpecificReason string, warning, isOccurring bool)
}

Problem is a problem that was found in the devenv environment

type Report

type Report struct {
	// Problems is a list of problems that were found
	Problems []Problem

	// Resources is a list of resources that were found
	// that had a given problem
	Resources []Resource
}

Report is a report of problems that were found in the devenv environment

func ReportFromResources

func ReportFromResources(resources []Resource) Report

ReportFromResources creates a report from a list of resources

func (*Report) ByProblem

func (r *Report) ByProblem() map[string][]*Resource

ByProblem returns a map of resources by problem ID

func (*Report) BySeverity

func (r *Report) BySeverity() map[Severity]map[string][]*Resource

BySeverity returns a map of problems by severity with a map of resources by problem ID

func (*Report) GetProblemByID

func (r *Report) GetProblemByID(id string) *Problem

GetProblemByID returns a problem by ID

type Resource

type Resource struct {
	// Name is the name of the resource having a problem,
	// this is usually a pod name or the like.
	Name string

	// Owner is the team that owns this resource, if that information
	// is present.
	Owner string

	// Type is the type of resource that is having a problem
	// e.g. pod, deployment, etc.
	Type string

	// ProblemID is the ID of the problem that is occurring
	ProblemID string

	// ProblemDetails is details about the problem specific
	// to the resource.
	ProblemDetails string

	// Warning denotes if this is a warning or not, e.g. isn't actually
	// causing a problem _now_. This is usually used for problems that
	// previously occurred or aren't otherwise currently occurring.
	Warning bool
}

Resource is a resource that has a problem associated with it

type ResourceProblem

type ResourceProblem struct {
	// Owner is the team that owns this resource, if that information
	// is present.
	ResourceOwner string

	// ResourceName is the name of the resource having a problem,
	// this is usually a pod name or the like.
	ResourceName string

	// ResourceType is the type of resource that is having a problem
	// e.g. pod, deployment, etc.
	ResourceType string

	// ResourceProblemDetails is details about the problem specific
	// to the resource.
	ResourceProblemDetails string

	// Warning denotes if this is a warning or not, e.g. isn't actually
	// causing a problem _now_. This is usually used for problems that
	// previously occurred or aren't otherwise currently occurring.
	Warning bool

	// Problem is the problem that is happening with the resource
	Problem Problem
}

ResourceProblem is a problem with a resource, e.g. a pod

type Severity

type Severity int

Service is a the severity of a problem

const (
	// SeverityError is an error
	SeverityError Severity = iota
	// SeverityWarning is a warning
	SeverityWarning
)

serverity levels

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL