Merge pull request #45198 from tianon/libexec-docker-init

Prefer loading `docker-init` from an appropriate "libexec" directory
This commit is contained in:
Sebastiaan van Stijn 2023-03-29 00:47:13 +02:00 committed by GitHub
commit 0d761d19b9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 17 deletions

View file

@ -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 {

View file

@ -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)

View file

@ -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,