github.com/AbhinandanKurakure/podman/v3@v3.4.10/libpod/oci_util.go (about) 1 package libpod 2 3 import ( 4 "fmt" 5 "net" 6 "os" 7 "regexp" 8 "strings" 9 "time" 10 11 "github.com/containers/podman/v3/libpod/define" 12 "github.com/cri-o/ocicni/pkg/ocicni" 13 "github.com/pkg/errors" 14 "github.com/sirupsen/logrus" 15 ) 16 17 // Timeout before declaring that runtime has failed to kill a given 18 // container 19 const killContainerTimeout = 5 * time.Second 20 21 // ociError is used to parse the OCI runtime JSON log. It is not part of the 22 // OCI runtime specifications, it follows what runc does 23 type ociError struct { 24 Level string `json:"level,omitempty"` 25 Time string `json:"time,omitempty"` 26 Msg string `json:"msg,omitempty"` 27 } 28 29 // Create systemd unit name for cgroup scopes 30 func createUnitName(prefix string, name string) string { 31 return fmt.Sprintf("%s-%s.scope", prefix, name) 32 } 33 34 // Bind ports to keep them closed on the host 35 func bindPorts(ports []ocicni.PortMapping) ([]*os.File, error) { 36 var files []*os.File 37 notifySCTP := false 38 for _, i := range ports { 39 isV6 := net.ParseIP(i.HostIP).To4() == nil 40 if i.HostIP == "" { 41 isV6 = false 42 } 43 switch i.Protocol { 44 case "udp": 45 var ( 46 addr *net.UDPAddr 47 err error 48 ) 49 if isV6 { 50 addr, err = net.ResolveUDPAddr("udp6", fmt.Sprintf("[%s]:%d", i.HostIP, i.HostPort)) 51 } else { 52 addr, err = net.ResolveUDPAddr("udp4", fmt.Sprintf("%s:%d", i.HostIP, i.HostPort)) 53 } 54 if err != nil { 55 return nil, errors.Wrapf(err, "cannot resolve the UDP address") 56 } 57 58 proto := "udp4" 59 if isV6 { 60 proto = "udp6" 61 } 62 server, err := net.ListenUDP(proto, addr) 63 if err != nil { 64 return nil, errors.Wrapf(err, "cannot listen on the UDP port") 65 } 66 f, err := server.File() 67 if err != nil { 68 return nil, errors.Wrapf(err, "cannot get file for UDP socket") 69 } 70 files = append(files, f) 71 // close the listener 72 // note that this does not affect the fd, see the godoc for server.File() 73 err = server.Close() 74 if err != nil { 75 logrus.Warnf("failed to close connection: %v", err) 76 } 77 78 case "tcp": 79 var ( 80 addr *net.TCPAddr 81 err error 82 ) 83 if isV6 { 84 addr, err = net.ResolveTCPAddr("tcp6", fmt.Sprintf("[%s]:%d", i.HostIP, i.HostPort)) 85 } else { 86 addr, err = net.ResolveTCPAddr("tcp4", fmt.Sprintf("%s:%d", i.HostIP, i.HostPort)) 87 } 88 if err != nil { 89 return nil, errors.Wrapf(err, "cannot resolve the TCP address") 90 } 91 92 proto := "tcp4" 93 if isV6 { 94 proto = "tcp6" 95 } 96 server, err := net.ListenTCP(proto, addr) 97 if err != nil { 98 return nil, errors.Wrapf(err, "cannot listen on the TCP port") 99 } 100 f, err := server.File() 101 if err != nil { 102 return nil, errors.Wrapf(err, "cannot get file for TCP socket") 103 } 104 files = append(files, f) 105 // close the listener 106 // note that this does not affect the fd, see the godoc for server.File() 107 err = server.Close() 108 if err != nil { 109 logrus.Warnf("failed to close connection: %v", err) 110 } 111 112 case "sctp": 113 if !notifySCTP { 114 notifySCTP = true 115 logrus.Warnf("port reservation for SCTP is not supported") 116 } 117 default: 118 return nil, fmt.Errorf("unknown protocol %s", i.Protocol) 119 } 120 } 121 return files, nil 122 } 123 124 func getOCIRuntimeError(runtimeMsg string) error { 125 includeFullOutput := logrus.GetLevel() == logrus.DebugLevel 126 127 if match := regexp.MustCompile("(?i).*permission denied.*|.*operation not permitted.*").FindString(runtimeMsg); match != "" { 128 errStr := match 129 if includeFullOutput { 130 errStr = runtimeMsg 131 } 132 return errors.Wrapf(define.ErrOCIRuntimePermissionDenied, "%s", strings.Trim(errStr, "\n")) 133 } 134 if match := regexp.MustCompile("(?i).*executable file not found in.*|.*no such file or directory.*").FindString(runtimeMsg); match != "" { 135 errStr := match 136 if includeFullOutput { 137 errStr = runtimeMsg 138 } 139 return errors.Wrapf(define.ErrOCIRuntimeNotFound, "%s", strings.Trim(errStr, "\n")) 140 } 141 if match := regexp.MustCompile("`/proc/[a-z0-9-].+/attr.*`").FindString(runtimeMsg); match != "" { 142 errStr := match 143 if includeFullOutput { 144 errStr = runtimeMsg 145 } 146 if strings.HasSuffix(match, "/exec`") { 147 return errors.Wrapf(define.ErrSetSecurityAttribute, "%s", strings.Trim(errStr, "\n")) 148 } else if strings.HasSuffix(match, "/current`") { 149 return errors.Wrapf(define.ErrGetSecurityAttribute, "%s", strings.Trim(errStr, "\n")) 150 } 151 return errors.Wrapf(define.ErrSecurityAttribute, "%s", strings.Trim(errStr, "\n")) 152 } 153 return errors.Wrapf(define.ErrOCIRuntime, "%s", strings.Trim(runtimeMsg, "\n")) 154 }