From a533fe7094b63a6f62070f6f819db9e1610063f5 Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Wed, 11 Mar 2020 09:36:12 -0700 Subject: [PATCH] Use vendored ipvs package The ipvs package was moved to a separate repo. The ipvs package is a fairly generic set of helpers for managing IPVS. The ipvs package is used by docker swarm and kubernetes. Because we want to merge libnetwork back into the moby/moby codebase while also not creating more dependencies for other projects on moby/moby itself, it was decided that the best path for ipvs is to live on it's own since there are no other ties to libnetwork. Ref: https://github.com/moby/libnetwork/issues/2522 Signed-off-by: Brian Goff --- libnetwork/ipvs/ipvs_test.go | 385 ------------------ libnetwork/service_linux.go | 2 +- libnetwork/vendor.conf | 2 + .../vendor/github.com/moby/ipvs/LICENSE | 202 +++++++++ .../github.com/moby}/ipvs/constants.go | 0 libnetwork/vendor/github.com/moby/ipvs/doc.go | 1 + libnetwork/vendor/github.com/moby/ipvs/go.mod | 12 + .../{ => vendor/github.com/moby}/ipvs/ipvs.go | 0 .../github.com/moby}/ipvs/netlink.go | 0 9 files changed, 218 insertions(+), 386 deletions(-) delete mode 100644 libnetwork/ipvs/ipvs_test.go create mode 100644 libnetwork/vendor/github.com/moby/ipvs/LICENSE rename libnetwork/{ => vendor/github.com/moby}/ipvs/constants.go (100%) create mode 100644 libnetwork/vendor/github.com/moby/ipvs/doc.go create mode 100644 libnetwork/vendor/github.com/moby/ipvs/go.mod rename libnetwork/{ => vendor/github.com/moby}/ipvs/ipvs.go (100%) rename libnetwork/{ => vendor/github.com/moby}/ipvs/netlink.go (100%) diff --git a/libnetwork/ipvs/ipvs_test.go b/libnetwork/ipvs/ipvs_test.go deleted file mode 100644 index a18b312977..0000000000 --- a/libnetwork/ipvs/ipvs_test.go +++ /dev/null @@ -1,385 +0,0 @@ -// +build linux - -package ipvs - -import ( - "net" - "testing" - "time" - - "github.com/docker/libnetwork/testutils" - "github.com/vishvananda/netlink" - "github.com/vishvananda/netlink/nl" - "golang.org/x/sys/unix" - "gotest.tools/assert" - is "gotest.tools/assert/cmp" -) - -var ( - schedMethods = []string{ - RoundRobin, - LeastConnection, - DestinationHashing, - SourceHashing, - WeightedLeastConnection, - WeightedRoundRobin, - } - - protocols = []string{ - "TCP", - "UDP", - "FWM", - } - - fwdMethods = []uint32{ - ConnectionFlagMasq, - ConnectionFlagTunnel, - ConnectionFlagDirectRoute, - } - - fwdMethodStrings = []string{ - "Masq", - "Tunnel", - "Route", - } -) - -func lookupFwMethod(fwMethod uint32) string { - - switch fwMethod { - case ConnectionFlagMasq: - return fwdMethodStrings[0] - case ConnectionFlagTunnel: - return fwdMethodStrings[1] - case ConnectionFlagDirectRoute: - return fwdMethodStrings[2] - } - return "" -} - -func checkDestination(t *testing.T, i *Handle, s *Service, d *Destination, checkPresent bool) { - var dstFound bool - - dstArray, err := i.GetDestinations(s) - assert.NilError(t, err) - - for _, dst := range dstArray { - if dst.Address.Equal(d.Address) && dst.Port == d.Port && lookupFwMethod(dst.ConnectionFlags) == lookupFwMethod(d.ConnectionFlags) { - dstFound = true - break - } - } - - switch checkPresent { - case true: //The test expects the service to be present - if !dstFound { - - t.Fatalf("Did not find the service %s in ipvs output", d.Address.String()) - } - case false: //The test expects that the service should not be present - if dstFound { - t.Fatalf("Did not find the destination %s fwdMethod %s in ipvs output", d.Address.String(), lookupFwMethod(d.ConnectionFlags)) - } - } - -} - -func checkService(t *testing.T, i *Handle, s *Service, checkPresent bool) { - - svcArray, err := i.GetServices() - assert.NilError(t, err) - - var svcFound bool - - for _, svc := range svcArray { - - if svc.Protocol == s.Protocol && svc.Address.String() == s.Address.String() && svc.Port == s.Port { - svcFound = true - break - } - } - - switch checkPresent { - case true: //The test expects the service to be present - if !svcFound { - - t.Fatalf("Did not find the service %s in ipvs output", s.Address.String()) - } - case false: //The test expects that the service should not be present - if svcFound { - t.Fatalf("Did not expect the service %s in ipvs output", s.Address.String()) - } - } - -} - -func TestGetFamily(t *testing.T) { - if testutils.RunningOnCircleCI() { - t.Skip("Skipping as not supported on CIRCLE CI kernel") - } - - id, err := getIPVSFamily() - assert.NilError(t, err) - assert.Check(t, 0 != id) -} - -func TestService(t *testing.T) { - if testutils.RunningOnCircleCI() { - t.Skip("Skipping as not supported on CIRCLE CI kernel") - } - - defer testutils.SetupTestOSContext(t)() - - i, err := New("") - assert.NilError(t, err) - - for _, protocol := range protocols { - for _, schedMethod := range schedMethods { - testDatas := []struct { - AddressFamily uint16 - IP string - Netmask uint32 - }{ - { - AddressFamily: nl.FAMILY_V4, - IP: "1.2.3.4", - Netmask: 0xFFFFFFFF, - }, { - AddressFamily: nl.FAMILY_V6, - IP: "2001:db8:3c4d:15::1a00", - Netmask: 128, - }, - } - for _, td := range testDatas { - s := Service{ - AddressFamily: td.AddressFamily, - SchedName: schedMethod, - } - - switch protocol { - case "FWM": - s.FWMark = 1234 - s.Netmask = td.Netmask - case "TCP": - s.Protocol = unix.IPPROTO_TCP - s.Port = 80 - s.Address = net.ParseIP(td.IP) - s.Netmask = td.Netmask - case "UDP": - s.Protocol = unix.IPPROTO_UDP - s.Port = 53 - s.Address = net.ParseIP(td.IP) - s.Netmask = td.Netmask - } - - err := i.NewService(&s) - assert.NilError(t, err) - checkService(t, i, &s, true) - for _, updateSchedMethod := range schedMethods { - if updateSchedMethod == schedMethod { - continue - } - - s.SchedName = updateSchedMethod - err = i.UpdateService(&s) - assert.NilError(t, err) - checkService(t, i, &s, true) - - scopy, err := i.GetService(&s) - assert.NilError(t, err) - assert.Check(t, is.Equal((*scopy).Address.String(), s.Address.String())) - assert.Check(t, is.Equal((*scopy).Port, s.Port)) - assert.Check(t, is.Equal((*scopy).Protocol, s.Protocol)) - } - - err = i.DelService(&s) - assert.NilError(t, err) - checkService(t, i, &s, false) - } - } - } - - svcs := []Service{ - { - AddressFamily: nl.FAMILY_V4, - SchedName: RoundRobin, - Protocol: unix.IPPROTO_TCP, - Port: 80, - Address: net.ParseIP("10.20.30.40"), - Netmask: 0xFFFFFFFF, - }, - { - AddressFamily: nl.FAMILY_V4, - SchedName: LeastConnection, - Protocol: unix.IPPROTO_UDP, - Port: 8080, - Address: net.ParseIP("10.20.30.41"), - Netmask: 0xFFFFFFFF, - }, - } - // Create services for testing flush - for _, svc := range svcs { - if !i.IsServicePresent(&svc) { - err = i.NewService(&svc) - assert.NilError(t, err) - checkService(t, i, &svc, true) - } else { - t.Errorf("svc: %v exists", svc) - } - } - err = i.Flush() - assert.NilError(t, err) - got, err := i.GetServices() - assert.NilError(t, err) - if len(got) != 0 { - t.Errorf("Unexpected services after flush") - } -} - -func createDummyInterface(t *testing.T) { - if testutils.RunningOnCircleCI() { - t.Skip("Skipping as not supported on CIRCLE CI kernel") - } - - dummy := &netlink.Dummy{ - LinkAttrs: netlink.LinkAttrs{ - Name: "dummy", - }, - } - - err := netlink.LinkAdd(dummy) - assert.NilError(t, err) - - dummyLink, err := netlink.LinkByName("dummy") - assert.NilError(t, err) - - ip, ipNet, err := net.ParseCIDR("10.1.1.1/24") - assert.NilError(t, err) - - ipNet.IP = ip - - ipAddr := &netlink.Addr{IPNet: ipNet, Label: ""} - err = netlink.AddrAdd(dummyLink, ipAddr) - assert.NilError(t, err) -} - -func TestDestination(t *testing.T) { - defer testutils.SetupTestOSContext(t)() - - createDummyInterface(t) - i, err := New("") - assert.NilError(t, err) - - for _, protocol := range protocols { - testDatas := []struct { - AddressFamily uint16 - IP string - Netmask uint32 - Destinations []string - }{ - { - AddressFamily: nl.FAMILY_V4, - IP: "1.2.3.4", - Netmask: 0xFFFFFFFF, - Destinations: []string{"10.1.1.2", "10.1.1.3", "10.1.1.4"}, - }, { - AddressFamily: nl.FAMILY_V6, - IP: "2001:db8:3c4d:15::1a00", - Netmask: 128, - Destinations: []string{"2001:db8:3c4d:15::1a2b", "2001:db8:3c4d:15::1a2c", "2001:db8:3c4d:15::1a2d"}, - }, - } - for _, td := range testDatas { - s := Service{ - AddressFamily: td.AddressFamily, - SchedName: RoundRobin, - } - - switch protocol { - case "FWM": - s.FWMark = 1234 - s.Netmask = td.Netmask - case "TCP": - s.Protocol = unix.IPPROTO_TCP - s.Port = 80 - s.Address = net.ParseIP(td.IP) - s.Netmask = td.Netmask - case "UDP": - s.Protocol = unix.IPPROTO_UDP - s.Port = 53 - s.Address = net.ParseIP(td.IP) - s.Netmask = td.Netmask - } - - err := i.NewService(&s) - assert.NilError(t, err) - checkService(t, i, &s, true) - - s.SchedName = "" - for _, fwdMethod := range fwdMethods { - destinations := make([]Destination, 0) - for _, ip := range td.Destinations { - d := Destination{ - AddressFamily: td.AddressFamily, - Address: net.ParseIP(ip), - Port: 5000, - Weight: 1, - ConnectionFlags: fwdMethod, - } - destinations = append(destinations, d) - err := i.NewDestination(&s, &d) - assert.NilError(t, err) - checkDestination(t, i, &s, &d, true) - } - - for _, updateFwdMethod := range fwdMethods { - if updateFwdMethod == fwdMethod { - continue - } - for _, d := range destinations { - d.ConnectionFlags = updateFwdMethod - err = i.UpdateDestination(&s, &d) - assert.NilError(t, err) - checkDestination(t, i, &s, &d, true) - } - } - for _, d := range destinations { - err = i.DelDestination(&s, &d) - assert.NilError(t, err) - checkDestination(t, i, &s, &d, false) - } - } - - } - } -} - -func TestTimeouts(t *testing.T) { - if testutils.RunningOnCircleCI() { - t.Skip("Skipping as not supported on CIRCLE CI kernel") - } - defer testutils.SetupTestOSContext(t)() - - i, err := New("") - assert.NilError(t, err) - - _, err = i.GetConfig() - assert.NilError(t, err) - - cfg := Config{66 * time.Second, 66 * time.Second, 66 * time.Second} - err = i.SetConfig(&cfg) - assert.NilError(t, err) - - c2, err := i.GetConfig() - assert.NilError(t, err) - assert.DeepEqual(t, cfg, *c2) - - // A timeout value 0 means that the current timeout value of the corresponding entry is preserved - cfg = Config{77 * time.Second, 0 * time.Second, 77 * time.Second} - err = i.SetConfig(&cfg) - assert.NilError(t, err) - - c3, err := i.GetConfig() - assert.NilError(t, err) - assert.DeepEqual(t, *c3, Config{77 * time.Second, 66 * time.Second, 77 * time.Second}) -} diff --git a/libnetwork/service_linux.go b/libnetwork/service_linux.go index 451f760b61..02ea8ff6bc 100644 --- a/libnetwork/service_linux.go +++ b/libnetwork/service_linux.go @@ -16,10 +16,10 @@ import ( "github.com/docker/docker/pkg/reexec" "github.com/docker/libnetwork/iptables" - "github.com/docker/libnetwork/ipvs" "github.com/docker/libnetwork/ns" "github.com/gogo/protobuf/proto" "github.com/ishidawataru/sctp" + "github.com/moby/ipvs" "github.com/sirupsen/logrus" "github.com/vishvananda/netlink/nl" "github.com/vishvananda/netns" diff --git a/libnetwork/vendor.conf b/libnetwork/vendor.conf index 45d9dbbe76..8ccababbfa 100644 --- a/libnetwork/vendor.conf +++ b/libnetwork/vendor.conf @@ -57,3 +57,5 @@ go.opencensus.io 9c377598961b706d1542bd2d84d538b5094d596e gotest.tools 1083505acf35a0bd8a696b26837e1fb3187a7a83 # v2.3.0 github.com/google/go-cmp 3af367b6b30c263d47e8895973edcca9a49cf029 # v0.2.0 + +github.com/moby/ipvs 45bd6e080830fe2f2a43320b154d82b8f3f5aa0c diff --git a/libnetwork/vendor/github.com/moby/ipvs/LICENSE b/libnetwork/vendor/github.com/moby/ipvs/LICENSE new file mode 100644 index 0000000000..e06d208186 --- /dev/null +++ b/libnetwork/vendor/github.com/moby/ipvs/LICENSE @@ -0,0 +1,202 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/libnetwork/ipvs/constants.go b/libnetwork/vendor/github.com/moby/ipvs/constants.go similarity index 100% rename from libnetwork/ipvs/constants.go rename to libnetwork/vendor/github.com/moby/ipvs/constants.go diff --git a/libnetwork/vendor/github.com/moby/ipvs/doc.go b/libnetwork/vendor/github.com/moby/ipvs/doc.go new file mode 100644 index 0000000000..91ce6808ad --- /dev/null +++ b/libnetwork/vendor/github.com/moby/ipvs/doc.go @@ -0,0 +1 @@ +package ipvs diff --git a/libnetwork/vendor/github.com/moby/ipvs/go.mod b/libnetwork/vendor/github.com/moby/ipvs/go.mod new file mode 100644 index 0000000000..0a03722344 --- /dev/null +++ b/libnetwork/vendor/github.com/moby/ipvs/go.mod @@ -0,0 +1,12 @@ +module github.com/moby/ipvs + +go 1.13 + +require ( + github.com/pkg/errors v0.8.1 // indirect + github.com/sirupsen/logrus v1.4.1 + github.com/vishvananda/netlink v1.0.0 + github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f + golang.org/x/sys v0.0.0-20190303122642-d455e41777fc + gotest.tools v1.4.1-0.20181223230014-1083505acf35 +) diff --git a/libnetwork/ipvs/ipvs.go b/libnetwork/vendor/github.com/moby/ipvs/ipvs.go similarity index 100% rename from libnetwork/ipvs/ipvs.go rename to libnetwork/vendor/github.com/moby/ipvs/ipvs.go diff --git a/libnetwork/ipvs/netlink.go b/libnetwork/vendor/github.com/moby/ipvs/netlink.go similarity index 100% rename from libnetwork/ipvs/netlink.go rename to libnetwork/vendor/github.com/moby/ipvs/netlink.go