From b7b5b6f8e3072530f4c3fc07e5960e54c90729b5 Mon Sep 17 00:00:00 2001 From: baude Date: Thu, 29 Oct 2020 15:54:33 -0500 Subject: network aliases for container creation podman can now support adding network aliases when running containers (--network-alias). It requires an updated dnsname plugin as well as an updated ocicni to work properly. Signed-off-by: baude --- cmd/podman/common/create_opts.go | 7 +- cmd/podman/common/netflags.go | 14 ++++ cmd/podman/common/specgen.go | 11 +++ docs/source/markdown/podman-create.1.md | 2 +- docs/source/markdown/podman-run.1.md | 2 +- go.mod | 4 +- go.sum | 4 +- libpod/network/config.go | 5 +- libpod/network/netconflist.go | 7 +- libpod/networking_linux.go | 7 ++ pkg/domain/entities/types.go | 1 + pkg/specgen/generate/container_create.go | 4 + pkg/specgen/specgen.go | 3 + test/e2e/network_test.go | 39 +++++++++ .../github.com/cri-o/ocicni/pkg/ocicni/ocicni.go | 93 ++++++++++------------ vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go | 18 ++++- .../cri-o/ocicni/pkg/ocicni/util_linux.go | 79 ++++++++++++++++++ .../cri-o/ocicni/pkg/ocicni/util_unsupported.go | 19 ++++- vendor/modules.txt | 2 +- 19 files changed, 255 insertions(+), 66 deletions(-) diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go index 8b2efc988..4b52663c3 100644 --- a/cmd/podman/common/create_opts.go +++ b/cmd/podman/common/create_opts.go @@ -133,6 +133,7 @@ func stringMaptoArray(m map[string]string) []string { // a specgen spec. func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, cgroupsManager string) (*ContainerCLIOpts, []string, error) { var ( + aliases []string capAdd []string cappDrop []string entrypoint string @@ -242,8 +243,11 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, cgroup // network names endpointsConfig := cc.NetworkingConfig.EndpointsConfig cniNetworks := make([]string, 0, len(endpointsConfig)) - for netName := range endpointsConfig { + for netName, endpoint := range endpointsConfig { cniNetworks = append(cniNetworks, netName) + if len(endpoint.Aliases) > 0 { + aliases = append(aliases, endpoint.Aliases...) + } } // netMode @@ -262,6 +266,7 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, cgroup // defined when there is only one network. netInfo := entities.NetOptions{ AddHosts: cc.HostConfig.ExtraHosts, + Aliases: aliases, CNINetworks: cniNetworks, DNSOptions: cc.HostConfig.DNSOptions, DNSSearch: cc.HostConfig.DNSSearch, diff --git a/cmd/podman/common/netflags.go b/cmd/podman/common/netflags.go index 1b8297c36..935a5f7b9 100644 --- a/cmd/podman/common/netflags.go +++ b/cmd/podman/common/netflags.go @@ -43,6 +43,10 @@ func GetNetFlags() *pflag.FlagSet { "network", containerConfig.NetNS(), "Connect a container to a network", ) + netFlags.StringSlice( + "network-alias", []string{}, + "Add network-scoped alias for the container", + ) netFlags.StringSliceP( "publish", "p", []string{}, "Publish a container's port, or a range of ports, to the host (default [])", @@ -158,6 +162,9 @@ func NetFlagsToNetOptions(cmd *cobra.Command) (*entities.NetOptions, error) { } opts.NoHosts, err = cmd.Flags().GetBool("no-hosts") + if err != nil { + return nil, err + } if cmd.Flags().Changed("network") { network, err := cmd.Flags().GetString("network") @@ -181,5 +188,12 @@ func NetFlagsToNetOptions(cmd *cobra.Command) (*entities.NetOptions, error) { opts.CNINetworks = cniNets } + aliases, err := cmd.Flags().GetStringSlice("network-alias") + if err != nil { + return nil, err + } + if len(aliases) > 0 { + opts.Aliases = aliases + } return &opts, err } diff --git a/cmd/podman/common/specgen.go b/cmd/podman/common/specgen.go index ca1e25be1..39ff02857 100644 --- a/cmd/podman/common/specgen.go +++ b/cmd/podman/common/specgen.go @@ -396,6 +396,17 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string s.ShmSize = &shmSize } s.CNINetworks = c.Net.CNINetworks + + // Network aliases + if len(c.Net.Aliases) > 0 { + // build a map of aliases where key=cniName + aliases := make(map[string][]string, len(s.CNINetworks)) + for _, cniNetwork := range s.CNINetworks { + aliases[cniNetwork] = c.Net.Aliases + } + s.Aliases = aliases + } + s.HostAdd = c.Net.AddHosts s.UseImageResolvConf = c.Net.UseImageResolvConf s.DNSServers = c.Net.DNSServers diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md index e243a5842..105e8c63d 100644 --- a/docs/source/markdown/podman-create.1.md +++ b/docs/source/markdown/podman-create.1.md @@ -600,7 +600,7 @@ Valid values are: **--network-alias**=*alias* -Not implemented +Add network-scoped alias for the container **--no-healthcheck**=*true|false* diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md index 0166a344a..f655e5d62 100644 --- a/docs/source/markdown/podman-run.1.md +++ b/docs/source/markdown/podman-run.1.md @@ -626,7 +626,7 @@ Valid _mode_ values are: **--network-alias**=*alias* -Not implemented. +Add network-scoped alias for the container **--no-healthcheck**=*true|false* diff --git a/go.mod b/go.mod index 06ac75047..b136fb12e 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/containers/psgo v1.5.1 github.com/containers/storage v1.23.9 github.com/coreos/go-systemd/v22 v22.1.0 - github.com/cri-o/ocicni v0.2.0 + github.com/cri-o/ocicni v0.2.1-0.20201102180012-75c612fda1a2 github.com/cyphar/filepath-securejoin v0.2.2 github.com/davecgh/go-spew v1.1.1 github.com/docker/distribution v2.7.1+incompatible @@ -72,3 +72,5 @@ require ( k8s.io/apimachinery v0.19.3 k8s.io/client-go v0.0.0-20190620085101-78d2af792bab ) + +replace github.com/cri-o/ocicni => github.com/cri-o/ocicni v0.2.1-0.20201109200316-afdc16ba66df diff --git a/go.sum b/go.sum index 842473111..ae0f14863 100644 --- a/go.sum +++ b/go.sum @@ -119,8 +119,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cri-o/ocicni v0.2.0 h1:p0kO+/fcLTO574CcDwzAosFdP2U+NEL+a4wph3Bt85k= -github.com/cri-o/ocicni v0.2.0/go.mod h1:ZOuIEOp/3MB1eCBWANnNxM3zUA3NWh76wSRCsnKAg2c= +github.com/cri-o/ocicni v0.2.1-0.20201109200316-afdc16ba66df h1:c35uRFkER07nAkB1X21e+PI5xO21SOyI6G7tdfvz1z4= +github.com/cri-o/ocicni v0.2.1-0.20201109200316-afdc16ba66df/go.mod h1:vingr1ztOAzP2WyTgGbpMov9dFhbjNxdLtDv0+PhAvY= github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ= diff --git a/libpod/network/config.go b/libpod/network/config.go index a08e684d8..ce8a4446c 100644 --- a/libpod/network/config.go +++ b/libpod/network/config.go @@ -131,8 +131,9 @@ func (f FirewallConfig) Bytes() ([]byte, error) { // DNSNameConfig describes the dns container name resolution plugin config type DNSNameConfig struct { - PluginType string `json:"type"` - DomainName string `json:"domainName"` + PluginType string `json:"type"` + DomainName string `json:"domainName"` + Capabilities map[string]bool `json:"capabilities"` } // Bytes outputs the configuration as []byte diff --git a/libpod/network/netconflist.go b/libpod/network/netconflist.go index 8187fdb39..13f472413 100644 --- a/libpod/network/netconflist.go +++ b/libpod/network/netconflist.go @@ -126,9 +126,12 @@ func NewFirewallPlugin() FirewallConfig { // NewDNSNamePlugin creates the dnsname config with a given // domainname func NewDNSNamePlugin(domainName string) DNSNameConfig { + caps := make(map[string]bool, 1) + caps["aliases"] = true return DNSNameConfig{ - PluginType: "dnsname", - DomainName: domainName, + PluginType: "dnsname", + DomainName: domainName, + Capabilities: caps, } } diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index 28dca8dd8..4bc9381bd 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -105,6 +105,13 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) ([]*cnitypes.Re podName := getCNIPodName(ctr) podNetwork := r.getPodNetwork(ctr.ID(), podName, ctrNS.Path(), ctr.config.Networks, ctr.config.PortMappings, requestedIP, requestedMAC) + aliases, err := ctr.runtime.state.GetAllNetworkAliases(ctr) + if err != nil { + return nil, err + } + if len(aliases) > 0 { + podNetwork.Aliases = aliases + } results, err := r.netPlugin.SetUpPod(podNetwork) if err != nil { diff --git a/pkg/domain/entities/types.go b/pkg/domain/entities/types.go index d8ad2d891..12135c2b1 100644 --- a/pkg/domain/entities/types.go +++ b/pkg/domain/entities/types.go @@ -32,6 +32,7 @@ type VolumeDeleteReport struct{ Report } // pods and containers type NetOptions struct { AddHosts []string + Aliases []string CNINetworks []string UseImageResolvConf bool DNSOptions []string diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go index 53dc35df1..c049e64cf 100644 --- a/pkg/specgen/generate/container_create.go +++ b/pkg/specgen/generate/container_create.go @@ -133,6 +133,10 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener } options = append(options, libpod.WithExitCommand(exitCommandArgs)) + if len(s.Aliases) > 0 { + options = append(options, libpod.WithNetworkAliases(s.Aliases)) + } + runtimeSpec, err := SpecGenToOCI(ctx, s, rt, rtc, newImage, finalMounts, pod, command) if err != nil { return nil, err diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go index d68f55402..0a9a16ea7 100644 --- a/pkg/specgen/specgen.go +++ b/pkg/specgen/specgen.go @@ -328,6 +328,9 @@ type ContainerCgroupConfig struct { // ContainerNetworkConfig contains information on a container's network // configuration. type ContainerNetworkConfig struct { + // Aliases are a list of network-scoped aliases for container + // Optional + Aliases map[string][]string `json:"aliases"` // NetNS is the configuration to use for the container's network // namespace. // Mandatory. diff --git a/test/e2e/network_test.go b/test/e2e/network_test.go index 9bd16c008..7933580a5 100644 --- a/test/e2e/network_test.go +++ b/test/e2e/network_test.go @@ -6,6 +6,7 @@ import ( "os" "path/filepath" "strings" + "time" "github.com/containers/podman/v2/pkg/rootless" . "github.com/containers/podman/v2/test/utils" @@ -351,4 +352,42 @@ var _ = Describe("Podman network", func() { Expect(lines[0]).To(Equal(netName1)) Expect(lines[1]).To(Equal(netName2)) }) + It("podman network with multiple aliases", func() { + Skip("Until DNSName is updated on our CI images") + var worked bool + netName := "aliasTest" + stringid.GenerateNonCryptoID() + session := podmanTest.Podman([]string{"network", "create", netName}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(BeZero()) + defer podmanTest.removeCNINetwork(netName) + + top := podmanTest.Podman([]string{"run", "-dt", "--name=web", "--network=" + netName, "--network-alias=web1", "--network-alias=web2", nginx}) + top.WaitWithDefaultTimeout() + Expect(top.ExitCode()).To(BeZero()) + interval := time.Duration(250 * time.Millisecond) + // Wait for the nginx service to be running + for i := 0; i < 6; i++ { + // Test curl against the container's name + c1 := podmanTest.Podman([]string{"run", "--network=" + netName, nginx, "curl", "web"}) + c1.WaitWithDefaultTimeout() + worked = Expect(c1.ExitCode()).To(BeZero()) + if worked { + break + } + time.Sleep(interval) + interval *= 2 + } + Expect(worked).To(BeTrue()) + + // Nginx is now running so no need to do a loop + // Test against the first alias + c2 := podmanTest.Podman([]string{"run", "--network=" + netName, nginx, "curl", "web1"}) + c2.WaitWithDefaultTimeout() + Expect(c2.ExitCode()).To(BeZero()) + + // Test against the second alias + c3 := podmanTest.Podman([]string{"run", "--network=" + netName, nginx, "curl", "web2"}) + c3.WaitWithDefaultTimeout() + Expect(c3.ExitCode()).To(BeZero()) + }) }) diff --git a/vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go b/vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go index a8e2fbfa8..ee09adc8d 100644 --- a/vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go +++ b/vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go @@ -24,7 +24,6 @@ import ( type cniNetworkPlugin struct { cniConfig *libcni.CNIConfig - loNetwork *cniNetwork sync.RWMutex defaultNetName netName @@ -217,7 +216,6 @@ func initCNI(exec cniinvoke.Exec, cacheDir, defaultNetName string, confDir strin changeable: defaultNetName == "", }, networks: make(map[string]*cniNetwork), - loNetwork: getLoNetwork(), confDir: confDir, binDirs: binDirs, shutdownChan: make(chan struct{}), @@ -335,31 +333,9 @@ func loadNetworks(confDir string, cni *libcni.CNIConfig) (map[string]*cniNetwork } const ( - loIfname string = "lo" - loNetname string = "cni-loopback" + loIfname string = "lo" ) -func getLoNetwork() *cniNetwork { - loConfig, err := libcni.ConfListFromBytes([]byte(fmt.Sprintf(`{ - "cniVersion": "0.3.1", - "name": "%s", - "plugins": [{ - "type": "loopback" - }] -}`, loNetname))) - if err != nil { - // The hardcoded config above should always be valid and unit tests will - // catch this - panic(err) - } - loNetwork := &cniNetwork{ - name: loIfname, - config: loConfig, - } - - return loNetwork -} - func (plugin *cniNetworkPlugin) syncNetworkConfig() error { networks, defaultNetName, err := loadNetworks(plugin.confDir, plugin.cniConfig) if err != nil { @@ -525,16 +501,11 @@ func (plugin *cniNetworkPlugin) forEachNetwork(podNetwork *PodNetwork, fromCache return nil } -func buildLoopbackRuntimeConf(cacheDir string, podNetwork *PodNetwork) *libcni.RuntimeConf { - return &libcni.RuntimeConf{ - ContainerID: podNetwork.ID, - NetNS: podNetwork.NetNS, - CacheDir: cacheDir, - IfName: loIfname, - } +func (plugin *cniNetworkPlugin) SetUpPod(podNetwork PodNetwork) ([]NetResult, error) { + return plugin.SetUpPodWithContext(context.Background(), podNetwork) } -func (plugin *cniNetworkPlugin) SetUpPod(podNetwork PodNetwork) ([]NetResult, error) { +func (plugin *cniNetworkPlugin) SetUpPodWithContext(ctx context.Context, podNetwork PodNetwork) ([]NetResult, error) { if err := plugin.networksAvailable(&podNetwork); err != nil { return nil, err } @@ -542,15 +513,15 @@ func (plugin *cniNetworkPlugin) SetUpPod(podNetwork PodNetwork) ([]NetResult, er plugin.podLock(podNetwork).Lock() defer plugin.podUnlock(podNetwork) - loRt := buildLoopbackRuntimeConf(plugin.cacheDir, &podNetwork) - if _, err := plugin.loNetwork.addToNetwork(loRt, plugin.cniConfig); err != nil { - logrus.Errorf("Error while adding to cni lo network: %s", err) + // Set up loopback interface + if err := bringUpLoopback(podNetwork.NetNS); err != nil { + logrus.Errorf(err.Error()) return nil, err } results := make([]NetResult, 0) if err := plugin.forEachNetwork(&podNetwork, false, func(network *cniNetwork, podNetwork *PodNetwork, rt *libcni.RuntimeConf) error { - result, err := network.addToNetwork(rt, plugin.cniConfig) + result, err := network.addToNetwork(ctx, rt, plugin.cniConfig) if err != nil { logrus.Errorf("Error while adding pod to CNI network %q: %s", network.name, err) return err @@ -622,7 +593,7 @@ func (plugin *cniNetworkPlugin) getCachedNetworkInfo(containerID string) ([]NetA continue } // Ignore the loopback interface; it's handled separately - if cachedInfo.IfName == loIfname && cachedInfo.NetName == loNetname { + if cachedInfo.IfName == loIfname && cachedInfo.NetName == "cni-loopback" { continue } if cachedInfo.IfName == "" || cachedInfo.NetName == "" { @@ -641,6 +612,10 @@ func (plugin *cniNetworkPlugin) getCachedNetworkInfo(containerID string) ([]NetA // TearDownPod tears down pod networks. Prefers cached pod attachment information // but falls back to given network attachment information. func (plugin *cniNetworkPlugin) TearDownPod(podNetwork PodNetwork) error { + return plugin.TearDownPodWithContext(context.Background(), podNetwork) +} + +func (plugin *cniNetworkPlugin) TearDownPodWithContext(ctx context.Context, podNetwork PodNetwork) error { if len(podNetwork.Networks) == 0 { attachments, err := plugin.getCachedNetworkInfo(podNetwork.ID) if err == nil && len(attachments) > 0 { @@ -652,17 +627,16 @@ func (plugin *cniNetworkPlugin) TearDownPod(podNetwork PodNetwork) error { return err } - loRt := buildLoopbackRuntimeConf(plugin.cacheDir, &podNetwork) - if err := plugin.loNetwork.deleteFromNetwork(loRt, plugin.cniConfig); err != nil { - logrus.Errorf("Error while removing pod from CNI lo network: %v", err) - // Loopback teardown errors are not fatal - } - plugin.podLock(podNetwork).Lock() defer plugin.podUnlock(podNetwork) + if err := tearDownLoopback(podNetwork.NetNS); err != nil { + // ignore error + logrus.Errorf("Ignoring error tearing down loopback interface: %v", err) + } + return plugin.forEachNetwork(&podNetwork, true, func(network *cniNetwork, podNetwork *PodNetwork, rt *libcni.RuntimeConf) error { - if err := network.deleteFromNetwork(rt, plugin.cniConfig); err != nil { + if err := network.deleteFromNetwork(ctx, rt, plugin.cniConfig); err != nil { logrus.Errorf("Error while removing pod from CNI network %q: %s", network.name, err) return err } @@ -673,12 +647,23 @@ func (plugin *cniNetworkPlugin) TearDownPod(podNetwork PodNetwork) error { // GetPodNetworkStatus returns IP addressing and interface details for all // networks attached to the pod. func (plugin *cniNetworkPlugin) GetPodNetworkStatus(podNetwork PodNetwork) ([]NetResult, error) { + return plugin.GetPodNetworkStatusWithContext(context.Background(), podNetwork) +} + +// GetPodNetworkStatusWithContext returns IP addressing and interface details for all +// networks attached to the pod. +func (plugin *cniNetworkPlugin) GetPodNetworkStatusWithContext(ctx context.Context, podNetwork PodNetwork) ([]NetResult, error) { plugin.podLock(podNetwork).Lock() defer plugin.podUnlock(podNetwork) + if err := checkLoopback(podNetwork.NetNS); err != nil { + logrus.Errorf(err.Error()) + return nil, err + } + results := make([]NetResult, 0) if err := plugin.forEachNetwork(&podNetwork, true, func(network *cniNetwork, podNetwork *PodNetwork, rt *libcni.RuntimeConf) error { - result, err := network.checkNetwork(rt, plugin.cniConfig, plugin.nsManager, podNetwork.NetNS) + result, err := network.checkNetwork(ctx, rt, plugin.cniConfig, plugin.nsManager, podNetwork.NetNS) if err != nil { logrus.Errorf("Error while checking pod to CNI network %q: %s", network.name, err) return err @@ -700,9 +685,9 @@ func (plugin *cniNetworkPlugin) GetPodNetworkStatus(podNetwork PodNetwork) ([]Ne return results, nil } -func (network *cniNetwork) addToNetwork(rt *libcni.RuntimeConf, cni *libcni.CNIConfig) (cnitypes.Result, error) { +func (network *cniNetwork) addToNetwork(ctx context.Context, rt *libcni.RuntimeConf, cni *libcni.CNIConfig) (cnitypes.Result, error) { logrus.Infof("About to add CNI network %s (type=%v)", network.name, network.config.Plugins[0].Network.Type) - res, err := cni.AddNetworkList(context.Background(), network.config, rt) + res, err := cni.AddNetworkList(ctx, network.config, rt) if err != nil { logrus.Errorf("Error adding network: %v", err) return nil, err @@ -711,7 +696,7 @@ func (network *cniNetwork) addToNetwork(rt *libcni.RuntimeConf, cni *libcni.CNIC return res, nil } -func (network *cniNetwork) checkNetwork(rt *libcni.RuntimeConf, cni *libcni.CNIConfig, nsManager *nsManager, netns string) (cnitypes.Result, error) { +func (network *cniNetwork) checkNetwork(ctx context.Context, rt *libcni.RuntimeConf, cni *libcni.CNIConfig, nsManager *nsManager, netns string) (cnitypes.Result, error) { logrus.Infof("About to check CNI network %s (type=%v)", network.name, network.config.Plugins[0].Network.Type) gtet, err := cniversion.GreaterThanOrEqualTo(network.config.CNIVersion, "0.4.0") @@ -723,7 +708,7 @@ func (network *cniNetwork) checkNetwork(rt *libcni.RuntimeConf, cni *libcni.CNIC // When CNIVersion supports Check, use it. Otherwise fall back on what was done initially. if gtet { - err = cni.CheckNetworkList(context.Background(), network.config, rt) + err = cni.CheckNetworkList(ctx, network.config, rt) logrus.Infof("Checking CNI network %s (config version=%v)", network.name, network.config.CNIVersion) if err != nil { logrus.Errorf("Error checking network: %v", err) @@ -783,9 +768,9 @@ func (network *cniNetwork) checkNetwork(rt *libcni.RuntimeConf, cni *libcni.CNIC return converted, nil } -func (network *cniNetwork) deleteFromNetwork(rt *libcni.RuntimeConf, cni *libcni.CNIConfig) error { +func (network *cniNetwork) deleteFromNetwork(ctx context.Context, rt *libcni.RuntimeConf, cni *libcni.CNIConfig) error { logrus.Infof("About to del CNI network %s (type=%v)", network.name, network.config.Plugins[0].Network.Type) - if err := cni.DelNetworkList(context.Background(), network.config, rt); err != nil { + if err := cni.DelNetworkList(ctx, network.config, rt); err != nil { logrus.Errorf("Error deleting network: %v", err) return err } @@ -848,6 +833,10 @@ func buildCNIRuntimeConf(cacheDir string, podNetwork *PodNetwork, ifName string, rt.CapabilityArgs["ipRanges"] = runtimeConfig.IpRanges } + // Set Aliases in Capabilities + if len(podNetwork.Aliases) > 0 { + rt.CapabilityArgs["aliases"] = podNetwork.Aliases + } return rt, nil } diff --git a/vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go b/vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go index 717ecda33..7326b4b40 100644 --- a/vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go +++ b/vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go @@ -1,6 +1,8 @@ package ocicni import ( + "context" + "github.com/containernetworking/cni/pkg/types" ) @@ -87,6 +89,11 @@ type PodNetwork struct { // It is optional, and can be omitted for some or all specified networks // without issue. RuntimeConfig map[string]RuntimeConfig + + // Aliases are network-scoped names for resolving a container + // by name. The key value is the network name and the value is + // is a string slice of aliases + Aliases map[string][]string } // NetAttachment describes a container network attachment @@ -122,12 +129,21 @@ type CNIPlugin interface { // pod are launched. SetUpPod(network PodNetwork) ([]NetResult, error) + // SetUpPodWithContext is the same as SetUpPod but takes a context + SetUpPodWithContext(ctx context.Context, network PodNetwork) ([]NetResult, error) + // TearDownPod is the method called before a pod's sandbox container will be deleted TearDownPod(network PodNetwork) error - // Status is the method called to obtain the ipv4 or ipv6 addresses of the pod sandbox + // TearDownPodWithContext is the same as TearDownPod but takes a context + TearDownPodWithContext(ctx context.Context, network PodNetwork) error + + // GetPodNetworkStatus is the method called to obtain the ipv4 or ipv6 addresses of the pod sandbox GetPodNetworkStatus(network PodNetwork) ([]NetResult, error) + // GetPodNetworkStatusWithContext is the same as GetPodNetworkStatus but takes a context + GetPodNetworkStatusWithContext(ctx context.Context, network PodNetwork) ([]NetResult, error) + // NetworkStatus returns error if the network plugin is in error state Status() error diff --git a/vendor/github.com/cri-o/ocicni/pkg/ocicni/util_linux.go b/vendor/github.com/cri-o/ocicni/pkg/ocicni/util_linux.go index d263ae4df..53c22f83f 100644 --- a/vendor/github.com/cri-o/ocicni/pkg/ocicni/util_linux.go +++ b/vendor/github.com/cri-o/ocicni/pkg/ocicni/util_linux.go @@ -7,6 +7,9 @@ import ( "net" "os/exec" "strings" + + "github.com/containernetworking/plugins/pkg/ns" + "github.com/vishvananda/netlink" ) var defaultNamespaceEnterCommandName = "nsenter" @@ -69,3 +72,79 @@ func getContainerDetails(nsm *nsManager, netnsPath, interfaceName, addrType stri return ipNet, &mac, nil } + +func tearDownLoopback(netns string) error { + return ns.WithNetNSPath(netns, func(_ ns.NetNS) error { + link, err := netlink.LinkByName(loIfname) + if err != nil { + return err // not tested + } + err = netlink.LinkSetDown(link) + if err != nil { + return err // not tested + } + return nil + }) +} + +func bringUpLoopback(netns string) error { + if err := ns.WithNetNSPath(netns, func(_ ns.NetNS) error { + link, err := netlink.LinkByName(loIfname) + if err == nil { + err = netlink.LinkSetUp(link) + } + if err != nil { + return err + } + + v4Addrs, err := netlink.AddrList(link, netlink.FAMILY_V4) + if err != nil { + return err + } + if len(v4Addrs) != 0 { + // sanity check that this is a loopback address + for _, addr := range v4Addrs { + if !addr.IP.IsLoopback() { + return fmt.Errorf("loopback interface found with non-loopback address %q", addr.IP) + } + } + } + + v6Addrs, err := netlink.AddrList(link, netlink.FAMILY_V6) + if err != nil { + return err + } + if len(v6Addrs) != 0 { + // sanity check that this is a loopback address + for _, addr := range v6Addrs { + if !addr.IP.IsLoopback() { + return fmt.Errorf("loopback interface found with non-loopback address %q", addr.IP) + } + } + } + + return nil + }); err != nil { + return fmt.Errorf("error adding loopback interface: %s", err) + } + return nil +} + +func checkLoopback(netns string) error { + // Make sure loopback interface is up + if err := ns.WithNetNSPath(netns, func(_ ns.NetNS) error { + link, err := netlink.LinkByName(loIfname) + if err != nil { + return err + } + + if link.Attrs().Flags&net.FlagUp != net.FlagUp { + return fmt.Errorf("loopback interface is down") + } + + return nil + }); err != nil { + return fmt.Errorf("error checking loopback interface: %v", err) + } + return nil +} diff --git a/vendor/github.com/cri-o/ocicni/pkg/ocicni/util_unsupported.go b/vendor/github.com/cri-o/ocicni/pkg/ocicni/util_unsupported.go index 0b1c72208..b87f0d373 100644 --- a/vendor/github.com/cri-o/ocicni/pkg/ocicni/util_unsupported.go +++ b/vendor/github.com/cri-o/ocicni/pkg/ocicni/util_unsupported.go @@ -3,17 +3,32 @@ package ocicni import ( - "fmt" + "errors" "net" ) type nsManager struct { } +var errUnsupportedPlatform = errors.New("unsupported platform") + func (nsm *nsManager) init() error { return nil } func getContainerDetails(nsm *nsManager, netnsPath, interfaceName, addrType string) (*net.IPNet, *net.HardwareAddr, error) { - return nil, nil, fmt.Errorf("not supported yet") + return nil, nil, errUnsupportedPlatform +} + +func tearDownLoopback(netns string) error { + return errUnsupportedPlatform +} + +func bringUpLoopback(netns string) error { + return errUnsupportedPlatform +} + +func checkLoopback(netns string) error { + return errUnsupportedPlatform + } diff --git a/vendor/modules.txt b/vendor/modules.txt index 79db4807e..49a205e4c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -216,7 +216,7 @@ github.com/coreos/go-systemd/v22/dbus github.com/coreos/go-systemd/v22/internal/dlopen github.com/coreos/go-systemd/v22/journal github.com/coreos/go-systemd/v22/sdjournal -# github.com/cri-o/ocicni v0.2.0 +# github.com/cri-o/ocicni v0.2.1-0.20201102180012-75c612fda1a2 => github.com/cri-o/ocicni v0.2.1-0.20201109200316-afdc16ba66df github.com/cri-o/ocicni/pkg/ocicni # github.com/cyphar/filepath-securejoin v0.2.2 github.com/cyphar/filepath-securejoin -- cgit v1.2.3-54-g00ecf