From b96be3af1b9d00662758211420c955becbaf2f9e Mon Sep 17 00:00:00 2001
From: baude <bbaude@redhat.com>
Date: Wed, 20 Jun 2018 13:23:24 -0500
Subject: changes to allow for darwin compilation

Signed-off-by: baude <bbaude@redhat.com>

Closes: #1015
Approved by: baude
---
 pkg/chrootuser/user.go               |   6 ++
 pkg/chrootuser/user_linux.go         |   4 --
 pkg/rootless/rootless.go             | 104 +------------------------------
 pkg/rootless/rootless_linux.go       | 117 +++++++++++++++++++++++++++++++++++
 pkg/rootless/rootless_unsupported.go |  18 ++++++
 pkg/spec/config_linux.go             |  84 +++++++++++++++++++++++++
 pkg/spec/config_unsupported.go       |  12 ++++
 pkg/spec/createconfig.go             |  17 -----
 pkg/spec/parse.go                    |  15 -----
 pkg/spec/spec.go                     |  43 ++-----------
 10 files changed, 243 insertions(+), 177 deletions(-)
 create mode 100644 pkg/rootless/rootless_linux.go
 create mode 100644 pkg/rootless/rootless_unsupported.go
 create mode 100644 pkg/spec/config_linux.go
 create mode 100644 pkg/spec/config_unsupported.go

(limited to 'pkg')

diff --git a/pkg/chrootuser/user.go b/pkg/chrootuser/user.go
index 1fbb5566e..3de138b86 100644
--- a/pkg/chrootuser/user.go
+++ b/pkg/chrootuser/user.go
@@ -8,6 +8,12 @@ import (
 	"github.com/pkg/errors"
 )
 
+var (
+	// ErrNoSuchUser indicates that the user provided by the caller does not
+	// exist in /etc/passws
+	ErrNoSuchUser = errors.New("user does not exist in /etc/passwd")
+)
+
 // GetUser will return the uid, gid of the user specified in the userspec
 // it will use the /etc/passwd and /etc/group files inside of the rootdir
 // to return this information.
diff --git a/pkg/chrootuser/user_linux.go b/pkg/chrootuser/user_linux.go
index d48a1c7c2..acd0af822 100644
--- a/pkg/chrootuser/user_linux.go
+++ b/pkg/chrootuser/user_linux.go
@@ -4,7 +4,6 @@ package chrootuser
 
 import (
 	"bufio"
-	"errors"
 	"flag"
 	"fmt"
 	"io"
@@ -79,9 +78,6 @@ func openChrootedFile(rootdir, filename string) (*exec.Cmd, io.ReadCloser, error
 
 var (
 	lookupUser, lookupGroup sync.Mutex
-	// ErrNoSuchUser indicates that the user provided by the caller does not
-	// exist in /etc/passws
-	ErrNoSuchUser = errors.New("user does not exist in /etc/passwd")
 )
 
 type lookupPasswdEntry struct {
diff --git a/pkg/rootless/rootless.go b/pkg/rootless/rootless.go
index 737fc91c7..ca851f9bc 100644
--- a/pkg/rootless/rootless.go
+++ b/pkg/rootless/rootless.go
@@ -2,16 +2,9 @@ package rootless
 
 import (
 	"fmt"
-	"io/ioutil"
+	"github.com/containers/storage/pkg/idtools"
 	"os"
 	"os/exec"
-	gosignal "os/signal"
-	"runtime"
-	"syscall"
-
-	"github.com/containers/storage/pkg/idtools"
-	"github.com/docker/docker/pkg/signal"
-	"github.com/pkg/errors"
 )
 
 /*
@@ -25,11 +18,6 @@ func runInUser() error {
 	return nil
 }
 
-// IsRootless tells us if we are running in rootless mode
-func IsRootless() bool {
-	return os.Getuid() != 0 || os.Getenv("_LIBPOD_USERNS_CONFIGURED") != ""
-}
-
 func tryMappingTool(tool string, pid int, hostID int, mappings []idtools.IDMap) error {
 	path, err := exec.LookPath(tool)
 	if err != nil {
@@ -53,93 +41,3 @@ func tryMappingTool(tool string, pid int, hostID int, mappings []idtools.IDMap)
 	}
 	return cmd.Run()
 }
-
-// BecomeRootInUserNS re-exec podman in a new userNS
-func BecomeRootInUserNS() (bool, error) {
-
-	if os.Getuid() == 0 || os.Getenv("_LIBPOD_USERNS_CONFIGURED") != "" {
-		if os.Getenv("_LIBPOD_USERNS_CONFIGURED") == "init" {
-			return false, runInUser()
-		}
-		return false, nil
-	}
-
-	runtime.LockOSThread()
-	defer runtime.UnlockOSThread()
-
-	r, w, err := os.Pipe()
-	if err != nil {
-		return false, err
-	}
-	defer r.Close()
-	defer w.Close()
-
-	pidC := C.reexec_in_user_namespace(C.int(r.Fd()))
-	pid := int(pidC)
-	if pid < 0 {
-		return false, errors.Errorf("cannot re-exec process")
-	}
-
-	setgroups := fmt.Sprintf("/proc/%d/setgroups", pid)
-	err = ioutil.WriteFile(setgroups, []byte("deny\n"), 0666)
-	if err != nil {
-		return false, errors.Wrapf(err, "cannot write setgroups file")
-	}
-
-	var uids, gids []idtools.IDMap
-	username := os.Getenv("USER")
-	mappings, err := idtools.NewIDMappings(username, username)
-	if err == nil {
-		uids = mappings.UIDs()
-		gids = mappings.GIDs()
-	}
-
-	uidsMapped := false
-	if mappings != nil && uids != nil {
-		uidsMapped = tryMappingTool("newuidmap", pid, os.Getuid(), uids) == nil
-	}
-	if !uidsMapped {
-		uidMap := fmt.Sprintf("/proc/%d/uid_map", pid)
-		err = ioutil.WriteFile(uidMap, []byte(fmt.Sprintf("%d %d 1\n", 0, os.Getuid())), 0666)
-		if err != nil {
-			return false, errors.Wrapf(err, "cannot write uid_map")
-		}
-	}
-
-	gidsMapped := false
-	if mappings != nil && gids != nil {
-		gidsMapped = tryMappingTool("newgidmap", pid, os.Getgid(), gids) == nil
-	}
-	if !gidsMapped {
-		gidMap := fmt.Sprintf("/proc/%d/gid_map", pid)
-		err = ioutil.WriteFile(gidMap, []byte(fmt.Sprintf("%d %d 1\n", 0, os.Getgid())), 0666)
-		if err != nil {
-			return false, errors.Wrapf(err, "cannot write gid_map")
-		}
-	}
-
-	_, err = w.Write([]byte("1"))
-	if err != nil {
-		return false, errors.Wrapf(err, "write to sync pipe")
-	}
-
-	c := make(chan os.Signal, 1)
-
-	gosignal.Notify(c)
-	defer gosignal.Reset()
-	go func() {
-		for s := range c {
-			if s == signal.SIGCHLD || s == signal.SIGPIPE {
-				continue
-			}
-
-			syscall.Kill(int(pidC), s.(syscall.Signal))
-		}
-	}()
-
-	if C.reexec_in_user_namespace_wait(pidC) < 0 {
-		return false, errors.Wrapf(err, "error waiting for the re-exec process")
-	}
-
-	return true, nil
-}
diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go
new file mode 100644
index 000000000..5b4094bf2
--- /dev/null
+++ b/pkg/rootless/rootless_linux.go
@@ -0,0 +1,117 @@
+// build +linux
+
+package rootless
+
+import (
+	"fmt"
+	"io/ioutil"
+	"os"
+	gosignal "os/signal"
+	"runtime"
+	"syscall"
+
+	"github.com/containers/storage/pkg/idtools"
+	"github.com/docker/docker/pkg/signal"
+	"github.com/pkg/errors"
+)
+
+/*
+extern int reexec_in_user_namespace(int ready);
+extern int reexec_in_user_namespace_wait(int pid);
+*/
+import "C"
+
+// IsRootless tells us if we are running in rootless mode
+func IsRootless() bool {
+	return os.Getuid() != 0 || os.Getenv("_LIBPOD_USERNS_CONFIGURED") != ""
+}
+
+// BecomeRootInUserNS re-exec podman in a new userNS
+func BecomeRootInUserNS() (bool, error) {
+
+	if os.Getuid() == 0 || os.Getenv("_LIBPOD_USERNS_CONFIGURED") != "" {
+		if os.Getenv("_LIBPOD_USERNS_CONFIGURED") == "init" {
+			return false, runInUser()
+		}
+		return false, nil
+	}
+
+	runtime.LockOSThread()
+	defer runtime.UnlockOSThread()
+
+	r, w, err := os.Pipe()
+	if err != nil {
+		return false, err
+	}
+	defer r.Close()
+	defer w.Close()
+
+	pidC := C.reexec_in_user_namespace(C.int(r.Fd()))
+	pid := int(pidC)
+	if pid < 0 {
+		return false, errors.Errorf("cannot re-exec process")
+	}
+
+	setgroups := fmt.Sprintf("/proc/%d/setgroups", pid)
+	err = ioutil.WriteFile(setgroups, []byte("deny\n"), 0666)
+	if err != nil {
+		return false, errors.Wrapf(err, "cannot write setgroups file")
+	}
+
+	var uids, gids []idtools.IDMap
+	username := os.Getenv("USER")
+	mappings, err := idtools.NewIDMappings(username, username)
+	if err == nil {
+		uids = mappings.UIDs()
+		gids = mappings.GIDs()
+	}
+
+	uidsMapped := false
+	if mappings != nil && uids != nil {
+		uidsMapped = tryMappingTool("newuidmap", pid, os.Getuid(), uids) == nil
+	}
+	if !uidsMapped {
+		uidMap := fmt.Sprintf("/proc/%d/uid_map", pid)
+		err = ioutil.WriteFile(uidMap, []byte(fmt.Sprintf("%d %d 1\n", 0, os.Getuid())), 0666)
+		if err != nil {
+			return false, errors.Wrapf(err, "cannot write uid_map")
+		}
+	}
+
+	gidsMapped := false
+	if mappings != nil && gids != nil {
+		gidsMapped = tryMappingTool("newgidmap", pid, os.Getgid(), gids) == nil
+	}
+	if !gidsMapped {
+		gidMap := fmt.Sprintf("/proc/%d/gid_map", pid)
+		err = ioutil.WriteFile(gidMap, []byte(fmt.Sprintf("%d %d 1\n", 0, os.Getgid())), 0666)
+		if err != nil {
+			return false, errors.Wrapf(err, "cannot write gid_map")
+		}
+	}
+
+	_, err = w.Write([]byte("1"))
+	if err != nil {
+		return false, errors.Wrapf(err, "write to sync pipe")
+	}
+
+	c := make(chan os.Signal, 1)
+
+	gosignal.Notify(c)
+	defer gosignal.Reset()
+	go func() {
+		for s := range c {
+			if s == signal.SIGCHLD || s == signal.SIGPIPE {
+				continue
+			}
+
+			syscall.Kill(int(pidC), s.(syscall.Signal))
+		}
+	}()
+
+	if C.reexec_in_user_namespace_wait(pidC) < 0 {
+		return false, errors.Wrapf(err, "error waiting for the re-exec process")
+	}
+
+	return true, nil
+}
diff --git a/pkg/rootless/rootless_unsupported.go b/pkg/rootless/rootless_unsupported.go
new file mode 100644
index 000000000..e4067a764
--- /dev/null
+++ b/pkg/rootless/rootless_unsupported.go
@@ -0,0 +1,18 @@
+// +build !linux
+
+package rootless
+
+import (
+	"github.com/pkg/errors"
+)
+
+// IsRootless returns false on all non-linux platforms
+func IsRootless() bool {
+	return false
+}
+
+// BecomeRootInUserNS is a stub function that always returns false and an
+// error on unsupported OS's
+func BecomeRootInUserNS() (bool, error) {
+	return false, errors.New("this function is not supported on this os")
+}
diff --git a/pkg/spec/config_linux.go b/pkg/spec/config_linux.go
new file mode 100644
index 000000000..69b99232f
--- /dev/null
+++ b/pkg/spec/config_linux.go
@@ -0,0 +1,84 @@
+// +build linux
+
+package createconfig
+
+import (
+	"io/ioutil"
+
+	"github.com/docker/docker/profiles/seccomp"
+	"github.com/opencontainers/runc/libcontainer/configs"
+	"github.com/opencontainers/runc/libcontainer/devices"
+	spec "github.com/opencontainers/runtime-spec/specs-go"
+	"github.com/opencontainers/runtime-tools/generate"
+	"github.com/pkg/errors"
+)
+
+// Device transforms a libcontainer configs.Device to a specs.LinuxDevice object.
+func Device(d *configs.Device) spec.LinuxDevice {
+	return spec.LinuxDevice{
+		Type:     string(d.Type),
+		Path:     d.Path,
+		Major:    d.Major,
+		Minor:    d.Minor,
+		FileMode: fmPtr(int64(d.FileMode)),
+		UID:      u32Ptr(int64(d.Uid)),
+		GID:      u32Ptr(int64(d.Gid)),
+	}
+}
+
+func addDevice(g *generate.Generator, device string) error {
+	dev, err := devices.DeviceFromPath(device, "rwm")
+	if err != nil {
+		return errors.Wrapf(err, "%s is not a valid device", device)
+	}
+	linuxdev := spec.LinuxDevice{
+		Path:     dev.Path,
+		Type:     string(dev.Type),
+		Major:    dev.Major,
+		Minor:    dev.Minor,
+		FileMode: &dev.FileMode,
+		UID:      &dev.Uid,
+		GID:      &dev.Gid,
+	}
+	g.AddDevice(linuxdev)
+	g.AddLinuxResourcesDevice(true, string(dev.Type), &dev.Major, &dev.Minor, dev.Permissions)
+	return nil
+}
+
+// AddPrivilegedDevices iterates through host devices and adds all
+// host devices to the spec
+func (c *CreateConfig) AddPrivilegedDevices(g *generate.Generator) error {
+	hostDevices, err := devices.HostDevices()
+	if err != nil {
+		return err
+	}
+	g.ClearLinuxDevices()
+	for _, d := range hostDevices {
+		g.AddDevice(Device(d))
+	}
+	g.AddLinuxResourcesDevice(true, "", nil, nil, "rwm")
+	return nil
+}
+
+func getSeccompConfig(config *CreateConfig, configSpec *spec.Spec) (*spec.LinuxSeccomp, error) {
+	var seccompConfig *spec.LinuxSeccomp
+	var err error
+
+	if config.SeccompProfilePath != "" {
+		seccompProfile, err := ioutil.ReadFile(config.SeccompProfilePath)
+		if err != nil {
+			return nil, errors.Wrapf(err, "opening seccomp profile (%s) failed", config.SeccompProfilePath)
+		}
+		seccompConfig, err = seccomp.LoadProfile(string(seccompProfile), configSpec)
+		if err != nil {
+			return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath)
+		}
+	} else {
+		seccompConfig, err = seccomp.GetDefaultProfile(configSpec)
+		if err != nil {
+			return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath)
+		}
+	}
+
+	return seccompConfig, nil
+}
diff --git a/pkg/spec/config_unsupported.go b/pkg/spec/config_unsupported.go
new file mode 100644
index 000000000..b3b05acea
--- /dev/null
+++ b/pkg/spec/config_unsupported.go
@@ -0,0 +1,12 @@
+// +build !linux
+
+package createconfig
+
+import (
+	spec "github.com/opencontainers/runtime-spec/specs-go"
+	"github.com/pkg/errors"
+)
+
+func getSeccompConfig(config *CreateConfig, configSpec *spec.Spec) (*spec.LinuxSeccomp, error) {
+	return nil, errors.New("function not supported on non-linux OS's")
+}
diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go
index 27df0c395..451c09eb3 100644
--- a/pkg/spec/createconfig.go
+++ b/pkg/spec/createconfig.go
@@ -10,9 +10,7 @@ import (
 	"github.com/cri-o/ocicni/pkg/ocicni"
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/go-connections/nat"
-	"github.com/opencontainers/runc/libcontainer/devices"
 	spec "github.com/opencontainers/runtime-spec/specs-go"
-	"github.com/opencontainers/runtime-tools/generate"
 	"github.com/opencontainers/selinux/go-selinux/label"
 	"github.com/pkg/errors"
 	"github.com/projectatomic/libpod/libpod"
@@ -488,21 +486,6 @@ func (c *CreateConfig) CreatePortBindings() ([]ocicni.PortMapping, error) {
 	return portBindings, nil
 }
 
-// AddPrivilegedDevices iterates through host devices and adds all
-// host devices to the spec
-func (c *CreateConfig) AddPrivilegedDevices(g *generate.Generator) error {
-	hostDevices, err := devices.HostDevices()
-	if err != nil {
-		return err
-	}
-	g.ClearLinuxDevices()
-	for _, d := range hostDevices {
-		g.AddDevice(Device(d))
-	}
-	g.AddLinuxResourcesDevice(true, "", nil, nil, "rwm")
-	return nil
-}
-
 func getStatFromPath(path string) (unix.Stat_t, error) {
 	s := unix.Stat_t{}
 	err := unix.Stat(path, &s)
diff --git a/pkg/spec/parse.go b/pkg/spec/parse.go
index 920674b10..82ca92dff 100644
--- a/pkg/spec/parse.go
+++ b/pkg/spec/parse.go
@@ -6,8 +6,6 @@ import (
 	"strings"
 
 	"github.com/docker/go-units"
-	"github.com/opencontainers/runc/libcontainer/configs"
-	spec "github.com/opencontainers/runtime-spec/specs-go"
 )
 
 // weightDevice is a structure that holds device:weight pair
@@ -113,16 +111,3 @@ func getLoggingPath(opts []string) string {
 	}
 	return ""
 }
-
-// Device transforms a libcontainer configs.Device to a specs.LinuxDevice object.
-func Device(d *configs.Device) spec.LinuxDevice {
-	return spec.LinuxDevice{
-		Type:     string(d.Type),
-		Path:     d.Path,
-		Major:    d.Major,
-		Minor:    d.Minor,
-		FileMode: fmPtr(int64(d.FileMode)),
-		UID:      u32Ptr(int64(d.Uid)),
-		GID:      u32Ptr(int64(d.Gid)),
-	}
-}
diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go
index 2faa3c2cd..f9c60fdfa 100644
--- a/pkg/spec/spec.go
+++ b/pkg/spec/spec.go
@@ -6,14 +6,11 @@ import (
 	"github.com/docker/docker/daemon/caps"
 	"github.com/docker/docker/pkg/mount"
 	"github.com/docker/go-units"
-	"github.com/opencontainers/runc/libcontainer/devices"
 	spec "github.com/opencontainers/runtime-spec/specs-go"
 	"github.com/opencontainers/runtime-tools/generate"
 	"github.com/pkg/errors"
 	"github.com/projectatomic/libpod/pkg/rootless"
-	seccomp "github.com/seccomp/containers-golang"
 	"github.com/sirupsen/logrus"
-	"io/ioutil"
 )
 
 const cpuPeriod = 100000
@@ -236,24 +233,13 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
 	}
 
 	// HANDLE SECCOMP
+
 	if config.SeccompProfilePath != "unconfined" {
-		if config.SeccompProfilePath != "" {
-			seccompProfile, err := ioutil.ReadFile(config.SeccompProfilePath)
-			if err != nil {
-				return nil, errors.Wrapf(err, "opening seccomp profile (%s) failed", config.SeccompProfilePath)
-			}
-			seccompConfig, err := seccomp.LoadProfile(string(seccompProfile), configSpec)
-			if err != nil {
-				return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath)
-			}
-			configSpec.Linux.Seccomp = seccompConfig
-		} else {
-			seccompConfig, err := seccomp.GetDefaultProfile(configSpec)
-			if err != nil {
-				return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath)
-			}
-			configSpec.Linux.Seccomp = seccompConfig
+		seccompConfig, err := getSeccompConfig(config, configSpec)
+		if err != nil {
+			return nil, err
 		}
+		configSpec.Linux.Seccomp = seccompConfig
 	}
 
 	// Clear default Seccomp profile from Generator for privileged containers
@@ -429,22 +415,3 @@ func setupCapabilities(config *CreateConfig, configSpec *spec.Spec) error {
 	configSpec.Process.Capabilities.Bounding = caplist
 	return nil
 }
-
-func addDevice(g *generate.Generator, device string) error {
-	dev, err := devices.DeviceFromPath(device, "rwm")
-	if err != nil {
-		return errors.Wrapf(err, "%s is not a valid device", device)
-	}
-	linuxdev := spec.LinuxDevice{
-		Path:     dev.Path,
-		Type:     string(dev.Type),
-		Major:    dev.Major,
-		Minor:    dev.Minor,
-		FileMode: &dev.FileMode,
-		UID:      &dev.Uid,
-		GID:      &dev.Gid,
-	}
-	g.AddDevice(linuxdev)
-	g.AddLinuxResourcesDevice(true, string(dev.Type), &dev.Major, &dev.Minor, dev.Permissions)
-	return nil
-}
-- 
cgit v1.2.3-54-g00ecf