Merge pull request #1099 from giuseppe/per-user-conf-files

rootless: allow to override configuration files
This commit is contained in:
Matthew Heon
2018-07-20 12:29:04 -04:00
committed by GitHub
5 changed files with 44 additions and 12 deletions

View File

@ -57,6 +57,11 @@ func GetDefaultStoreOptions() (storage.StoreOptions, error) {
if err != nil { if err != nil {
return storageOpts, err return storageOpts, err
} }
storageConf := filepath.Join(os.Getenv("HOME"), ".config/containers/storage.conf")
if _, err := os.Stat(storageConf); err == nil {
storage.ReloadConfigurationFile(storageConf, &storageOpts)
}
} }
return storageOpts, nil return storageOpts, nil
} }

View File

@ -117,7 +117,7 @@ Print the version
**libpod.conf** (`/etc/containers/libpod.conf`) **libpod.conf** (`/etc/containers/libpod.conf`)
libpod.conf is the configuration file for all tools using libpod to manage containers. This file is ignored when running in rootless mode. libpod.conf is the configuration file for all tools using libpod to manage containers. When Podman runs in rootless mode, then the file `$HOME/.config/containers/libpod.conf` is used.
**storage.conf** (`/etc/containers/storage.conf`) **storage.conf** (`/etc/containers/storage.conf`)
@ -125,6 +125,8 @@ storage.conf is the storage configuration file for all tools using containers/st
The storage configuration file specifies all of the available container storage options for tools using shared container storage. The storage configuration file specifies all of the available container storage options for tools using shared container storage.
When Podman runs in rootless mode, the file `$HOME/.config/containers/storage.conf` is also loaded.
**mounts.conf** (`/usr/share/containers/mounts.conf` and optionally `/etc/containers/mounts.conf`) **mounts.conf** (`/usr/share/containers/mounts.conf` and optionally `/etc/containers/mounts.conf`)
The mounts.conf files specify volume mount directories that are automatically mounted inside containers when executing the `podman run` or `podman start` commands. Container processes can then use this content. The volume mount content does not get committed to the final image if you do a `podman commit`. The mounts.conf files specify volume mount directories that are automatically mounted inside containers when executing the `podman run` or `podman start` commands. Container processes can then use this content. The volume mount content does not get committed to the final image if you do a `podman commit`.
@ -137,6 +139,8 @@ The format of the mounts.conf is the volume format /SRC:/DEST, one mount per lin
Note this is not a volume mount. The content of the volumes is copied into container storage, not bind mounted directly from the host. Note this is not a volume mount. The content of the volumes is copied into container storage, not bind mounted directly from the host.
When Podman runs in rootless mode, the file `$HOME/.config/containers/mounts.conf` is also used.
**hook JSON** (`/usr/share/containers/oci/hooks.d/*.json`) **hook JSON** (`/usr/share/containers/oci/hooks.d/*.json`)
Each `*.json` file in `/usr/share/containers/oci/hooks.d` configures a hook for Podman containers. For more details on the syntax of the JSON files and the semantics of hook injection, see `oci-hooks(5)`. Each `*.json` file in `/usr/share/containers/oci/hooks.d` configures a hook for Podman containers. For more details on the syntax of the JSON files and the semantics of hook injection, see `oci-hooks(5)`.
@ -153,6 +157,8 @@ Hooks are not used when running in rootless mode.
registries.conf is the configuration file which specifies which container registries should be consulted when completing image names which do not include a registry or domain portion. registries.conf is the configuration file which specifies which container registries should be consulted when completing image names which do not include a registry or domain portion.
When Podman runs in rootless mode, the file `$HOME/.config/containers/registries.conf` is used.
## Rootless mode ## Rootless mode
Podman can also be used as non-root user. When podman runs in rootless mode, an user namespace is automatically created. Podman can also be used as non-root user. When podman runs in rootless mode, an user namespace is automatically created.

View File

@ -4,7 +4,6 @@ import (
"context" "context"
"fmt" "fmt"
"io" "io"
"os"
"strings" "strings"
cp "github.com/containers/image/copy" cp "github.com/containers/image/copy"
@ -277,12 +276,7 @@ func (i *Image) createNamesToPull() ([]*pullStruct, error) {
pullNames = append(pullNames, &ps) pullNames = append(pullNames, &ps)
} else { } else {
registryConfigPath := "" searchRegistries, err := registries.GetRegistries()
envOverride := os.Getenv("REGISTRIES_CONFIG_PATH")
if len(envOverride) > 0 {
registryConfigPath = envOverride
}
searchRegistries, err := sysregistries.GetRegistries(&types.SystemContext{SystemRegistriesConfPath: registryConfigPath})
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -2,15 +2,27 @@ package registries
import ( import (
"os" "os"
"path/filepath"
"github.com/containers/image/pkg/sysregistries" "github.com/containers/image/pkg/sysregistries"
"github.com/containers/image/types" "github.com/containers/image/types"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/pkg/rootless"
) )
// userRegistriesFile is the path to the per user registry configuration file.
var userRegistriesFile = filepath.Join(os.Getenv("HOME"), ".config/containers/registries.conf")
// GetRegistries obtains the list of registries defined in the global registries file. // GetRegistries obtains the list of registries defined in the global registries file.
func GetRegistries() ([]string, error) { func GetRegistries() ([]string, error) {
registryConfigPath := "" registryConfigPath := ""
if rootless.IsRootless() {
if _, err := os.Stat(userRegistriesFile); err == nil {
registryConfigPath = userRegistriesFile
}
}
envOverride := os.Getenv("REGISTRIES_CONFIG_PATH") envOverride := os.Getenv("REGISTRIES_CONFIG_PATH")
if len(envOverride) > 0 { if len(envOverride) > 0 {
registryConfigPath = envOverride registryConfigPath = envOverride
@ -25,6 +37,11 @@ func GetRegistries() ([]string, error) {
// GetInsecureRegistries obtains the list of insecure registries from the global registration file. // GetInsecureRegistries obtains the list of insecure registries from the global registration file.
func GetInsecureRegistries() ([]string, error) { func GetInsecureRegistries() ([]string, error) {
registryConfigPath := "" registryConfigPath := ""
if _, err := os.Stat(userRegistriesFile); err == nil {
registryConfigPath = userRegistriesFile
}
envOverride := os.Getenv("REGISTRIES_CONFIG_PATH") envOverride := os.Getenv("REGISTRIES_CONFIG_PATH")
if len(envOverride) > 0 { if len(envOverride) > 0 {
registryConfigPath = envOverride registryConfigPath = envOverride

View File

@ -10,6 +10,7 @@ import (
rspec "github.com/opencontainers/runtime-spec/specs-go" rspec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/selinux/go-selinux/label" "github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/pkg/rootless"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -20,6 +21,9 @@ var (
// OverrideMountsFile holds the default mount paths in the form // OverrideMountsFile holds the default mount paths in the form
// "host_path:container_path" overridden by the user // "host_path:container_path" overridden by the user
OverrideMountsFile = "/etc/containers/mounts.conf" OverrideMountsFile = "/etc/containers/mounts.conf"
// UserOverrideMountsFile holds the default mount paths in the form
// "host_path:container_path" overridden by the rootless user
UserOverrideMountsFile = filepath.Join(os.Getenv("HOME"), ".config/containers/mounts.conf")
) )
// secretData stores the name of the file and the content read from it // secretData stores the name of the file and the content read from it
@ -143,15 +147,21 @@ func SecretMountsWithUIDGID(mountLabel, containerWorkingDir, mountFile, mountPre
// Note for testing purposes only // Note for testing purposes only
if mountFile == "" { if mountFile == "" {
mountFiles = append(mountFiles, []string{OverrideMountsFile, DefaultMountsFile}...) mountFiles = append(mountFiles, []string{OverrideMountsFile, DefaultMountsFile}...)
if rootless.IsRootless() {
mountFiles = append([]string{UserOverrideMountsFile}, mountFiles...)
}
} else { } else {
mountFiles = append(mountFiles, mountFile) mountFiles = append(mountFiles, mountFile)
} }
for _, file := range mountFiles { for _, file := range mountFiles {
if _, err := os.Stat(file); err == nil {
mounts, err := addSecretsFromMountsFile(file, mountLabel, containerWorkingDir, mountPrefix, uid, gid) mounts, err := addSecretsFromMountsFile(file, mountLabel, containerWorkingDir, mountPrefix, uid, gid)
if err != nil { if err != nil {
logrus.Warnf("error mounting secrets, skipping: %v", err) logrus.Warnf("error mounting secrets, skipping: %v", err)
} }
secretMounts = append(secretMounts, mounts...) secretMounts = mounts
break
}
} }
// Add FIPS mode secret if /etc/system-fips exists on the host // Add FIPS mode secret if /etc/system-fips exists on the host