forked from kubernetes/minikube
-
Notifications
You must be signed in to change notification settings - Fork 1
/
errors.go
123 lines (99 loc) · 4.36 KB
/
errors.go
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
/*
Copyright 2020 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package oci
import (
"errors"
"os/exec"
"strings"
"k8s.io/klog/v2"
)
// FailFastError type is an error that could not be solved by trying again
type FailFastError struct {
Err error
}
func (f *FailFastError) Error() string {
return f.Err.Error()
}
// ErrWindowsContainers is thrown when docker been configured to run windows containers instead of Linux
var ErrWindowsContainers = &FailFastError{errors.New("docker container type is windows")}
// ErrCPUCountLimit is thrown when docker daemon doesn't have enough CPUs for the requested container
var ErrCPUCountLimit = &FailFastError{errors.New("not enough CPUs is available for container")}
// ErrIPinUse is thrown when the container been given an IP used by another container
var ErrIPinUse = &FailFastError{errors.New("can't create with that IP, address already in use")}
// ErrExitedUnexpectedly is thrown when container is created/started without error but later it exists and it's status is not running anymore.
var ErrExitedUnexpectedly = errors.New("container exited unexpectedly")
// ErrDaemonInfo is thrown when docker/podman info is failing or not responding
var ErrDaemonInfo = errors.New("daemon info not responding")
// ErrInsufficientDockerStorage is thrown when there is not more storage for docker
var ErrInsufficientDockerStorage = &FailFastError{errors.New("insufficient docker storage, no space left on device")}
// ErrNetworkSubnetTaken is thrown when a subnet is taken by another network
var ErrNetworkSubnetTaken = errors.New("subnet is taken")
// ErrNetworkNotFound is when given network was not found
var ErrNetworkNotFound = errors.New("kic network not found")
// ErrNetworkGatewayTaken is when given network gatway is taken
var ErrNetworkGatewayTaken = errors.New("network gateway is taken")
// ErrNetworkInUse is when trying to delete a network which is attached to another container
var ErrNetworkInUse = errors.New("unable to delete a network that is attached to a running container")
// LogContainerDebug will print relevant docker/podman infos after a container fails
func LogContainerDebug(ociBin string, name string) string {
rr, err := containerInspect(ociBin, name)
if err != nil {
klog.Warningf("Failed to get postmortem inspect. %s :%v", rr.Command(), err)
} else {
klog.Infof("Postmortem inspect (%q): %s", rr.Command(), rr.Output())
}
rr, err = containerLogs(ociBin, name)
if err != nil {
klog.Warningf("Failed to get postmortem logs. %s :%v", rr.Command(), err)
} else {
klog.Infof("Postmortem logs (%q): %s", rr.Command(), rr.Output())
}
if ociBin == Docker {
di, err := dockerSystemInfo()
if err != nil {
klog.Warningf("Failed to get postmortem docker info: %v", err)
} else {
klog.Infof("postmortem docker info: %+v", di)
}
logDockerNetworkInspect(ociBin, name)
} else {
pi, err := podmanSystemInfo()
if err != nil {
klog.Warningf("couldn't get postmortem podman info: %v", err)
} else {
klog.Infof("postmortem podman info: %+v", pi)
}
logDockerNetworkInspect(ociBin, name)
}
if rr.Stdout.Len() == 0 {
return ""
}
// If available, return an excerpt of the post-mortem logs for inclusion in error message
excerpt := strings.Split(strings.TrimSpace(rr.Stdout.String()), "\n")
if len(excerpt) > 4 {
excerpt = excerpt[len(excerpt)-4:]
}
return strings.Join(excerpt, "\n")
}
// containerLogs will return out the logs for a container
func containerLogs(ociBin string, name string) (*RunResult, error) {
if ociBin == Docker {
return runCmd(exec.Command(ociBin, "logs", "--timestamps", "--details", name))
}
// podman doesn't have --details
return runCmd(exec.Command(ociBin, "logs", "--timestamps", name))
}
// containerInspect will return the inspect for a container
func containerInspect(ociBin string, name string) (*RunResult, error) {
return runCmd(exec.Command(ociBin, "inspect", name))
}