github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/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/libpod/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  		switch i.Protocol {
    40  		case "udp":
    41  			addr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", i.HostIP, i.HostPort))
    42  			if err != nil {
    43  				return nil, errors.Wrapf(err, "cannot resolve the UDP address")
    44  			}
    45  
    46  			server, err := net.ListenUDP("udp", addr)
    47  			if err != nil {
    48  				return nil, errors.Wrapf(err, "cannot listen on the UDP port")
    49  			}
    50  			f, err := server.File()
    51  			if err != nil {
    52  				return nil, errors.Wrapf(err, "cannot get file for UDP socket")
    53  			}
    54  			files = append(files, f)
    55  
    56  		case "tcp":
    57  			addr, err := net.ResolveTCPAddr("tcp4", fmt.Sprintf("%s:%d", i.HostIP, i.HostPort))
    58  			if err != nil {
    59  				return nil, errors.Wrapf(err, "cannot resolve the TCP address")
    60  			}
    61  
    62  			server, err := net.ListenTCP("tcp4", addr)
    63  			if err != nil {
    64  				return nil, errors.Wrapf(err, "cannot listen on the TCP port")
    65  			}
    66  			f, err := server.File()
    67  			if err != nil {
    68  				return nil, errors.Wrapf(err, "cannot get file for TCP socket")
    69  			}
    70  			files = append(files, f)
    71  		case "sctp":
    72  			if !notifySCTP {
    73  				notifySCTP = true
    74  				logrus.Warnf("port reservation for SCTP is not supported")
    75  			}
    76  		default:
    77  			return nil, fmt.Errorf("unknown protocol %s", i.Protocol)
    78  
    79  		}
    80  	}
    81  	return files, nil
    82  }
    83  
    84  func getOCIRuntimeError(runtimeMsg string) error {
    85  	includeFullOutput := logrus.GetLevel() == logrus.DebugLevel
    86  
    87  	if match := regexp.MustCompile("(?i).*permission denied.*|.*operation not permitted.*").FindString(runtimeMsg); match != "" {
    88  		errStr := match
    89  		if includeFullOutput {
    90  			errStr = runtimeMsg
    91  		}
    92  		return errors.Wrapf(define.ErrOCIRuntimePermissionDenied, "%s", strings.Trim(errStr, "\n"))
    93  	}
    94  	if match := regexp.MustCompile("(?i).*executable file not found in.*|.*no such file or directory.*").FindString(runtimeMsg); match != "" {
    95  		errStr := match
    96  		if includeFullOutput {
    97  			errStr = runtimeMsg
    98  		}
    99  		return errors.Wrapf(define.ErrOCIRuntimeNotFound, "%s", strings.Trim(errStr, "\n"))
   100  	}
   101  	return errors.Wrapf(define.ErrOCIRuntime, "%s", strings.Trim(runtimeMsg, "\n"))
   102  }