13
"github.com/containers/common/libnetwork/types"
14
"github.com/containers/podman/v5/libpod/define"
15
"github.com/sirupsen/logrus"
18
// Timeout before declaring that runtime has failed to kill a given
20
const killContainerTimeout = 5 * time.Second
22
// ociError is used to parse the OCI runtime JSON log. It is not part of the
23
// OCI runtime specifications, it follows what runc does
25
Level string `json:"level,omitempty"`
26
Time string `json:"time,omitempty"`
27
Msg string `json:"msg,omitempty"`
30
// Create systemd unit name for cgroup scopes
31
func createUnitName(prefix string, name string) string {
32
return fmt.Sprintf("%s-%s.scope", prefix, name)
35
// Bind ports to keep them closed on the host
36
func bindPorts(ports []types.PortMapping) ([]*os.File, error) {
39
for _, port := range ports {
40
isV6 := net.ParseIP(port.HostIP).To4() == nil
41
if port.HostIP == "" {
44
protocols := strings.Split(port.Protocol, ",")
45
for _, protocol := range protocols {
46
for i := uint16(0); i < port.Range; i++ {
47
f, err := bindPort(protocol, port.HostIP, port.HostPort+i, isV6, &sctpWarning)
52
files = append(files, f)
60
func bindPort(protocol, hostIP string, port uint16, isV6 bool, sctpWarning *bool) (*os.File, error) {
69
addr, err = net.ResolveUDPAddr("udp6", fmt.Sprintf("[%s]:%d", hostIP, port))
71
addr, err = net.ResolveUDPAddr("udp4", fmt.Sprintf("%s:%d", hostIP, port))
74
return nil, fmt.Errorf("cannot resolve the UDP address: %w", err)
81
server, err := net.ListenUDP(proto, addr)
83
return nil, fmt.Errorf("cannot listen on the UDP port: %w", err)
85
file, err = server.File()
87
return nil, fmt.Errorf("cannot get file for UDP socket: %w", err)
90
// note that this does not affect the fd, see the godoc for server.File()
93
logrus.Warnf("Failed to close connection: %v", err)
102
addr, err = net.ResolveTCPAddr("tcp6", fmt.Sprintf("[%s]:%d", hostIP, port))
104
addr, err = net.ResolveTCPAddr("tcp4", fmt.Sprintf("%s:%d", hostIP, port))
107
return nil, fmt.Errorf("cannot resolve the TCP address: %w", err)
114
server, err := net.ListenTCP(proto, addr)
116
return nil, fmt.Errorf("cannot listen on the TCP port: %w", err)
118
file, err = server.File()
120
return nil, fmt.Errorf("cannot get file for TCP socket: %w", err)
122
// close the listener
123
// note that this does not affect the fd, see the godoc for server.File()
126
logrus.Warnf("Failed to close connection: %v", err)
131
logrus.Info("Port reservation for SCTP is not supported")
135
return nil, fmt.Errorf("unknown protocol %s", protocol)
140
func getOCIRuntimeError(name, runtimeMsg string) error {
141
includeFullOutput := logrus.GetLevel() == logrus.DebugLevel
143
if match := regexp.MustCompile("(?i).*permission denied.*|.*operation not permitted.*").FindString(runtimeMsg); match != "" {
145
if includeFullOutput {
148
return fmt.Errorf("%s: %s: %w", name, strings.Trim(errStr, "\n"), define.ErrOCIRuntimePermissionDenied)
150
if match := regexp.MustCompile("(?i).*executable file not found in.*|.*no such file or directory.*").FindString(runtimeMsg); match != "" {
152
if includeFullOutput {
155
return fmt.Errorf("%s: %s: %w", name, strings.Trim(errStr, "\n"), define.ErrOCIRuntimeNotFound)
157
if match := regexp.MustCompile("`/proc/[a-z0-9-].+/attr.*`").FindString(runtimeMsg); match != "" {
159
if includeFullOutput {
162
if strings.HasSuffix(match, "/exec`") {
163
return fmt.Errorf("%s: %s: %w", name, strings.Trim(errStr, "\n"), define.ErrSetSecurityAttribute)
164
} else if strings.HasSuffix(match, "/current`") {
165
return fmt.Errorf("%s: %s: %w", name, strings.Trim(errStr, "\n"), define.ErrGetSecurityAttribute)
167
return fmt.Errorf("%s: %s: %w", name, strings.Trim(errStr, "\n"), define.ErrSecurityAttribute)
169
return fmt.Errorf("%s: %s: %w", name, strings.Trim(runtimeMsg, "\n"), define.ErrOCIRuntime)