summaryrefslogtreecommitdiff
path: root/libpod/oci_util.go
diff options
context:
space:
mode:
authorMatthew Heon <matthew.heon@pm.me>2019-10-08 13:53:36 -0400
committerMatthew Heon <matthew.heon@pm.me>2019-10-10 10:19:32 -0400
commit6f630bc09b3e937fe3ddc4a829715bacd5b6c779 (patch)
tree4f95293e4673bd5f046847c6b669bf124e57e90c /libpod/oci_util.go
parenta7f266891ca20214f56d0bb742896e9112f4905a (diff)
downloadpodman-6f630bc09b3e937fe3ddc4a829715bacd5b6c779.tar.gz
podman-6f630bc09b3e937fe3ddc4a829715bacd5b6c779.tar.bz2
podman-6f630bc09b3e937fe3ddc4a829715bacd5b6c779.zip
Move OCI runtime implementation behind an interface
For future work, we need multiple implementations of the OCI runtime, not just a Conmon-wrapped runtime matching the runc CLI. As part of this, do some refactoring on the interface for exec (move to a struct, not a massive list of arguments). Also, add 'all' support to Kill and Stop (supported by runc and used a bit internally for removing containers). Signed-off-by: Matthew Heon <matthew.heon@pm.me>
Diffstat (limited to 'libpod/oci_util.go')
-rw-r--r--libpod/oci_util.go113
1 files changed, 113 insertions, 0 deletions
diff --git a/libpod/oci_util.go b/libpod/oci_util.go
new file mode 100644
index 000000000..cb85b153d
--- /dev/null
+++ b/libpod/oci_util.go
@@ -0,0 +1,113 @@
+package libpod
+
+import (
+ "fmt"
+ "net"
+ "os"
+ "regexp"
+ "strings"
+ "time"
+
+ "github.com/containers/libpod/libpod/define"
+ "github.com/cri-o/ocicni/pkg/ocicni"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+)
+
+const (
+ // CgroupfsCgroupsManager represents cgroupfs native cgroup manager
+ CgroupfsCgroupsManager = "cgroupfs"
+ // SystemdCgroupsManager represents systemd native cgroup manager
+ SystemdCgroupsManager = "systemd"
+
+ // ContainerCreateTimeout is the timeout before we decide we've failed
+ // to create a container.
+ // TODO: Make this generic - all OCI runtime operations should use the
+ // same timeout, this one.
+ // TODO: Consider dropping from 240 to 60 seconds. I don't think waiting
+ // 4 minutes versus 1 minute makes a real difference.
+ ContainerCreateTimeout = 240 * time.Second
+
+ // Timeout before declaring that runtime has failed to kill a given
+ // container
+ killContainerTimeout = 5 * time.Second
+ // DefaultShmSize is the default shm size
+ DefaultShmSize = 64 * 1024 * 1024
+ // NsRunDir is the default directory in which running network namespaces
+ // are stored
+ NsRunDir = "/var/run/netns"
+)
+
+// ociError is used to parse the OCI runtime JSON log. It is not part of the
+// OCI runtime specifications, it follows what runc does
+type ociError struct {
+ Level string `json:"level,omitempty"`
+ Time string `json:"time,omitempty"`
+ Msg string `json:"msg,omitempty"`
+}
+
+// Create systemd unit name for cgroup scopes
+func createUnitName(prefix string, name string) string {
+ return fmt.Sprintf("%s-%s.scope", prefix, name)
+}
+
+// Bind ports to keep them closed on the host
+func bindPorts(ports []ocicni.PortMapping) ([]*os.File, error) {
+ var files []*os.File
+ notifySCTP := false
+ for _, i := range ports {
+ switch i.Protocol {
+ case "udp":
+ addr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", i.HostIP, i.HostPort))
+ if err != nil {
+ return nil, errors.Wrapf(err, "cannot resolve the UDP address")
+ }
+
+ server, err := net.ListenUDP("udp", addr)
+ if err != nil {
+ return nil, errors.Wrapf(err, "cannot listen on the UDP port")
+ }
+ f, err := server.File()
+ if err != nil {
+ return nil, errors.Wrapf(err, "cannot get file for UDP socket")
+ }
+ files = append(files, f)
+
+ case "tcp":
+ addr, err := net.ResolveTCPAddr("tcp4", fmt.Sprintf("%s:%d", i.HostIP, i.HostPort))
+ if err != nil {
+ return nil, errors.Wrapf(err, "cannot resolve the TCP address")
+ }
+
+ server, err := net.ListenTCP("tcp4", addr)
+ if err != nil {
+ return nil, errors.Wrapf(err, "cannot listen on the TCP port")
+ }
+ f, err := server.File()
+ if err != nil {
+ return nil, errors.Wrapf(err, "cannot get file for TCP socket")
+ }
+ files = append(files, f)
+ case "sctp":
+ if !notifySCTP {
+ notifySCTP = true
+ logrus.Warnf("port reservation for SCTP is not supported")
+ }
+ default:
+ return nil, fmt.Errorf("unknown protocol %s", i.Protocol)
+
+ }
+ }
+ return files, nil
+}
+
+func getOCIRuntimeError(runtimeMsg string) error {
+ r := strings.ToLower(runtimeMsg)
+ if match, _ := regexp.MatchString(".*permission denied.*|.*operation not permitted.*", r); match {
+ return errors.Wrapf(define.ErrOCIRuntimePermissionDenied, "%s", strings.Trim(runtimeMsg, "\n"))
+ }
+ if match, _ := regexp.MatchString(".*executable file not found in.*|.*no such file or directory.*", r); match {
+ return errors.Wrapf(define.ErrOCIRuntimeNotFound, "%s", strings.Trim(runtimeMsg, "\n"))
+ }
+ return errors.Wrapf(define.ErrOCIRuntime, "%s", strings.Trim(runtimeMsg, "\n"))
+}