From de4093fb4034fcd2977775d4a6b4de92dedb3123 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Fri, 8 Mar 2024 14:03:40 +0100 Subject: [PATCH] libnetwork/pasta: add new Setup2 to return result Currently both callers in podman and buildah join and inspect the netns to get the local ip configured by pasta in order to add it to /etc/hosts. So instead of doing this in two places let's just do it here once and returnt the result to the caller. In order to not cause vendoring issues I decided against breaking the API and added a new Setup2 function instead. I will then update podman and buildah to make use of it. Also I plan on adding more fields in the result, i.e. dns address. Signed-off-by: Paul Holzinger --- libnetwork/pasta/pasta.go | 49 ++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/libnetwork/pasta/pasta.go b/libnetwork/pasta/pasta.go index 0da7607f6..a22135bb8 100644 --- a/libnetwork/pasta/pasta.go +++ b/libnetwork/pasta/pasta.go @@ -13,9 +13,11 @@ package pasta import ( "errors" "fmt" + "net" "os/exec" "strings" + "github.com/containernetworking/plugins/pkg/ns" "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/config" "github.com/sirupsen/logrus" @@ -37,11 +39,21 @@ type SetupOptions struct { ExtraOptions []string } -// Setup start the pasta process for the given netns. -// The pasta binary is looked up in the HelperBinariesDir and $PATH. -// Note that there is no need any special cleanup logic, the pasta process will -// automatically exit when the netns path is deleted. +type SetupResult struct { + // IpAddresses configured by pasta + IPAddresses []net.IP +} + func Setup(opts *SetupOptions) error { + _, err := Setup2(opts) + return err +} + +// Setup2 start the pasta process for the given netns. +// The pasta binary is looked up in the HelperBinariesDir and $PATH. +// Note that there is no need for any special cleanup logic, the pasta +// process will automatically exit when the netns path is deleted. +func Setup2(opts *SetupOptions) (*SetupResult, error) { NoTCPInitPorts := true NoUDPInitPorts := true NoTCPNamespacePorts := true @@ -51,7 +63,7 @@ func Setup(opts *SetupOptions) error { path, err := opts.Config.FindHelperBinary(BinaryName, true) if err != nil { - return fmt.Errorf("could not find pasta, the network namespace can't be configured: %w", err) + return nil, fmt.Errorf("could not find pasta, the network namespace can't be configured: %w", err) } cmdArgs := []string{} @@ -72,7 +84,7 @@ func Setup(opts *SetupOptions) error { case "udp": cmdArgs = append(cmdArgs, "-u") default: - return fmt.Errorf("can't forward protocol: %s", protocol) + return nil, fmt.Errorf("can't forward protocol: %s", protocol) } arg := fmt.Sprintf("%s%d-%d:%d-%d", addr, @@ -140,10 +152,10 @@ func Setup(opts *SetupOptions) error { if err != nil { exitErr := &exec.ExitError{} if errors.As(err, &exitErr) { - return fmt.Errorf("pasta failed with exit code %d:\n%s", + return nil, fmt.Errorf("pasta failed with exit code %d:\n%s", exitErr.ExitCode(), string(out)) } - return fmt.Errorf("failed to start pasta: %w", err) + return nil, fmt.Errorf("failed to start pasta: %w", err) } if len(out) > 0 { @@ -154,5 +166,24 @@ func Setup(opts *SetupOptions) error { logrus.Infof("pasta logged warnings: %q", string(out)) } - return nil + result := &SetupResult{} + err = ns.WithNetNSPath(opts.Netns, func(_ ns.NetNS) error { + addrs, err := net.InterfaceAddrs() + if err != nil { + return err + } + for _, addr := range addrs { + if ipnet, ok := addr.(*net.IPNet); ok && ipnet.IP.IsGlobalUnicast() { + // make sure to skip localhost and other special addresses + if ipnet.IP.IsGlobalUnicast() { + result.IPAddresses = append(result.IPAddresses, ipnet.IP) + } + } + } + return nil + }) + if err != nil { + return nil, err + } + return result, nil }