Prefer loading docker-init
from an appropriate "libexec" directory
The `docker-init` binary is not intended to be a user-facing command, and as such it is more appropriate for it to be found in `/usr/libexec` (or similar) than in `PATH` (see the FHS, especially https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch04s07.html and https://refspecs.linuxfoundation.org/FHS_2.3/fhs-2.3.html#USRLIBLIBRARIESFORPROGRAMMINGANDPA). This adjusts the logic for using that configuration option to take this into account and appropriately search for `docker-init` (or the user's configured alternative) in these directories before falling back to the existing `PATH` lookup behavior. This behavior _used_ to exist for the old `dockerinit` binary (of a similar name and used in a similar way but for an alternative purpose), but that behavior was removed in4357ed4a73
when that older `dockerinit` was also removed. Most of this reasoning _also_ applies to `docker-proxy` (and various `containerd-xxx` binaries such as the shims), but this change does not affect those. It would be relatively straightforward to adapt `LookupInitPath` to be a more generic function such as `libexecLookupPath` or similar if we wanted to explore that. See14482589df/cli-plugins/manager/manager_unix.go
for the related path list in the CLI which loads CLI plugins from a similar set of paths (with a similar rationale - plugin binaries are not typically intended to be run directly by users but rather invoked _via_ the CLI binary). Signed-off-by: Tianon Gravi <admwiggin@gmail.com>
This commit is contained in:
parent
1855a55d8c
commit
6caaa8cadc
3 changed files with 43 additions and 17 deletions
|
@ -118,6 +118,34 @@ func (conf *Config) GetInitPath() string {
|
|||
return DefaultInitBinary
|
||||
}
|
||||
|
||||
// LookupInitPath returns an absolute path to the "docker-init" binary by searching relevant "libexec" directories (per FHS 3.0 & 2.3) followed by PATH
|
||||
func (conf *Config) LookupInitPath() (string, error) {
|
||||
binary := conf.GetInitPath()
|
||||
if filepath.IsAbs(binary) {
|
||||
return binary, nil
|
||||
}
|
||||
|
||||
for _, dir := range []string{
|
||||
// FHS 3.0: "/usr/libexec includes internal binaries that are not intended to be executed directly by users or shell scripts. Applications may use a single subdirectory under /usr/libexec."
|
||||
// https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch04s07.html
|
||||
"/usr/local/libexec/docker",
|
||||
"/usr/libexec/docker",
|
||||
|
||||
// FHS 2.3: "/usr/lib includes object files, libraries, and internal binaries that are not intended to be executed directly by users or shell scripts."
|
||||
// https://refspecs.linuxfoundation.org/FHS_2.3/fhs-2.3.html#USRLIBLIBRARIESFORPROGRAMMINGANDPA
|
||||
"/usr/local/lib/docker",
|
||||
"/usr/lib/docker",
|
||||
} {
|
||||
// exec.LookPath has a fast-path short-circuit for paths that contain "/" (skipping the PATH lookup) that then verifies whether the given path is likely to be an actual executable binary (so we invoke that instead of reimplementing the same checks)
|
||||
if file, err := exec.LookPath(filepath.Join(dir, binary)); err == nil {
|
||||
return file, nil
|
||||
}
|
||||
}
|
||||
|
||||
// if we checked all the "libexec" directories and found no matches, fall back to PATH
|
||||
return exec.LookPath(binary)
|
||||
}
|
||||
|
||||
// GetResolvConf returns the appropriate resolv.conf
|
||||
// Check setupResolvConf on how this is selected
|
||||
func (conf *Config) GetResolvConf() string {
|
||||
|
|
|
@ -40,7 +40,6 @@ func (daemon *Daemon) fillPlatformInfo(v *types.Info, sysInfo *sysinfo.SysInfo)
|
|||
}
|
||||
v.Runtimes = daemon.configStore.GetAllRuntimes()
|
||||
v.DefaultRuntime = daemon.configStore.GetDefaultRuntimeName()
|
||||
v.InitBinary = daemon.configStore.GetInitPath()
|
||||
v.RuncCommit.ID = "N/A"
|
||||
v.ContainerdCommit.ID = "N/A"
|
||||
v.InitCommit.ID = "N/A"
|
||||
|
@ -63,15 +62,17 @@ func (daemon *Daemon) fillPlatformInfo(v *types.Info, sysInfo *sysinfo.SysInfo)
|
|||
logrus.Warnf("failed to retrieve containerd version: %v", err)
|
||||
}
|
||||
|
||||
defaultInitBinary := daemon.configStore.GetInitPath()
|
||||
if rv, err := exec.Command(defaultInitBinary, "--version").Output(); err == nil {
|
||||
v.InitBinary = daemon.configStore.GetInitPath()
|
||||
if initBinary, err := daemon.configStore.LookupInitPath(); err != nil {
|
||||
logrus.Warnf("failed to find docker-init: %s", err)
|
||||
} else if rv, err := exec.Command(initBinary, "--version").Output(); err == nil {
|
||||
if _, commit, err := parseInitVersion(string(rv)); err != nil {
|
||||
logrus.Warnf("failed to parse %s version: %s", defaultInitBinary, err)
|
||||
logrus.Warnf("failed to parse %s version: %s", initBinary, err)
|
||||
} else {
|
||||
v.InitCommit.ID = commit
|
||||
}
|
||||
} else {
|
||||
logrus.Warnf("failed to retrieve %s version: %s", defaultInitBinary, err)
|
||||
logrus.Warnf("failed to retrieve %s version: %s", initBinary, err)
|
||||
}
|
||||
|
||||
// Set expected and actual commits to the same value to prevent the client
|
||||
|
@ -195,13 +196,14 @@ func (daemon *Daemon) fillPlatformVersion(v *types.Version) {
|
|||
}
|
||||
}
|
||||
|
||||
defaultInitBinary := daemon.configStore.GetInitPath()
|
||||
if rv, err := exec.Command(defaultInitBinary, "--version").Output(); err == nil {
|
||||
if initBinary, err := daemon.configStore.LookupInitPath(); err != nil {
|
||||
logrus.Warnf("failed to find docker-init: %s", err)
|
||||
} else if rv, err := exec.Command(initBinary, "--version").Output(); err == nil {
|
||||
if ver, commit, err := parseInitVersion(string(rv)); err != nil {
|
||||
logrus.Warnf("failed to parse %s version: %s", defaultInitBinary, err)
|
||||
logrus.Warnf("failed to parse %s version: %s", initBinary, err)
|
||||
} else {
|
||||
v.Components = append(v.Components, types.ComponentVersion{
|
||||
Name: filepath.Base(defaultInitBinary),
|
||||
Name: filepath.Base(initBinary),
|
||||
Version: ver,
|
||||
Details: map[string]string{
|
||||
"GitCommit": commit,
|
||||
|
@ -209,7 +211,7 @@ func (daemon *Daemon) fillPlatformVersion(v *types.Version) {
|
|||
})
|
||||
}
|
||||
} else {
|
||||
logrus.Warnf("failed to retrieve %s version: %s", defaultInitBinary, err)
|
||||
logrus.Warnf("failed to retrieve %s version: %s", initBinary, err)
|
||||
}
|
||||
|
||||
daemon.fillRootlessVersion(v)
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
@ -748,12 +747,9 @@ func WithCommonOptions(daemon *Daemon, c *container.Container) coci.SpecOpts {
|
|||
if (c.HostConfig.Init != nil && *c.HostConfig.Init) ||
|
||||
(c.HostConfig.Init == nil && daemon.configStore.Init) {
|
||||
s.Process.Args = append([]string{inContainerInitPath, "--", c.Path}, c.Args...)
|
||||
path := daemon.configStore.InitPath
|
||||
if path == "" {
|
||||
path, err = exec.LookPath(dconfig.DefaultInitBinary)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
path, err := daemon.configStore.LookupInitPath() // this will fall back to DefaultInitBinary and return an absolute path
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Mounts = append(s.Mounts, specs.Mount{
|
||||
Destination: inContainerInitPath,
|
||||
|
|
Loading…
Add table
Reference in a new issue