diff options
-rw-r--r-- | libpod/networking_linux.go | 15 | ||||
-rw-r--r-- | pkg/api/handlers/compat/networks.go | 47 | ||||
-rw-r--r-- | test/apiv2/35-networks.at | 14 |
3 files changed, 57 insertions, 19 deletions
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index 48b0c495c..15639aac4 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -177,6 +177,21 @@ func (r *RootlessCNI) Do(toRun func() error) error { if err != nil { return err } + logrus.Debugf("The actual path of /etc/resolv.conf on the host is %q", resolvePath) + // When /etc/resolv.conf on the host is a symlink to /run/systemd/resolve/stub-resolv.conf, + // we have to mount an empty filesystem on /run/systemd/resolve in the child namespace, + // so as to isolate the directory from the host mount namespace. + // + // Otherwise our bind-mount for /run/systemd/resolve/stub-resolv.conf is unmounted + // when systemd-resolved unlinks and recreates /run/systemd/resolve/stub-resolv.conf on the host. + // see: https://github.com/containers/podman/issues/10929 + if strings.HasPrefix(resolvePath, "/run/systemd/resolve/") { + rsr := r.getPath("/run/systemd/resolve") + err = unix.Mount("", rsr, "tmpfs", unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV, "") + if err != nil { + return errors.Wrapf(err, "failed to mount tmpfs on %q for rootless cni", rsr) + } + } if strings.HasPrefix(resolvePath, "/run/") { resolvePath = r.getPath(resolvePath) err = os.MkdirAll(filepath.Dir(resolvePath), 0700) diff --git a/pkg/api/handlers/compat/networks.go b/pkg/api/handlers/compat/networks.go index 4e1f31404..b990a916b 100644 --- a/pkg/api/handlers/compat/networks.go +++ b/pkg/api/handlers/compat/networks.go @@ -25,6 +25,12 @@ import ( "github.com/sirupsen/logrus" ) +type pluginInterface struct { + PluginType string `json:"type"` + IPAM network.IPAMConfig `json:"ipam"` + IsGW bool `json:"isGateway"` +} + func InspectNetwork(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value("runtime").(*libpod.Runtime) @@ -103,12 +109,12 @@ func getNetworkResourceByNameOrID(nameOrID string, runtime *libpod.Runtime, filt } } - // No Bridge plugin means we bail - bridge, err := genericPluginsToBridge(conf.Plugins, network.DefaultNetworkDriver) + plugin, err := getPlugin(conf.Plugins) if err != nil { return nil, err } - for _, outer := range bridge.IPAM.Ranges { + + for _, outer := range plugin.IPAM.Ranges { for _, n := range outer { ipamConfig := dockerNetwork.IPAMConfig{ Subnet: n.Subnet, @@ -140,19 +146,26 @@ func getNetworkResourceByNameOrID(nameOrID string, runtime *libpod.Runtime, filt labels = map[string]string{} } + isInternal := false + dockerDriver := plugin.PluginType + if plugin.PluginType == network.DefaultNetworkDriver { + isInternal = !plugin.IsGW + dockerDriver = "default" + } + report := types.NetworkResource{ Name: conf.Name, ID: networkid.GetNetworkID(conf.Name), Created: time.Unix(int64(stat.Ctim.Sec), int64(stat.Ctim.Nsec)), // nolint: unconvert Scope: "local", - Driver: network.DefaultNetworkDriver, + Driver: plugin.PluginType, EnableIPv6: false, IPAM: dockerNetwork.IPAM{ - Driver: "default", + Driver: dockerDriver, Options: map[string]string{}, Config: ipamConfigs, }, - Internal: !bridge.IsGW, + Internal: isInternal, Attachable: false, Ingress: false, ConfigFrom: dockerNetwork.ConfigReference{}, @@ -166,23 +179,19 @@ func getNetworkResourceByNameOrID(nameOrID string, runtime *libpod.Runtime, filt return &report, nil } -func genericPluginsToBridge(plugins []*libcni.NetworkConfig, pluginType string) (network.HostLocalBridge, error) { - var bridge network.HostLocalBridge - generic, err := findPluginByName(plugins, pluginType) - if err != nil { - return bridge, err - } - err = json.Unmarshal(generic, &bridge) - return bridge, err -} +func getPlugin(plugins []*libcni.NetworkConfig) (pluginInterface, error) { + var plugin pluginInterface -func findPluginByName(plugins []*libcni.NetworkConfig, pluginType string) ([]byte, error) { for _, p := range plugins { - if pluginType == p.Network.Type { - return p.Bytes, nil + for _, pluginType := range network.SupportedNetworkDrivers { + if pluginType == p.Network.Type { + err := json.Unmarshal(p.Bytes, &plugin) + return plugin, err + } } } - return nil, errors.New("unable to find bridge plugin") + + return plugin, errors.New("unable to find supported plugin") } func ListNetworks(w http.ResponseWriter, r *http.Request) { diff --git a/test/apiv2/35-networks.at b/test/apiv2/35-networks.at index 59947faac..7a36b605f 100644 --- a/test/apiv2/35-networks.at +++ b/test/apiv2/35-networks.at @@ -142,4 +142,18 @@ t GET networks?filters='{"label":["zaq"]}' 200 length=1 t POST networks/prune?filters='{"until":["5000000000"]}' 200 t GET networks?filters='{"label":["zaq"]}' 200 length=0 +# test macvlan network response +podman network create --driver macvlan macvlan1 + +# libpod api inspect the macvlan network +t GET libpod/networks/macvlan1/json 200 .name="macvlan1" + +# compat api inspect the macvlan network +t GET networks/macvlan1 200 .Name="macvlan1" + +# clean the macvlan network +t DELETE libpod/networks/macvlan1 200 \ + .[0].Name~macvlan1 \ + .[0].Err=null + # vim: filetype=sh |