OptionExecRoot did not configure the controller it was passed to: it set the directory for all network namespaces in package osl, which every controller in the process shared. The overlay driver found that directory by generating a sandbox key for a made-up ID and taking the key's parent directory. Replace it with OptionNetnsDir, available on Linux and FreeBSD, which sets the directory in the controller's config. OptionExecRoot was a no-op on Windows. The controller generates its sandboxes' keys from the directory, and the overlay driver is given the directory when it is registered and builds its own keys. Each overlay driver instance scans its own directory for the VNIs of the sandboxes a previous run of the daemon left behind. The controller creates the directory when it is created, instead of osl creating the package-wide directory when it first creates a namespace. The daemon still keeps the namespaces in <exec-root>/netns. The directory has no default: on Linux and FreeBSD, the controller refuses to create a sandbox when none is configured, as does the overlay driver, so a test which leaves out the option fails instead of leaving network namespaces behind in a directory shared with the host. Tests which create sandboxes keep them in a temporary directory, and unmount the namespaces left in it when they end. The key formats do not change on Linux. On FreeBSD, sandbox keys become paths in the directory, as on Linux. Drop GenerateKey's lookup of an existing key for an ID starting with "-": no caller passes such an ID. Signed-off-by: Cory Snider <csnider@mirantis.com> Assisted-By: Claude Opus 5.5
38 lines
963 B
Go
38 lines
963 B
Go
//go:build linux || freebsd
|
|
|
|
package libnetwork
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
// createNetnsDir creates the directory the network namespaces of sandboxes
|
|
// are kept in, if one is configured.
|
|
func (c *Controller) createNetnsDir() error {
|
|
if c.cfg.NetnsDir == "" {
|
|
return nil
|
|
}
|
|
if err := os.MkdirAll(c.cfg.NetnsDir, 0o755); err != nil {
|
|
return fmt.Errorf("creating netns directory: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// requireNetnsDir returns an error if no directory is configured for the
|
|
// network namespaces of sandboxes.
|
|
func (c *Controller) requireNetnsDir() error {
|
|
if c.cfg.NetnsDir == "" {
|
|
return errors.New("no netns directory is configured (see config.OptionNetnsDir)")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// sandboxKey returns the key of the sandbox with the given ID: the path of
|
|
// its network namespace.
|
|
func (c *Controller) sandboxKey(sandboxID string) string {
|
|
return filepath.Join(c.cfg.NetnsDir, sandboxID[:min(len(sandboxID), 12)])
|
|
}
|