pkg/config: read user local config also as root

There is really no need to limit reading the config under
$XDG_CONFIG_HOME or $HOME to rootless users only. This poses two
problems, first on a multi user system any config that should be only
applied to root in /etc will also be read by all other users which makes
this impossible to use without having all user overwrite that option
with their local containers.conf. If we read the config from $HOME as
root as well then such changes are easy.
Second, because connections/farms are currently written by the cli it
means as root is tries to write under /etc which is not good as in some
envs /etc is mounted read only.

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:
Paul Holzinger 2024-01-05 15:37:52 +01:00
parent 029ea2b917
commit 8f0f7109e5
9 changed files with 48 additions and 96 deletions

View File

@ -11,10 +11,9 @@ a TOML format that can be easily modified and versioned.
Container engines read the __/usr/share/containers/containers.conf__,
__/etc/containers/containers.conf__, and __/etc/containers/containers.conf.d/\*.conf__
files if they exist.
When running in rootless mode, they also read
__$HOME/.config/containers/containers.conf__ and
__$HOME/.config/containers/containers.conf.d/\*.conf__ files.
for global configuration that effects all users.
For user specific configuration it reads __\$XDG_CONFIG_HOME/containers/containers.conf__ and
__\$XDG_CONFIG_HOME/containers/containers.conf.d/\*.conf__ files. When `$XDG_CONFIG_HOME` is not set it falls back to using `$HOME/.config` instead.
Fields specified in containers conf override the default options, as well as
options in previously read containers.conf files.
@ -42,13 +41,13 @@ instance, `CONTAINERS_CONF=/tmp/my_containers.conf`.
## MODULES
A module is a containers.conf file located directly in or a sub-directory of the following three directories:
- __$HOME/.config/containers/containers.conf.modules__
- __\$XDG_CONFIG_HOME/containers/containers.conf.modules__ or __\$HOME/.config/containers/containers.conf.modules__ if `$XDG_CONFIG_HOME` is not set.
- __/etc/containers/containers.conf.modules__
- __/usr/share/containers/containers.conf.modules__
Files in those locations are not loaded by default but only on-demand. They are loaded after all system and user configuration files but before `CONTAINERS_CONF_OVERRIDE` hence allowing for overriding system and user configs.
Modules are currently supported by podman(1). The `podman --module` flag allows for loading a module and can be specified multiple times. If the specified value is an absolute path, the config file will be loaded directly. Relative paths are resolved relative to the three module directories mentioned above and in the specified order such that modules in `$HOME` allow for overriding those in `/etc` and `/usr/share`. Modules in `$HOME` (or `$XDG_CONFIG_HOME` if specified) are only used for rootless users.
Modules are currently supported by podman(1). The `podman --module` flag allows for loading a module and can be specified multiple times. If the specified value is an absolute path, the config file will be loaded directly. Relative paths are resolved relative to the three module directories mentioned above and in the specified order such that modules in `$XDG_CONFIG_HOME/$HOME` allow for overriding those in `/etc` and `/usr/share`.
## APPENDING TO STRING ARRAYS
@ -459,7 +458,7 @@ and "$graphroot/networks" as rootless.
**firewall_driver**=""
The firewall driver to be used by netavark.
The default is empty which means netavark will pick one accordingly. Current supported
The default is empty which means netavark will pick one accordingly. Current supported
drivers are "iptables", "none" (no firewall rules will be created) and "firewalld" (firewalld is
experimental at the moment and not recommend outside of testing). In the future we are
planning to add support for a "nftables" driver.
@ -952,8 +951,8 @@ provide a default configuration. Administrators can override fields in this
file by creating __/etc/containers/containers.conf__ to specify their own
configuration. They may also drop `.conf` files in
__/etc/containers/containers.conf.d__ which will be loaded in alphanumeric order.
Rootless users can further override fields in the config by creating a config
file stored in the __$HOME/.config/containers/containers.conf__ file or __.conf__ files in __$HOME/.config/containers/containers.conf.d__.
For user specific configuration it reads __\$XDG_CONFIG_HOME/containers/containers.conf__ and
__\$XDG_CONFIG_HOME/containers/containers.conf.d/\*.conf__ files. When `$XDG_CONFIG_HOME` is not set it falls back to using `$HOME/.config` instead.
Fields specified in a containers.conf file override the default options, as
well as options in previously loaded containers.conf files.

View File

@ -1008,16 +1008,11 @@ func IsValidDeviceMode(mode string) bool {
return true
}
func rootlessConfigPath() (string, error) {
if configHome := os.Getenv("XDG_CONFIG_HOME"); configHome != "" {
return filepath.Join(configHome, _configPath), nil
func customConfigFile() (string, error) {
if path, found := os.LookupEnv(containersConfEnv); found {
return path, nil
}
home, err := unshare.HomeDir()
if err != nil {
return "", err
}
return filepath.Join(home, UserOverrideContainersConfig), nil
return userConfigPath()
}
// ReadCustomConfig reads the custom config and only generates a config based on it

View File

@ -1,9 +1,5 @@
package config
import (
"os"
)
const (
// OverrideContainersConfig holds the default config path overridden by the root user
OverrideContainersConfig = "/etc/" + _configPath
@ -19,18 +15,6 @@ const (
_typeBind = "bind"
)
// podman remote clients on darwin cannot use unshare.isRootless() to determine the configuration file locations.
func customConfigFile() (string, error) {
if path, found := os.LookupEnv(containersConfEnv); found {
return path, nil
}
return rootlessConfigPath()
}
func ifRootlessConfigPath() (string, error) {
return rootlessConfigPath()
}
var defaultHelperBinariesDir = []string{
// Relative to the binary directory
"$BINDIR/../libexec/podman",

View File

@ -1,9 +1,5 @@
package config
import (
"os"
)
const (
// OverrideContainersConfig holds the default config path overridden by the root user
OverrideContainersConfig = "/usr/local/etc/" + _configPath
@ -19,18 +15,6 @@ const (
_typeBind = "nullfs"
)
// podman remote clients on freebsd cannot use unshare.isRootless() to determine the configuration file locations.
func customConfigFile() (string, error) {
if path, found := os.LookupEnv(containersConfEnv); found {
return path, nil
}
return rootlessConfigPath()
}
func ifRootlessConfigPath() (string, error) {
return rootlessConfigPath()
}
var defaultHelperBinariesDir = []string{
"/usr/local/bin",
"/usr/local/libexec/podman",

View File

@ -1,9 +1,6 @@
package config
import (
"os"
"github.com/containers/storage/pkg/unshare"
selinux "github.com/opencontainers/selinux/go-selinux"
)
@ -26,31 +23,6 @@ func selinuxEnabled() bool {
return selinux.GetEnabled()
}
func customConfigFile() (string, error) {
if path, found := os.LookupEnv(containersConfEnv); found {
return path, nil
}
if unshare.GetRootlessUID() > 0 {
path, err := rootlessConfigPath()
if err != nil {
return "", err
}
return path, nil
}
return OverrideContainersConfig, nil
}
func ifRootlessConfigPath() (string, error) {
if unshare.GetRootlessUID() > 0 {
path, err := rootlessConfigPath()
if err != nil {
return "", err
}
return path, nil
}
return "", nil
}
var defaultHelperBinariesDir = []string{
"/usr/local/libexec/podman",
"/usr/local/lib/podman",

View File

@ -0,0 +1,25 @@
//go:build !windows
package config
import (
"os"
"path/filepath"
"github.com/containers/storage/pkg/unshare"
)
// userConfigPath returns the path to the users local config that is
// not shared with other users. It uses $XDG_CONFIG_HOME/containers...
// if set or $HOME/.config/containers... if not.
func userConfigPath() (string, error) {
if configHome := os.Getenv("XDG_CONFIG_HOME"); configHome != "" {
return filepath.Join(configHome, _configPath), nil
}
home, err := unshare.HomeDir()
if err != nil {
return "", err
}
return filepath.Join(home, UserOverrideContainersConfig), nil
}

View File

@ -17,15 +17,9 @@ const (
_typeBind = "bind"
)
// podman remote clients on windows cannot use unshare.isRootless() to determine the configuration file locations.
func customConfigFile() (string, error) {
if path, found := os.LookupEnv(containersConfEnv); found {
return path, nil
}
return os.Getenv("APPDATA") + "\\containers\\containers.conf", nil
}
func ifRootlessConfigPath() (string, error) {
// userConfigPath returns the path to the users local config that is
// not shared with other users. It uses $APPDATA/containers...
func userConfigPath() (string, error) {
return os.Getenv("APPDATA") + "\\containers\\containers.conf", nil
}

View File

@ -10,7 +10,8 @@
# locations in the following order:
# 1. /usr/share/containers/containers.conf
# 2. /etc/containers/containers.conf
# 3. $HOME/.config/containers/containers.conf (Rootless containers ONLY)
# 3. $XDG_CONFIG_HOME/containers/containers.conf or
# $HOME/.config/containers/containers.conf if $XDG_CONFIG_HOME is not set
# Items specified in the latter containers.conf, if they exist, override the
# previous containers.conf settings, or the default settings.
@ -348,7 +349,7 @@ default_sysctls = [
#]
# The firewall driver to be used by netavark.
# The default is empty which means netavark will pick one accordingly. Current supported
# The default is empty which means netavark will pick one accordingly. Current supported
# drivers are "iptables", "none" (no firewall rules will be created) and "firewalld" (firewalld is
# experimental at the moment and not recommend outside of testing). In the future we are
# planning to add support for a "nftables" driver.

View File

@ -165,16 +165,14 @@ func systemConfigs() (configs []string, finalErr error) {
return nil, err
}
path, err := ifRootlessConfigPath()
path, err := userConfigPath()
if err != nil {
return nil, err
}
if path != "" {
configs = append(configs, path)
configs, err = addConfigs(path+".d", configs)
if err != nil {
return nil, err
}
configs = append(configs, path)
configs, err = addConfigs(path+".d", configs)
if err != nil {
return nil, err
}
return configs, nil
}