Skip to content

Commit

Permalink
Separate the service_destinations section from containers.conf
Browse files Browse the repository at this point in the history
Move the service_destinations section from
containers.conf to connections.conf.

Fixes #1515

Signed-off-by: Toshiki Sonoda <sonoda.toshiki@fujitsu.com>
  • Loading branch information
sstosh committed Jul 18, 2023
1 parent d3497e0 commit 94b93cd
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 33 deletions.
34 changes: 34 additions & 0 deletions docs/containers-connections.conf.5.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
% containers-connections.conf(5)

## NAME
containers-connections.conf - configuration file for remote connections to the API service

## DESCRIPTION
The connections.conf file configure the service API destinations. By default, root user reads from **/etc/containers/connections.conf**, while rootless user read from **$HOME/.config/containers/connections.conf**.

## FORMAT
**[{service_name}]**
URI to access the API service
**uri="ssh://user@production.example.com/run/user/1001/podman/podman.sock"**

Example URIs:

- **rootless local** - unix://run/user/1000/podman/podman.sock
- **rootless remote** - ssh://user@engineering.lab.company.com/run/user/1000/podman/podman.sock
- **rootful local** - unix://run/podman/podman.sock
- **rootful remote** - ssh://root@10.10.1.136:22/run/podman/podman.sock

**identity="~/.ssh/id_rsa**

Path to file containing ssh identity key

## EXAMPLE
[hoge]
uri=unix://run/user/1000/podman/podman.sock

[fuga]
uri=ssh://user@engineering.lab.company.com/run/user/1000/podman/podman.sock
identity="~/.ssh/id_rsa"

## HISTORY
June 2023, Originally compiled by Toshiki Sonoda <sonoda.toshiki@fujitsu.com>
2 changes: 1 addition & 1 deletion docs/containers.conf.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ The `engine` table contains configuration options used to set up container engin

**active_service**=""

Name of destination for accessing the Podman service. See SERVICE DESTINATION TABLE below.
Name of destination for accessing the Podman service. See connections.conf(5).

**cgroup_manager**="systemd"

Expand Down
79 changes: 77 additions & 2 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ const (
_configPath = "containers/containers.conf"
// UserOverrideContainersConfig holds the containers config path overridden by the rootless user
UserOverrideContainersConfig = ".config/" + _configPath
// _connectionPath is the path to the containers/connections.conf
// inside a given config directory.
_connectionPath = "containers/connections.conf"
// UserOverrideContainersConnection holds the containers connection path overridden by the rootless user
UserOverrideContainersConnection = ".config/" + _connectionPath
// Token prefix for looking for helper binary under $BINDIR
bindirPrefix = "$BINDIR"
)
Expand Down Expand Up @@ -757,6 +762,22 @@ func readConfigFromFile(path string, config *Config) error {
return nil
}

// readConnectionFromFile reads the specified connection file at `path` and attempts to
// unmarshal its content into a Service Destination.
func readConnectionFromFile(path string, connections map[string]Destination) error {
logrus.Tracef("Reading connection file %q", path)
meta, err := toml.DecodeFile(path, &connections)
if err != nil {
return fmt.Errorf("decode connection %v: %w", path, err)
}
keys := meta.Undecoded()
if len(keys) > 0 {
logrus.Debugf("Failed to decode the keys %q from %q.", keys, path)
}

return nil
}

// addConfigs will search one level in the config dirPath for config files
// If the dirPath does not exist, addConfigs will return nil
func addConfigs(dirPath string, configs []string) ([]string, error) {
Expand Down Expand Up @@ -1186,15 +1207,23 @@ func resolveHomeDir(path string) (string, error) {
}

func rootlessConfigPath() (string, error) {
return rootlessPath(_configPath, UserOverrideContainersConfig)
}

func rootlessConnectionPath() (string, error) {
return rootlessPath(_connectionPath, UserOverrideContainersConnection)
}

func rootlessPath(path, override string) (string, error) {
if configHome := os.Getenv("XDG_CONFIG_HOME"); configHome != "" {
return filepath.Join(configHome, _configPath), nil
return filepath.Join(configHome, path), nil
}
home, err := unshare.HomeDir()
if err != nil {
return "", err
}

return filepath.Join(home, UserOverrideContainersConfig), nil
return filepath.Join(home, override), nil
}

func stringsEq(a, b []string) bool {
Expand Down Expand Up @@ -1275,6 +1304,25 @@ func ReadCustomConfig() (*Config, error) {
return newConfig, nil
}

// ReadConnection reads the connection config
func ReadConnection() (map[string]Destination, error) {
newServiceDestinations := map[string]Destination{}
path, err := ConnectionFile()
if err != nil {
return nil, err
}
if _, err := os.Stat(path); err == nil {
if err := readConnectionFromFile(path, newServiceDestinations); err != nil {
return nil, err
}
} else {
if !errors.Is(err, os.ErrNotExist) {
return nil, err
}
}
return newServiceDestinations, nil
}

// Write writes the configuration to the default file
func (c *Config) Write() error {
var err error
Expand Down Expand Up @@ -1302,6 +1350,33 @@ func (c *Config) Write() error {
return configFile.Commit()
}

// WriteConnection writes the connection.conf file
func (c *Config) WriteConnection() error {
var err error
path, err := ConnectionFile()
if err != nil {
return err
}
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
return err
}

opts := &ioutils.AtomicFileWriterOptions{ExplicitCommit: true}
connectionFile, err := ioutils.NewAtomicFileWriterWithOpts(path, 0o644, opts)
if err != nil {
return err
}
defer connectionFile.Close()

enc := toml.NewEncoder(connectionFile)
if err := enc.Encode(c.Engine.ServiceDestinations); err != nil {
return err
}

// If no errors commit the changes to the config file
return connectionFile.Commit()
}

// Reload clean the cached config and reloads the configuration from containers.conf files
// This function is meant to be used for long-running processes that need to reload potential changes made to
// the cached containers.conf files.
Expand Down
7 changes: 7 additions & 0 deletions pkg/config/config_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ const (
// DefaultContainersConfig holds the default containers config path
DefaultContainersConfig = "/usr/share/" + _configPath

// DefaultConnectionConfig holds the default connection path overridden by the root user
DefaultConnectionConfig = "/etc/" + _connectionPath

// DefaultSignaturePolicyPath is the default value for the
// policy.json file.
DefaultSignaturePolicyPath = "/etc/containers/policy.json"
Expand All @@ -31,6 +34,10 @@ func ifRootlessConfigPath() (string, error) {
return rootlessConfigPath()
}

func ConnectionFile() (string, error) {
return rootlessConfigPath()
}

var defaultHelperBinariesDir = []string{
// Homebrew install paths
"/usr/local/opt/podman/libexec/podman",
Expand Down
7 changes: 7 additions & 0 deletions pkg/config/config_freebsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ const (
// DefaultContainersConfig holds the default containers config path
DefaultContainersConfig = "/usr/local/share/" + _configPath

// DefaultConnectionConfig holds the default connection path overridden by the root user
DefaultConnectionConfig = "/usr/local/etc/" + _connectionPath

// DefaultSignaturePolicyPath is the default value for the
// policy.json file.
DefaultSignaturePolicyPath = "/usr/local/etc/containers/policy.json"
Expand All @@ -31,6 +34,10 @@ func ifRootlessConfigPath() (string, error) {
return rootlessConfigPath()
}

func ConnectionFile() (string, error) {
return rootlessConfigPath()
}

var defaultHelperBinariesDir = []string{
"/usr/local/bin",
"/usr/local/libexec/podman",
Expand Down
14 changes: 14 additions & 0 deletions pkg/config/config_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ const (
// DefaultContainersConfig holds the default containers config path
DefaultContainersConfig = "/usr/share/" + _configPath

// DefaultConnectionConfig holds the default connection path overridden by the root user
DefaultConnectionConfig = "/etc/" + _connectionPath

// DefaultSignaturePolicyPath is the default value for the
// policy.json file.
DefaultSignaturePolicyPath = "/etc/containers/policy.json"
Expand Down Expand Up @@ -51,6 +54,17 @@ func ifRootlessConfigPath() (string, error) {
return "", nil
}

func ConnectionFile() (string, error) {
if unshare.GetRootlessUID() > 0 {
path, err := rootlessConfigPath()
if err != nil {
return "", err
}
return path, nil
}
return DefaultConnectionConfig, nil
}

var defaultHelperBinariesDir = []string{
"/usr/local/libexec/podman",
"/usr/local/lib/podman",
Expand Down
15 changes: 0 additions & 15 deletions pkg/config/containers.conf
Original file line number Diff line number Diff line change
Expand Up @@ -637,21 +637,6 @@ default_sysctls = [
#
#exit_command_delay = 300

# map of service destinations
#
# [engine.service_destinations]
# [engine.service_destinations.production]
# URI to access the Podman service
# Examples:
# rootless "unix://run/user/$UID/podman/podman.sock" (Default)
# rootful "unix://run/podman/podman.sock (Default)
# remote rootless ssh://engineering.lab.company.com/run/user/1000/podman/podman.sock
# remote rootful ssh://root@10.10.1.136:22/run/podman/podman.sock
#
# uri = "ssh://user@production.example.com/run/user/1001/podman/podman.sock"
# Path to file containing ssh identity key
# identity = "~/.ssh/id_rsa"

# Directory for temporary files. Must be tmpfs (wiped after reboot)
#
#tmp_dir = "/run/libpod"
Expand Down
15 changes: 0 additions & 15 deletions pkg/config/containers.conf-freebsd
Original file line number Diff line number Diff line change
Expand Up @@ -536,21 +536,6 @@ default_sysctls = [
#
#exit_command_delay = 300

# map of service destinations
#
#[service_destinations]
# [service_destinations.production]
# URI to access the Podman service
# Examples:
# rootless "unix://run/user/$UID/podman/podman.sock" (Default)
# rootful "unix://run/podman/podman.sock (Default)
# remote rootless ssh://engineering.lab.company.com/run/user/1000/podman/podman.sock
# remote rootful ssh://root@10.10.1.136:22/run/podman/podman.sock
#
# uri = "ssh://user@production.example.com/run/user/1001/podman/podman.sock"
# Path to file containing ssh identity key
# identity = "~/.ssh/id_rsa"

# Directory for temporary files. Must be tmpfs (wiped after reboot)
#
#tmp_dir = "/run/libpod"
Expand Down

0 comments on commit 94b93cd

Please sign in to comment.