diff --git a/go.mod b/go.mod index f590a95dd..c04ec0417 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/containers/prometheus-podman-exporter go 1.20 require ( - github.com/containers/common v0.58.0 + github.com/containers/common v0.58.1 github.com/containers/image/v5 v5.30.0 github.com/containers/podman/v5 v5.0.0 github.com/go-kit/log v0.2.1 diff --git a/go.sum b/go.sum index 86fc25866..0d1648c09 100644 --- a/go.sum +++ b/go.sum @@ -64,8 +64,8 @@ github.com/containernetworking/plugins v1.4.0 h1:+w22VPYgk7nQHw7KT92lsRmuToHvb7w github.com/containernetworking/plugins v1.4.0/go.mod h1:UYhcOyjefnrQvKvmmyEKsUA+M9Nfn7tqULPpH0Pkcj0= github.com/containers/buildah v1.35.1 h1:m4TF6V8b06cS4jH9/t39PUsUIjzDQg/P14FLpwjr40Y= github.com/containers/buildah v1.35.1/go.mod h1:vVSVUlTu8+99H5j43gBJscpkb/quZvdJg78+6X1HeTM= -github.com/containers/common v0.58.0 h1:iQuwMxDD4ubZ9s1tmgdsiaHxMU4TdVBpV6kctJc6Bk8= -github.com/containers/common v0.58.0/go.mod h1:l3vMqanJGj7tZ3W/i76gEJ128VXgFUO1tLaohJXPvdk= +github.com/containers/common v0.58.1 h1:E1DN9Lr7kgMVQy7AXLv1CYQCiqnweklMiYWbf0KOnqY= +github.com/containers/common v0.58.1/go.mod h1:l3vMqanJGj7tZ3W/i76gEJ128VXgFUO1tLaohJXPvdk= github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg= github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I= github.com/containers/image/v5 v5.30.0 h1:CmHeSwI6W2kTRWnUsxATDFY5TEX4b58gPkaQcEyrLIA= diff --git a/vendor/github.com/containers/common/libnetwork/etchosts/ip.go b/vendor/github.com/containers/common/libnetwork/etchosts/ip.go index b81274abf..909fcf67d 100644 --- a/vendor/github.com/containers/common/libnetwork/etchosts/ip.go +++ b/vendor/github.com/containers/common/libnetwork/etchosts/ip.go @@ -1,6 +1,8 @@ package etchosts import ( + "net" + "github.com/containers/common/libnetwork/types" "github.com/containers/common/libnetwork/util" "github.com/containers/common/pkg/config" @@ -8,9 +10,16 @@ import ( "github.com/containers/storage/pkg/unshare" ) -// GetHostContainersInternalIP return the host.containers.internal ip +// GetHostContainersInternalIP returns the host.containers.internal ip // if netStatus is not nil then networkInterface also must be non nil otherwise this function panics func GetHostContainersInternalIP(conf *config.Config, netStatus map[string]types.StatusBlock, networkInterface types.ContainerNetwork) string { + return GetHostContainersInternalIPExcluding(conf, netStatus, networkInterface, nil) +} + +// GetHostContainersInternalIPExcluding returns the host.containers.internal ip +// Exclude are ips that should not be returned, this is useful to prevent returning the same ip as in the container. +// if netStatus is not nil then networkInterface also must be non nil otherwise this function panics +func GetHostContainersInternalIPExcluding(conf *config.Config, netStatus map[string]types.StatusBlock, networkInterface types.ContainerNetwork, exclude []net.IP) string { switch conf.Containers.HostContainersInternalIP { case "": // if empty (default) we will automatically choose one below @@ -27,7 +36,7 @@ func GetHostContainersInternalIP(conf *config.Config, netStatus map[string]types // Only use the bridge ip when root, as rootless the interfaces are created // inside the special netns and not the host so we cannot use them. if unshare.IsRootless() { - return util.GetLocalIP() + return util.GetLocalIPExcluding(exclude) } for net, status := range netStatus { network, err := networkInterface.NetworkInspect(net) @@ -51,7 +60,7 @@ func GetHostContainersInternalIP(conf *config.Config, netStatus map[string]types if ip != "" { return ip } - return util.GetLocalIP() + return util.GetLocalIPExcluding(exclude) } // GetNetworkHostEntries returns HostEntries for all ips in the network status diff --git a/vendor/github.com/containers/common/libnetwork/internal/rootlessnetns/netns_linux.go b/vendor/github.com/containers/common/libnetwork/internal/rootlessnetns/netns_linux.go index 1531ee52e..98961935d 100644 --- a/vendor/github.com/containers/common/libnetwork/internal/rootlessnetns/netns_linux.go +++ b/vendor/github.com/containers/common/libnetwork/internal/rootlessnetns/netns_linux.go @@ -158,7 +158,8 @@ func (n *Netns) setupPasta(nsPath string) error { Netns: nsPath, ExtraOptions: []string{"--pid", pidPath}, } - if err := pasta.Setup(&pastaOpts); err != nil { + res, err := pasta.Setup2(&pastaOpts) + if err != nil { return fmt.Errorf("setting up Pasta: %w", err) } @@ -185,11 +186,9 @@ func (n *Netns) setupPasta(nsPath string) error { Namespaces: []specs.LinuxNamespace{ {Type: specs.NetworkNamespace}, }, - // TODO: Need a way to determine if there is a valid v6 address on any - // external interface of the system. - IPv6Enabled: false, + IPv6Enabled: res.IPv6, KeepHostServers: true, - Nameservers: []string{}, + Nameservers: res.DNSForwardIPs, }); err != nil { return wrapError("create resolv.conf", err) } diff --git a/vendor/github.com/containers/common/libnetwork/pasta/pasta.go b/vendor/github.com/containers/common/libnetwork/pasta/pasta_linux.go similarity index 61% rename from vendor/github.com/containers/common/libnetwork/pasta/pasta.go rename to vendor/github.com/containers/common/libnetwork/pasta/pasta_linux.go index 0da7607f6..4b31320b5 100644 --- a/vendor/github.com/containers/common/libnetwork/pasta/pasta.go +++ b/vendor/github.com/containers/common/libnetwork/pasta/pasta_linux.go @@ -13,16 +13,23 @@ 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/libnetwork/util" "github.com/containers/common/pkg/config" "github.com/sirupsen/logrus" ) const ( - BinaryName = "pasta" + dnsForwardOpt = "--dns-forward" + + // dnsForwardIpv4 static ip used as nameserver address inside the netns, + // given this is a "link local" ip it should be very unlikely that it causes conflicts + dnsForwardIpv4 = "169.254.0.1" ) type SetupOptions struct { @@ -37,21 +44,25 @@ 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. 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 NoUDPNamespacePorts := true NoMapGW := true - NoDNS := true 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 +83,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, @@ -89,6 +100,7 @@ func Setup(opts *SetupOptions) error { // then append the ones that were set on the cli cmdArgs = append(cmdArgs, opts.ExtraOptions...) + var dnsForwardIPs []string for i, opt := range cmdArgs { switch opt { case "-t", "--tcp-ports": @@ -103,11 +115,20 @@ func Setup(opts *SetupOptions) error { NoMapGW = false // not an actual pasta(1) option cmdArgs = append(cmdArgs[:i], cmdArgs[i+1:]...) - case "-D", "--dns", "--dns-forward": - NoDNS = false + case dnsForwardOpt: + // if there is no arg after it pasta will likely error out anyway due invalid cli args + if len(cmdArgs) > i+1 { + dnsForwardIPs = append(dnsForwardIPs, cmdArgs[i+1]) + } } } + if len(dnsForwardIPs) == 0 { + // the user did not request custom --dns-forward so add our own. + cmdArgs = append(cmdArgs, dnsForwardOpt, dnsForwardIpv4) + dnsForwardIPs = append(dnsForwardIPs, dnsForwardIpv4) + } + if NoTCPInitPorts { cmdArgs = append(cmdArgs, "-t", "none") } @@ -123,12 +144,6 @@ func Setup(opts *SetupOptions) error { if NoMapGW { cmdArgs = append(cmdArgs, "--no-map-gw") } - if NoDNS { - // disable pasta reading from /etc/resolv.conf which hides the - // "Couldn't get any nameserver address" warning when only - // localhost resolvers are configured. - cmdArgs = append(cmdArgs, "--dns", "none") - } // always pass --quiet to silence the info output from pasta cmdArgs = append(cmdArgs, "--quiet", "--netns", opts.Netns) @@ -140,10 +155,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 +169,39 @@ func Setup(opts *SetupOptions) error { logrus.Infof("pasta logged warnings: %q", string(out)) } - return nil + var ipv4, ipv6 bool + result := &SetupResult{} + err = ns.WithNetNSPath(opts.Netns, func(_ ns.NetNS) error { + addrs, err := net.InterfaceAddrs() + if err != nil { + return err + } + for _, addr := range addrs { + // make sure to skip localhost and other special addresses + if ipnet, ok := addr.(*net.IPNet); ok && ipnet.IP.IsGlobalUnicast() { + result.IPAddresses = append(result.IPAddresses, ipnet.IP) + if !ipv4 && util.IsIPv4(ipnet.IP) { + ipv4 = true + } + if !ipv6 && util.IsIPv6(ipnet.IP) { + ipv6 = true + } + } + } + return nil + }) + if err != nil { + return nil, err + } + + result.IPv6 = ipv6 + for _, ip := range dnsForwardIPs { + ipp := net.ParseIP(ip) + // add the namesever ip only if the address family matches + if ipv4 && util.IsIPv4(ipp) || ipv6 && util.IsIPv6(ipp) { + result.DNSForwardIPs = append(result.DNSForwardIPs, ip) + } + } + + return result, nil } diff --git a/vendor/github.com/containers/common/libnetwork/pasta/types.go b/vendor/github.com/containers/common/libnetwork/pasta/types.go new file mode 100644 index 000000000..b601e5169 --- /dev/null +++ b/vendor/github.com/containers/common/libnetwork/pasta/types.go @@ -0,0 +1,15 @@ +package pasta + +import "net" + +const BinaryName = "pasta" + +type SetupResult struct { + // IpAddresses configured by pasta + IPAddresses []net.IP + // DNSForwardIP is the ip used in --dns-forward, it should be added as first + // entry to resolv.conf in the container. + DNSForwardIPs []string + // IPv6 says whenever pasta run with ipv6 support + IPv6 bool +} diff --git a/vendor/github.com/containers/common/libnetwork/slirp4netns/const.go b/vendor/github.com/containers/common/libnetwork/slirp4netns/const.go index 9dc0c2625..fa95e5a90 100644 --- a/vendor/github.com/containers/common/libnetwork/slirp4netns/const.go +++ b/vendor/github.com/containers/common/libnetwork/slirp4netns/const.go @@ -1,5 +1,7 @@ package slirp4netns +import "net" + const ( ipv6ConfDefaultAcceptDadSysctl = "/proc/sys/net/ipv6/conf/default/accept_dad" BinaryName = "slirp4netns" @@ -10,3 +12,13 @@ const ( // default slirp4ns subnet defaultSubnet = "10.0.2.0/24" ) + +// SetupResult return type from Setup() +type SetupResult struct { + // Pid of the created slirp4netns process + Pid int + // Subnet which is used by slirp4netns + Subnet *net.IPNet + // IPv6 whenever Ipv6 is enabled in slirp4netns + IPv6 bool +} diff --git a/vendor/github.com/containers/common/libnetwork/slirp4netns/slirp4netns.go b/vendor/github.com/containers/common/libnetwork/slirp4netns/slirp4netns.go index d37893414..6f713431c 100644 --- a/vendor/github.com/containers/common/libnetwork/slirp4netns/slirp4netns.go +++ b/vendor/github.com/containers/common/libnetwork/slirp4netns/slirp4netns.go @@ -86,16 +86,6 @@ type SetupOptions struct { Pdeathsig syscall.Signal } -// SetupResult return type from Setup() -type SetupResult struct { - // Pid of the created slirp4netns process - Pid int - // Subnet which is used by slirp4netns - Subnet *net.IPNet - // IPv6 whenever Ipv6 is enabled in slirp4netns - IPv6 bool -} - type logrusDebugWriter struct { prefix string } diff --git a/vendor/github.com/containers/common/libnetwork/util/ip.go b/vendor/github.com/containers/common/libnetwork/util/ip.go index 1e426926e..5dd93363b 100644 --- a/vendor/github.com/containers/common/libnetwork/util/ip.go +++ b/vendor/github.com/containers/common/libnetwork/util/ip.go @@ -59,14 +59,31 @@ func NormalizeIP(ip *net.IP) { // If no ipv4 address is found it may return an ipv6 address. // When no ip is found and empty string is returned. func GetLocalIP() string { + return GetLocalIPExcluding(nil) +} + +// GetLocalIPExcluding returns the first non loopback local IPv4 of the host. +// If no ipv4 address is found it may return an ipv6 address. +// Additionally you can specify a list of ips that should not be returned. +// When no ip is found and empty string is returned. +func GetLocalIPExcluding(exclude []net.IP) string { addrs, err := net.InterfaceAddrs() if err != nil { return "" } ip := "" +outer: for _, address := range addrs { // check the address type and if it is not a loopback the display it if ipnet, ok := address.(*net.IPNet); ok && ipnet.IP.IsGlobalUnicast() { + // cannot use slices.Contains for net.IP + for _, eip := range exclude { + if eip.Equal(ipnet.IP) { + // ip should be excluded skip to next one + continue outer + } + } + if IsIPv4(ipnet.IP) { return ipnet.IP.String() } diff --git a/vendor/github.com/containers/common/version/version.go b/vendor/github.com/containers/common/version/version.go index cd77bf892..87d93c9d6 100644 --- a/vendor/github.com/containers/common/version/version.go +++ b/vendor/github.com/containers/common/version/version.go @@ -1,4 +1,4 @@ package version // Version is the version of the build. -const Version = "0.58.0" +const Version = "0.58.1" diff --git a/vendor/modules.txt b/vendor/modules.txt index e367f04fb..5e294d78f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -141,7 +141,7 @@ github.com/containers/buildah/pkg/rusage github.com/containers/buildah/pkg/sshagent github.com/containers/buildah/pkg/util github.com/containers/buildah/util -# github.com/containers/common v0.58.0 +# github.com/containers/common v0.58.1 ## explicit; go 1.20 github.com/containers/common/internal github.com/containers/common/internal/attributedstring