summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libpod/networking_linux.go15
-rw-r--r--pkg/api/handlers/compat/networks.go47
-rw-r--r--test/apiv2/35-networks.at14
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