diff options
-rw-r--r-- | cmd/podman/cliconfig/config.go | 1 | ||||
-rw-r--r-- | cmd/podman/libpodruntime/runtime.go | 3 | ||||
-rw-r--r-- | cmd/podman/main.go | 1 | ||||
-rw-r--r-- | docs/libpod.conf.5.md | 4 | ||||
-rw-r--r-- | docs/podman.1.md | 3 | ||||
-rw-r--r-- | libpod/image/pull.go | 2 | ||||
-rw-r--r-- | libpod/networking_linux.go | 13 | ||||
-rw-r--r-- | libpod/options.go | 14 | ||||
-rw-r--r-- | libpod/runtime.go | 2 | ||||
-rw-r--r-- | pkg/rootless/rootless_linux.go | 59 | ||||
-rw-r--r-- | test/e2e/rootless_test.go | 2 |
11 files changed, 42 insertions, 62 deletions
diff --git a/cmd/podman/cliconfig/config.go b/cmd/podman/cliconfig/config.go index 7945cb6cb..d58964489 100644 --- a/cmd/podman/cliconfig/config.go +++ b/cmd/podman/cliconfig/config.go @@ -25,6 +25,7 @@ type MainFlags struct { StorageOpts []string Syslog bool Trace bool + NetworkCmdPath string Config string CpuProfile string diff --git a/cmd/podman/libpodruntime/runtime.go b/cmd/podman/libpodruntime/runtime.go index 2b96f0c20..3faea493c 100644 --- a/cmd/podman/libpodruntime/runtime.go +++ b/cmd/podman/libpodruntime/runtime.go @@ -86,6 +86,9 @@ func getRuntime(c *cliconfig.PodmanCommand, renumber bool) (*libpod.Runtime, err if c.Flags().Changed("tmpdir") { options = append(options, libpod.WithTmpDir(c.GlobalFlags.TmpDir)) } + if c.Flags().Changed("network-cmd-path") { + options = append(options, libpod.WithNetworkCmdPath(c.GlobalFlags.NetworkCmdPath)) + } if c.Flags().Changed("cgroup-manager") { options = append(options, libpod.WithCgroupManager(c.GlobalFlags.CGroupManager)) diff --git a/cmd/podman/main.go b/cmd/podman/main.go index 7d4b650a9..3571f526e 100644 --- a/cmd/podman/main.go +++ b/cmd/podman/main.go @@ -104,6 +104,7 @@ func init() { rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.CpuProfile, "cpu-profile", "", "Path for the cpu profiling results") rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.Config, "config", "", "Path of a libpod config file detailing container server configuration options") rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.ConmonPath, "conmon", "", "Path of the conmon binary") + rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.NetworkCmdPath, "network-cmd-path", "", "Path to the command for configuring the network") rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.CniConfigDir, "cni-config-dir", "", "Path of the configuration directory for CNI networks") rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.DefaultMountsFile, "default-mounts-file", "", "Path to default mounts file") rootCmd.PersistentFlags().MarkHidden("defaults-mount-file") diff --git a/docs/libpod.conf.5.md b/docs/libpod.conf.5.md index 9a19e1224..777edeacb 100644 --- a/docs/libpod.conf.5.md +++ b/docs/libpod.conf.5.md @@ -91,6 +91,10 @@ libpod to manage containers. Directory where named volumes will be created in using the default volume driver. By default this will be configured relative to where containers/storage stores containers. +**network_cmd_path**="" + Path to the command binary to use for setting up a network. It is currently only used for setting up + a slirp4netns network. If "" is used then the binary is looked up using the $PATH environment variable. + ## FILES `/usr/share/containers/libpod.conf`, default libpod configuration path diff --git a/docs/podman.1.md b/docs/podman.1.md index 5c930995c..0182690d0 100644 --- a/docs/podman.1.md +++ b/docs/podman.1.md @@ -72,6 +72,9 @@ Default state dir is configured in /etc/containers/storage.conf. Name of the OCI runtime as specified in libpod.conf or absolute path to the OCI compatible binary used to run containers. +**--network-cmd-path**=**path** +Path to the command binary to use for setting up a network. It is currently only used for setting up a slirp4netns network. If "" is used then the binary is looked up using the $PATH environment variable. + **--storage-driver**=**value** Storage driver. The default storage driver for UID 0 is configured in /etc/containers/storage.conf (`$HOME/.config/containers/storage.conf` in rootless mode), and is *vfs* for non-root users when *fuse-overlayfs* is not available. The `STORAGE_DRIVER` environment variable overrides the default. The --storage-driver specified driver overrides all. diff --git a/libpod/image/pull.go b/libpod/image/pull.go index 6b9f7fc67..607829771 100644 --- a/libpod/image/pull.go +++ b/libpod/image/pull.go @@ -267,7 +267,7 @@ func (ir *Runtime) doPullImage(ctx context.Context, sc *types.SystemContext, goa _, err = cp.Image(ctx, policyContext, imageInfo.dstRef, imageInfo.srcRef, copyOptions) if err != nil { pullErrors = multierror.Append(pullErrors, err) - logrus.Debugf("Error pulling image ref %s: %v", imageInfo.srcRef.StringWithinTransport(), err) + logrus.Errorf("Error pulling image ref %s: %v", imageInfo.srcRef.StringWithinTransport(), err) if writer != nil { io.WriteString(writer, "Failed\n") } diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index f9caf26d1..80d7d8213 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -139,10 +139,15 @@ func (r *Runtime) setupRootlessNetNS(ctr *Container) (err error) { defer ctr.rootlessSlirpSyncR.Close() defer ctr.rootlessSlirpSyncW.Close() - path, err := exec.LookPath("slirp4netns") - if err != nil { - logrus.Errorf("could not find slirp4netns, the network namespace won't be configured: %v", err) - return nil + path := r.config.NetworkCmdPath + + if path == "" { + var err error + path, err = exec.LookPath("slirp4netns") + if err != nil { + logrus.Errorf("could not find slirp4netns, the network namespace won't be configured: %v", err) + return nil + } } syncR, syncW, err := os.Pipe() diff --git a/libpod/options.go b/libpod/options.go index 5ad2824d9..64b425c57 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -193,6 +193,20 @@ func WithConmonEnv(environment []string) RuntimeOption { } } +// WithNetworkCmdPath specifies the path to the slirp4netns binary which manages the +// runtime. +func WithNetworkCmdPath(path string) RuntimeOption { + return func(rt *Runtime) error { + if rt.valid { + return ErrRuntimeFinalized + } + + rt.config.NetworkCmdPath = path + + return nil + } +} + // WithCgroupManager specifies the manager implementation name which is used to // handle cgroups for containers. // Current valid values are "cgroupfs" and "systemd". diff --git a/libpod/runtime.go b/libpod/runtime.go index 9667abfe6..535b6f41b 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -217,6 +217,8 @@ type RuntimeConfig struct { EnablePortReservation bool `toml:"enable_port_reservation"` // EnableLabeling indicates wether libpod will support container labeling EnableLabeling bool `toml:"label"` + // NetworkCmdPath is the path to the slirp4netns binary + NetworkCmdPath string `toml:"network_cmd_path"` // NumLocks is the number of locks to make available for containers and // pods. diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go index 933cfa2c2..d43151e8e 100644 --- a/pkg/rootless/rootless_linux.go +++ b/pkg/rootless/rootless_linux.go @@ -11,7 +11,6 @@ import ( "os/user" "runtime" "strconv" - "strings" "sync" "syscall" "unsafe" @@ -192,22 +191,6 @@ func JoinNSPath(path string) (bool, int, error) { return true, int(ret), nil } -const defaultMinimumMappings = 65536 - -func getMinimumIDs(p string) int { - content, err := ioutil.ReadFile(p) - if err != nil { - logrus.Debugf("error reading data from %q, use a default value of %d", p, defaultMinimumMappings) - return defaultMinimumMappings - } - ret, err := strconv.Atoi(strings.TrimSuffix(string(content), "\n")) - if err != nil { - logrus.Debugf("error reading data from %q, use a default value of %d", p, defaultMinimumMappings) - return defaultMinimumMappings - } - return ret + 1 -} - // BecomeRootInUserNS re-exec podman in a new userNS. It returns whether podman was re-executed // into a new user namespace and the return code from the re-executed podman process. // If podman was re-executed the caller needs to propagate the error code returned by the child @@ -237,47 +220,18 @@ func BecomeRootInUserNS() (bool, int, error) { return false, -1, errors.Errorf("cannot re-exec process") } - allowSingleIDMapping := os.Getenv("PODMAN_ALLOW_SINGLE_ID_MAPPING_IN_USERNS") != "" - var uids, gids []idtools.IDMap username := os.Getenv("USER") if username == "" { user, err := user.LookupId(fmt.Sprintf("%d", os.Getuid())) - if err != nil && !allowSingleIDMapping { - if os.IsNotExist(err) { - return false, 0, errors.Wrapf(err, "/etc/subuid or /etc/subgid does not exist, see subuid/subgid man pages for information on these files") - } - return false, 0, errors.Wrapf(err, "could not find user by UID nor USER env was set") - } if err == nil { username = user.Username } } mappings, err := idtools.NewIDMappings(username, username) - if !allowSingleIDMapping { - if err != nil { - return false, -1, err - } - - availableGIDs, availableUIDs := 0, 0 - for _, i := range mappings.UIDs() { - availableUIDs += i.Size - } - - minUIDs := getMinimumIDs("/proc/sys/kernel/overflowuid") - if availableUIDs < minUIDs { - return false, 0, fmt.Errorf("not enough UIDs available for the user, at least %d are needed", minUIDs) - } - - for _, i := range mappings.GIDs() { - availableGIDs += i.Size - } - minGIDs := getMinimumIDs("/proc/sys/kernel/overflowgid") - if availableGIDs < minGIDs { - return false, 0, fmt.Errorf("not enough GIDs available for the user, at least %d are needed", minGIDs) - } - } - if err == nil { + if err != nil { + logrus.Warnf("cannot find mappings for user %s: %v", username, err) + } else { uids = mappings.UIDs() gids = mappings.GIDs() } @@ -285,12 +239,10 @@ func BecomeRootInUserNS() (bool, int, error) { uidsMapped := false if mappings != nil && uids != nil { err := tryMappingTool("newuidmap", pid, os.Getuid(), uids) - if !allowSingleIDMapping && err != nil { - return false, 0, err - } uidsMapped = err == nil } if !uidsMapped { + logrus.Warnf("using rootless single mapping into the namespace. This might break some images. Check /etc/subuid and /etc/subgid for adding subids") setgroups := fmt.Sprintf("/proc/%d/setgroups", pid) err = ioutil.WriteFile(setgroups, []byte("deny\n"), 0666) if err != nil { @@ -307,9 +259,6 @@ func BecomeRootInUserNS() (bool, int, error) { gidsMapped := false if mappings != nil && gids != nil { err := tryMappingTool("newgidmap", pid, os.Getgid(), gids) - if !allowSingleIDMapping && err != nil { - return false, 0, err - } gidsMapped = err == nil } if !gidsMapped { diff --git a/test/e2e/rootless_test.go b/test/e2e/rootless_test.go index 908c459da..cd771e2ba 100644 --- a/test/e2e/rootless_test.go +++ b/test/e2e/rootless_test.go @@ -126,7 +126,6 @@ var _ = Describe("Podman rootless", func() { env := os.Environ() env = append(env, fmt.Sprintf("XDG_RUNTIME_DIR=%s", xdgRuntimeDir)) env = append(env, fmt.Sprintf("HOME=%s", home)) - env = append(env, "PODMAN_ALLOW_SINGLE_ID_MAPPING_IN_USERNS=1") env = append(env, "USER=foo") cmd := rootlessTest.PodmanAsUser([]string{"pod", "create", "--infra=false"}, 1000, 1000, "", env) @@ -171,7 +170,6 @@ var _ = Describe("Podman rootless", func() { env := os.Environ() env = append(env, fmt.Sprintf("XDG_RUNTIME_DIR=%s", xdgRuntimeDir)) env = append(env, fmt.Sprintf("HOME=%s", home)) - env = append(env, "PODMAN_ALLOW_SINGLE_ID_MAPPING_IN_USERNS=1") env = append(env, "USER=foo") allArgs := append([]string{"run"}, args...) |