From 2f858675b3178c76f0a38a35e7b4ba7530906540 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Wed, 28 Aug 2024 13:31:49 +0200 Subject: [PATCH] vendor latest c/common Includes my pasta changes. Signed-off-by: Paul Holzinger --- go.mod | 4 +- go.sum | 8 +- .../containers/common/libimage/filters.go | 2 +- .../containers/common/libimage/search.go | 4 +- .../containers/common/libnetwork/cni/run.go | 2 - .../common/libnetwork/etchosts/hosts.go | 10 +- .../common/libnetwork/etchosts/ip.go | 56 ++++++--- .../internal/rootlessnetns/netns_linux.go | 82 ++++++++++---- .../common/libnetwork/internal/util/util.go | 2 +- .../libnetwork/internal/util/validate.go | 1 - .../common/libnetwork/netavark/config.go | 2 +- .../common/libnetwork/pasta/pasta_linux.go | 106 ++++++++++++------ .../common/libnetwork/pasta/types.go | 3 + .../libnetwork/slirp4netns/slirp4netns.go | 2 +- .../common/libnetwork/types/network.go | 4 + .../common/pkg/cgroups/systemd_linux.go | 2 +- .../common/pkg/config/default_linux.go | 4 +- .../pkg/hooks/exec/runtimeconfigfilter.go | 1 - .../common/pkg/netns/netns_linux.go | 2 +- .../common/pkg/report/camelcase/camelcase.go | 2 +- .../containers/common/pkg/report/template.go | 2 +- .../common/pkg/systemd/systemd_linux.go | 2 +- vendor/modules.txt | 6 +- 23 files changed, 210 insertions(+), 99 deletions(-) diff --git a/go.mod b/go.mod index e17ae86af5..2df1815496 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/checkpoint-restore/go-criu/v7 v7.1.1-0.20240728160228-a9064d7e053c github.com/containernetworking/plugins v1.5.1 github.com/containers/buildah v1.37.0 - github.com/containers/common v0.60.1-0.20240829105055-8483ef6022b4 + github.com/containers/common v0.60.1-0.20240906123248-5298b838dcbd github.com/containers/conmon v2.0.20+incompatible github.com/containers/gvisor-tap-vsock v0.7.5 github.com/containers/image/v5 v5.32.1-0.20240806084436-e3e9287ca8e6 @@ -72,7 +72,7 @@ require ( go.etcd.io/bbolt v1.3.11 golang.org/x/crypto v0.27.0 golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 - golang.org/x/net v0.29.0 + golang.org/x/net v0.28.0 golang.org/x/sync v0.8.0 golang.org/x/sys v0.25.0 golang.org/x/term v0.24.0 diff --git a/go.sum b/go.sum index 436c7bb66f..9229414029 100644 --- a/go.sum +++ b/go.sum @@ -81,8 +81,8 @@ github.com/containernetworking/plugins v1.5.1 h1:T5ji+LPYjjgW0QM+KyrigZbLsZ8jaX+ github.com/containernetworking/plugins v1.5.1/go.mod h1:MIQfgMayGuHYs0XdNudf31cLLAC+i242hNm6KuDGqCM= github.com/containers/buildah v1.37.0 h1:jvHwu1vIwIqnHyOSg9eef9Apdpry+5oWLrm43gdf8Rk= github.com/containers/buildah v1.37.0/go.mod h1:MKd79tkluMf6vtH06SedhBQK5OB7E0pFVIuiTTw3dJk= -github.com/containers/common v0.60.1-0.20240829105055-8483ef6022b4 h1:Ybhbv5Dt0sditi2blwWX0nlmSGCfXejCQ+GvIoU1lCw= -github.com/containers/common v0.60.1-0.20240829105055-8483ef6022b4/go.mod h1:q4SarwqmM2pfrAauTrFQMtDTnGoPsNzcG5p5UxeHQgg= +github.com/containers/common v0.60.1-0.20240906123248-5298b838dcbd h1:eUzsKokkxMAxqBwCD1agfKf6lIZEQ/ayPru7Tb/oW9Y= +github.com/containers/common v0.60.1-0.20240906123248-5298b838dcbd/go.mod h1:f/n9w0F2lW52S3ppXjQlSVazsyNdilFZ80AyrFl4zn4= 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/gvisor-tap-vsock v0.7.5 h1:bTy4u3DOmmUPwurL6me2rsgfypAFDhyeJleUcQmBR/E= @@ -605,8 +605,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= diff --git a/vendor/github.com/containers/common/libimage/filters.go b/vendor/github.com/containers/common/libimage/filters.go index acb1df9fdc..aa11d54f53 100644 --- a/vendor/github.com/containers/common/libimage/filters.go +++ b/vendor/github.com/containers/common/libimage/filters.go @@ -34,7 +34,7 @@ func (i *Image) applyFilters(ctx context.Context, filters compiledFilters, tree // meantime, so do an extra check and make the // error non-fatal (see containers/podman/issues/12582). if errCorrupted := i.isCorrupted(ctx, ""); errCorrupted != nil { - logrus.Errorf(errCorrupted.Error()) + logrus.Error(errCorrupted.Error()) return false, nil } return false, err diff --git a/vendor/github.com/containers/common/libimage/search.go b/vendor/github.com/containers/common/libimage/search.go index b26ad80d26..6ab016b3b5 100644 --- a/vendor/github.com/containers/common/libimage/search.go +++ b/vendor/github.com/containers/common/libimage/search.go @@ -215,7 +215,7 @@ func (r *Runtime) searchImageInRegistry(ctx context.Context, term, registry stri } paramsArr := []SearchResult{} - for i := 0; i < limit; i++ { + for i := range limit { // Check whether query matches filters if !(filterMatchesAutomatedFilter(&options.Filter, results[i]) && filterMatchesOfficialFilter(&options.Filter, results[i]) && filterMatchesStarFilter(&options.Filter, results[i])) { continue @@ -275,7 +275,7 @@ func searchRepositoryTags(ctx context.Context, sys *types.SystemContext, registr } } paramsArr := []SearchResult{} - for i := 0; i < limit; i++ { + for i := range limit { params := SearchResult{ Name: imageRef.DockerReference().Name(), Tag: tags[i], diff --git a/vendor/github.com/containers/common/libnetwork/cni/run.go b/vendor/github.com/containers/common/libnetwork/cni/run.go index 337a27b8ef..68a42945c0 100644 --- a/vendor/github.com/containers/common/libnetwork/cni/run.go +++ b/vendor/github.com/containers/common/libnetwork/cni/run.go @@ -62,7 +62,6 @@ func (n *cniNetwork) Setup(namespacePath string, options types.SetupOptions) (ma } for name, netOpts := range options.Networks { - netOpts := netOpts network := n.networks[name] rt := getRuntimeConfig(namespacePath, options.ContainerName, options.ContainerID, name, ports, &netOpts) @@ -237,7 +236,6 @@ func (n *cniNetwork) teardown(namespacePath string, options types.TeardownOption var multiErr *multierror.Error teardown := func() error { for name, netOpts := range options.Networks { - netOpts := netOpts rt := getRuntimeConfig(namespacePath, options.ContainerName, options.ContainerID, name, ports, &netOpts) cniConfList, newRt, err := getCachedNetworkConfig(n.cniConf, name, rt) diff --git a/vendor/github.com/containers/common/libnetwork/etchosts/hosts.go b/vendor/github.com/containers/common/libnetwork/etchosts/hosts.go index 7ca62137b2..8a7cc534e6 100644 --- a/vendor/github.com/containers/common/libnetwork/etchosts/hosts.go +++ b/vendor/github.com/containers/common/libnetwork/etchosts/hosts.go @@ -229,9 +229,10 @@ func checkIfEntryExists(current HostEntry, entries HostEntries) bool { return false } -// parseExtraHosts converts a slice of "name:ip" string to entries. -// Because podman and buildah both store the extra hosts in this format -// we convert it here instead of having to this on the caller side. +// parseExtraHosts converts a slice of "name1;name2;name3:ip" string to entries. +// Each entry can contain one or more hostnames separated by semicolons and an IP address separated by a colon. +// Because podman and buildah both store the extra hosts in this format, +// we convert it here instead of having to do this on the caller side. func parseExtraHosts(extraHosts []string, hostContainersInternalIP string) (HostEntries, error) { entries := make(HostEntries, 0, len(extraHosts)) for _, entry := range extraHosts { @@ -252,7 +253,8 @@ func parseExtraHosts(extraHosts []string, hostContainersInternalIP string) (Host } ip = hostContainersInternalIP } - e := HostEntry{IP: ip, Names: []string{values[0]}} + names := strings.Split(values[0], ";") + e := HostEntry{IP: ip, Names: names} entries = append(entries, e) } return entries, nil diff --git a/vendor/github.com/containers/common/libnetwork/etchosts/ip.go b/vendor/github.com/containers/common/libnetwork/etchosts/ip.go index 909fcf67d2..588fbff352 100644 --- a/vendor/github.com/containers/common/libnetwork/etchosts/ip.go +++ b/vendor/github.com/containers/common/libnetwork/etchosts/ip.go @@ -10,17 +10,27 @@ import ( "github.com/containers/storage/pkg/unshare" ) -// 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) +// HostContainersInternalOptions contains the options for GetHostContainersInternalIP() +type HostContainersInternalOptions struct { + // Conf is the containers.Conf, must not be nil + Conf *config.Config + // NetStatus is the network status for the container, + // if this is set networkInterface must not be nil + NetStatus map[string]types.StatusBlock + // NetworkInterface of the current runtime + NetworkInterface types.ContainerNetwork + // Exclude are then ips that should not be returned, this is + // useful to prevent returning the same ip as in the container. + Exclude []net.IP + // PreferIP is a ip that should be used if set but it has a + // lower priority than the containers.conf config option. + // This is used for the pasta --map-guest-addr ip. + PreferIP string } -// 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 { +// GetHostContainersInternalIP returns the host.containers.internal ip +func GetHostContainersInternalIP(opts HostContainersInternalOptions) string { + switch opts.Conf.Containers.HostContainersInternalIP { case "": // if empty (default) we will automatically choose one below // if machine using gvproxy we let the gvproxy dns server handle the dns name so do not add it @@ -30,16 +40,22 @@ func GetHostContainersInternalIPExcluding(conf *config.Config, netStatus map[str case "none": return "" default: - return conf.Containers.HostContainersInternalIP + return opts.Conf.Containers.HostContainersInternalIP + } + + // caller has a specific ip it prefers + if opts.PreferIP != "" { + return opts.PreferIP } + ip := "" // 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.GetLocalIPExcluding(exclude) + return util.GetLocalIPExcluding(opts.Exclude) } - for net, status := range netStatus { - network, err := networkInterface.NetworkInspect(net) + for net, status := range opts.NetStatus { + network, err := opts.NetworkInterface.NetworkInspect(net) // only add the host entry for bridge networks // ip/macvlan gateway is normally not on the host if err != nil || network.Driver != types.BridgeNetworkDriver { @@ -60,7 +76,19 @@ func GetHostContainersInternalIPExcluding(conf *config.Config, netStatus map[str if ip != "" { return ip } - return util.GetLocalIPExcluding(exclude) + return util.GetLocalIPExcluding(opts.Exclude) +} + +// 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 { + return GetHostContainersInternalIP(HostContainersInternalOptions{ + Conf: conf, + NetStatus: netStatus, + NetworkInterface: networkInterface, + Exclude: 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 f8b9b76dfd..84bc4f621a 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 @@ -1,6 +1,7 @@ package rootlessnetns import ( + "encoding/json" "errors" "fmt" "io/fs" @@ -34,6 +35,9 @@ const ( // refCountFile file name for the ref count file refCountFile = "ref-count" + // infoCacheFile file name for the cache file used to store the rootless netns info + infoCacheFile = "info.json" + // rootlessNetNsConnPidFile is the name of the rootless netns slirp4netns/pasta pid file rootlessNetNsConnPidFile = "rootless-netns-conn.pid" @@ -54,11 +58,9 @@ type Netns struct { // config contains containers.conf options. config *config.Config - // ipAddresses used in the netns, this is needed to store - // the netns ips that are used by pasta. This is then handed - // back to the caller via IPAddresses() which then can make - // sure to not use them for host.containers.internal. - ipAddresses []net.IP + // info contain information about ip addresses used in the netns. + // A caller can get this info via Info(). + info *types.RootlessNetnsInfo } type rootlessNetnsError struct { @@ -115,6 +117,9 @@ func (n *Netns) getOrCreateNetns() (ns.NetNS, bool, error) { // quick check if pasta/slirp4netns are still running err := unix.Kill(pid, 0) if err == nil { + if err := n.deserializeInfo(); err != nil { + return nil, false, wrapError("deserialize info", err) + } // All good, return the netns. return nsRef, false, nil } @@ -227,6 +232,15 @@ func (n *Netns) setupPasta(nsPath string) error { return wrapError("create resolv.conf", err) } + n.info = &types.RootlessNetnsInfo{ + IPAddresses: res.IPAddresses, + DnsForwardIps: res.DNSForwardIPs, + MapGuestIps: res.MapGuestAddrIPs, + } + if err := n.serializeInfo(); err != nil { + return wrapError("serialize info", err) + } + return nil } @@ -261,6 +275,12 @@ func (n *Netns) setupSlirp4netns(nsPath string) error { if err != nil { return wrapError("determine default slirp4netns DNS address", err) } + nameservers := []string{resolveIP.String()} + + netnsIP, err := slirp4netns.GetIP(res.Subnet) + if err != nil { + return wrapError("determine default slirp4netns ip address", err) + } if err := resolvconf.New(&resolvconf.Params{ Path: n.getPath(resolvConfName), @@ -270,10 +290,19 @@ func (n *Netns) setupSlirp4netns(nsPath string) error { }, IPv6Enabled: res.IPv6, KeepHostServers: true, - Nameservers: []string{resolveIP.String()}, + Nameservers: nameservers, }); err != nil { return wrapError("create resolv.conf", err) } + + n.info = &types.RootlessNetnsInfo{ + IPAddresses: []net.IP{*netnsIP}, + DnsForwardIps: nameservers, + } + if err := n.serializeInfo(); err != nil { + return wrapError("serialize info", err) + } + return nil } @@ -541,20 +570,6 @@ func (n *Netns) runInner(toRun func() error, cleanup bool) (err error) { if err := toRun(); err != nil { return err } - - // get the current active addresses in the netns, and store them - addrs, err := net.InterfaceAddrs() - if err != nil { - return err - } - ips := make([]net.IP, 0, len(addrs)) - for _, addr := range addrs { - // make sure to skip localhost and other special addresses - if ipnet, ok := addr.(*net.IPNet); ok && ipnet.IP.IsGlobalUnicast() { - ips = append(ips, ipnet.IP) - } - } - n.ipAddresses = ips return nil }) } @@ -630,9 +645,7 @@ func (n *Netns) Run(lock *lockfile.LockFile, toRun func() error) error { // IPAddresses returns the currently used ip addresses in the netns // These should then not be assigned for the host.containers.internal entry. func (n *Netns) Info() *types.RootlessNetnsInfo { - return &types.RootlessNetnsInfo{ - IPAddresses: n.ipAddresses, - } + return n.info } func refCount(dir string, inc int) (int, error) { @@ -671,3 +684,26 @@ func readPidFile(path string) (int, error) { } return strconv.Atoi(strings.TrimSpace(string(b))) } + +func (n *Netns) serializeInfo() error { + f, err := os.Create(filepath.Join(n.dir, infoCacheFile)) + if err != nil { + return err + } + return json.NewEncoder(f).Encode(n.info) +} + +func (n *Netns) deserializeInfo() error { + f, err := os.Open(filepath.Join(n.dir, infoCacheFile)) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + return nil + } + return err + } + defer f.Close() + if n.info == nil { + n.info = new(types.RootlessNetnsInfo) + } + return json.NewDecoder(f).Decode(n.info) +} diff --git a/vendor/github.com/containers/common/libnetwork/internal/util/util.go b/vendor/github.com/containers/common/libnetwork/internal/util/util.go index 96c21e76f6..260e74d06e 100644 --- a/vendor/github.com/containers/common/libnetwork/internal/util/util.go +++ b/vendor/github.com/containers/common/libnetwork/internal/util/util.go @@ -112,7 +112,7 @@ func GetFreeIPv4NetworkSubnet(usedNetworks []*net.IPNet, subnetPools []config.Su // GetFreeIPv6NetworkSubnet returns a unused ipv6 subnet func GetFreeIPv6NetworkSubnet(usedNetworks []*net.IPNet) (*types.Subnet, error) { // FIXME: Is 10000 fine as limit? We should prevent an endless loop. - for i := 0; i < 10000; i++ { + for range 10000 { // RFC4193: Choose the ipv6 subnet random and NOT sequentially. network, err := getRandomIPv6Subnet() if err != nil { diff --git a/vendor/github.com/containers/common/libnetwork/internal/util/validate.go b/vendor/github.com/containers/common/libnetwork/internal/util/validate.go index 55995440e4..ddc778a5fe 100644 --- a/vendor/github.com/containers/common/libnetwork/internal/util/validate.go +++ b/vendor/github.com/containers/common/libnetwork/internal/util/validate.go @@ -129,7 +129,6 @@ func ValidateSetupOptions(n NetUtil, namespacePath string, options types.SetupOp return errors.New("must specify at least one network") } for name, netOpts := range options.Networks { - netOpts := netOpts network, err := n.Network(name) if err != nil { return err diff --git a/vendor/github.com/containers/common/libnetwork/netavark/config.go b/vendor/github.com/containers/common/libnetwork/netavark/config.go index 842c7e3122..8b43a787e4 100644 --- a/vendor/github.com/containers/common/libnetwork/netavark/config.go +++ b/vendor/github.com/containers/common/libnetwork/netavark/config.go @@ -126,7 +126,7 @@ func (n *netavarkNetwork) networkCreate(newNetwork *types.Network, defaultNet bo // generate random network ID var i int - for i = 0; i < 1000; i++ { + for i = range 1000 { id := stringid.GenerateNonCryptoID() if _, err := n.getNetwork(id); err != nil { newNetwork.ID = id diff --git a/vendor/github.com/containers/common/libnetwork/pasta/pasta_linux.go b/vendor/github.com/containers/common/libnetwork/pasta/pasta_linux.go index fd68f87f27..10b667eb6c 100644 --- a/vendor/github.com/containers/common/libnetwork/pasta/pasta_linux.go +++ b/vendor/github.com/containers/common/libnetwork/pasta/pasta_linux.go @@ -26,11 +26,16 @@ import ( ) const ( - dnsForwardOpt = "--dns-forward" + dnsForwardOpt = "--dns-forward" + mapGuestAddrOpt = "--map-guest-addr" // 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" + dnsForwardIpv4 = "169.254.1.1" + + // mapGuestAddrIpv4 static ip used as forwarder address inside the netns to reach the host, + // given this is a "link local" ip it should be very unlikely that it causes conflicts + mapGuestAddrIpv4 = "169.254.1.2" ) type SetupOptions struct { @@ -45,45 +50,61 @@ type SetupOptions struct { ExtraOptions []string } -func Setup(opts *SetupOptions) error { - _, err := Setup2(opts) - return err +// Setup2 alias for Setup() +func Setup2(opts *SetupOptions) (*SetupResult, error) { + return Setup(opts) } -// Setup2 start the pasta process for the given netns. +// 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 for any special cleanup logic, the pasta // process will automatically exit when the netns path is deleted. -func Setup2(opts *SetupOptions) (*SetupResult, error) { +func Setup(opts *SetupOptions) (*SetupResult, error) { path, err := opts.Config.FindHelperBinary(BinaryName, true) if err != nil { return nil, fmt.Errorf("could not find pasta, the network namespace can't be configured: %w", err) } - cmdArgs, dnsForwardIPs, err := createPastaArgs(opts) + cmdArgs, dnsForwardIPs, mapGuestAddrIPs, err := createPastaArgs(opts) if err != nil { return nil, err } logrus.Debugf("pasta arguments: %s", strings.Join(cmdArgs, " ")) - // pasta forks once ready, and quits once we delete the target namespace - out, err := exec.Command(path, cmdArgs...).CombinedOutput() - if err != nil { - exitErr := &exec.ExitError{} - if errors.As(err, &exitErr) { - return nil, fmt.Errorf("pasta failed with exit code %d:\n%s", - exitErr.ExitCode(), string(out)) + for { + // pasta forks once ready, and quits once we delete the target namespace + out, err := exec.Command(path, cmdArgs...).CombinedOutput() + if err != nil { + exitErr := &exec.ExitError{} + if errors.As(err, &exitErr) { + // special backwards compat check, --map-guest-addr was added in pasta version 20240814 so we + // cannot hard require it yet. Once we are confident that the update is most distros we can remove it. + if exitErr.ExitCode() == 1 && + strings.Contains(string(out), "unrecognized option '"+mapGuestAddrOpt) && + len(mapGuestAddrIPs) == 1 && mapGuestAddrIPs[0] == mapGuestAddrIpv4 { + // we did add the default --map-guest-addr option, if users set something different we want + // to get to the error below. We have to unset mapGuestAddrIPs here to avoid a infinite loop. + mapGuestAddrIPs = nil + // Trim off last two args which are --map-guest-addr 169.254.1.2. + cmdArgs = cmdArgs[:len(cmdArgs)-2] + continue + } + return nil, fmt.Errorf("pasta failed with exit code %d:\n%s", + exitErr.ExitCode(), string(out)) + } + return nil, fmt.Errorf("failed to start pasta: %w", err) } - return nil, fmt.Errorf("failed to start pasta: %w", err) - } - if len(out) > 0 { - // TODO: This should be warning but right now pasta still prints - // things with --quiet that we do not care about. - // For now info is fine and we can bump it up later, it is only a - // nice to have. - logrus.Infof("pasta logged warnings: %q", string(out)) + if len(out) > 0 { + // TODO: This should be warning but as of August 2024 pasta still prints + // things with --quiet that we do not care about. In podman CI I still see + // "Couldn't get any nameserver address" so until this is fixed we cannot + // enable it. For now info is fine and we can bump it up later, it is only a + // nice to have. + logrus.Infof("pasta logged warnings: %q", strings.TrimSpace(string(out))) + } + break } var ipv4, ipv6 bool @@ -112,19 +133,27 @@ func Setup2(opts *SetupOptions) (*SetupResult, error) { } result.IPv6 = ipv6 - for _, ip := range dnsForwardIPs { + result.DNSForwardIPs = filterIpFamily(dnsForwardIPs, ipv4, ipv6) + result.MapGuestAddrIPs = filterIpFamily(mapGuestAddrIPs, ipv4, ipv6) + + return result, nil +} + +func filterIpFamily(ips []string, ipv4, ipv6 bool) []string { + var result []string + for _, ip := range ips { ipp := net.ParseIP(ip) - // add the namesever ip only if the address family matches + // add the ip only if the address family matches if ipv4 && util.IsIPv4(ipp) || ipv6 && util.IsIPv6(ipp) { - result.DNSForwardIPs = append(result.DNSForwardIPs, ip) + result = append(result, ip) } } - - return result, nil + return result } -// createPastaArgs creates the pasta arguments, it returns the args to be passed to pasta(1) and as second arg the dns forward ips used. -func createPastaArgs(opts *SetupOptions) ([]string, []string, error) { +// createPastaArgs creates the pasta arguments, it returns the args to be passed to pasta(1) +// and as second arg the dns forward ips used. As third arg the map guest addr ips used. +func createPastaArgs(opts *SetupOptions) ([]string, []string, []string, error) { noTCPInitPorts := true noUDPInitPorts := true noTCPNamespacePorts := true @@ -149,6 +178,7 @@ func createPastaArgs(opts *SetupOptions) ([]string, []string, error) { }) var dnsForwardIPs []string + var mapGuestAddrIPs []string for i, opt := range cmdArgs { switch opt { case "-t", "--tcp-ports": @@ -166,6 +196,10 @@ func createPastaArgs(opts *SetupOptions) ([]string, []string, error) { if len(cmdArgs) > i+1 { dnsForwardIPs = append(dnsForwardIPs, cmdArgs[i+1]) } + case mapGuestAddrOpt: + if len(cmdArgs) > i+1 { + mapGuestAddrIPs = append(mapGuestAddrIPs, cmdArgs[i+1]) + } } } @@ -186,7 +220,7 @@ func createPastaArgs(opts *SetupOptions) ([]string, []string, error) { noUDPInitPorts = false cmdArgs = append(cmdArgs, "-u") default: - return nil, nil, fmt.Errorf("can't forward protocol: %s", protocol) + return nil, nil, nil, fmt.Errorf("can't forward protocol: %s", protocol) } arg := fmt.Sprintf("%s%d-%d:%d-%d", addr, @@ -226,5 +260,13 @@ func createPastaArgs(opts *SetupOptions) ([]string, []string, error) { cmdArgs = append(cmdArgs, "--netns", opts.Netns) - return cmdArgs, dnsForwardIPs, nil + // do this as last arg so we can easily trim them off in the error case when we have an older version + if len(mapGuestAddrIPs) == 0 { + // the user did not request custom --map-guest-addr so add our own so that we can use this + // for our own host.containers.internal host entry. + cmdArgs = append(cmdArgs, mapGuestAddrOpt, mapGuestAddrIpv4) + mapGuestAddrIPs = append(mapGuestAddrIPs, mapGuestAddrIpv4) + } + + return cmdArgs, dnsForwardIPs, mapGuestAddrIPs, nil } diff --git a/vendor/github.com/containers/common/libnetwork/pasta/types.go b/vendor/github.com/containers/common/libnetwork/pasta/types.go index b601e51695..f570afc3e5 100644 --- a/vendor/github.com/containers/common/libnetwork/pasta/types.go +++ b/vendor/github.com/containers/common/libnetwork/pasta/types.go @@ -10,6 +10,9 @@ type SetupResult struct { // DNSForwardIP is the ip used in --dns-forward, it should be added as first // entry to resolv.conf in the container. DNSForwardIPs []string + // MapGuestIps are the ips used for the --map-guest-addr option which + // we can use for the host.containers.internal entry. + MapGuestAddrIPs []string // IPv6 says whenever pasta run with ipv6 support 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 6f713431c8..9721750abf 100644 --- a/vendor/github.com/containers/common/libnetwork/slirp4netns/slirp4netns.go +++ b/vendor/github.com/containers/common/libnetwork/slirp4netns/slirp4netns.go @@ -645,7 +645,7 @@ func setupRootlessPortMappingViaSlirp(ports []types.PortMapping, cmd *exec.Cmd, if hostIP == "" { hostIP = "0.0.0.0" } - for i := uint16(0); i < port.Range; i++ { + for i := range port.Range { if err := openSlirp4netnsPort(apiSocket, protocol, hostIP, port.HostPort+i, port.ContainerPort+i); err != nil { return err } diff --git a/vendor/github.com/containers/common/libnetwork/types/network.go b/vendor/github.com/containers/common/libnetwork/types/network.go index 9741103f5b..77c76bf787 100644 --- a/vendor/github.com/containers/common/libnetwork/types/network.go +++ b/vendor/github.com/containers/common/libnetwork/types/network.go @@ -342,6 +342,10 @@ type TeardownOptions struct { type RootlessNetnsInfo struct { // IPAddresses used in the netns, must not be used for host.containers.internal IPAddresses []net.IP + // DnsForwardIps ips used in resolv.conf + DnsForwardIps []string + // MapGuestIps should be used for the host.containers.internal entry when set + MapGuestIps []string } // FilterFunc can be passed to NetworkList to filter the networks. diff --git a/vendor/github.com/containers/common/pkg/cgroups/systemd_linux.go b/vendor/github.com/containers/common/pkg/cgroups/systemd_linux.go index ead630e755..b1529410f9 100644 --- a/vendor/github.com/containers/common/pkg/cgroups/systemd_linux.go +++ b/vendor/github.com/containers/common/pkg/cgroups/systemd_linux.go @@ -23,7 +23,7 @@ func systemdCreate(resources *configs.Resources, path string, c *systemdDbus.Con slice = strings.TrimSuffix(slice, "/") var lastError error - for i := 0; i < 2; i++ { + for i := range 2 { properties := []systemdDbus.Property{ systemdDbus.PropDescription("cgroup " + name), systemdDbus.PropWants(slice), diff --git a/vendor/github.com/containers/common/pkg/config/default_linux.go b/vendor/github.com/containers/common/pkg/config/default_linux.go index 9e2ae4796b..64a98384e7 100644 --- a/vendor/github.com/containers/common/pkg/config/default_linux.go +++ b/vendor/github.com/containers/common/pkg/config/default_linux.go @@ -28,9 +28,9 @@ func getDefaultProcessLimits() []string { dat, err := os.ReadFile("/proc/sys/kernel/pid_max") if err == nil { val := strings.TrimSuffix(string(dat), "\n") - max, err := strconv.ParseUint(val, 10, 64) + maxLimit, err := strconv.ParseUint(val, 10, 64) if err == nil { - rlim = unix.Rlimit{Cur: max, Max: max} + rlim = unix.Rlimit{Cur: maxLimit, Max: maxLimit} } } defaultLimits := []string{} diff --git a/vendor/github.com/containers/common/pkg/hooks/exec/runtimeconfigfilter.go b/vendor/github.com/containers/common/pkg/hooks/exec/runtimeconfigfilter.go index ac17ac64da..3027112609 100644 --- a/vendor/github.com/containers/common/pkg/hooks/exec/runtimeconfigfilter.go +++ b/vendor/github.com/containers/common/pkg/hooks/exec/runtimeconfigfilter.go @@ -56,7 +56,6 @@ func RuntimeConfigFilterWithOptions(ctx context.Context, options RuntimeConfigFi return nil, err } for i, hook := range options.Hooks { - hook := hook var stdout bytes.Buffer hookErr, err = RunWithOptions(ctx, RunOptions{Hook: &hook, Dir: options.Dir, State: data, Stdout: &stdout, PostKillTimeout: options.PostKillTimeout}) if err != nil { diff --git a/vendor/github.com/containers/common/pkg/netns/netns_linux.go b/vendor/github.com/containers/common/pkg/netns/netns_linux.go index bbcedc0f6c..db35fd15a1 100644 --- a/vendor/github.com/containers/common/pkg/netns/netns_linux.go +++ b/vendor/github.com/containers/common/pkg/netns/netns_linux.go @@ -60,7 +60,7 @@ func NewNSAtPath(nsPath string) (ns.NetNS, error) { // NewNS creates a new persistent (bind-mounted) network namespace and returns // an object representing that namespace, without switching to it. func NewNS() (ns.NetNS, error) { - for i := 0; i < 10000; i++ { + for range 10000 { b := make([]byte, 16) _, err := rand.Reader.Read(b) if err != nil { diff --git a/vendor/github.com/containers/common/pkg/report/camelcase/camelcase.go b/vendor/github.com/containers/common/pkg/report/camelcase/camelcase.go index 830482ff0c..adafb1c26c 100644 --- a/vendor/github.com/containers/common/pkg/report/camelcase/camelcase.go +++ b/vendor/github.com/containers/common/pkg/report/camelcase/camelcase.go @@ -73,7 +73,7 @@ func Split(src string) (entries []string) { } // handle upper case -> lower case sequences, e.g. // "PDFL", "oader" -> "PDF", "Loader" - for i := 0; i < len(runes)-1; i++ { + for i := range len(runes) - 1 { if unicode.IsUpper(runes[i][0]) && unicode.IsLower(runes[i+1][0]) { runes[i+1] = append([]rune{runes[i][len(runes[i])-1]}, runes[i+1]...) runes[i] = runes[i][:len(runes[i])-1] diff --git a/vendor/github.com/containers/common/pkg/report/template.go b/vendor/github.com/containers/common/pkg/report/template.go index 0f7d5e5bfe..607bb7ff2b 100644 --- a/vendor/github.com/containers/common/pkg/report/template.go +++ b/vendor/github.com/containers/common/pkg/report/template.go @@ -101,7 +101,7 @@ func Headers(object any, overrides map[string]string) []map[string]string { // Column header will be field name upper-cased. headers := make(map[string]string, value.NumField()) - for i := 0; i < value.Type().NumField(); i++ { + for i := range value.Type().NumField() { field := value.Type().Field(i) // Recurse to find field names from promoted structs if field.Type.Kind() == reflect.Struct && field.Anonymous { diff --git a/vendor/github.com/containers/common/pkg/systemd/systemd_linux.go b/vendor/github.com/containers/common/pkg/systemd/systemd_linux.go index c1d8ed72e9..ea61ecaa18 100644 --- a/vendor/github.com/containers/common/pkg/systemd/systemd_linux.go +++ b/vendor/github.com/containers/common/pkg/systemd/systemd_linux.go @@ -74,7 +74,7 @@ func MoveRootlessNetnsSlirpProcessToUserSlice(pid int) error { func MovePauseProcessToScope(pausePidPath string) { var err error - for i := 0; i < 10; i++ { + for range 10 { randBytes := make([]byte, 4) _, err = rand.Read(randBytes) if err != nil { diff --git a/vendor/modules.txt b/vendor/modules.txt index 6349e5f305..43f98ccedf 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -171,8 +171,8 @@ github.com/containers/buildah/pkg/sshagent github.com/containers/buildah/pkg/util github.com/containers/buildah/pkg/volumes github.com/containers/buildah/util -# github.com/containers/common v0.60.1-0.20240829105055-8483ef6022b4 -## explicit; go 1.21.0 +# github.com/containers/common v0.60.1-0.20240906123248-5298b838dcbd +## explicit; go 1.22.0 github.com/containers/common/internal github.com/containers/common/internal/attributedstring github.com/containers/common/libimage @@ -1193,7 +1193,7 @@ golang.org/x/exp/slices ## explicit; go 1.18 golang.org/x/mod/semver golang.org/x/mod/sumdb/note -# golang.org/x/net v0.29.0 +# golang.org/x/net v0.28.0 ## explicit; go 1.18 golang.org/x/net/bpf golang.org/x/net/context