From 92a8b1c1c9cd9e292c7a39d3df0fdf6b6b3d83e2 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 13 Jun 2018 14:51:29 -0500 Subject: [PATCH] vendor: update containernetworking/cni and add containernetworking/plugins Updated containernetworking/cni moves pkg/ns to containernetworking/plugins so we need that now too. --- glide.lock | 7 +- glide.yaml | 7 +- multus/multus.go | 2 +- .../containernetworking/cni/.appveyor.yml | 17 + .../containernetworking/cni/.gitignore | 1 + .../containernetworking/cni/.travis.yml | 14 +- .../cni/CODE-OF-CONDUCT.md | 4 + .../containernetworking/cni/CONVENTIONS.md | 38 +- .../cni/Documentation/host-local.md | 82 -- .../containernetworking/cni/GOVERNANCE.md | 44 + .../containernetworking/cni/MAINTAINERS | 2 +- .../containernetworking/cni/README.md | 61 +- .../containernetworking/cni/RELEASING.md | 34 + .../containernetworking/cni/ROADMAP.md | 32 +- .../containernetworking/cni/SPEC.md | 359 +++++-- .../containernetworking/cni/Vagrantfile | 12 +- .../containernetworking/cni/build.sh | 29 - .../containernetworking/cni/cnitool/README.md | 47 + .../cni/cnitool/{cni.go => cnitool.go} | 64 +- .../containernetworking/cni/libcni/api.go | 254 ++++- .../cni/libcni/api_test.go | 676 ++++++++++++- .../libcni/backwards_compatibility_test.go | 32 +- .../containernetworking/cni/libcni/conf.go | 3 + .../cni/libcni/conf_test.go | 84 +- .../cni/libcni/libcni_suite_test.go | 30 +- .../containernetworking/cni/logo.png | Bin 0 -> 11604 bytes .../cni/pkg/invoke/args.go | 17 +- .../cni/pkg/invoke/args_test.go | 60 ++ .../cni/pkg/invoke/delegate.go | 42 +- .../cni/pkg/invoke/delegate_test.go | 201 ++++ .../cni/pkg/invoke/exec.go | 104 +- .../cni/pkg/invoke/exec_test.go | 43 +- .../cni/pkg/invoke/fakes/raw_exec.go | 16 + .../invoke/get_version_integration_test.go | 31 +- .../cni/pkg/invoke/raw_exec.go | 12 +- .../cni/pkg/invoke/raw_exec_test.go | 2 +- .../containernetworking/cni/pkg/ip/ipmasq.go | 66 -- .../cni/pkg/ns/ns_linux.go | 149 --- .../containernetworking/cni/pkg/skel/skel.go | 86 +- .../cni/pkg/skel/skel_test.go | 222 ++++- .../cni/pkg/types/020/types.go | 16 +- .../cni/pkg/types/020/types_test.go | 2 + .../containernetworking/cni/pkg/types/args.go | 15 +- .../cni/pkg/types/args_test.go | 11 + .../cni/pkg/types/current/types.go | 45 +- .../cni/pkg/types/current/types_test.go | 64 +- .../cni/pkg/types/types.go | 18 +- .../cni/pkg/types/types_test.go | 141 +++ .../legacy_examples/example_runtime.go | 202 ++-- .../pkg/version/legacy_examples/examples.go | 4 + .../legacy_examples/legacy_examples_test.go | 7 +- .../cni/pkg/version/plugin.go | 59 ++ .../cni/pkg/version/plugin_test.go | 56 ++ .../version/testhelpers/testhelpers_test.go | 4 + .../cni/pkg/version/version.go | 4 +- .../host-local/backend/allocator/allocator.go | 277 ------ .../backend/allocator/allocator_test.go | 356 ------- .../host-local/backend/allocator/config.go | 84 -- .../ipam/host-local/host_local_test.go | 292 ------ .../cni/plugins/ipam/host-local/main.go | 86 -- .../cni/plugins/main/bridge/bridge_test.go | 529 ---------- .../cni/plugins/test/noop/main.go | 24 +- .../cni/plugins/test/noop/noop_test.go | 37 +- .../cni/scripts/docker-run.sh | 2 +- .../cni/scripts/release-with-rkt.sh | 50 - .../cni/scripts/release.sh | 38 + .../containernetworking/cni/test.sh | 60 +- .../coreos/go-systemd/activation/listeners.go | 37 - .../onsi/ginkgo/ginkgo/bootstrap_command.go | 182 ---- .../onsi/ginkgo/ginkgo/build_command.go | 68 -- .../ginkgo/ginkgo/convert/ginkgo_ast_nodes.go | 123 --- .../onsi/ginkgo/ginkgo/convert/import.go | 91 -- .../ginkgo/ginkgo/convert/package_rewriter.go | 127 --- .../onsi/ginkgo/ginkgo/convert/test_finder.go | 56 -- .../ginkgo/convert/testfile_rewriter.go | 163 ---- .../ginkgo/convert/testing_t_rewriter.go | 130 --- .../onsi/ginkgo/ginkgo/convert_command.go | 44 - .../onsi/ginkgo/ginkgo/generate_command.go | 164 ---- .../onsi/ginkgo/ginkgo/help_command.go | 31 - .../interrupthandler/interrupt_handler.go | 52 - .../sigquit_swallower_unix.go | 14 - .../sigquit_swallower_windows.go | 7 - .../github.com/onsi/ginkgo/ginkgo/main.go | 291 ------ .../onsi/ginkgo/ginkgo/nodot/nodot.go | 194 ---- .../onsi/ginkgo/ginkgo/nodot_command.go | 76 -- .../onsi/ginkgo/ginkgo/notifications.go | 141 --- .../onsi/ginkgo/ginkgo/run_command.go | 192 ---- .../run_watch_and_build_command_flags.go | 121 --- .../onsi/ginkgo/ginkgo/suite_runner.go | 172 ---- .../ginkgo/ginkgo/testrunner/log_writer.go | 52 - .../ginkgo/ginkgo/testrunner/run_result.go | 27 - .../ginkgo/ginkgo/testrunner/test_runner.go | 460 --------- .../ginkgo/ginkgo/testsuite/test_suite.go | 106 -- .../onsi/ginkgo/ginkgo/unfocus_command.go | 38 - .../onsi/ginkgo/ginkgo/version_command.go | 23 - .../onsi/ginkgo/ginkgo/watch/delta.go | 22 - .../onsi/ginkgo/ginkgo/watch/delta_tracker.go | 71 -- .../onsi/ginkgo/ginkgo/watch/dependencies.go | 91 -- .../onsi/ginkgo/ginkgo/watch/package_hash.go | 103 -- .../ginkgo/ginkgo/watch/package_hashes.go | 82 -- .../onsi/ginkgo/ginkgo/watch/suite.go | 87 -- .../onsi/ginkgo/ginkgo/watch_command.go | 172 ---- .../onsi/ginkgo/integration/integration.go | 1 - .../containernetworking/plugins/.appveyor.yml | 28 + .../containernetworking/plugins/.gitignore | 30 + .../containernetworking/plugins/.travis.yml | 38 + .../plugins/CONTRIBUTING.md | 134 +++ .../{cni => plugins}/Godeps/Godeps.json | 86 +- .../{cni => plugins}/Godeps/Readme | 0 .../containernetworking/plugins/LICENSE | 201 ++++ .../containernetworking/plugins/README.md | 26 + .../containernetworking/plugins/RELEASING.md | 35 + .../containernetworking/plugins/Vagrantfile | 21 + .../containernetworking/plugins/build.sh | 30 + .../integration/integration_linux_test.go | 270 +++++ .../integration/integration_suite_test.go | 44 + .../basic-bridge/network-chain-test.json | 12 + .../integration/testdata/basic-ptp.json | 11 + .../network-chain-test.conflist | 27 + .../testdata/chained-ptp-bandwidth.conflist | 26 + .../plugins/pkg/ip/addr_linux.go | 68 ++ .../{cni => plugins}/pkg/ip/cidr.go | 10 + .../{cni => plugins}/pkg/ip/ip_suite_test.go | 2 +- .../plugins/pkg/ip/ipforward_linux.go | 61 ++ .../plugins/pkg/ip/ipforward_linux_test.go | 31 + .../plugins/pkg/ip/ipmasq_linux.go | 119 +++ .../link.go => plugins/pkg/ip/link_linux.go} | 74 +- .../pkg/ip/link_linux_test.go} | 62 +- .../{cni => plugins}/pkg/ip/route_linux.go | 6 + .../ipforward.go => plugins/pkg/ipam/ipam.go} | 17 +- .../pkg/ipam/ipam_linux.go} | 50 +- .../pkg/ipam/ipam_linux_test.go} | 56 +- .../pkg/ipam/ipam_suite_test.go | 2 +- .../{cni => plugins}/pkg/ns/README.md | 19 +- .../ns/ns.go => plugins/pkg/ns/ns_linux.go} | 46 +- .../pkg/ns/ns_linux_test.go} | 26 +- .../{cni => plugins}/pkg/ns/ns_suite_test.go | 2 +- .../pkg/testutils/bad_reader.go | 0 .../{cni => plugins}/pkg/testutils/cmd.go | 16 +- .../pkg/testutils/echosvr/echosvr_test.go | 74 ++ .../pkg/testutils/echosvr/init_test.go | 13 + .../plugins/pkg/testutils/echosvr/main.go | 57 ++ .../plugins/pkg/testutils/netns_linux.go | 157 +++ .../plugins/pkg/testutils/ping.go | 55 ++ .../pkg/utils/hwaddr/hwaddr.go | 0 .../pkg/utils/hwaddr/hwaddr_suite_test.go | 2 +- .../pkg/utils/hwaddr/hwaddr_test.go | 2 +- .../pkg/utils/sysctl/sysctl_linux.go | 0 .../{cni => plugins}/pkg/utils/utils.go | 0 .../pkg/utils/utils_suite_test.go | 2 +- .../{cni => plugins}/pkg/utils/utils_test.go | 0 .../plugins/ipam/dhcp/README.md} | 6 +- .../plugins/ipam/dhcp/daemon.go | 41 +- .../plugins/ipam/dhcp/dhcp_suite_test.go} | 16 +- .../plugins/plugins/ipam/dhcp/dhcp_test.go | 319 ++++++ .../plugins/ipam/dhcp/lease.go | 30 +- .../plugins/ipam/dhcp/main.go | 16 +- .../plugins/ipam/dhcp/options.go | 0 .../plugins/ipam/dhcp/options_test.go | 0 .../plugins/plugins/ipam/host-local/README.md | 142 +++ .../host-local/backend/allocator/allocator.go | 217 +++++ .../backend/allocator/allocator_suite_test.go | 2 +- .../backend/allocator/allocator_test.go | 333 +++++++ .../host-local/backend/allocator/config.go | 160 +++ .../backend/allocator/config_test.go | 382 ++++++++ .../host-local/backend/allocator/range.go | 164 ++++ .../host-local/backend/allocator/range_set.go | 97 ++ .../backend/allocator/range_set_test.go | 70 ++ .../backend/allocator/range_test.go | 209 ++++ .../ipam/host-local/backend/disk/backend.go | 33 +- .../backend/disk/disk_suite_test.go} | 23 +- .../ipam/host-local/backend/disk/lock.go | 23 +- .../ipam/host-local/backend/disk/lock_test.go | 63 ++ .../plugins/ipam/host-local/backend/store.go | 4 +- .../host-local/backend/testing/fake_store.go | 25 +- .../plugins/ipam/host-local/dns.go | 0 .../plugins/ipam/host-local/dns_test.go | 0 .../ipam/host-local/host_local_suite_test.go | 2 +- .../ipam/host-local/host_local_test.go | 538 ++++++++++ .../plugins/plugins/ipam/host-local/main.go | 140 +++ .../plugins/plugins/ipam/static/README.md | 45 + .../plugins/plugins/ipam/static/main.go | 142 +++ .../plugins/ipam/static/static_suite_test.go} | 29 +- .../plugins/ipam/static/static_test.go | 161 +++ .../plugins/plugins/linux_only.txt | 11 + .../plugins/main/bridge/README.md} | 1 + .../plugins/main/bridge/bridge.go | 275 ++++-- .../plugins/main/bridge/bridge_suite_test.go | 2 +- .../plugins/main/bridge/bridge_test.go | 919 ++++++++++++++++++ .../plugins/main/host-device/README.md | 21 + .../plugins/main/host-device/host-device.go | 221 +++++ .../host-device/host-device_suite_test.go | 27 + .../main/host-device/host-device_test.go | 157 +++ .../plugins/main/ipvlan/README.md} | 11 +- .../plugins/main/ipvlan/ipvlan.go | 81 +- .../plugins/main/ipvlan/ipvlan_suite_test.go | 2 +- .../plugins/main/ipvlan/ipvlan_test.go | 259 +++++ .../plugins/main/loopback/loopback.go | 2 +- .../main/loopback/loopback_suite_test.go | 4 +- .../plugins/main/loopback/loopback_test.go | 14 +- .../plugins/main/macvlan/README.md} | 0 .../plugins/main/macvlan/macvlan.go | 60 +- .../main/macvlan/macvlan_suite_test.go | 2 +- .../plugins/main/macvlan/macvlan_test.go | 22 +- .../plugins/main/ptp/README.md} | 2 +- .../{cni => plugins}/plugins/main/ptp/ptp.go | 80 +- .../plugins/main/ptp/ptp_suite_test.go | 2 +- .../plugins/main/ptp/ptp_test.go | 110 ++- .../plugins/plugins/main/vlan/vlan.go | 196 ++++ .../plugins/main/vlan/vlan_suite_test.go | 27 + .../plugins/main/vlan/vlan_test.go} | 128 +-- .../plugins/plugins/meta/bandwidth/README.md | 64 ++ .../meta/bandwidth/bandwidth_linux_test.go | 727 ++++++++++++++ .../meta/bandwidth/bandwidth_suite_test.go | 200 ++++ .../plugins/meta/bandwidth/ifb_creator.go | 167 ++++ .../plugins/plugins/meta/bandwidth/main.go | 236 +++++ .../plugins/meta/flannel/README.md} | 0 .../plugins/meta/flannel/flannel.go | 3 + .../meta/flannel/flannel_linux_test.go} | 19 +- .../meta/flannel/flannel_suite_test.go | 2 +- .../plugins/plugins/meta/portmap/README.md | 133 +++ .../plugins/plugins/meta/portmap/chain.go | 133 +++ .../plugins/meta/portmap/chain_test.go | 196 ++++ .../plugins/plugins/meta/portmap/main.go | 205 ++++ .../plugins/plugins/meta/portmap/portmap.go | 348 +++++++ .../meta/portmap/portmap_integ_test.go | 249 +++++ .../meta/portmap/portmap_suite_test.go | 78 ++ .../plugins/meta/portmap/portmap_test.go | 330 +++++++ .../plugins/plugins/meta/portmap/utils.go | 117 +++ .../plugins/meta/tuning/README.md} | 0 .../plugins/meta/tuning/tuning.go | 43 +- .../plugins/meta/tuning/tuning_suite_test.go | 27 + .../plugins/meta/tuning/tuning_test.go | 112 +++ .../plugins/plugins/sample/README.md | 7 + .../plugins/plugins/sample/main.go | 145 +++ .../plugins/sample/sample_linux_test.go | 138 +++ .../plugins/sample/sample_suite_test.go | 15 + .../plugins/scripts/release.sh | 36 + .../containernetworking/plugins/test.sh | 41 + .../github.com/alexflint/go-filemutex/LICENSE | 21 + .../alexflint/go-filemutex/README.md | 31 + .../alexflint/go-filemutex/filemutex_flock.go | 67 ++ .../go-filemutex/filemutex_windows.go | 102 ++ .../containernetworking/cni/LICENSE | 202 ++++ .../containernetworking/cni/libcni/api.go | 219 +++++ .../containernetworking/cni/libcni/conf.go | 256 +++++ .../cni/pkg/invoke/args.go | 82 ++ .../cni/pkg/invoke/delegate.go | 53 + .../cni/pkg/invoke/exec.go | 95 ++ .../cni/pkg/invoke/find.go | 43 + .../cni/pkg/invoke/os_unix.go | 20 + .../cni/pkg/invoke/os_windows.go | 18 + .../cni/pkg/invoke/raw_exec.go | 59 ++ .../containernetworking/cni/pkg/skel/skel.go | 228 +++++ .../cni/pkg/types/020/types.go | 135 +++ .../containernetworking/cni/pkg/types/args.go | 112 +++ .../cni/pkg/types/current/types.go | 300 ++++++ .../cni/pkg/types/types.go | 189 ++++ .../cni/pkg/version/conf.go | 37 + .../cni/pkg/version/plugin.go | 81 ++ .../cni/pkg/version/reconcile.go | 49 + .../cni/pkg/version/version.go | 61 ++ .../github.com/coreos/go-iptables/LICENSE | 0 .../github.com/coreos/go-iptables/NOTICE | 5 + .../coreos/go-iptables/iptables/iptables.go | 170 +++- .../coreos/go-iptables/iptables/lock.go | 0 .../github.com/coreos/go-systemd/LICENSE | 0 .../github.com/coreos/go-systemd/NOTICE | 5 + .../coreos/go-systemd/activation/files.go | 19 +- .../coreos/go-systemd/activation/listeners.go | 103 ++ .../go-systemd/activation/packetconns.go | 5 +- .../vendor/github.com/d2g/dhcp4/LICENSE | 0 .../vendor/github.com/d2g/dhcp4/README.md | 0 .../vendor/github.com/d2g/dhcp4/constants.go | 0 .../vendor/github.com/d2g/dhcp4/helpers.go | 0 .../vendor/github.com/d2g/dhcp4/option.go | 0 .../vendor/github.com/d2g/dhcp4/packet.go | 0 .../vendor/github.com/d2g/dhcp4client/LICENSE | 0 .../github.com/d2g/dhcp4client/README.md | 0 .../github.com/d2g/dhcp4client/client.go | 0 .../github.com/d2g/dhcp4client/inetsock.go | 0 .../vendor/github.com/d2g/dhcp4client/init.go | 0 .../d2g/dhcp4client/pktsock_linux.go | 0 .../vendor/github.com/d2g/dhcp4server/LICENSE | 354 +++++++ .../github.com/d2g/dhcp4server/README.md | 4 + .../d2g/dhcp4server/leasepool/lease.go | 95 ++ .../d2g/dhcp4server/leasepool/lease_test.go | 51 + .../d2g/dhcp4server/leasepool/leasepool.go | 49 + .../leasepool/memorypool/memorypool.go | 150 +++ .../leasepool/memorypool/memorypool_test.go | 51 + .../github.com/d2g/dhcp4server/server.go | 572 +++++++++++ .../github.com/d2g/dhcp4server/server_test.go | 426 ++++++++ .../github.com/j-keck/arping/.gitignore | 1 + .../vendor/github.com/j-keck/arping/LICENSE | 22 + .../vendor/github.com/j-keck/arping/README.md | 29 + .../github.com/j-keck/arping/arp_datagram.go | 97 ++ .../vendor/github.com/j-keck/arping/arping.go | 197 ++++ .../github.com/j-keck/arping/arping_bsd.go | 101 ++ .../github.com/j-keck/arping/arping_linux.go | 38 + .../j-keck/arping/arping_windows.go | 28 + .../github.com/j-keck/arping/netutils.go | 64 ++ .../mattn/go-shellwords/.travis.yml | 8 + .../github.com/mattn/go-shellwords/LICENSE | 21 + .../github.com/mattn/go-shellwords/README.md | 47 + .../mattn/go-shellwords/shellwords.go | 145 +++ .../mattn/go-shellwords/util_posix.go | 19 + .../mattn/go-shellwords/util_windows.go | 17 + .../vendor/github.com/onsi/ginkgo/.gitignore | 0 .../vendor/github.com/onsi/ginkgo/.travis.yml | 0 .../github.com/onsi/ginkgo/CHANGELOG.md | 0 .../vendor/github.com/onsi/ginkgo/LICENSE | 0 .../vendor/github.com/onsi/ginkgo/README.md | 0 .../github.com/onsi/ginkgo/config/config.go | 0 .../onsi/ginkgo/extensions/table/table.go | 0 .../ginkgo/extensions/table/table_entry.go | 0 .../github.com/onsi/ginkgo/ginkgo_dsl.go | 0 .../internal/codelocation/code_location.go | 0 .../internal/containernode/container_node.go | 0 .../onsi/ginkgo/internal/failer/failer.go | 0 .../ginkgo/internal/leafnodes/benchmarker.go | 0 .../ginkgo/internal/leafnodes/interfaces.go | 0 .../onsi/ginkgo/internal/leafnodes/it_node.go | 0 .../ginkgo/internal/leafnodes/measure_node.go | 0 .../onsi/ginkgo/internal/leafnodes/runner.go | 0 .../ginkgo/internal/leafnodes/setup_nodes.go | 0 .../ginkgo/internal/leafnodes/suite_nodes.go | 0 .../synchronized_after_suite_node.go | 0 .../synchronized_before_suite_node.go | 0 .../onsi/ginkgo/internal/remote/aggregator.go | 0 .../internal/remote/forwarding_reporter.go | 0 .../internal/remote/output_interceptor.go | 0 .../remote/output_interceptor_unix.go | 0 .../internal/remote/output_interceptor_win.go | 0 .../onsi/ginkgo/internal/remote/server.go | 0 .../ginkgo/internal/spec/index_computer.go | 0 .../onsi/ginkgo/internal/spec/spec.go | 0 .../onsi/ginkgo/internal/spec/specs.go | 0 .../ginkgo/internal/specrunner/random_id.go | 0 .../ginkgo/internal/specrunner/spec_runner.go | 0 .../onsi/ginkgo/internal/suite/suite.go | 0 .../internal/testingtproxy/testing_t_proxy.go | 0 .../ginkgo/internal/writer/fake_writer.go | 0 .../onsi/ginkgo/internal/writer/writer.go | 0 .../onsi/ginkgo/reporters/default_reporter.go | 0 .../onsi/ginkgo/reporters/fake_reporter.go | 0 .../onsi/ginkgo/reporters/junit_reporter.go | 0 .../onsi/ginkgo/reporters/reporter.go | 0 .../reporters/stenographer/console_logging.go | 0 .../stenographer/fake_stenographer.go | 0 .../reporters/stenographer/stenographer.go | 0 .../ginkgo/reporters/teamcity_reporter.go | 0 .../onsi/ginkgo/types/code_location.go | 0 .../onsi/ginkgo/types/synchronization.go | 0 .../github.com/onsi/ginkgo/types/types.go | 0 .../vendor/github.com/onsi/gomega/.gitignore | 0 .../vendor/github.com/onsi/gomega/.travis.yml | 0 .../github.com/onsi/gomega/CHANGELOG.md | 0 .../vendor/github.com/onsi/gomega/LICENSE | 0 .../vendor/github.com/onsi/gomega/README.md | 0 .../github.com/onsi/gomega/format/format.go | 0 .../github.com/onsi/gomega/gbytes/buffer.go | 0 .../onsi/gomega/gbytes/say_matcher.go | 0 .../github.com/onsi/gomega/gexec/build.go | 0 .../onsi/gomega/gexec/exit_matcher.go | 0 .../onsi/gomega/gexec/prefixed_writer.go | 0 .../github.com/onsi/gomega/gexec/session.go | 0 .../github.com/onsi/gomega/gomega_dsl.go | 0 .../gomega/internal/assertion/assertion.go | 0 .../asyncassertion/async_assertion.go | 0 .../internal/oraclematcher/oracle_matcher.go | 0 .../testingtsupport/testing_t_support.go | 0 .../vendor/github.com/onsi/gomega/matchers.go | 0 .../github.com/onsi/gomega/matchers/and.go | 0 .../matchers/assignable_to_type_of_matcher.go | 0 .../onsi/gomega/matchers/be_a_directory.go | 0 .../onsi/gomega/matchers/be_a_regular_file.go | 0 .../gomega/matchers/be_an_existing_file.go | 0 .../onsi/gomega/matchers/be_closed_matcher.go | 0 .../onsi/gomega/matchers/be_empty_matcher.go | 0 .../matchers/be_equivalent_to_matcher.go | 0 .../onsi/gomega/matchers/be_false_matcher.go | 0 .../onsi/gomega/matchers/be_nil_matcher.go | 0 .../gomega/matchers/be_numerically_matcher.go | 0 .../onsi/gomega/matchers/be_sent_matcher.go | 0 .../gomega/matchers/be_temporally_matcher.go | 0 .../onsi/gomega/matchers/be_true_matcher.go | 0 .../onsi/gomega/matchers/be_zero_matcher.go | 0 .../onsi/gomega/matchers/consist_of.go | 0 .../matchers/contain_element_matcher.go | 0 .../matchers/contain_substring_matcher.go | 0 .../onsi/gomega/matchers/equal_matcher.go | 0 .../onsi/gomega/matchers/have_key_matcher.go | 0 .../matchers/have_key_with_value_matcher.go | 0 .../onsi/gomega/matchers/have_len_matcher.go | 0 .../gomega/matchers/have_occurred_matcher.go | 0 .../gomega/matchers/have_prefix_matcher.go | 0 .../gomega/matchers/have_suffix_matcher.go | 0 .../gomega/matchers/match_error_matcher.go | 0 .../gomega/matchers/match_json_matcher.go | 0 .../gomega/matchers/match_regexp_matcher.go | 0 .../github.com/onsi/gomega/matchers/not.go | 0 .../github.com/onsi/gomega/matchers/or.go | 0 .../onsi/gomega/matchers/panic_matcher.go | 0 .../onsi/gomega/matchers/receive_matcher.go | 0 .../onsi/gomega/matchers/succeed_matcher.go | 0 .../goraph/bipartitegraph/bipartitegraph.go | 0 .../bipartitegraph/bipartitegraphmatching.go | 0 .../matchers/support/goraph/edge/edge.go | 0 .../matchers/support/goraph/node/node.go | 0 .../matchers/support/goraph/util/util.go | 0 .../onsi/gomega/matchers/type_support.go | 0 .../onsi/gomega/matchers/with_transform.go | 0 .../github.com/onsi/gomega/types/types.go | 0 .../github.com/safchain/ethtool/ethtool.go | 240 +++++ .../vishvananda/netlink/.travis.yml | 5 + .../github.com/vishvananda/netlink/LICENSE | 0 .../github.com/vishvananda/netlink/Makefile | 0 .../github.com/vishvananda/netlink/README.md | 0 .../github.com/vishvananda/netlink/addr.go | 12 +- .../vishvananda/netlink/addr_linux.go | 31 +- .../vishvananda/netlink/bpf_linux.go | 0 .../vishvananda/netlink/bridge_linux.go | 115 +++ .../github.com/vishvananda/netlink/class.go | 0 .../vishvananda/netlink/class_linux.go | 0 .../vishvananda/netlink/conntrack_linux.go | 352 +++++++ .../netlink/conntrack_unspecified.go | 53 + .../github.com/vishvananda/netlink/filter.go | 41 +- .../vishvananda/netlink/filter_linux.go | 47 +- .../vishvananda/netlink/genetlink_linux.go | 167 ++++ .../netlink/genetlink_unspecified.go | 25 + .../vishvananda/netlink/gtp_linux.go | 238 +++++ .../vishvananda/netlink/handle_linux.go | 0 .../vishvananda/netlink/handle_unspecified.go | 0 .../github.com/vishvananda/netlink/link.go | 39 +- .../vishvananda/netlink/link_linux.go | 193 +++- .../vishvananda/netlink/link_tuntap_linux.go | 0 .../github.com/vishvananda/netlink/neigh.go | 0 .../vishvananda/netlink/neigh_linux.go | 0 .../github.com/vishvananda/netlink/netlink.go | 0 .../vishvananda/netlink/netlink_linux.go | 0 .../netlink/netlink_unspecified.go | 10 +- .../vishvananda/netlink/nl/addr_linux.go | 29 + .../vishvananda/netlink/nl/bridge_linux.go | 74 ++ .../vishvananda/netlink/nl/conntrack_linux.go | 189 ++++ .../vishvananda/netlink/nl/genetlink_linux.go | 89 ++ .../vishvananda/netlink/nl/link_linux.go | 74 +- .../vishvananda/netlink/nl/mpls_linux.go | 0 .../vishvananda/netlink/nl/nl_linux.go | 43 +- .../vishvananda/netlink/nl/nl_unspecified.go | 0 .../vishvananda/netlink/nl/route_linux.go | 0 .../vishvananda/netlink/nl/syscall.go | 0 .../vishvananda/netlink/nl/tc_linux.go | 0 .../vishvananda/netlink/nl/xfrm_linux.go | 0 .../netlink/nl/xfrm_monitor_linux.go | 0 .../netlink/nl/xfrm_policy_linux.go | 0 .../netlink/nl/xfrm_state_linux.go | 0 .../github.com/vishvananda/netlink/order.go | 0 .../vishvananda/netlink/protinfo.go | 20 +- .../vishvananda/netlink/protinfo_linux.go | 4 + .../github.com/vishvananda/netlink/qdisc.go | 0 .../vishvananda/netlink/qdisc_linux.go | 0 .../github.com/vishvananda/netlink/route.go | 0 .../vishvananda/netlink/route_linux.go | 2 +- .../vishvananda/netlink/route_unspecified.go | 0 .../github.com/vishvananda/netlink/rule.go | 0 .../vishvananda/netlink/rule_linux.go | 0 .../github.com/vishvananda/netlink/socket.go | 0 .../vishvananda/netlink/socket_linux.go | 0 .../github.com/vishvananda/netlink/xfrm.go | 0 .../vishvananda/netlink/xfrm_monitor_linux.go | 0 .../vishvananda/netlink/xfrm_policy.go | 0 .../vishvananda/netlink/xfrm_policy_linux.go | 0 .../vishvananda/netlink/xfrm_state.go | 0 .../vishvananda/netlink/xfrm_state_linux.go | 0 .../github.com/vishvananda/netns/LICENSE | 0 .../github.com/vishvananda/netns/README.md | 1 + .../github.com/vishvananda/netns/netns.go | 2 +- .../vishvananda/netns/netns_linux.go | 2 + .../vishvananda/netns/netns_unspecified.go | 8 + .../vendor/golang.org/x/net/bpf/asm.go | 41 + .../vendor/golang.org/x/net/bpf/constants.go | 215 ++++ .../vendor/golang.org/x/net/bpf/doc.go | 82 ++ .../golang.org/x/net/bpf/instructions.go | 434 +++++++++ .../golang.org/x/net/bpf/instructions_test.go | 184 ++++ .../x/net/bpf/testdata/all_instructions.bpf | 1 + .../x/net/bpf/testdata/all_instructions.txt | 79 ++ .../plugins/vendor/golang.org/x/net/bpf/vm.go | 140 +++ .../golang.org/x/net/bpf/vm_aluop_test.go | 512 ++++++++++ .../golang.org/x/net/bpf/vm_bpf_test.go | 192 ++++ .../golang.org/x/net/bpf/vm_extension_test.go | 49 + .../golang.org/x/net/bpf/vm_instructions.go | 174 ++++ .../golang.org/x/net/bpf/vm_jump_test.go | 380 ++++++++ .../golang.org/x/net/bpf/vm_load_test.go | 246 +++++ .../golang.org/x/net/bpf/vm_ret_test.go | 115 +++ .../golang.org/x/net/bpf/vm_scratch_test.go | 247 +++++ .../vendor/golang.org/x/net/bpf/vm_test.go | 144 +++ .../golang.org/x/net/internal/iana/const.go | 180 ++++ .../golang.org/x/net/internal/iana/gen.go | 293 ++++++ .../vendor/golang.org/x/net/ipv4/bpf_test.go | 93 ++ .../golang.org/x/net/ipv4/bpfopt_linux.go | 27 + .../golang.org/x/net/ipv4/bpfopt_stub.go | 16 + .../vendor/golang.org/x/net/ipv4/control.go | 70 ++ .../golang.org/x/net/ipv4/control_bsd.go | 40 + .../golang.org/x/net/ipv4/control_pktinfo.go | 37 + .../golang.org/x/net/ipv4/control_stub.go | 23 + .../golang.org/x/net/ipv4/control_unix.go | 164 ++++ .../golang.org/x/net/ipv4/control_windows.go | 27 + .../golang.org/x/net/ipv4/defs_darwin.go | 77 ++ .../golang.org/x/net/ipv4/defs_dragonfly.go | 38 + .../golang.org/x/net/ipv4/defs_freebsd.go | 75 ++ .../golang.org/x/net/ipv4/defs_linux.go | 120 +++ .../golang.org/x/net/ipv4/defs_netbsd.go | 37 + .../golang.org/x/net/ipv4/defs_openbsd.go | 37 + .../golang.org/x/net/ipv4/defs_solaris.go | 57 ++ .../golang.org/x/net/ipv4/dgramopt_posix.go | 251 +++++ .../golang.org/x/net/ipv4/dgramopt_stub.go | 106 ++ .../vendor/golang.org/x/net/ipv4/doc.go | 242 +++++ .../vendor/golang.org/x/net/ipv4/endpoint.go | 187 ++++ .../golang.org/x/net/ipv4/example_test.go | 224 +++++ .../vendor/golang.org/x/net/ipv4/gen.go | 208 ++++ .../golang.org/x/net/ipv4/genericopt_posix.go | 59 ++ .../golang.org/x/net/ipv4/genericopt_stub.go | 29 + .../vendor/golang.org/x/net/ipv4/header.go | 132 +++ .../golang.org/x/net/ipv4/header_test.go | 138 +++ .../vendor/golang.org/x/net/ipv4/helper.go | 59 ++ .../golang.org/x/net/ipv4/helper_stub.go | 23 + .../golang.org/x/net/ipv4/helper_unix.go | 50 + .../golang.org/x/net/ipv4/helper_windows.go | 49 + .../vendor/golang.org/x/net/ipv4/iana.go | 34 + .../vendor/golang.org/x/net/ipv4/icmp.go | 57 ++ .../golang.org/x/net/ipv4/icmp_linux.go | 25 + .../vendor/golang.org/x/net/ipv4/icmp_stub.go | 25 + .../vendor/golang.org/x/net/ipv4/icmp_test.go | 95 ++ .../x/net/ipv4/mocktransponder_test.go | 21 + .../golang.org/x/net/ipv4/multicast_test.go | 330 +++++++ .../x/net/ipv4/multicastlistener_test.go | 249 +++++ .../x/net/ipv4/multicastsockopt_test.go | 195 ++++ .../vendor/golang.org/x/net/ipv4/packet.go | 97 ++ .../vendor/golang.org/x/net/ipv4/payload.go | 15 + .../golang.org/x/net/ipv4/payload_cmsg.go | 81 ++ .../golang.org/x/net/ipv4/payload_nocmsg.go | 42 + .../golang.org/x/net/ipv4/readwrite_test.go | 174 ++++ .../vendor/golang.org/x/net/ipv4/sockopt.go | 46 + .../golang.org/x/net/ipv4/sockopt_asmreq.go | 83 ++ .../x/net/ipv4/sockopt_asmreq_stub.go | 21 + .../x/net/ipv4/sockopt_asmreq_unix.go | 46 + .../x/net/ipv4/sockopt_asmreq_windows.go | 45 + .../x/net/ipv4/sockopt_asmreqn_stub.go | 17 + .../x/net/ipv4/sockopt_asmreqn_unix.go | 42 + .../x/net/ipv4/sockopt_ssmreq_stub.go | 17 + .../x/net/ipv4/sockopt_ssmreq_unix.go | 61 ++ .../golang.org/x/net/ipv4/sockopt_stub.go | 11 + .../golang.org/x/net/ipv4/sockopt_unix.go | 122 +++ .../golang.org/x/net/ipv4/sockopt_windows.go | 68 ++ .../vendor/golang.org/x/net/ipv4/sys_bsd.go | 34 + .../golang.org/x/net/ipv4/sys_darwin.go | 96 ++ .../golang.org/x/net/ipv4/sys_freebsd.go | 73 ++ .../vendor/golang.org/x/net/ipv4/sys_linux.go | 55 ++ .../golang.org/x/net/ipv4/sys_openbsd.go | 32 + .../vendor/golang.org/x/net/ipv4/sys_stub.go | 13 + .../golang.org/x/net/ipv4/sys_windows.go | 61 ++ .../x/net/ipv4/syscall_linux_386.go | 31 + .../golang.org/x/net/ipv4/syscall_unix.go | 26 + .../golang.org/x/net/ipv4/thunk_linux_386.s | 8 + .../golang.org/x/net/ipv4/unicast_test.go | 246 +++++ .../x/net/ipv4/unicastsockopt_test.go | 139 +++ .../golang.org/x/net/ipv4/zsys_darwin.go | 99 ++ .../golang.org/x/net/ipv4/zsys_dragonfly.go | 33 + .../golang.org/x/net/ipv4/zsys_freebsd_386.go | 93 ++ .../x/net/ipv4/zsys_freebsd_amd64.go | 95 ++ .../golang.org/x/net/ipv4/zsys_freebsd_arm.go | 95 ++ .../golang.org/x/net/ipv4/zsys_linux_386.go | 146 +++ .../golang.org/x/net/ipv4/zsys_linux_amd64.go | 148 +++ .../golang.org/x/net/ipv4/zsys_linux_arm.go | 146 +++ .../golang.org/x/net/ipv4/zsys_linux_arm64.go | 150 +++ .../x/net/ipv4/zsys_linux_mips64.go | 150 +++ .../x/net/ipv4/zsys_linux_mips64le.go | 150 +++ .../golang.org/x/net/ipv4/zsys_linux_ppc.go | 148 +++ .../golang.org/x/net/ipv4/zsys_linux_ppc64.go | 150 +++ .../x/net/ipv4/zsys_linux_ppc64le.go | 150 +++ .../golang.org/x/net/ipv4/zsys_linux_s390x.go | 150 +++ .../golang.org/x/net/ipv4/zsys_netbsd.go | 30 + .../golang.org/x/net/ipv4/zsys_openbsd.go | 30 + .../golang.org/x/net/ipv4/zsys_solaris.go | 60 ++ .../vendor/golang.org/x/sys/AUTHORS | 0 .../vendor/golang.org/x/sys/CONTRIBUTORS | 0 .../vendor/golang.org/x/sys/LICENSE | 0 .../vendor/golang.org/x/sys/PATENTS | 0 .../vendor/golang.org/x/sys/unix/.gitignore | 0 .../vendor/golang.org/x/sys/unix/asm.s | 0 .../golang.org/x/sys/unix/asm_darwin_386.s | 0 .../golang.org/x/sys/unix/asm_darwin_amd64.s | 0 .../golang.org/x/sys/unix/asm_darwin_arm.s | 0 .../golang.org/x/sys/unix/asm_darwin_arm64.s | 0 .../x/sys/unix/asm_dragonfly_amd64.s | 0 .../golang.org/x/sys/unix/asm_freebsd_386.s | 0 .../golang.org/x/sys/unix/asm_freebsd_amd64.s | 0 .../golang.org/x/sys/unix/asm_freebsd_arm.s | 0 .../golang.org/x/sys/unix/asm_linux_386.s | 0 .../golang.org/x/sys/unix/asm_linux_amd64.s | 0 .../golang.org/x/sys/unix/asm_linux_arm.s | 0 .../golang.org/x/sys/unix/asm_linux_arm64.s | 0 .../golang.org/x/sys/unix/asm_linux_mips64x.s | 0 .../golang.org/x/sys/unix/asm_linux_ppc64x.s | 0 .../golang.org/x/sys/unix/asm_linux_s390x.s | 0 .../golang.org/x/sys/unix/asm_netbsd_386.s | 0 .../golang.org/x/sys/unix/asm_netbsd_amd64.s | 0 .../golang.org/x/sys/unix/asm_netbsd_arm.s | 0 .../golang.org/x/sys/unix/asm_openbsd_386.s | 0 .../golang.org/x/sys/unix/asm_openbsd_amd64.s | 0 .../golang.org/x/sys/unix/asm_solaris_amd64.s | 0 .../golang.org/x/sys/unix/bluetooth_linux.go | 0 .../vendor/golang.org/x/sys/unix/constants.go | 0 .../vendor/golang.org/x/sys/unix/env_unix.go | 0 .../vendor/golang.org/x/sys/unix/env_unset.go | 0 .../vendor/golang.org/x/sys/unix/flock.go | 0 .../x/sys/unix/flock_linux_32bit.go | 0 .../vendor/golang.org/x/sys/unix/gccgo.go | 0 .../vendor/golang.org/x/sys/unix/gccgo_c.c | 0 .../x/sys/unix/gccgo_linux_amd64.go | 0 .../vendor/golang.org/x/sys/unix/mkall.sh | 0 .../vendor/golang.org/x/sys/unix/mkerrors.sh | 0 .../vendor/golang.org/x/sys/unix/mkpost.go | 0 .../vendor/golang.org/x/sys/unix/mksyscall.pl | 0 .../x/sys/unix/mksyscall_solaris.pl | 0 .../golang.org/x/sys/unix/mksysctl_openbsd.pl | 0 .../golang.org/x/sys/unix/mksysnum_darwin.pl | 0 .../x/sys/unix/mksysnum_dragonfly.pl | 0 .../golang.org/x/sys/unix/mksysnum_freebsd.pl | 0 .../golang.org/x/sys/unix/mksysnum_linux.pl | 0 .../golang.org/x/sys/unix/mksysnum_netbsd.pl | 0 .../golang.org/x/sys/unix/mksysnum_openbsd.pl | 0 .../vendor/golang.org/x/sys/unix/race.go | 0 .../vendor/golang.org/x/sys/unix/race0.go | 0 .../golang.org/x/sys/unix/sockcmsg_linux.go | 0 .../golang.org/x/sys/unix/sockcmsg_unix.go | 0 .../vendor/golang.org/x/sys/unix/str.go | 0 .../vendor/golang.org/x/sys/unix/syscall.go | 0 .../golang.org/x/sys/unix/syscall_bsd.go | 0 .../golang.org/x/sys/unix/syscall_darwin.go | 0 .../x/sys/unix/syscall_darwin_386.go | 0 .../x/sys/unix/syscall_darwin_amd64.go | 0 .../x/sys/unix/syscall_darwin_arm.go | 0 .../x/sys/unix/syscall_darwin_arm64.go | 0 .../x/sys/unix/syscall_dragonfly.go | 0 .../x/sys/unix/syscall_dragonfly_amd64.go | 0 .../golang.org/x/sys/unix/syscall_freebsd.go | 0 .../x/sys/unix/syscall_freebsd_386.go | 0 .../x/sys/unix/syscall_freebsd_amd64.go | 0 .../x/sys/unix/syscall_freebsd_arm.go | 0 .../golang.org/x/sys/unix/syscall_linux.go | 0 .../x/sys/unix/syscall_linux_386.go | 0 .../x/sys/unix/syscall_linux_amd64.go | 0 .../x/sys/unix/syscall_linux_arm.go | 0 .../x/sys/unix/syscall_linux_arm64.go | 0 .../x/sys/unix/syscall_linux_mips64x.go | 0 .../x/sys/unix/syscall_linux_ppc64x.go | 0 .../x/sys/unix/syscall_linux_s390x.go | 0 .../golang.org/x/sys/unix/syscall_netbsd.go | 0 .../x/sys/unix/syscall_netbsd_386.go | 0 .../x/sys/unix/syscall_netbsd_amd64.go | 0 .../x/sys/unix/syscall_netbsd_arm.go | 0 .../golang.org/x/sys/unix/syscall_no_getwd.go | 0 .../golang.org/x/sys/unix/syscall_openbsd.go | 0 .../x/sys/unix/syscall_openbsd_386.go | 0 .../x/sys/unix/syscall_openbsd_amd64.go | 0 .../golang.org/x/sys/unix/syscall_solaris.go | 0 .../x/sys/unix/syscall_solaris_amd64.go | 0 .../golang.org/x/sys/unix/syscall_unix.go | 0 .../golang.org/x/sys/unix/types_darwin.go | 0 .../golang.org/x/sys/unix/types_dragonfly.go | 0 .../golang.org/x/sys/unix/types_freebsd.go | 0 .../golang.org/x/sys/unix/types_linux.go | 0 .../golang.org/x/sys/unix/types_netbsd.go | 0 .../golang.org/x/sys/unix/types_openbsd.go | 0 .../golang.org/x/sys/unix/types_solaris.go | 0 .../x/sys/unix/zerrors_darwin_386.go | 0 .../x/sys/unix/zerrors_darwin_amd64.go | 0 .../x/sys/unix/zerrors_darwin_arm.go | 0 .../x/sys/unix/zerrors_darwin_arm64.go | 0 .../x/sys/unix/zerrors_dragonfly_amd64.go | 0 .../x/sys/unix/zerrors_freebsd_386.go | 0 .../x/sys/unix/zerrors_freebsd_amd64.go | 0 .../x/sys/unix/zerrors_freebsd_arm.go | 0 .../x/sys/unix/zerrors_linux_386.go | 0 .../x/sys/unix/zerrors_linux_amd64.go | 0 .../x/sys/unix/zerrors_linux_arm.go | 0 .../x/sys/unix/zerrors_linux_arm64.go | 0 .../x/sys/unix/zerrors_linux_mips64.go | 0 .../x/sys/unix/zerrors_linux_mips64le.go | 0 .../x/sys/unix/zerrors_linux_ppc64.go | 0 .../x/sys/unix/zerrors_linux_ppc64le.go | 0 .../x/sys/unix/zerrors_linux_s390x.go | 0 .../x/sys/unix/zerrors_netbsd_386.go | 0 .../x/sys/unix/zerrors_netbsd_amd64.go | 0 .../x/sys/unix/zerrors_netbsd_arm.go | 0 .../x/sys/unix/zerrors_openbsd_386.go | 0 .../x/sys/unix/zerrors_openbsd_amd64.go | 0 .../x/sys/unix/zerrors_solaris_amd64.go | 0 .../x/sys/unix/zsyscall_darwin_386.go | 0 .../x/sys/unix/zsyscall_darwin_amd64.go | 0 .../x/sys/unix/zsyscall_darwin_arm.go | 0 .../x/sys/unix/zsyscall_darwin_arm64.go | 0 .../x/sys/unix/zsyscall_dragonfly_amd64.go | 0 .../x/sys/unix/zsyscall_freebsd_386.go | 0 .../x/sys/unix/zsyscall_freebsd_amd64.go | 0 .../x/sys/unix/zsyscall_freebsd_arm.go | 0 .../x/sys/unix/zsyscall_linux_386.go | 0 .../x/sys/unix/zsyscall_linux_amd64.go | 0 .../x/sys/unix/zsyscall_linux_arm.go | 0 .../x/sys/unix/zsyscall_linux_arm64.go | 0 .../x/sys/unix/zsyscall_linux_mips64.go | 0 .../x/sys/unix/zsyscall_linux_mips64le.go | 0 .../x/sys/unix/zsyscall_linux_ppc64.go | 0 .../x/sys/unix/zsyscall_linux_ppc64le.go | 0 .../x/sys/unix/zsyscall_linux_s390x.go | 0 .../x/sys/unix/zsyscall_netbsd_386.go | 0 .../x/sys/unix/zsyscall_netbsd_amd64.go | 0 .../x/sys/unix/zsyscall_netbsd_arm.go | 0 .../x/sys/unix/zsyscall_openbsd_386.go | 0 .../x/sys/unix/zsyscall_openbsd_amd64.go | 0 .../x/sys/unix/zsyscall_solaris_amd64.go | 0 .../golang.org/x/sys/unix/zsysctl_openbsd.go | 0 .../x/sys/unix/zsysnum_darwin_386.go | 0 .../x/sys/unix/zsysnum_darwin_amd64.go | 0 .../x/sys/unix/zsysnum_darwin_arm.go | 0 .../x/sys/unix/zsysnum_darwin_arm64.go | 0 .../x/sys/unix/zsysnum_dragonfly_amd64.go | 0 .../x/sys/unix/zsysnum_freebsd_386.go | 0 .../x/sys/unix/zsysnum_freebsd_amd64.go | 0 .../x/sys/unix/zsysnum_freebsd_arm.go | 0 .../x/sys/unix/zsysnum_linux_386.go | 0 .../x/sys/unix/zsysnum_linux_amd64.go | 0 .../x/sys/unix/zsysnum_linux_arm.go | 0 .../x/sys/unix/zsysnum_linux_arm64.go | 0 .../x/sys/unix/zsysnum_linux_mips64.go | 0 .../x/sys/unix/zsysnum_linux_mips64le.go | 0 .../x/sys/unix/zsysnum_linux_ppc64.go | 0 .../x/sys/unix/zsysnum_linux_ppc64le.go | 0 .../x/sys/unix/zsysnum_linux_s390x.go | 0 .../x/sys/unix/zsysnum_netbsd_386.go | 0 .../x/sys/unix/zsysnum_netbsd_amd64.go | 0 .../x/sys/unix/zsysnum_netbsd_arm.go | 0 .../x/sys/unix/zsysnum_openbsd_386.go | 0 .../x/sys/unix/zsysnum_openbsd_amd64.go | 0 .../x/sys/unix/zsysnum_solaris_amd64.go | 0 .../x/sys/unix/ztypes_darwin_386.go | 0 .../x/sys/unix/ztypes_darwin_amd64.go | 0 .../x/sys/unix/ztypes_darwin_arm.go | 0 .../x/sys/unix/ztypes_darwin_arm64.go | 0 .../x/sys/unix/ztypes_dragonfly_amd64.go | 0 .../x/sys/unix/ztypes_freebsd_386.go | 0 .../x/sys/unix/ztypes_freebsd_amd64.go | 0 .../x/sys/unix/ztypes_freebsd_arm.go | 0 .../golang.org/x/sys/unix/ztypes_linux_386.go | 0 .../x/sys/unix/ztypes_linux_amd64.go | 0 .../golang.org/x/sys/unix/ztypes_linux_arm.go | 0 .../x/sys/unix/ztypes_linux_arm64.go | 0 .../x/sys/unix/ztypes_linux_mips64.go | 0 .../x/sys/unix/ztypes_linux_mips64le.go | 0 .../x/sys/unix/ztypes_linux_ppc64.go | 0 .../x/sys/unix/ztypes_linux_ppc64le.go | 0 .../x/sys/unix/ztypes_linux_s390x.go | 0 .../x/sys/unix/ztypes_netbsd_386.go | 0 .../x/sys/unix/ztypes_netbsd_amd64.go | 0 .../x/sys/unix/ztypes_netbsd_arm.go | 0 .../x/sys/unix/ztypes_openbsd_386.go | 0 .../x/sys/unix/ztypes_openbsd_amd64.go | 0 .../x/sys/unix/ztypes_solaris_amd64.go | 0 769 files changed, 32948 insertions(+), 6936 deletions(-) create mode 100644 vendor/github.com/containernetworking/cni/.appveyor.yml create mode 100644 vendor/github.com/containernetworking/cni/CODE-OF-CONDUCT.md delete mode 100644 vendor/github.com/containernetworking/cni/Documentation/host-local.md create mode 100644 vendor/github.com/containernetworking/cni/GOVERNANCE.md create mode 100644 vendor/github.com/containernetworking/cni/RELEASING.md delete mode 100755 vendor/github.com/containernetworking/cni/build.sh create mode 100644 vendor/github.com/containernetworking/cni/cnitool/README.md rename vendor/github.com/containernetworking/cni/cnitool/{cni.go => cnitool.go} (55%) create mode 100644 vendor/github.com/containernetworking/cni/logo.png create mode 100644 vendor/github.com/containernetworking/cni/pkg/invoke/args_test.go create mode 100644 vendor/github.com/containernetworking/cni/pkg/invoke/delegate_test.go delete mode 100644 vendor/github.com/containernetworking/cni/pkg/ip/ipmasq.go delete mode 100644 vendor/github.com/containernetworking/cni/pkg/ns/ns_linux.go create mode 100644 vendor/github.com/containernetworking/cni/pkg/types/types_test.go delete mode 100644 vendor/github.com/containernetworking/cni/plugins/ipam/host-local/backend/allocator/allocator.go delete mode 100644 vendor/github.com/containernetworking/cni/plugins/ipam/host-local/backend/allocator/allocator_test.go delete mode 100644 vendor/github.com/containernetworking/cni/plugins/ipam/host-local/backend/allocator/config.go delete mode 100644 vendor/github.com/containernetworking/cni/plugins/ipam/host-local/host_local_test.go delete mode 100644 vendor/github.com/containernetworking/cni/plugins/ipam/host-local/main.go delete mode 100644 vendor/github.com/containernetworking/cni/plugins/main/bridge/bridge_test.go delete mode 100755 vendor/github.com/containernetworking/cni/scripts/release-with-rkt.sh create mode 100755 vendor/github.com/containernetworking/cni/scripts/release.sh delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/coreos/go-systemd/activation/listeners.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/bootstrap_command.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/build_command.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/ginkgo_ast_nodes.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/import.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/package_rewriter.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/test_finder.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/testfile_rewriter.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/testing_t_rewriter.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert_command.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/generate_command.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/help_command.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/interrupthandler/interrupt_handler.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/interrupthandler/sigquit_swallower_unix.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/interrupthandler/sigquit_swallower_windows.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/main.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/nodot/nodot.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/nodot_command.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/notifications.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/run_command.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/run_watch_and_build_command_flags.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/suite_runner.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/testrunner/log_writer.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/testrunner/run_result.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/testrunner/test_runner.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/testsuite/test_suite.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/unfocus_command.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/version_command.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/delta.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/delta_tracker.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/dependencies.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/package_hash.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/package_hashes.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/suite.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch_command.go delete mode 100644 vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/integration/integration.go create mode 100644 vendor/github.com/containernetworking/plugins/.appveyor.yml create mode 100644 vendor/github.com/containernetworking/plugins/.gitignore create mode 100644 vendor/github.com/containernetworking/plugins/.travis.yml create mode 100644 vendor/github.com/containernetworking/plugins/CONTRIBUTING.md rename vendor/github.com/containernetworking/{cni => plugins}/Godeps/Godeps.json (69%) rename vendor/github.com/containernetworking/{cni => plugins}/Godeps/Readme (100%) create mode 100644 vendor/github.com/containernetworking/plugins/LICENSE create mode 100644 vendor/github.com/containernetworking/plugins/README.md create mode 100644 vendor/github.com/containernetworking/plugins/RELEASING.md create mode 100644 vendor/github.com/containernetworking/plugins/Vagrantfile create mode 100755 vendor/github.com/containernetworking/plugins/build.sh create mode 100644 vendor/github.com/containernetworking/plugins/integration/integration_linux_test.go create mode 100644 vendor/github.com/containernetworking/plugins/integration/integration_suite_test.go create mode 100644 vendor/github.com/containernetworking/plugins/integration/testdata/basic-bridge/network-chain-test.json create mode 100644 vendor/github.com/containernetworking/plugins/integration/testdata/basic-ptp.json create mode 100644 vendor/github.com/containernetworking/plugins/integration/testdata/chained-bridge-bandwidth/network-chain-test.conflist create mode 100644 vendor/github.com/containernetworking/plugins/integration/testdata/chained-ptp-bandwidth.conflist create mode 100644 vendor/github.com/containernetworking/plugins/pkg/ip/addr_linux.go rename vendor/github.com/containernetworking/{cni => plugins}/pkg/ip/cidr.go (87%) rename vendor/github.com/containernetworking/{cni => plugins}/pkg/ip/ip_suite_test.go (96%) create mode 100644 vendor/github.com/containernetworking/plugins/pkg/ip/ipforward_linux.go create mode 100644 vendor/github.com/containernetworking/plugins/pkg/ip/ipforward_linux_test.go create mode 100644 vendor/github.com/containernetworking/plugins/pkg/ip/ipmasq_linux.go rename vendor/github.com/containernetworking/{cni/pkg/ip/link.go => plugins/pkg/ip/link_linux.go} (72%) rename vendor/github.com/containernetworking/{cni/pkg/ip/link_test.go => plugins/pkg/ip/link_linux_test.go} (78%) rename vendor/github.com/containernetworking/{cni => plugins}/pkg/ip/route_linux.go (85%) rename vendor/github.com/containernetworking/{cni/pkg/ip/ipforward.go => plugins/pkg/ipam/ipam.go} (65%) rename vendor/github.com/containernetworking/{cni/pkg/ipam/ipam.go => plugins/pkg/ipam/ipam_linux.go} (63%) rename vendor/github.com/containernetworking/{cni/pkg/ipam/ipam_test.go => plugins/pkg/ipam/ipam_linux_test.go} (83%) rename vendor/github.com/containernetworking/{cni => plugins}/pkg/ipam/ipam_suite_test.go (96%) rename vendor/github.com/containernetworking/{cni => plugins}/pkg/ns/README.md (55%) rename vendor/github.com/containernetworking/{cni/pkg/ns/ns.go => plugins/pkg/ns/ns_linux.go} (81%) rename vendor/github.com/containernetworking/{cni/pkg/ns/ns_test.go => plugins/pkg/ns/ns_linux_test.go} (89%) rename vendor/github.com/containernetworking/{cni => plugins}/pkg/ns/ns_suite_test.go (96%) rename vendor/github.com/containernetworking/{cni => plugins}/pkg/testutils/bad_reader.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/pkg/testutils/cmd.go (74%) create mode 100644 vendor/github.com/containernetworking/plugins/pkg/testutils/echosvr/echosvr_test.go create mode 100644 vendor/github.com/containernetworking/plugins/pkg/testutils/echosvr/init_test.go create mode 100644 vendor/github.com/containernetworking/plugins/pkg/testutils/echosvr/main.go create mode 100644 vendor/github.com/containernetworking/plugins/pkg/testutils/netns_linux.go create mode 100644 vendor/github.com/containernetworking/plugins/pkg/testutils/ping.go rename vendor/github.com/containernetworking/{cni => plugins}/pkg/utils/hwaddr/hwaddr.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/pkg/utils/hwaddr/hwaddr_suite_test.go (95%) rename vendor/github.com/containernetworking/{cni => plugins}/pkg/utils/hwaddr/hwaddr_test.go (97%) rename vendor/github.com/containernetworking/{cni => plugins}/pkg/utils/sysctl/sysctl_linux.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/pkg/utils/utils.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/pkg/utils/utils_suite_test.go (96%) rename vendor/github.com/containernetworking/{cni => plugins}/pkg/utils/utils_test.go (100%) rename vendor/github.com/containernetworking/{cni/Documentation/dhcp.md => plugins/plugins/ipam/dhcp/README.md} (72%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/ipam/dhcp/daemon.go (77%) rename vendor/github.com/containernetworking/{cni/pkg/ip/route.go => plugins/plugins/ipam/dhcp/dhcp_suite_test.go} (67%) create mode 100644 vendor/github.com/containernetworking/plugins/plugins/ipam/dhcp/dhcp_test.go rename vendor/github.com/containernetworking/{cni => plugins}/plugins/ipam/dhcp/lease.go (90%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/ipam/dhcp/main.go (82%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/ipam/dhcp/options.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/ipam/dhcp/options_test.go (100%) create mode 100644 vendor/github.com/containernetworking/plugins/plugins/ipam/host-local/README.md create mode 100644 vendor/github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator/allocator.go rename vendor/github.com/containernetworking/{cni => plugins}/plugins/ipam/host-local/backend/allocator/allocator_suite_test.go (92%) create mode 100644 vendor/github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator/allocator_test.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator/config.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator/config_test.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator/range.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator/range_set.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator/range_set_test.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator/range_test.go rename vendor/github.com/containernetworking/{cni => plugins}/plugins/ipam/host-local/backend/disk/backend.go (71%) rename vendor/github.com/containernetworking/{cni/pkg/ip/route_unspecified.go => plugins/plugins/ipam/host-local/backend/disk/disk_suite_test.go} (54%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/ipam/host-local/backend/disk/lock.go (76%) create mode 100644 vendor/github.com/containernetworking/plugins/plugins/ipam/host-local/backend/disk/lock_test.go rename vendor/github.com/containernetworking/{cni => plugins}/plugins/ipam/host-local/backend/store.go (87%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/ipam/host-local/backend/testing/fake_store.go (70%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/ipam/host-local/dns.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/ipam/host-local/dns_test.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/ipam/host-local/host_local_suite_test.go (94%) create mode 100644 vendor/github.com/containernetworking/plugins/plugins/ipam/host-local/host_local_test.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/ipam/host-local/main.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/ipam/static/README.md create mode 100644 vendor/github.com/containernetworking/plugins/plugins/ipam/static/main.go rename vendor/github.com/containernetworking/{cni/pkg/ns/ns_unspecified.go => plugins/plugins/ipam/static/static_suite_test.go} (54%) create mode 100644 vendor/github.com/containernetworking/plugins/plugins/ipam/static/static_test.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/linux_only.txt rename vendor/github.com/containernetworking/{cni/Documentation/bridge.md => plugins/plugins/main/bridge/README.md} (95%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/main/bridge/bridge.go (61%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/main/bridge/bridge_suite_test.go (95%) create mode 100644 vendor/github.com/containernetworking/plugins/plugins/main/bridge/bridge_test.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/main/host-device/README.md create mode 100644 vendor/github.com/containernetworking/plugins/plugins/main/host-device/host-device.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/main/host-device/host-device_suite_test.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/main/host-device/host-device_test.go rename vendor/github.com/containernetworking/{cni/Documentation/ipvlan.md => plugins/plugins/main/ipvlan/README.md} (69%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/main/ipvlan/ipvlan.go (67%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/main/ipvlan/ipvlan_suite_test.go (95%) create mode 100644 vendor/github.com/containernetworking/plugins/plugins/main/ipvlan/ipvlan_test.go rename vendor/github.com/containernetworking/{cni => plugins}/plugins/main/loopback/loopback.go (97%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/main/loopback/loopback_suite_test.go (93%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/main/loopback/loopback_test.go (90%) rename vendor/github.com/containernetworking/{cni/Documentation/macvlan.md => plugins/plugins/main/macvlan/README.md} (100%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/main/macvlan/macvlan.go (86%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/main/macvlan/macvlan_suite_test.go (95%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/main/macvlan/macvlan_test.go (88%) rename vendor/github.com/containernetworking/{cni/Documentation/ptp.md => plugins/plugins/main/ptp/README.md} (92%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/main/ptp/ptp.go (84%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/main/ptp/ptp_suite_test.go (95%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/main/ptp/ptp_test.go (62%) create mode 100644 vendor/github.com/containernetworking/plugins/plugins/main/vlan/vlan.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/main/vlan/vlan_suite_test.go rename vendor/github.com/containernetworking/{cni/plugins/main/ipvlan/ipvlan_test.go => plugins/plugins/main/vlan/vlan_test.go} (68%) create mode 100644 vendor/github.com/containernetworking/plugins/plugins/meta/bandwidth/README.md create mode 100644 vendor/github.com/containernetworking/plugins/plugins/meta/bandwidth/bandwidth_linux_test.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/meta/bandwidth/bandwidth_suite_test.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/meta/bandwidth/ifb_creator.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/meta/bandwidth/main.go rename vendor/github.com/containernetworking/{cni/Documentation/flannel.md => plugins/plugins/meta/flannel/README.md} (100%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/meta/flannel/flannel.go (98%) rename vendor/github.com/containernetworking/{cni/plugins/meta/flannel/flannel_test.go => plugins/plugins/meta/flannel/flannel_linux_test.go} (90%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/meta/flannel/flannel_suite_test.go (95%) create mode 100644 vendor/github.com/containernetworking/plugins/plugins/meta/portmap/README.md create mode 100644 vendor/github.com/containernetworking/plugins/plugins/meta/portmap/chain.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/meta/portmap/chain_test.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/meta/portmap/main.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/meta/portmap/portmap.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/meta/portmap/portmap_integ_test.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/meta/portmap/portmap_suite_test.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/meta/portmap/portmap_test.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/meta/portmap/utils.go rename vendor/github.com/containernetworking/{cni/Documentation/tuning.md => plugins/plugins/meta/tuning/README.md} (100%) rename vendor/github.com/containernetworking/{cni => plugins}/plugins/meta/tuning/tuning.go (64%) create mode 100644 vendor/github.com/containernetworking/plugins/plugins/meta/tuning/tuning_suite_test.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/meta/tuning/tuning_test.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/sample/README.md create mode 100644 vendor/github.com/containernetworking/plugins/plugins/sample/main.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/sample/sample_linux_test.go create mode 100644 vendor/github.com/containernetworking/plugins/plugins/sample/sample_suite_test.go create mode 100755 vendor/github.com/containernetworking/plugins/scripts/release.sh create mode 100755 vendor/github.com/containernetworking/plugins/test.sh create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/alexflint/go-filemutex/LICENSE create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/alexflint/go-filemutex/README.md create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/alexflint/go-filemutex/filemutex_flock.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/alexflint/go-filemutex/filemutex_windows.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/containernetworking/cni/LICENSE create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/containernetworking/cni/libcni/api.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/containernetworking/cni/libcni/conf.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/containernetworking/cni/pkg/invoke/args.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/containernetworking/cni/pkg/invoke/delegate.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/containernetworking/cni/pkg/invoke/exec.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/containernetworking/cni/pkg/invoke/find.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/containernetworking/cni/pkg/invoke/os_unix.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/containernetworking/cni/pkg/invoke/os_windows.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/containernetworking/cni/pkg/skel/skel.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/containernetworking/cni/pkg/types/020/types.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/containernetworking/cni/pkg/types/args.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/containernetworking/cni/pkg/types/current/types.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/containernetworking/cni/pkg/types/types.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/containernetworking/cni/pkg/version/conf.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/containernetworking/cni/pkg/version/plugin.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/containernetworking/cni/pkg/version/reconcile.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/containernetworking/cni/pkg/version/version.go rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/coreos/go-iptables/LICENSE (100%) create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/coreos/go-iptables/NOTICE rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/coreos/go-iptables/iptables/iptables.go (59%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/coreos/go-iptables/iptables/lock.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/coreos/go-systemd/LICENSE (100%) create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/coreos/go-systemd/NOTICE rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/coreos/go-systemd/activation/files.go (62%) create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/coreos/go-systemd/activation/listeners.go rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/coreos/go-systemd/activation/packetconns.go (93%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/d2g/dhcp4/LICENSE (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/d2g/dhcp4/README.md (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/d2g/dhcp4/constants.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/d2g/dhcp4/helpers.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/d2g/dhcp4/option.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/d2g/dhcp4/packet.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/d2g/dhcp4client/LICENSE (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/d2g/dhcp4client/README.md (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/d2g/dhcp4client/client.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/d2g/dhcp4client/inetsock.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/d2g/dhcp4client/init.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/d2g/dhcp4client/pktsock_linux.go (100%) create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/d2g/dhcp4server/LICENSE create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/d2g/dhcp4server/README.md create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/d2g/dhcp4server/leasepool/lease.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/d2g/dhcp4server/leasepool/lease_test.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/d2g/dhcp4server/leasepool/leasepool.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/d2g/dhcp4server/leasepool/memorypool/memorypool.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/d2g/dhcp4server/leasepool/memorypool/memorypool_test.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/d2g/dhcp4server/server.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/d2g/dhcp4server/server_test.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/j-keck/arping/.gitignore create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/j-keck/arping/LICENSE create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/j-keck/arping/README.md create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/j-keck/arping/arp_datagram.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/j-keck/arping/arping.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/j-keck/arping/arping_bsd.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/j-keck/arping/arping_linux.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/j-keck/arping/arping_windows.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/j-keck/arping/netutils.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/mattn/go-shellwords/.travis.yml create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/mattn/go-shellwords/LICENSE create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/mattn/go-shellwords/README.md create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/mattn/go-shellwords/shellwords.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/mattn/go-shellwords/util_posix.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/mattn/go-shellwords/util_windows.go rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/.gitignore (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/.travis.yml (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/CHANGELOG.md (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/LICENSE (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/README.md (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/config/config.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/extensions/table/table.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/extensions/table/table_entry.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/ginkgo_dsl.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/codelocation/code_location.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/containernode/container_node.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/failer/failer.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/leafnodes/benchmarker.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/leafnodes/interfaces.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/leafnodes/it_node.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/leafnodes/measure_node.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/leafnodes/runner.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/leafnodes/setup_nodes.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/leafnodes/suite_nodes.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/leafnodes/synchronized_after_suite_node.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/leafnodes/synchronized_before_suite_node.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/remote/aggregator.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/remote/forwarding_reporter.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_unix.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/remote/output_interceptor_win.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/remote/server.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/spec/index_computer.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/spec/spec.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/spec/specs.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/specrunner/random_id.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/specrunner/spec_runner.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/suite/suite.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/testingtproxy/testing_t_proxy.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/writer/fake_writer.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/internal/writer/writer.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/reporters/default_reporter.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/reporters/fake_reporter.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/reporters/junit_reporter.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/reporters/reporter.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/reporters/stenographer/console_logging.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/reporters/stenographer/fake_stenographer.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/reporters/stenographer/stenographer.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/reporters/teamcity_reporter.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/types/code_location.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/types/synchronization.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/ginkgo/types/types.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/.gitignore (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/.travis.yml (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/CHANGELOG.md (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/LICENSE (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/README.md (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/format/format.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/gbytes/buffer.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/gbytes/say_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/gexec/build.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/gexec/exit_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/gexec/prefixed_writer.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/gexec/session.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/gomega_dsl.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/internal/assertion/assertion.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/internal/asyncassertion/async_assertion.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/internal/oraclematcher/oracle_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/internal/testingtsupport/testing_t_support.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/and.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/assignable_to_type_of_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/be_a_directory.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/be_a_regular_file.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/be_an_existing_file.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/be_closed_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/be_empty_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/be_equivalent_to_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/be_false_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/be_nil_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/be_numerically_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/be_sent_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/be_temporally_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/be_true_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/be_zero_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/consist_of.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/contain_element_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/contain_substring_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/equal_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/have_key_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/have_len_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/have_occurred_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/have_prefix_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/have_suffix_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/match_json_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/match_regexp_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/not.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/or.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/panic_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/receive_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/succeed_matcher.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraph.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraphmatching.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/support/goraph/edge/edge.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/support/goraph/node/node.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/support/goraph/util/util.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/type_support.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/matchers/with_transform.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/onsi/gomega/types/types.go (100%) create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/safchain/ethtool/ethtool.go rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/.travis.yml (59%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/LICENSE (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/Makefile (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/README.md (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/addr.go (89%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/addr_linux.go (85%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/bpf_linux.go (100%) create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/vishvananda/netlink/bridge_linux.go rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/class.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/class_linux.go (100%) create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/vishvananda/netlink/conntrack_linux.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/vishvananda/netlink/conntrack_unspecified.go rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/filter.go (83%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/filter_linux.go (92%) create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/vishvananda/netlink/genetlink_linux.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/vishvananda/netlink/genetlink_unspecified.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/vishvananda/netlink/gtp_linux.go rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/handle_linux.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/handle_unspecified.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/link.go (95%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/link_linux.go (88%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/link_tuntap_linux.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/neigh.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/neigh_linux.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/netlink.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/netlink_linux.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/netlink_unspecified.go (95%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/nl/addr_linux.go (57%) create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/vishvananda/netlink/nl/bridge_linux.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/vishvananda/netlink/nl/conntrack_linux.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/github.com/vishvananda/netlink/nl/genetlink_linux.go rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/nl/link_linux.go (84%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/nl/mpls_linux.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/nl/nl_linux.go (94%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/nl/nl_unspecified.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/nl/route_linux.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/nl/syscall.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/nl/tc_linux.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/nl/xfrm_linux.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/nl/xfrm_monitor_linux.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/nl/xfrm_policy_linux.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/nl/xfrm_state_linux.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/order.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/protinfo.go (73%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/protinfo_linux.go (91%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/qdisc.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/qdisc_linux.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/route.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/route_linux.go (99%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/route_unspecified.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/rule.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/rule_linux.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/socket.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/socket_linux.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/xfrm.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/xfrm_monitor_linux.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/xfrm_policy.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/xfrm_policy_linux.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/xfrm_state.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netlink/xfrm_state_linux.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netns/LICENSE (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netns/README.md (98%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netns/netns.go (98%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netns/netns_linux.go (99%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/github.com/vishvananda/netns/netns_unspecified.go (76%) create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/bpf/asm.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/bpf/constants.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/bpf/doc.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/bpf/instructions.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/bpf/instructions_test.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/bpf/testdata/all_instructions.bpf create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/bpf/testdata/all_instructions.txt create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/bpf/vm.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/bpf/vm_aluop_test.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/bpf/vm_bpf_test.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/bpf/vm_extension_test.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/bpf/vm_instructions.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/bpf/vm_jump_test.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/bpf/vm_load_test.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/bpf/vm_ret_test.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/bpf/vm_scratch_test.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/bpf/vm_test.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/internal/iana/const.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/internal/iana/gen.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/bpf_test.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/bpfopt_linux.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/bpfopt_stub.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/control.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/control_bsd.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/control_pktinfo.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/control_stub.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/control_unix.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/control_windows.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/defs_darwin.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/defs_dragonfly.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/defs_freebsd.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/defs_linux.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/defs_netbsd.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/defs_openbsd.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/defs_solaris.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/dgramopt_posix.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/dgramopt_stub.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/doc.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/endpoint.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/example_test.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/gen.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/genericopt_posix.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/genericopt_stub.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/header.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/header_test.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/helper.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/helper_stub.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/helper_unix.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/helper_windows.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/iana.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/icmp.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/icmp_linux.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/icmp_stub.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/icmp_test.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/mocktransponder_test.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/multicast_test.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/multicastlistener_test.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/multicastsockopt_test.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/packet.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/payload.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/payload_cmsg.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/payload_nocmsg.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/readwrite_test.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/sockopt.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/sockopt_asmreq.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/sockopt_asmreq_stub.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/sockopt_asmreq_unix.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/sockopt_asmreq_windows.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/sockopt_asmreqn_stub.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/sockopt_asmreqn_unix.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/sockopt_ssmreq_stub.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/sockopt_ssmreq_unix.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/sockopt_stub.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/sockopt_unix.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/sockopt_windows.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/sys_bsd.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/sys_darwin.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/sys_freebsd.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/sys_linux.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/sys_openbsd.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/sys_stub.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/sys_windows.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/syscall_linux_386.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/syscall_unix.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/thunk_linux_386.s create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/unicast_test.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/unicastsockopt_test.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/zsys_darwin.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/zsys_dragonfly.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/zsys_freebsd_386.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/zsys_freebsd_amd64.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/zsys_linux_386.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/zsys_linux_arm.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/zsys_netbsd.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/zsys_openbsd.go create mode 100644 vendor/github.com/containernetworking/plugins/vendor/golang.org/x/net/ipv4/zsys_solaris.go rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/AUTHORS (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/CONTRIBUTORS (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/LICENSE (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/PATENTS (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/.gitignore (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/asm.s (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/asm_darwin_386.s (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/asm_darwin_amd64.s (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/asm_darwin_arm.s (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/asm_darwin_arm64.s (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/asm_freebsd_386.s (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/asm_freebsd_arm.s (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/asm_linux_386.s (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/asm_linux_amd64.s (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/asm_linux_arm.s (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/asm_linux_arm64.s (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/asm_linux_mips64x.s (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/asm_linux_s390x.s (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/asm_netbsd_386.s (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/asm_netbsd_arm.s (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/asm_openbsd_386.s (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/asm_solaris_amd64.s (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/bluetooth_linux.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/constants.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/env_unix.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/env_unset.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/flock.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/flock_linux_32bit.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/gccgo.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/gccgo_c.c (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/mkall.sh (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/mkerrors.sh (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/mkpost.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/mksyscall.pl (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/mksyscall_solaris.pl (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/mksysctl_openbsd.pl (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/mksysnum_darwin.pl (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/mksysnum_dragonfly.pl (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/mksysnum_freebsd.pl (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/mksysnum_linux.pl (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/mksysnum_netbsd.pl (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/mksysnum_openbsd.pl (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/race.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/race0.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/sockcmsg_linux.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/sockcmsg_unix.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/str.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_bsd.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_darwin.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_darwin_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_darwin_arm.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_dragonfly.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_dragonfly_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_freebsd.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_freebsd_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_linux.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_linux_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_linux_arm.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_netbsd.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_netbsd_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_netbsd_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_netbsd_arm.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_no_getwd.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_openbsd.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_openbsd_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_openbsd_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_solaris.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/syscall_unix.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/types_darwin.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/types_dragonfly.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/types_freebsd.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/types_linux.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/types_netbsd.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/types_openbsd.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/types_solaris.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zerrors_darwin_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zerrors_dragonfly_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zerrors_linux_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zerrors_netbsd_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zerrors_netbsd_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zerrors_openbsd_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zerrors_openbsd_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zerrors_solaris_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysctl_openbsd.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysnum_darwin_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysnum_darwin_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysnum_dragonfly_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/zsysnum_solaris_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/ztypes_linux_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go (100%) rename vendor/github.com/containernetworking/{cni => plugins}/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go (100%) diff --git a/glide.lock b/glide.lock index ef75d0316..0376fecfe 100644 --- a/glide.lock +++ b/glide.lock @@ -2,18 +2,21 @@ hash: 9f567f5e6122fc0f7092f9373f1cfd491978315b0d9ff01ab81cebe269ffa048 updated: 2018-05-08T04:22:31.321965197-04:00 imports: - name: github.com/containernetworking/cni - version: 137b4975ecab6e1f0c24c1e3c228a50a3cfba75e + version: 07c1a6da47b7fbf8b357f4949ecce2113e598491 subpackages: - libcni - pkg/invoke - pkg/ip - pkg/ipam - - pkg/ns - pkg/skel - pkg/types - pkg/types/020 - pkg/types/current - pkg/version +- name: github.com/containernetworking/plugins + version: 2b8b1ac0af4568e928d96ccc5f47b075416eeabd + subpackages: + - pkg/ns - name: github.com/davecgh/go-spew version: 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d subpackages: diff --git a/glide.yaml b/glide.yaml index 945c5cd1e..95304261a 100644 --- a/glide.yaml +++ b/glide.yaml @@ -1,14 +1,17 @@ package: github.com/intel/multus-cni import: - package: github.com/containernetworking/cni - version: v0.5.2 + version: 07c1a6da47b7fbf8b357f4949ecce2113e598491 subpackages: - pkg/ip - pkg/ipam - - pkg/ns - pkg/skel - pkg/types - pkg/version +- package: github.com/containernetworking/plugins + version: 2b8b1ac0af4568e928d96ccc5f47b075416eeabd + subpackages: + - pkg/ns - package: github.com/golang/glog - package: github.com/vishvananda/netlink - package: k8s.io/client-go diff --git a/multus/multus.go b/multus/multus.go index 0c0edf08d..84b78c039 100644 --- a/multus/multus.go +++ b/multus/multus.go @@ -26,10 +26,10 @@ import ( "path/filepath" "github.com/containernetworking/cni/pkg/invoke" - "github.com/containernetworking/cni/pkg/ns" "github.com/containernetworking/cni/pkg/skel" cnitypes "github.com/containernetworking/cni/pkg/types" "github.com/containernetworking/cni/pkg/version" + "github.com/containernetworking/plugins/pkg/ns" k8s "github.com/intel/multus-cni/k8sclient" "github.com/intel/multus-cni/types" "github.com/vishvananda/netlink" diff --git a/vendor/github.com/containernetworking/cni/.appveyor.yml b/vendor/github.com/containernetworking/cni/.appveyor.yml new file mode 100644 index 000000000..6bd301b27 --- /dev/null +++ b/vendor/github.com/containernetworking/cni/.appveyor.yml @@ -0,0 +1,17 @@ +clone_folder: c:\gopath\src\github.com\containernetworking\cni + +environment: + GOPATH: c:\gopath + +install: + - echo %PATH% + - echo %GOPATH% + - set PATH=%GOPATH%\bin;c:\go\bin;%PATH% + - go version + - go env + +build: off + +test_script: + - go get -t ./... + - go test -v ./... diff --git a/vendor/github.com/containernetworking/cni/.gitignore b/vendor/github.com/containernetworking/cni/.gitignore index f130579cf..0d94fb809 100644 --- a/vendor/github.com/containernetworking/cni/.gitignore +++ b/vendor/github.com/containernetworking/cni/.gitignore @@ -2,3 +2,4 @@ bin/ gopath/ *.sw[ponm] .vagrant +release-* diff --git a/vendor/github.com/containernetworking/cni/.travis.yml b/vendor/github.com/containernetworking/cni/.travis.yml index 234f88268..4bbce9b27 100644 --- a/vendor/github.com/containernetworking/cni/.travis.yml +++ b/vendor/github.com/containernetworking/cni/.travis.yml @@ -1,16 +1,11 @@ language: go -sudo: required dist: trusty go: - - 1.7.x - - 1.8.x + - 1.9.x + - 1.10.x env: - global: - - TOOLS_CMD=golang.org/x/tools/cmd - - PATH=$GOROOT/bin:$PATH - - GO15VENDOREXPERIMENT=1 matrix: - TARGET=amd64 - TARGET=arm @@ -22,16 +17,17 @@ matrix: fast_finish: true install: - - go get ${TOOLS_CMD}/cover + - go get golang.org/x/tools/cmd/cover - go get github.com/modocache/gover - go get github.com/mattn/goveralls + - go get -t ./... script: - > if [ "${TARGET}" == "amd64" ]; then GOARCH="${TARGET}" ./test.sh; else - GOARCH="${TARGET}" ./build.sh; + GOARCH="${TARGET}" go list ./... | xargs -n1 go build -v -o /dev/null fi notifications: diff --git a/vendor/github.com/containernetworking/cni/CODE-OF-CONDUCT.md b/vendor/github.com/containernetworking/cni/CODE-OF-CONDUCT.md new file mode 100644 index 000000000..b6e32163a --- /dev/null +++ b/vendor/github.com/containernetworking/cni/CODE-OF-CONDUCT.md @@ -0,0 +1,4 @@ +## Community Code of Conduct + +CNI follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). + diff --git a/vendor/github.com/containernetworking/cni/CONVENTIONS.md b/vendor/github.com/containernetworking/cni/CONVENTIONS.md index b7fee04e6..b9d5a3d9a 100644 --- a/vendor/github.com/containernetworking/cni/CONVENTIONS.md +++ b/vendor/github.com/containernetworking/cni/CONVENTIONS.md @@ -19,21 +19,18 @@ Establishing these conventions allows plugins to work across multiple runtimes. # Current conventions Additional conventions can be created by creating PRs which modify this document. -## Plugin specific fields +## Dynamic Plugin specific fields (Capabilities / Runtime Configuration) [Plugin specific fields](https://github.com/containernetworking/cni/blob/master/SPEC.md#network-configuration) formed part of the original CNI spec and have been present since the initial release. > Plugins may define additional fields that they accept and may generate an error if called with unknown fields. The exception to this is the args field may be used to pass arbitrary data which may be ignored by plugins. -A plugin can define any additional fields it needs to work properly. It is expected that it will return an error if it can't act on fields that were expected or where the field values were malformed. +A plugin can define any additional fields it needs to work properly. It should return an error if it can't act on fields that were expected or where the field values were malformed. -This method of passing information to a plugin is recommended when the following conditions hold +This method of passing information to a plugin is recommended when the following conditions hold: * The configuration has specific meaning to the plugin (i.e. it's not just general meta data) * the plugin is expected to act on the configuration or return an error if it can't -Dynamic information (i.e. data that a runtime fills out) should be placed in a `runtimeConfig` section. - -| Area | Purpose| Spec and Example | Runtime implementations | Plugin Implementations | -| ------ | ------ | ------ | ------ | ------ | ------ | -| port mappings | Pass mapping from ports on the host to ports in the container network namespace. | Operators can ask runtimes to pass port mapping information to plugins, by setting the following in the CNI config
"capabilities": {"portMappings": true} 
Runtimes should fill in the actual port mappings when the config is passed to plugins. It should be placed in a new section of the config "runtimeConfig" e.g.
"runtimeConfig": {
"portMappings" : [
{ "hostPort": 8080, "containerPort": 80, "protocol": "tcp" },
{ "hostPort": 8000, "containerPort": 8001, "protocol": "udp" }
]
}
| none | none | +Dynamic information (i.e. data that a runtime fills out) should be placed in a `runtimeConfig` section. Plugins can request +that the runtime insert this dynamic configuration by explicitly listing their `capabilities` in the network configuration. For example, the configuration for a port mapping plugin might look like this to an operator (it should be included as part of a [network configuration list](https://github.com/containernetworking/cni/blob/master/SPEC.md#network-configuration-lists). ```json @@ -57,15 +54,23 @@ But the runtime would fill in the mappings so the plugin itself would receive so } ``` +### Well-known Capabilities +| Area | Purpose | Capability | Spec and Example | Runtime implementations | Plugin Implementations | +| ----- | ------- | -----------| ---------------- | ----------------------- | --------------------- | +| port mappings | Pass mapping from ports on the host to ports in the container network namespace. | `portMappings` | A list of portmapping entries.
[
{ "hostPort": 8080, "containerPort": 80, "protocol": "tcp" },
{ "hostPort": 8000, "containerPort": 8001, "protocol": "udp" }
]
| kubernetes | CNI `portmap` plugin | +| ip ranges | Dynamically configure the IP range(s) for address allocation. Runtimes that manage IP pools, but not individual IP addresses, can pass these to plugins. | `ipRanges` | The same as the `ranges` key for `host-local` - a list of lists of subnets. The outer list is the number of IPs to allocate, and the inner list is a pool of subnets for each allocation.
[
[
{ "subnet": "10.1.2.0/24", "rangeStart": "10.1.2.3", "rangeEnd": 10.1.2.99", "gateway": "10.1.2.254" }
]
]
| none | cni `host-local` plugin | +| bandwidth limits | Dynamically configure interface bandwidth limits | `bandwidth` | Desired bandwidth limits. Rates are in bits per second, burst values are in bits.
 { "ingressRate": 2048, "ingressBurst": 1600, "egressRate": 4096, "egressBurst": 1600 } 
| none | cni `bandwidth` plugin | + + ## "args" in network config -`args` in [network config](https://github.com/containernetworking/cni/blob/master/SPEC.md#network-configuration) were introduced as an optional field into the `0.1.0` CNI spec. The first CNI code release that it appeared in was `v0.4.0`. +`args` in [network config](https://github.com/containernetworking/cni/blob/master/SPEC.md#network-configuration) were introduced as an optional field into the `0.2.0` release of the CNI spec. The first CNI code release that it appeared in was `v0.4.0`. > args (dictionary): Optional additional arguments provided by the container runtime. For example a dictionary of labels could be passed to CNI plugins by adding them to a labels field under args. `args` provide a way of providing more structured data than the flat strings that CNI_ARGS can support. `args` should be used for _optional_ meta-data. Runtimes can place additional data in `args` and plugins that don't understand that data should just ignore it. Runtimes should not require that a plugin understands or consumes that data provided, and so a runtime should not expect to receive an error if the data could not be acted on. -This method of passing information to a plugin is recommended when the information is optional and the plugin can choose to ignore it. It's often that case that such information is passed to all plugins by the runtime whithout regard for whether the plugin can understand it. +This method of passing information to a plugin is recommended when the information is optional and the plugin can choose to ignore it. It's often that case that such information is passed to all plugins by the runtime without regard for whether the plugin can understand it. The conventions documented here are all namepaced under `cni` so they don't conflict with any existing `args`. @@ -87,8 +92,9 @@ For example: ``` | Area | Purpose| Spec and Example | Runtime implementations | Plugin Implementations | -| ------ | ------ | ------ | ------ | ------ | ------ | +| ----- | ------ | ------------ | ----------------------- | ---------------------- | | labels | Pass`key=value` labels to plugins |
"labels" : [
{ "key" : "app", "value" : "myapp" },
{ "key" : "env", "value" : "prod" }
]
| none | none | +| ips | Request static IPs |
"ips": ["10.2.2.42", "2001:db8::5"]
| none | host-local | ## CNI_ARGS CNI_ARGS formed part of the original CNI spec and have been present since the initial release. @@ -97,6 +103,12 @@ CNI_ARGS formed part of the original CNI spec and have been present since the in The use of `CNI_ARGS` is deprecated and "args" should be used instead. | Field | Purpose| Spec and Example | Runtime implementations | Plugin Implementations | -| ------ | ------ | ------ | ------ | ------ | ------ | +| ------ | ------ | ---------------- | ----------------------- | ---------------------- | | IP | Request a specific IP from IPAM plugins | IP=192.168.10.4 | *rkt* supports passing additional arguments to plugins and the [documentation](https://coreos.com/rkt/docs/latest/networking/overriding-defaults.html) suggests IP can be used. | host-local (since version v0.2.0) supports the field for IPv4 only - [documentation](https://github.com/containernetworking/cni/blob/master/Documentation/host-local.md#supported-arguments).| - + +## Chained Plugins +If plugins are agnostic about the type of interface created, they SHOULD work in a chained mode and configure existing interfaces. Plugins MAY also create the desired interface when not run in a chain. + +For example, the `bridge` plugin adds the host-side interface to a bridge. So, it should accept any previous result that includes a host-side interface, including `tap` devices. If not called as a chained plugin, it creates a `veth` pair first. + +Plugins that meet this convention are usable by a larger set of runtimes and interfaces, including hypervisors and DPDK providers. diff --git a/vendor/github.com/containernetworking/cni/Documentation/host-local.md b/vendor/github.com/containernetworking/cni/Documentation/host-local.md deleted file mode 100644 index 073e369af..000000000 --- a/vendor/github.com/containernetworking/cni/Documentation/host-local.md +++ /dev/null @@ -1,82 +0,0 @@ -# host-local IP address management plugin - -host-local IPAM allocates IPv4 and IPv6 addresses out of a specified address range. Optionally, -it can include a DNS configuration from a `resolv.conf` file on the host. - -## Overview - -host-local IPAM plugin allocates IPv4 addresses out of a specified address range. -It stores the state locally on the host filesystem, therefore ensuring uniqueness of IP addresses on a single host. - -## Example configurations - -IPv4: -```json -{ - "ipam": { - "type": "host-local", - "subnet": "10.10.0.0/16", - "rangeStart": "10.10.1.20", - "rangeEnd": "10.10.3.50", - "gateway": "10.10.0.254", - "routes": [ - { "dst": "0.0.0.0/0" }, - { "dst": "192.168.0.0/16", "gw": "10.10.5.1" } - ], - "dataDir": "/var/my-orchestrator/container-ipam-state" - } -} -``` - -IPv6: -```json -{ - "ipam": { - "type": "host-local", - "subnet": "3ffe:ffff:0:01ff::/64", - "rangeStart": "3ffe:ffff:0:01ff::0010", - "rangeEnd": "3ffe:ffff:0:01ff::0020", - "routes": [ - { "dst": "3ffe:ffff:0:01ff::1/64" } - ], - "resolvConf": "/etc/resolv.conf" - } -} -``` - -We can test it out on the command-line: - -```bash -$ export CNI_COMMAND=ADD -$ export CNI_CONTAINERID=f81d4fae-7dec-11d0-a765-00a0c91e6bf6 -$ echo '{ "name": "default", "ipam": { "type": "host-local", "subnet": "203.0.113.0/24" } }' | ./host-local -``` - -```json -{ - "ip4": { - "ip": "203.0.113.1/24" - } -} -``` - -## Network configuration reference - -* `type` (string, required): "host-local". -* `subnet` (string, required): CIDR block to allocate out of. -* `rangeStart` (string, optional): IP inside of "subnet" from which to start allocating addresses. Defaults to ".2" IP inside of the "subnet" block. -* `rangeEnd` (string, optional): IP inside of "subnet" with which to end allocating addresses. Defaults to ".254" IP inside of the "subnet" block. -* `gateway` (string, optional): IP inside of "subnet" to designate as the gateway. Defaults to ".1" IP inside of the "subnet" block. -* `routes` (string, optional): list of routes to add to the container namespace. Each route is a dictionary with "dst" and optional "gw" fields. If "gw" is omitted, value of "gateway" will be used. -* `resolvConf` (string, optional): Path to a `resolv.conf` on the host to parse and return as the DNS configuration -* `dataDir` (string, optional): Path to a directory to use for maintaining state, e.g. which IPs have been allocated to which containers - - -## Supported arguments -The following [CNI_ARGS](https://github.com/containernetworking/cni/blob/master/SPEC.md#parameters) are supported: - -* `ip`: request a specific IP address from the subnet. If it's not available, the plugin will exit with an error - -## Files - -Allocated IP addresses are stored as files in `/var/lib/cni/networks/$NETWORK_NAME`. The prefix can be customized with the `dataDir` option listed above. diff --git a/vendor/github.com/containernetworking/cni/GOVERNANCE.md b/vendor/github.com/containernetworking/cni/GOVERNANCE.md new file mode 100644 index 000000000..b517630a2 --- /dev/null +++ b/vendor/github.com/containernetworking/cni/GOVERNANCE.md @@ -0,0 +1,44 @@ +# CNI Governance + +This document defines project governance for the project. + +## Voting + +The CNI project employs "organization voting" to ensure no single organization can dominate the project. + +Individuals not associated with or employed by a company or organization are allowed one organization vote. +Each company or organization (regardless of the number of maintainers associated with or employed by that company/organization) receives one organization vote. + +In other words, if two maintainers are employed by Company X, two by Company Y, two by Company Z, and one maintainer is an un-affiliated individual, a total of four "organization votes" are possible; one for X, one for Y, one for Z, and one for the un-affiliated individual. + +Any maintainer from an organization may cast the vote for that organization. + +For formal votes, a specific statement of what is being voted on should be added to the relevant github issue or PR, and a link to that issue or PR added to the maintainers meeting agenda document. +Maintainers should indicate their yes/no vote on that issue or PR, and after a suitable period of time, the votes will be tallied and the outcome noted. + +## Changes in Maintainership + +New maintainers are proposed by an existing maintainer and are elected by a 2/3 majority organization vote. + +Maintainers can be removed by a 2/3 majority organization vote. + +## Approving PRs + +Non-specification-related PRs may be merged after receiving at least two organization votes. + +Changes to the CNI Specification also follow the normal PR approval process (eg, 2 organization votes), but any maintainer can request that the approval require a 2/3 majority organization vote. + +## Github Project Administration + +Maintainers will be added to the containernetworking GitHub organization and added to the GitHub cni-maintainers team, and made a GitHub maintainer of that team. + +After 6 months a maintainer will be made an "owner" of the GitHub organization. + +## Changes in Governance + +All changes in Governance require a 2/3 majority organization vote. + +## Other Changes + +Unless specified above, all other changes to the project require a 2/3 majority organization vote. +Additionally, any maintainer may request that any change require a 2/3 majority organization vote. diff --git a/vendor/github.com/containernetworking/cni/MAINTAINERS b/vendor/github.com/containernetworking/cni/MAINTAINERS index 3d6debf5a..ca7962afd 100644 --- a/vendor/github.com/containernetworking/cni/MAINTAINERS +++ b/vendor/github.com/containernetworking/cni/MAINTAINERS @@ -2,5 +2,5 @@ Bryan Boreham (@bboreham) Casey Callendrello (@squeed) Dan Williams (@dcbw) Gabe Rosenhouse (@rosenhouse) +Matt Dupre (@matthewdupre) Stefan Junker (@steveeJ) -Tom Denham (@tomdee) diff --git a/vendor/github.com/containernetworking/cni/README.md b/vendor/github.com/containernetworking/cni/README.md index b250b3a68..65ccda9f9 100644 --- a/vendor/github.com/containernetworking/cni/README.md +++ b/vendor/github.com/containernetworking/cni/README.md @@ -1,12 +1,17 @@ -[![Build Status](https://travis-ci.org/containernetworking/cni.svg?branch=master)](https://travis-ci.org/containernetworking/cni) +[![Linux Build Status](https://travis-ci.org/containernetworking/cni.svg?branch=master)](https://travis-ci.org/containernetworking/cni) +[![Windows Build Status](https://ci.appveyor.com/api/projects/status/wtrkou8oow7x533e/branch/master?svg=true)](https://ci.appveyor.com/project/cni-bot/cni/branch/master) [![Coverage Status](https://coveralls.io/repos/github/containernetworking/cni/badge.svg?branch=master)](https://coveralls.io/github/containernetworking/cni?branch=master) [![Slack Status](https://cryptic-tundra-43194.herokuapp.com/badge.svg)](https://cryptic-tundra-43194.herokuapp.com/) +![CNI Logo](logo.png) + --- # Community Sync Meeting -There is a community sync meeting for users and developers every 1-2 months. The next meeting will help on a Google Hangout and the link is in the [agenda](https://docs.google.com/document/d/10ECyT2mBGewsJUcmYmS8QNo1AcNgy2ZIe2xS7lShYhE/edit?usp=sharing) (Notes from previous meeting are also in this doc). The next meeting will be held on *April 12th* at *3:00pm UTC* [Add to Calendar](https://www.worldtimebuddy.com/?qm=1&lid=100,5,2643743,5391959&h=100&date=2017-4-12&sln=15-16). +There is a community sync meeting for users and developers every 1-2 months. The next meeting will help on a Google Hangout and the link is in the [agenda](https://docs.google.com/document/d/10ECyT2mBGewsJUcmYmS8QNo1AcNgy2ZIe2xS7lShYhE/edit?usp=sharing) (Notes from previous meeting are also in this doc). + +The next meeting will be held on *Wednesday, October 4th* at *3:00pm UTC / 11:00am EDT / 8:00am PDT* [Add to Calendar](https://www.worldtimebuddy.com/?qm=1&lid=100,5,2643743,5391959&h=100&date=2017-10-04&sln=15-16). --- @@ -14,11 +19,11 @@ There is a community sync meeting for users and developers every 1-2 months. The ## What is CNI? -The CNI (_Container Network Interface_) project consists of a specification and libraries for writing plugins to configure network interfaces in Linux containers, along with a number of supported plugins. +CNI (_Container Network Interface_), a [Cloud Native Computing Foundation](https://cncf.io) project, consists of a specification and libraries for writing plugins to configure network interfaces in Linux containers, along with a number of supported plugins. CNI concerns itself only with network connectivity of containers and removing allocated resources when the container is deleted. Because of this focus, CNI has a wide range of support and the specification is simple to implement. -As well as the [specification](SPEC.md), this repository contains the Go source code of a library for integrating CNI into applications, an example command-line tool, a template for making new plugins, and the supported plugins. +As well as the [specification](SPEC.md), this repository contains the Go source code of a [library for integrating CNI into applications](libcni) and an [example command-line tool](cnitool) for executing CNI plugins. A [separate repository contains reference plugins](https://github.com/containernetworking/plugins) and a template for making new plugins. The template code makes it straight-forward to create a CNI plugin for an existing container networking project. CNI also makes a good framework for creating a new container networking project from scratch. @@ -33,10 +38,11 @@ To avoid duplication, we think it is prudent to define a common interface betwee ## Who is using CNI? ### Container runtimes - [rkt - container engine](https://coreos.com/blog/rkt-cni-networking.html) -- [Kurma - container runtime](http://kurma.io/) - [Kubernetes - a system to simplify container operations](http://kubernetes.io/docs/admin/network-plugins/) -- [Cloud Foundry - a platform for cloud applications](https://github.com/cloudfoundry-incubator/netman-release) -- [Mesos - a distributed systems kernel](https://github.com/apache/mesos/blob/master/docs/cni.md) +- [OpenShift - Kubernetes with additional enterprise features](https://github.com/openshift/origin/blob/master/docs/openshift_networking_requirements.md) +- [Cloud Foundry - a platform for cloud applications](https://github.com/cloudfoundry-incubator/cf-networking-release) +- [Apache Mesos - a distributed systems kernel](https://github.com/apache/mesos/blob/master/docs/cni.md) +- [Amazon ECS - a highly scalable, high performance container management service](https://aws.amazon.com/ecs/) ### 3rd party plugins - [Project Calico - a layer 3 virtual network](https://github.com/projectcalico/calico-cni) @@ -48,8 +54,15 @@ To avoid duplication, we think it is prudent to define a common interface betwee - [Multus - a Multi plugin](https://github.com/Intel-Corp/multus-cni) - [Romana - Layer 3 CNI plugin supporting network policy for Kubernetes](https://github.com/romana/kube) - [CNI-Genie - generic CNI network plugin](https://github.com/Huawei-PaaS/CNI-Genie) +- [Nuage CNI - Nuage Networks SDN plugin for network policy kubernetes support ](https://github.com/nuagenetworks/nuage-cni) +- [Silk - a CNI plugin designed for Cloud Foundry](https://github.com/cloudfoundry-incubator/silk) +- [Linen - a CNI plugin designed for overlay networks with Open vSwitch and fit in SDN/OpenFlow network environment](https://github.com/John-Lin/linen-cni) +- [Vhostuser - a Dataplane network plugin - Supports OVS-DPDK & VPP](https://github.com/intel/vhost-user-net-plugin) +- [Amazon ECS CNI Plugins - a collection of CNI Plugins to configure containers with Amazon EC2 elastic network interfaces (ENIs)](https://github.com/aws/amazon-ecs-cni-plugins) +- [Bonding CNI - a Link aggregating plugin to address failover and high availability network](https://github.com/Intel-Corp/bond-cni) +- [ovn-kubernetes - an container network plugin built on Open vSwitch (OVS) and Open Virtual Networking (OVN) with support for both Linux and Windows](https://github.com/openvswitch/ovn-kubernetes) -The CNI team also maintains some [core plugins](plugins). +The CNI team also maintains some [core plugins in a separate repository](https://github.com/containernetworking/plugins). ## Contributing to CNI @@ -61,19 +74,16 @@ If you intend to contribute to code or documentation, please read [CONTRIBUTING. ### Requirements -CNI requires Go 1.5+ to build. +The CNI spec is language agnostic. To use the Go language libraries in this repository, you'll need a recent version of Go. Our [automated tests](https://travis-ci.org/containernetworking/cni/builds) cover Go versions 1.7 and 1.8. -Go 1.5 users will need to set GO15VENDOREXPERIMENT=1 to get vendored -dependencies. This flag is set by default in 1.6. +### Reference Plugins -### Included Plugins - -This repository includes a number of common plugins in the `plugins/` directory. -Please see the [Documentation/](Documentation/) directory for documentation about particular plugins. +The CNI project maintains a set of [reference plugins](https://github.com/containernetworking/plugins) that implement the CNI specification. +NOTE: the reference plugins used to live in this repository but have been split out into a [separate repository](https://github.com/containernetworking/plugins) as of May 2017. ### Running the plugins -The scripts/ directory contains two scripts, `priv-net-run.sh` and `docker-run.sh`, that can be used to exercise the plugins. +After building and installing the [reference plugins](https://github.com/containernetworking/plugins), you can use the `priv-net-run.sh` and `docker-run.sh` scripts in the `scripts/` directory to exercise the plugins. **note - priv-net-run.sh depends on `jq`** @@ -111,14 +121,15 @@ The directory `/etc/cni/net.d` is the default location in which the scripts will Next, build the plugins: ```bash -$ ./build +$ cd $GOPATH/src/github.com/containernetworking/plugins +$ ./build.sh ``` Finally, execute a command (`ifconfig` in this example) in a private network namespace that has joined the `mynet` network: ```bash -$ CNI_PATH=`pwd`/bin -$ cd scripts +$ CNI_PATH=$GOPATH/src/github.com/containernetworking/plugins/bin +$ cd $GOPATH/src/github.com/containernetworking/cni/scripts $ sudo CNI_PATH=$CNI_PATH ./priv-net-run.sh ifconfig eth0 Link encap:Ethernet HWaddr f2:c2:6f:54:b8:2b inet addr:10.22.0.2 Bcast:0.0.0.0 Mask:255.255.0.0 @@ -126,7 +137,7 @@ eth0 Link encap:Ethernet HWaddr f2:c2:6f:54:b8:2b UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:1 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:1 overruns:0 carrier:0 - collisions:0 txqueuelen:0 + collisions:0 txqueuelen:0 RX bytes:90 (90.0 B) TX bytes:0 (0.0 B) lo Link encap:Local Loopback @@ -135,7 +146,7 @@ lo Link encap:Local Loopback UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 - collisions:0 txqueuelen:0 + collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) ``` @@ -147,8 +158,8 @@ Use the instructions in the previous section to define a netconf and build the p Next, docker-run.sh script wraps `docker run`, to execute the plugins prior to entering the container: ```bash -$ CNI_PATH=`pwd`/bin -$ cd scripts +$ CNI_PATH=$GOPATH/src/github.com/containernetworking/plugins/bin +$ cd $GOPATH/src/github.com/containernetworking/cni/scripts $ sudo CNI_PATH=$CNI_PATH ./docker-run.sh --rm busybox:latest ifconfig eth0 Link encap:Ethernet HWaddr fa:60:70:aa:07:d1 inet addr:10.22.0.2 Bcast:0.0.0.0 Mask:255.255.0.0 @@ -156,7 +167,7 @@ eth0 Link encap:Ethernet HWaddr fa:60:70:aa:07:d1 UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:1 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:1 overruns:0 carrier:0 - collisions:0 txqueuelen:0 + collisions:0 txqueuelen:0 RX bytes:90 (90.0 B) TX bytes:0 (0.0 B) lo Link encap:Local Loopback @@ -165,7 +176,7 @@ lo Link encap:Local Loopback UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 - collisions:0 txqueuelen:0 + collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) ``` diff --git a/vendor/github.com/containernetworking/cni/RELEASING.md b/vendor/github.com/containernetworking/cni/RELEASING.md new file mode 100644 index 000000000..dd1b7a94f --- /dev/null +++ b/vendor/github.com/containernetworking/cni/RELEASING.md @@ -0,0 +1,34 @@ +# Release process + +## Resulting artifacts +Creating a new release produces the following artifacts: + +- Binaries (stored in the `release-` directory) : + - `cni--.tgz` binaries + - `cni-.tgz` binary (copy of amd64 platform binary) + - `sha1`, `sha256` and `sha512` files for the above files. + +## Preparing for a release +1. Releases are performed by maintainers and should usually be discussed and planned at a maintainer meeting. + - Choose the version number. It should be prefixed with `v`, e.g. `v1.2.3` + - Take a quick scan through the PRs and issues to make sure there isn't anything crucial that _must_ be in the next release. + - Create a draft of the release note + - Discuss the level of testing that's needed and create a test plan if sensible + - Check what version of `go` is used in the build container, updating it if there's a new stable release. + +## Creating the release artifacts +1. Make sure you are on the master branch and don't have any local uncommitted changes. +1. Create a signed tag for the release `git tag -s $VERSION` (Ensure that GPG keys are created and added to GitHub) +1. Run the release script from the root of the repository + - `scripts/release.sh` + - The script requires Docker and ensures that a consistent environment is used. + - The artifacts will now be present in the `release-` directory. +1. Test these binaries according to the test plan. + +## Publishing the release +1. Push the tag to git `git push origin ` +1. Create a release on Github, using the tag which was just pushed. +1. Attach all the artifacts from the release directory. +1. Add the release note to the release. +1. Announce the release on at least the CNI mailing, IRC and Slack. + diff --git a/vendor/github.com/containernetworking/cni/ROADMAP.md b/vendor/github.com/containernetworking/cni/ROADMAP.md index 8e0828840..ec5f3c150 100644 --- a/vendor/github.com/containernetworking/cni/ROADMAP.md +++ b/vendor/github.com/containernetworking/cni/ROADMAP.md @@ -5,29 +5,19 @@ The list below is not complete, and we advise to get the current project state f ## CNI Milestones -### [v0.2.0](https://github.com/containernetworking/cni/milestones/v0.2.0) - -* Signed release binaries -* Introduction of a testing strategy/framework - -### [v0.3.0](https://github.com/containernetworking/cni/milestones/v0.3.0) - -* Further increase test coverage -* Simpler default route handling in bridge plugin -* Clarify project description, documentation and contribution guidelines - -### [v0.4.0](https://github.com/containernetworking/cni/milestones/v0.4.0) - -* Further increase test coverage -* Simpler bridging of host interface -* Improve IPAM allocator predictability -* Allow in- and output of arbitrary K/V pairs for plugins - -### [v1.0.0](https://github.com/containernetworking/cni/milestones/v1.0.0) +### [v0.6.0](https://github.com/containernetworking/cni/milestones/v0.6.0) - Plugin composition functionality - IPv6 support -- Stable SPEC - Strategy and tooling for backwards compatibility -- Complete test coverage - Integrate build artefact generation with CI + +### [v1.0.0](https://github.com/containernetworking/cni/milestones/v1.0.0) + +- More precise specification language +- GET action +- Conformance test suite for CNI plugins (both reference and 3rd party) +- Stable SPEC +- Complete test coverage +- Signed release binaries + diff --git a/vendor/github.com/containernetworking/cni/SPEC.md b/vendor/github.com/containernetworking/cni/SPEC.md index 89e859152..d27d859ea 100644 --- a/vendor/github.com/containernetworking/cni/SPEC.md +++ b/vendor/github.com/containernetworking/cni/SPEC.md @@ -1,10 +1,23 @@ -# Container Networking Interface Proposal +# Container Network Interface Specification ## Version -This is CNI **spec** version **0.3.1**. +This is CNI **spec** version **0.4.0-dev**. This spec contains **unreleased** changes. Note that this is **independent from the version of the CNI library and plugins** in this repository (e.g. the versions of [releases](https://github.com/containernetworking/cni/releases)). +#### Released versions +Released versions of the spec are available as Git tags. + +| tag | spec permalink | major changes | +| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------- | --------------------------------- | +| [`spec-v0.3.1`](https://github.com/containernetworking/cni/releases/tag/spec-v0.3.1) | [spec at v0.3.1](https://github.com/containernetworking/cni/blob/spec-v0.3.1/SPEC.md) | none (typo fix only) | +| [`spec-v0.3.0`](https://github.com/containernetworking/cni/releases/tag/spec-v0.3.0) | [spec at v0.3.0](https://github.com/containernetworking/cni/blob/spec-v0.3.0/SPEC.md) | rich result type, plugin chaining | +| [`spec-v0.2.0`](https://github.com/containernetworking/cni/releases/tag/spec-v0.2.0) | [spec at v0.2.0](https://github.com/containernetworking/cni/blob/spec-v0.2.0/SPEC.md) | VERSION command | +| [`spec-v0.1.0`](https://github.com/containernetworking/cni/releases/tag/spec-v0.1.0) | [spec at v0.1.0](https://github.com/containernetworking/cni/blob/spec-v0.1.0/SPEC.md) | initial version | + +*Do not rely on these tags being stable. In the future, we may change our mind about which particular commit is the right marker for a given historical spec version.* + + ## Overview This document proposes a generic plugin-based networking solution for application containers on Linux, the _Container Networking Interface_, or _CNI_. @@ -14,44 +27,45 @@ For the purposes of this proposal, we define two terms very specifically: - _container_ can be considered synonymous with a [Linux _network namespace_][namespaces]. What unit this corresponds to depends on a particular container runtime implementation: for example, in implementations of the [App Container Spec][appc-github] like rkt, each _pod_ runs in a unique network namespace. In [Docker][docker], on the other hand, network namespaces generally exist for each separate Docker container. - _network_ refers to a group of entities that are uniquely addressable that can communicate amongst each other. This could be either an individual container (as specified above), a machine, or some other network device (e.g. a router). Containers can be conceptually _added to_ or _removed from_ one or more networks. +This document aims to specify the interface between "runtimes" and "plugins". Whilst there are certain well known fields, runtimes may wish to pass additional information to plugins. These extentions are not part of this specification but are documented as [conventions](CONVENTIONS.md). The key words "must", "must not", "required", "shall", "shall not", "should", "should not", "recommended", "may" and "optional" are used as specified in [RFC 2119][rfc-2119]. + [rkt-networking-proposal]: https://docs.google.com/a/coreos.com/document/d/1PUeV68q9muEmkHmRuW10HQ6cHgd4819_67pIxDRVNlM/edit#heading=h.ievko3xsjwxd [rkt-networking-design]: https://docs.google.com/a/coreos.com/document/d/1CTAL4gwqRofjxyp4tTkbgHtAwb2YCcP14UEbHNizd8g [rkt-github]: https://github.com/coreos/rkt [namespaces]: http://man7.org/linux/man-pages/man7/namespaces.7.html [appc-github]: https://github.com/appc/spec -[docker]: https://docker.com - -This document aims to specify the interface between "runtimes" and "plugins". Whilst there are certain well known fields, runtimes may wish to pass additional information to plugins. These extentions are not part of this specification but are documented as [conventions](CONVENTIONS.md). +[docker]: https://docker.com +[rfc-2119]: https://www.ietf.org/rfc/rfc2119.txt ## General considerations -The intention is for the container runtime to first create a new network namespace for the container. -It then determines which networks this container should belong to and for each network, which plugin must be executed. -The network configuration is in JSON format and can easily be stored in a file. -The network configuration includes mandatory fields such as "name" and "type" as well as plugin (type) specific ones. -The network configuration allows for fields to change values between invocations. For this purpose there is an optional field "args" which should contain the varying information. -The container runtime sequentially sets up the networks by executing the corresponding plugin for each network. -Upon completion of the container lifecycle, the runtime executes the plugins in reverse order (relative to the order in which they were added) to disconnect them from the networks. +- The container runtime must create a new network namespace for the container before invoking any plugins. +- The runtime must then determine which networks this container should belong to, and for each network, which plugins must be executed. +- The network configuration is in JSON format and can easily be stored in a file. The network configuration includes mandatory fields such as "name" and "type" as well as plugin (type) specific ones. The network configuration allows for fields to change values between invocations. For this purpose there is an optional field "args" which must contain the varying information. +- The container runtime must add the container to each network by executing the corresponding plugins for each network sequentially. +- Upon completion of the container lifecycle, the runtime must execute the plugins in reverse order (relative to the order in which they were executed to add the container) to disconnect the container from the networks. +- The container runtime must not invoke parallel operations for the same container, but is allowed to invoke parallel operations for different containers. +- The container runtime must order ADD and DEL operations for a container, such that ADD is always eventually followed by a corresponding DEL. DEL may be followed by additional DELs but plugins should handle multiple DELs permissively (i.e. plugin DEL should be idempotent). +- A container must be uniquely identified by a ContainerID. Plugins that store state should do so using a primary key of `(network name, CNI_CONTAINERID, CNI_IFNAME)`. +- A runtime must not call ADD twice (without a corresponding DEL) for the same `(network name, container id, name of the interface inside the container)`. This implies that a given container ID may be added to a specific network more than once only if each addition is done with a different interface name. ## CNI Plugin ### Overview -Each CNI plugin is implemented as an executable that is invoked by the container management system (e.g. rkt or Docker). +Each CNI plugin must be implemented as an executable that is invoked by the container management system (e.g. rkt or Kubernetes). -A CNI plugin is responsible for inserting a network interface into the container network namespace (e.g. one end of a veth pair) and making any necessary changes on the host (e.g. attaching other end of veth into a bridge). -It should then assign the IP to the interface and setup the routes consistent with IP Address Management section by invoking appropriate IPAM plugin. +A CNI plugin is responsible for inserting a network interface into the container network namespace (e.g. one end of a veth pair) and making any necessary changes on the host (e.g. attaching the other end of the veth into a bridge). +It should then assign the IP to the interface and setup the routes consistent with the IP Address Management section by invoking appropriate IPAM plugin. ### Parameters -The operations that the CNI plugin needs to support are: +The operations that CNI plugins must support are: - -- Add container to network +- `ADD`: Add container to network - Parameters: - - **Version**. The version of CNI spec that the caller is using (container management system or the invoking plugin). - - **Container ID**. This is optional but recommended, and should be unique across an administrative domain while the container is live (it may be reused in the future). For example, an environment with an IPAM system may require that each container is allocated a unique ID and that each IP allocation can thus be correlated back to a particular container. As another example, in appc implementations this would be the _pod ID_. + - **Container ID**. A unique plaintext identifier for a container, allocated by the runtime. Must not be empty. - **Network namespace path**. This represents the path to the network namespace to be added, i.e. /proc/[pid]/ns/net or a bind-mount/link to it. - **Network configuration**. This is a JSON document describing a network to which a container can be joined. The schema is described below. - **Extra arguments**. This provides an alternative mechanism to allow simple configuration of CNI plugins on a per-container basis. @@ -61,47 +75,69 @@ The operations that the CNI plugin needs to support are: - **IP configuration assigned to each interface**. The IPv4 and/or IPv6 addresses, gateways, and routes assigned to sandbox and/or host interfaces. - **DNS information**. Dictionary that includes DNS information for nameservers, domain, search domains and options. -- Delete container from network +- `DEL`: Delete container from network - Parameters: - - **Version**. The version of CNI spec that the caller is using (container management system or the invoking plugin). - **Container ID**, as defined above. - **Network namespace path**, as defined above. - **Network configuration**, as defined above. - **Extra arguments**, as defined above. - **Name of the interface inside the container**, as defined above. + - All parameters should be the same as those passed to the corresponding add operation. + - A delete operation should release all resources held by the supplied containerid in the configured network. + - If there was a known previous `ADD` or `GET` action for the container, the runtime MUST add a `prevResult` field to the configuration JSON of the plugin (or all plugins in a chain), which MUST be the `Result` of the immediately previous `ADD` or `GET` action in JSON format ([see below](#network-configuration-list-runtime-examples)). + - When `CNI_NETNS` and/or `prevResult` are not provided, the plugin should clean up as many resources as possible (e.g. releasing IPAM allocations) and return a successful response. + - If the runtime cached the `Result` of a previous `ADD` or `GET` response for a given container, it must delete that cached response on a successful `DEL` for that container. -- Report version +- `GET`: Get container network configuration + - Parameters: + - **Container ID**, as defined for `ADD`. + - **Network namespace path**, as defined for `ADD`. + - **Network configuration**, as defined for `ADD`. + - **Extra arguments**, as defined for `ADD`. + - **Name of the interface inside the container**, as defined for `ADD`. + - Result: + - The plugin should return the same result as an `ADD` action for the same inputs. + - **Interfaces list**, as defined for `ADD` + - **IP configuration assigned to each interface**, as defined for `ADD` + - **DNS information**, as defined for `ADD` + - This action should return the same `Result` object as an `ADD` action for the same inputs. The result should not change over the lifetime of the container. + - The plugin should return an error if any general internal state is unexpected. For example, if the plugin's data storage is missing or corrupt, or its control plane is unavailable, it should return an error. + - The plugin should NOT return an error if its expected sandbox state (eg interfaces, IP addresses, routes, etc) is not found, as subsequent elements in the plugin's chain may alter sandbox state. + - A runtime may call `GET` at any time; but if `GET` is called for a container before an `ADD` or after a `DEL` for that container, the plugin should return error 3 to indicate the container is unknown (see [Well-known Error Codes](#well-known-error-codes) section). + - If the previous action for the container was `ADD` or `GET`, the runtime must add a `prevResult` field to the configuration JSON of the plugin (or all plugins in the chain), which must be the `Result` of that previous `ADD` or `GET` action in JSON format ([see below](#network-configuration-list-runtime-examples)). + +- `VERSION`: Report version - Parameters: NONE. - Result: information about the CNI spec versions supported by the plugin ``` { - "cniVersion": "0.3.1", // the version of the CNI spec in use for this output - "supportedVersions": [ "0.1.0", "0.2.0", "0.3.0", "0.3.1" ] // the list of CNI spec versions that this plugin supports + "cniVersion": "0.4.0", // the version of the CNI spec in use for this output + "supportedVersions": [ "0.1.0", "0.2.0", "0.3.0", "0.3.1", "0.4.0" ] // the list of CNI spec versions that this plugin supports } ``` -The executable command-line API uses the type of network (see [Network Configuration](#network-configuration) below) as the name of the executable to invoke. -It will then look for this executable in a list of predefined directories. Once found, it will invoke the executable using the following environment variables for argument passing: -- `CNI_COMMAND`: indicates the desired operation; `ADD`, `DEL` or `VERSION`. +Runtimes must use the type of network (see [Network Configuration](#network-configuration) below) as the name of the executable to invoke. +Runtimes should then look for this executable in a list of predefined directories (the list of directories is not prescribed by this specification). Once found, it must invoke the executable using the following environment variables for argument passing: +- `CNI_COMMAND`: indicates the desired operation; `ADD`, `DEL`, `GET`, or `VERSION`. - `CNI_CONTAINERID`: Container ID - `CNI_NETNS`: Path to network namespace file -- `CNI_IFNAME`: Interface name to set up; plugin must honor this interface name or return an error +- `CNI_IFNAME`: Interface name to set up; if the plugin is unable to use this interface name it must return an error - `CNI_ARGS`: Extra arguments passed in by the user at invocation time. Alphanumeric key-value pairs separated by semicolons; for example, "FOO=BAR;ABC=123" - `CNI_PATH`: List of paths to search for CNI plugin executables. Paths are separated by an OS-specific list separator; for example ':' on Linux and ';' on Windows -Network configuration in JSON format is streamed to the plugin through stdin. This means it is not tied to a particular file on disk and can contain information which changes between invocations. +Network configuration in JSON format must be streamed to the plugin through stdin. This means it is not tied to a particular file on disk and may contain information which changes between invocations. ### Result -Note that IPAM plugins return an abbreviated `Result` structure as described in [IP Allocation](#ip-allocation). +Note that IPAM plugins should return an abbreviated `Result` structure as described in [IP Allocation](#ip-allocation). -Success is indicated by a return code of zero and the following JSON printed to stdout in the case of the ADD command. The `ips` and `dns` items should be the same output as was returned by the IPAM plugin (see [IP Allocation](#ip-allocation) for details) except that the plugin should fill in the `interface` indexes appropriately, which are missing from IPAM plugin output since IPAM plugins should be unaware of interfaces. +Plugins must indicate success with a return code of zero and the following JSON printed to stdout in the case of the ADD command. The `ips` and `dns` items should be the same output as was returned by the IPAM plugin (see [IP Allocation](#ip-allocation) for details) except that the plugin should fill in the `interface` indexes appropriately, which are missing from IPAM plugin output since IPAM plugins should be unaware of interfaces. ``` { - "cniVersion": "0.3.1", + "cniVersion": "0.4.0", "interfaces": [ (this key omitted by IPAM plugins) { "name": "", @@ -134,7 +170,8 @@ Success is indicated by a return code of zero and the following JSON printed to } ``` -`cniVersion` specifies a [Semantic Version 2.0](http://semver.org) of CNI specification used by the plugin. +`cniVersion` specifies a [Semantic Version 2.0](http://semver.org) of CNI specification used by the plugin. A plugin may support multiple CNI spec versions (as it reports via the `VERSION` command), here the `cniVersion` returned by the plugin in the result must be consistent with the `cniVersion` specified in [Network Configuration](#network-configuration). If the `cniVersion` in the network configuration is not supported by the plugin, the plugin should return an error code 1 (see [Well-known Error Codes](#well-known-error-codes) for details). + `interfaces` describes specific network interfaces the plugin created. If the `CNI_IFNAME` variable exists the plugin must use that name for the sandbox/hypervisor interface or return an error if it cannot. - `mac` (string): the hardware address of the interface. @@ -152,10 +189,10 @@ See the [DNS well-known structure](#dns) section for more information. The specification does not declare how this information must be processed by CNI consumers. Examples include generating an `/etc/resolv.conf` file to be injected into the container filesystem or running a DNS forwarder on the host. -Errors are indicated by a non-zero return code and the following JSON being printed to stdout: +Errors must be indicated by a non-zero return code and the following JSON being printed to stdout: ``` { - "cniVersion": "0.3.1", + "cniVersion": "0.4.0", "code": , "msg": , "details": (optional) @@ -170,7 +207,7 @@ In addition, stderr can be used for unstructured output such as logs. ### Network Configuration -The network configuration is described in JSON form. The configuration can be stored on disk or generated from other sources by the container runtime. The following fields are well-known and have the following meaning: +The network configuration is described in JSON form. The configuration may be stored on disk or generated from other sources by the container runtime. The following fields are well-known and have the following meaning: - `cniVersion` (string): [Semantic Version 2.0](http://semver.org) of CNI specification to which this configuration conforms. - `name` (string): Network name. This should be unique across all containers on the host (or other administrative domain). - `type` (string): Refers to the filename of the CNI plugin executable. @@ -184,13 +221,13 @@ The network configuration is described in JSON form. The configuration can be st - `search` (list of strings): list of priority ordered search domains for short hostname lookups. Will be preferred over `domain` by most resolvers. - `options` (list of strings): list of options that can be passed to the resolver -Plugins may define additional fields that they accept and may generate an error if called with unknown fields. The exception to this is the `args` field may be used to pass arbitrary data which may be ignored by plugins. +Plugins may define additional fields that they accept and may generate an error if called with unknown fields. The exception to this is the `args` field may be used to pass arbitrary data which should be ignored by plugins if not understood. ### Example configurations ```json { - "cniVersion": "0.3.1", + "cniVersion": "0.4.0", "name": "dbnet", "type": "bridge", // type (plugin) specific @@ -209,7 +246,7 @@ Plugins may define additional fields that they accept and may generate an error ```json { - "cniVersion": "0.3.1", + "cniVersion": "0.4.0", "name": "pci", "type": "ovs", // type (plugin) specific @@ -230,7 +267,7 @@ Plugins may define additional fields that they accept and may generate an error ```json { - "cniVersion": "0.3.1", + "cniVersion": "0.4.0", "name": "wan", "type": "macvlan", // ipam specific @@ -257,8 +294,9 @@ The list is described in JSON form, and can be stored on disk or generated from When executing a plugin list, the runtime MUST replace the `name` and `cniVersion` fields in each individual network configuration in the list with the `name` and `cniVersion` field of the list itself. This ensures that the name and CNI version is the same for all plugin executions in the list, preventing versioning conflicts between plugins. The runtime may also pass capability-based keys as a map in the top-level `runtimeConfig` key of the plugin's config JSON if a plugin advertises it supports a specific capability via the `capabilities` key of its network configuration. The key passed in `runtimeConfig` MUST match the name of the specific capability from the `capabilities` key of the plugins network configuration. See CONVENTIONS.md for more information on capabilities and how they are sent to plugins via the `runtimeConfig` key. -For the ADD action, the runtime MUST also add a `prevResult` field to the configuration JSON of any plugin after the first one, which MUST be the Result of the previous plugin (if any) in JSON format ([see below](#network-configuration-list-runtime-examples)). -For the ADD action, plugins SHOULD echo the contents of the `prevResult` field to their stdout to allow subsequent plugins (and the runtime) to receive the result, unless they wish to modify or suppress a previous result. +For the `ADD` action, the runtime MUST also add a `prevResult` field to the configuration JSON of any plugin after the first one, which MUST be the `Result` of the previous plugin (if any) in JSON format ([see below](#network-configuration-list-runtime-examples)). +For the `GET` and `DEL` actions, the runtime MUST (if available) add a `prevResult` field to the configuration JSON of each plugin, which MUST be the `Result` of the immediately previous `ADD` or `GET` action in JSON format ([see below](#network-configuration-list-runtime-examples)). +For the `ADD` and `GET` actions, plugins SHOULD echo the contents of the `prevResult` field to their stdout to allow subsequent plugins (and the runtime) to receive the result, unless they wish to modify or suppress a previous result. Plugins are allowed to modify or suppress all or part of a `prevResult`. However, plugins that support a version of the CNI specification that includes the `prevResult` field MUST handle `prevResult` by either passing it through, modifying it, or suppressing it explicitly. It is a violation of this specification to be unaware of the `prevResult` field. @@ -279,7 +317,7 @@ Plugins should generally complete a DEL action without error even if some resour ```json { - "cniVersion": "0.3.1", + "cniVersion": "0.4.0", "name": "dbnet", "plugins": [ { @@ -314,14 +352,14 @@ Plugins should generally complete a DEL action without error even if some resour #### Network configuration list runtime examples -Given the network configuration list JSON [shown above](#example-network-configuration-lists) the container runtime would perform the following steps for the ADD action. +Given the network configuration list JSON [shown above](#example-network-configuration-lists) the container runtime would perform the following steps for the `ADD` action. Note that the runtime adds the `cniVersion` and `name` fields from configuration list to the configuration JSON passed to each plugin, to ensure consistent versioning and names for all plugins in the list. 1) first call the `bridge` plugin with the following JSON: ```json { - "cniVersion": "0.3.1", + "cniVersion": "0.4.0", "name": "dbnet", "type": "bridge", "bridge": "cni0", @@ -346,17 +384,35 @@ Note that the runtime adds the `cniVersion` and `name` fields from configuration ```json { - "cniVersion": "0.3.1", + "cniVersion": "0.4.0", "name": "dbnet", "type": "tuning", "sysctl": { "net.core.somaxconn": "500" }, "prevResult": { - "ip4": { - "ip": "10.1.0.3/16", - "gateway": "10.1.0.1", - }, + "ips": [ + { + "version": "4", + "address": "10.0.0.5/32", + "interface": 2 + } + ], + "interfaces": [ + { + "name": "cni0", + "mac": "00:11:22:33:44:55", + }, + { + "name": "veth3243", + "mac": "55:44:33:22:11:11", + }, + { + "name": "eth0", + "mac": "99:88:77:66:55:44", + "sandbox": "/var/run/netns/blue", + } + ], "dns": { "nameservers": [ "10.1.0.1" ] } @@ -364,28 +420,13 @@ Note that the runtime adds the `cniVersion` and `name` fields from configuration } ``` -Given the same network configuration JSON list, the container runtime would perform the following steps for the DEL action. -Note that no `prevResult` field is required as the DEL action does not return any result. -Also note that plugins are executed in reverse order from the ADD action. +Given the same network configuration JSON list, the container runtime would perform the following steps for the `GET` action. -1) first call the `tuning` plugin with the following JSON: +1) first call the `bridge` plugin with the following JSON, including the `prevResult` field containing the JSON response from the `ADD` operation: ```json { - "cniVersion": "0.3.1", - "name": "dbnet", - "type": "tuning", - "sysctl": { - "net.core.somaxconn": "500" - } -} -``` - -2) next call the `bridge` plugin with the following JSON: - -```json -{ - "cniVersion": "0.3.1", + "cniVersion": "0.4.0", "name": "dbnet", "type": "bridge", "bridge": "cni0", @@ -403,6 +444,168 @@ Also note that plugins are executed in reverse order from the ADD action. "dns": { "nameservers": [ "10.1.0.1" ] } + "prevResult": { + "ips": [ + { + "version": "4", + "address": "10.0.0.5/32", + "interface": 2 + } + ], + "interfaces": [ + { + "name": "cni0", + "mac": "00:11:22:33:44:55", + }, + { + "name": "veth3243", + "mac": "55:44:33:22:11:11", + }, + { + "name": "eth0", + "mac": "99:88:77:66:55:44", + "sandbox": "/var/run/netns/blue", + } + ], + "dns": { + "nameservers": [ "10.1.0.1" ] + } + } +} +``` + +2) next call the `tuning` plugin with the following JSON, including the `prevResult` field containing the JSON response from the `bridge` plugin: + +```json +{ + "cniVersion": "0.4.0", + "name": "dbnet", + "type": "tuning", + "sysctl": { + "net.core.somaxconn": "500" + }, + "prevResult": { + "ips": [ + { + "version": "4", + "address": "10.0.0.5/32", + "interface": 2 + } + ], + "interfaces": [ + { + "name": "cni0", + "mac": "00:11:22:33:44:55", + }, + { + "name": "veth3243", + "mac": "55:44:33:22:11:11", + }, + { + "name": "eth0", + "mac": "99:88:77:66:55:44", + "sandbox": "/var/run/netns/blue", + } + ], + "dns": { + "nameservers": [ "10.1.0.1" ] + } + } +} +``` + +Given the same network configuration JSON list, the container runtime would perform the following steps for the DEL action. +Note that plugins are executed in reverse order from the `ADD` and `GET` actions. + +1) first call the `tuning` plugin with the following JSON, including the `prevResult` field containing the JSON response from the `GET` action: + +```json +{ + "cniVersion": "0.4.0", + "name": "dbnet", + "type": "tuning", + "sysctl": { + "net.core.somaxconn": "500" + }, + "prevResult": { + "ips": [ + { + "version": "4", + "address": "10.0.0.5/32", + "interface": 2 + } + ], + "interfaces": [ + { + "name": "cni0", + "mac": "00:11:22:33:44:55", + }, + { + "name": "veth3243", + "mac": "55:44:33:22:11:11", + }, + { + "name": "eth0", + "mac": "99:88:77:66:55:44", + "sandbox": "/var/run/netns/blue", + } + ], + "dns": { + "nameservers": [ "10.1.0.1" ] + } + } +} +``` + +2) next call the `bridge` plugin with the following JSON, including the `prevResult` field containing the JSON response from the `GET` action: + +```json +{ + "cniVersion": "0.4.0", + "name": "dbnet", + "type": "bridge", + "bridge": "cni0", + "args": { + "labels" : { + "appVersion" : "1.0" + } + }, + "ipam": { + "type": "host-local", + // ipam specific + "subnet": "10.1.0.0/16", + "gateway": "10.1.0.1" + }, + "dns": { + "nameservers": [ "10.1.0.1" ] + }, + "prevResult": { + "ips": [ + { + "version": "4", + "address": "10.0.0.5/32", + "interface": 2 + } + ], + "interfaces": [ + { + "name": "cni0", + "mac": "00:11:22:33:44:55", + }, + { + "name": "veth3243", + "mac": "55:44:33:22:11:11", + }, + { + "name": "eth0", + "mac": "99:88:77:66:55:44", + "sandbox": "/var/run/netns/blue", + } + ], + "dns": { + "nameservers": [ "10.1.0.1" ] + } + } } ``` @@ -410,17 +613,17 @@ Also note that plugins are executed in reverse order from the ADD action. As part of its operation, a CNI plugin is expected to assign (and maintain) an IP address to the interface and install any necessary routes relevant for that interface. This gives the CNI plugin great flexibility but also places a large burden on it. Many CNI plugins would need to have the same code to support several IP management schemes that users may desire (e.g. dhcp, host-local). -To lessen the burden and make IP management strategy be orthogonal to the type of CNI plugin, we define a second type of plugin -- IP Address Management Plugin (IPAM plugin). It is however the responsibility of the CNI plugin to invoke the IPAM plugin at the proper moment in its execution. The IPAM plugin is expected to determine the interface IP/subnet, Gateway and Routes and return this information to the "main" plugin to apply. The IPAM plugin may obtain the information via a protocol (e.g. dhcp), data stored on a local filesystem, the "ipam" section of the Network Configuration file or a combination of the above. +To lessen the burden and make IP management strategy be orthogonal to the type of CNI plugin, we define a second type of plugin -- IP Address Management Plugin (IPAM plugin). It is however the responsibility of the CNI plugin to invoke the IPAM plugin at the proper moment in its execution. The IPAM plugin must determine the interface IP/subnet, Gateway and Routes and return this information to the "main" plugin to apply. The IPAM plugin may obtain the information via a protocol (e.g. dhcp), data stored on a local filesystem, the "ipam" section of the Network Configuration file or a combination of the above. #### IP Address Management (IPAM) Interface -Like CNI plugins, the IPAM plugins are invoked by running an executable. The executable is searched for in a predefined list of paths, indicated to the CNI plugin via `CNI_PATH`. The IPAM Plugin receives all the same environment variables that were passed in to the CNI plugin. Just like the CNI plugin, IPAM receives the network configuration via stdin. +Like CNI plugins, the IPAM plugins are invoked by running an executable. The executable is searched for in a predefined list of paths, indicated to the CNI plugin via `CNI_PATH`. The IPAM Plugin must receive all the same environment variables that were passed in to the CNI plugin. Just like the CNI plugin, IPAM plugins receive the network configuration via stdin. -Success is indicated by a zero return code and the following JSON being printed to stdout (in the case of the ADD command): +Success must be indicated by a zero return code and the following JSON being printed to stdout (in the case of the ADD command): ``` { - "cniVersion": "0.3.1", + "cniVersion": "0.4.0", "ips": [ { "version": "<4-or-6>", @@ -445,9 +648,9 @@ Success is indicated by a zero return code and the following JSON being printed } ``` -Note that unlike regular CNI plugins, IPAM plugins return an abbreviated `Result` structure that does not include the `interfaces` key, since IPAM plugins should be unaware of interfaces configured by their parent plugin except those specifically required for IPAM (eg, like the `dhcp` IPAM plugin). +Note that unlike regular CNI plugins, IPAM plugins should return an abbreviated `Result` structure that does not include the `interfaces` key, since IPAM plugins should be unaware of interfaces configured by their parent plugin except those specifically required for IPAM (eg, like the `dhcp` IPAM plugin). -`cniVersion` specifies a [Semantic Version 2.0](http://semver.org) of CNI specification used by the plugin. +`cniVersion` specifies a [Semantic Version 2.0](http://semver.org) of CNI specification used by the IPAM plugin. An IPAM plugin may support multiple CNI spec versions (as it reports via the `VERSION` command), here the `cniVersion` returned by the IPAM plugin in the result must be consistent with the `cniVersion` specified in [Network Configuration](#network-configuration). If the `cniVersion` in the network configuration is not supported by the IPAM plugin, the plugin should return an error code 1 (see [Well-known Error Codes](#well-known-error-codes) for details). The `ips` field is a list of IP configuration information. See the [IP well-known structure](#ips) section for more information. @@ -526,7 +729,11 @@ The `dns` field contains a dictionary consisting of common DNS information. - `search` (list of strings): list of priority ordered search domains for short hostname lookups. Will be preferred over `domain` by most resolvers. - `options` (list of strings): list of options that can be passed to the resolver. See [CNI Plugin Result](#result) section for more information. - + ## Well-known Error Codes + +Error codes 1-99 must not be used other than as specified here. + - `1` - Incompatible CNI version - `2` - Unsupported field in network configuration. The error message must contain the key and value of the unsupported field. +- `3` - Container unknown or does not exist. This error implies the runtime does not need to perform any container network cleanup (for example, calling the `DEL` action on the container). diff --git a/vendor/github.com/containernetworking/cni/Vagrantfile b/vendor/github.com/containernetworking/cni/Vagrantfile index 93b2866a6..210e4567e 100644 --- a/vendor/github.com/containernetworking/cni/Vagrantfile +++ b/vendor/github.com/containernetworking/cni/Vagrantfile @@ -10,11 +10,13 @@ Vagrant.configure(2) do |config| set -e -x -u apt-get update -y || (sleep 40 && apt-get update -y) - apt-get install -y golang git - echo "export GOPATH=/go" >> /root/.bashrc - export GOPATH=/go - go get github.com/tools/godep + apt-get install -y git + + wget -qO- https://storage.googleapis.com/golang/go1.10.linux-amd64.tar.gz | tar -C /usr/local -xz + + echo 'export GOPATH=/go; export PATH=/usr/local/go/bin:$GOPATH/bin:$PATH' >> /root/.bashrc + eval `tail -n1 /root/.bashrc` + cd /go/src/github.com/containernetworking/cni - /go/bin/godep restore SHELL end diff --git a/vendor/github.com/containernetworking/cni/build.sh b/vendor/github.com/containernetworking/cni/build.sh deleted file mode 100755 index d0e2885b2..000000000 --- a/vendor/github.com/containernetworking/cni/build.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash -set -e - -ORG_PATH="github.com/containernetworking" -REPO_PATH="${ORG_PATH}/cni" - -if [ ! -h gopath/src/${REPO_PATH} ]; then - mkdir -p gopath/src/${ORG_PATH} - ln -s ../../../.. gopath/src/${REPO_PATH} || exit 255 -fi - -export GO15VENDOREXPERIMENT=1 -export GOPATH=${PWD}/gopath - -echo "Building API" -go build "$@" ${REPO_PATH}/libcni - -echo "Building reference CLI" -go build -o ${PWD}/bin/cnitool "$@" ${REPO_PATH}/cnitool - -echo "Building plugins" -PLUGINS="plugins/meta/* plugins/main/* plugins/ipam/* plugins/test/*" -for d in $PLUGINS; do - if [ -d $d ]; then - plugin=$(basename $d) - echo " " $plugin - go build -o ${PWD}/bin/$plugin "$@" ${REPO_PATH}/$d - fi -done diff --git a/vendor/github.com/containernetworking/cni/cnitool/README.md b/vendor/github.com/containernetworking/cni/cnitool/README.md new file mode 100644 index 000000000..0b1956054 --- /dev/null +++ b/vendor/github.com/containernetworking/cni/cnitool/README.md @@ -0,0 +1,47 @@ +# cnitool + +`cnitool` is a simple program that executes a CNI configuration. It will +add or remove an interface in an already-created network namespace. + +## Example invocation +First, install cnitool: + +``` +go install github.com/containernetworking/cni/cnitool +``` + +Then, check out and build the plugins. All commands should be run from this directory. +``` +git clone https://github.com/containernetworking/plugins.git +cd plugins +./build.sh +``` + +Create a network configuration +``` +echo '{"cniVersion":"0.3.1","name":"myptp","type":"ptp","ipMasq":true,"ipam":{"type":"host-local","subnet":"172.16.29.0/24","routes":[{"dst":"0.0.0.0/0"}]}}' | sudo tee /etc/cni/net.d/10-myptp.conf +``` + +Create a network namespace. This will be called `testing`: + +``` +sudo ip netns add testing +``` + +Add the container to the network: +``` +sudo CNI_PATH=./bin cnitool add myptp /var/run/netns/testing +``` + +Test that it works: +``` +sudo ip -n testing addr +sudo ip netns exec testing ping -c 1 4.2.2.2 +``` + +And clean up: +``` +sudo CNI_PATH=./bin cnitool del myptp /var/run/netns/testing +sudo ip netns del testing +``` + diff --git a/vendor/github.com/containernetworking/cni/cnitool/cni.go b/vendor/github.com/containernetworking/cni/cnitool/cnitool.go similarity index 55% rename from vendor/github.com/containernetworking/cni/cnitool/cni.go rename to vendor/github.com/containernetworking/cni/cnitool/cnitool.go index 81128d5e4..f899e0257 100644 --- a/vendor/github.com/containernetworking/cni/cnitool/cni.go +++ b/vendor/github.com/containernetworking/cni/cnitool/cnitool.go @@ -15,16 +15,21 @@ package main import ( + "crypto/sha512" + "encoding/json" "fmt" "os" "path/filepath" + "strings" "github.com/containernetworking/cni/libcni" ) const ( - EnvCNIPath = "CNI_PATH" - EnvNetDir = "NETCONFPATH" + EnvCNIPath = "CNI_PATH" + EnvNetDir = "NETCONFPATH" + EnvCapabilityArgs = "CAP_ARGS" + EnvCNIArgs = "CNI_ARGS" DefaultNetDir = "/etc/cni/net.d" @@ -32,6 +37,22 @@ const ( CmdDel = "del" ) +func parseArgs(args string) ([][2]string, error) { + var result [][2]string + + pairs := strings.Split(args, ";") + for _, pair := range pairs { + kv := strings.Split(pair, "=") + if len(kv) != 2 || kv[0] == "" || kv[1] == "" { + return nil, fmt.Errorf("invalid CNI_ARGS pair %q", pair) + } + + result = append(result, [2]string{kv[0], kv[1]}) + } + + return result, nil +} + func main() { if len(os.Args) < 3 { usage() @@ -47,16 +68,41 @@ func main() { exit(err) } - netns := os.Args[3] - - cninet := &libcni.CNIConfig{ - Path: filepath.SplitList(os.Getenv(EnvCNIPath)), + var capabilityArgs map[string]interface{} + capabilityArgsValue := os.Getenv(EnvCapabilityArgs) + if len(capabilityArgsValue) > 0 { + if err = json.Unmarshal([]byte(capabilityArgsValue), &capabilityArgs); err != nil { + exit(err) + } } + var cniArgs [][2]string + args := os.Getenv(EnvCNIArgs) + if len(args) > 0 { + cniArgs, err = parseArgs(args) + if err != nil { + exit(err) + } + } + + netns := os.Args[3] + netns, err = filepath.Abs(netns) + if err != nil { + exit(err) + } + + // Generate the containerid by hashing the netns path + s := sha512.Sum512([]byte(netns)) + containerID := fmt.Sprintf("cnitool-%x", s[:10]) + + cninet := libcni.NewCNIConfig(filepath.SplitList(os.Getenv(EnvCNIPath)), nil) + rt := &libcni.RuntimeConf{ - ContainerID: "cni", - NetNS: netns, - IfName: "eth0", + ContainerID: containerID, + NetNS: netns, + IfName: "eth0", + Args: cniArgs, + CapabilityArgs: capabilityArgs, } switch os.Args[1] { diff --git a/vendor/github.com/containernetworking/cni/libcni/api.go b/vendor/github.com/containernetworking/cni/libcni/api.go index a23cbb2c5..d494e43d4 100644 --- a/vendor/github.com/containernetworking/cni/libcni/api.go +++ b/vendor/github.com/containernetworking/cni/libcni/api.go @@ -15,7 +15,11 @@ package libcni import ( + "encoding/json" + "fmt" + "io/ioutil" "os" + "path/filepath" "strings" "github.com/containernetworking/cni/pkg/invoke" @@ -23,6 +27,14 @@ import ( "github.com/containernetworking/cni/pkg/version" ) +var ( + CacheDir = "/var/lib/cni" +) + +// A RuntimeConf holds the arguments to one invocation of a CNI plugin +// excepting the network configuration, with the nested exception that +// the `runtimeConfig` from the network configuration is included +// here. type RuntimeConf struct { ContainerID string NetNS string @@ -34,6 +46,9 @@ type RuntimeConf struct { // in this map which match the capabilities of the plugin are passed // to the plugin CapabilityArgs map[string]interface{} + + // A cache directory in which to library data. Defaults to CacheDir + CacheDir string } type NetworkConfig struct { @@ -50,25 +65,38 @@ type NetworkConfigList struct { type CNI interface { AddNetworkList(net *NetworkConfigList, rt *RuntimeConf) (types.Result, error) + GetNetworkList(net *NetworkConfigList, rt *RuntimeConf) (types.Result, error) DelNetworkList(net *NetworkConfigList, rt *RuntimeConf) error AddNetwork(net *NetworkConfig, rt *RuntimeConf) (types.Result, error) + GetNetwork(net *NetworkConfig, rt *RuntimeConf) (types.Result, error) DelNetwork(net *NetworkConfig, rt *RuntimeConf) error } type CNIConfig struct { Path []string + exec invoke.Exec } // CNIConfig implements the CNI interface var _ CNI = &CNIConfig{} -func buildOneConfig(list *NetworkConfigList, orig *NetworkConfig, prevResult types.Result, rt *RuntimeConf) (*NetworkConfig, error) { +// NewCNIConfig returns a new CNIConfig object that will search for plugins +// in the given paths and use the given exec interface to run those plugins, +// or if the exec interface is not given, will use a default exec handler. +func NewCNIConfig(path []string, exec invoke.Exec) *CNIConfig { + return &CNIConfig{ + Path: path, + exec: exec, + } +} + +func buildOneConfig(name, cniVersion string, orig *NetworkConfig, prevResult types.Result, rt *RuntimeConf) (*NetworkConfig, error) { var err error inject := map[string]interface{}{ - "name": list.Name, - "cniVersion": list.CNIVersion, + "name": name, + "cniVersion": cniVersion, } // Add previous plugin result if prevResult != nil { @@ -119,21 +147,37 @@ func injectRuntimeConfig(orig *NetworkConfig, rt *RuntimeConf) (*NetworkConfig, return orig, nil } -// AddNetworkList executes a sequence of plugins with the ADD command -func (c *CNIConfig) AddNetworkList(list *NetworkConfigList, rt *RuntimeConf) (types.Result, error) { - var prevResult types.Result +// ensure we have a usable exec if the CNIConfig was not given one +func (c *CNIConfig) ensureExec() invoke.Exec { + if c.exec == nil { + c.exec = &invoke.DefaultExec{ + RawExec: &invoke.RawExec{Stderr: os.Stderr}, + PluginDecoder: version.PluginDecoder{}, + } + } + return c.exec +} + +func (c *CNIConfig) addOrGetNetwork(command, name, cniVersion string, net *NetworkConfig, prevResult types.Result, rt *RuntimeConf) (types.Result, error) { + c.ensureExec() + pluginPath, err := c.exec.FindInPath(net.Network.Type, c.Path) + if err != nil { + return nil, err + } + + newConf, err := buildOneConfig(name, cniVersion, net, prevResult, rt) + if err != nil { + return nil, err + } + + return invoke.ExecPluginWithResult(pluginPath, newConf.Bytes, c.args(command, rt), c.exec) +} + +// Note that only GET requests should pass an initial prevResult +func (c *CNIConfig) addOrGetNetworkList(command string, prevResult types.Result, list *NetworkConfigList, rt *RuntimeConf) (types.Result, error) { + var err error for _, net := range list.Plugins { - pluginPath, err := invoke.FindInPath(net.Network.Type, c.Path) - if err != nil { - return nil, err - } - - newConf, err := buildOneConfig(list, net, prevResult, rt) - if err != nil { - return nil, err - } - - prevResult, err = invoke.ExecPluginWithResult(pluginPath, newConf.Bytes, c.args("ADD", rt)) + prevResult, err = c.addOrGetNetwork(command, list.Name, list.CNIVersion, net, prevResult, rt) if err != nil { return nil, err } @@ -142,68 +186,194 @@ func (c *CNIConfig) AddNetworkList(list *NetworkConfigList, rt *RuntimeConf) (ty return prevResult, nil } +func getResultCacheFilePath(netName string, rt *RuntimeConf) string { + cacheDir := rt.CacheDir + if cacheDir == "" { + cacheDir = CacheDir + } + return filepath.Join(cacheDir, "results", fmt.Sprintf("%s-%s", netName, rt.ContainerID)) +} + +func setCachedResult(result types.Result, netName string, rt *RuntimeConf) error { + data, err := json.Marshal(result) + if err != nil { + return err + } + fname := getResultCacheFilePath(netName, rt) + if err := os.MkdirAll(filepath.Dir(fname), 0700); err != nil { + return err + } + return ioutil.WriteFile(fname, data, 0600) +} + +func delCachedResult(netName string, rt *RuntimeConf) error { + fname := getResultCacheFilePath(netName, rt) + return os.Remove(fname) +} + +func getCachedResult(netName, cniVersion string, rt *RuntimeConf) (types.Result, error) { + fname := getResultCacheFilePath(netName, rt) + data, err := ioutil.ReadFile(fname) + if err != nil { + // Ignore read errors; the cached result may not exist on-disk + return nil, nil + } + + // Read the version of the cached result + decoder := version.ConfigDecoder{} + resultCniVersion, err := decoder.Decode(data) + if err != nil { + return nil, err + } + + // Ensure we can understand the result + result, err := version.NewResult(resultCniVersion, data) + if err != nil { + return nil, err + } + + // Convert to the config version to ensure plugins get prevResult + // in the same version as the config. The cached result version + // should match the config version unless the config was changed + // while the container was running. + result, err = result.GetAsVersion(cniVersion) + if err != nil && resultCniVersion != cniVersion { + return nil, fmt.Errorf("failed to convert cached result version %q to config version %q: %v", resultCniVersion, cniVersion, err) + } + return result, err +} + +// AddNetworkList executes a sequence of plugins with the ADD command +func (c *CNIConfig) AddNetworkList(list *NetworkConfigList, rt *RuntimeConf) (types.Result, error) { + result, err := c.addOrGetNetworkList("ADD", nil, list, rt) + if err != nil { + return nil, err + } + + if err = setCachedResult(result, list.Name, rt); err != nil { + return nil, fmt.Errorf("failed to set network '%s' cached result: %v", list.Name, err) + } + + return result, nil +} + +// GetNetworkList executes a sequence of plugins with the GET command +func (c *CNIConfig) GetNetworkList(list *NetworkConfigList, rt *RuntimeConf) (types.Result, error) { + // GET was added in CNI spec version 0.4.0 and higher + if gtet, err := version.GreaterThanOrEqualTo(list.CNIVersion, "0.4.0"); err != nil { + return nil, err + } else if !gtet { + return nil, fmt.Errorf("configuration version %q does not support the GET command", list.CNIVersion) + } + + cachedResult, err := getCachedResult(list.Name, list.CNIVersion, rt) + if err != nil { + return nil, fmt.Errorf("failed to get network '%s' cached result: %v", list.Name, err) + } + return c.addOrGetNetworkList("GET", cachedResult, list, rt) +} + +func (c *CNIConfig) delNetwork(name, cniVersion string, net *NetworkConfig, prevResult types.Result, rt *RuntimeConf) error { + c.ensureExec() + pluginPath, err := c.exec.FindInPath(net.Network.Type, c.Path) + if err != nil { + return err + } + + newConf, err := buildOneConfig(name, cniVersion, net, prevResult, rt) + if err != nil { + return err + } + + return invoke.ExecPluginWithoutResult(pluginPath, newConf.Bytes, c.args("DEL", rt), c.exec) +} + // DelNetworkList executes a sequence of plugins with the DEL command func (c *CNIConfig) DelNetworkList(list *NetworkConfigList, rt *RuntimeConf) error { + var cachedResult types.Result + + // Cached result on DEL was added in CNI spec version 0.4.0 and higher + if gtet, err := version.GreaterThanOrEqualTo(list.CNIVersion, "0.4.0"); err != nil { + return err + } else if gtet { + cachedResult, err = getCachedResult(list.Name, list.CNIVersion, rt) + if err != nil { + return fmt.Errorf("failed to get network '%s' cached result: %v", list.Name, err) + } + } + for i := len(list.Plugins) - 1; i >= 0; i-- { net := list.Plugins[i] - - pluginPath, err := invoke.FindInPath(net.Network.Type, c.Path) - if err != nil { - return err - } - - newConf, err := buildOneConfig(list, net, nil, rt) - if err != nil { - return err - } - - if err := invoke.ExecPluginWithoutResult(pluginPath, newConf.Bytes, c.args("DEL", rt)); err != nil { + if err := c.delNetwork(list.Name, list.CNIVersion, net, cachedResult, rt); err != nil { return err } } + _ = delCachedResult(list.Name, rt) return nil } // AddNetwork executes the plugin with the ADD command func (c *CNIConfig) AddNetwork(net *NetworkConfig, rt *RuntimeConf) (types.Result, error) { - pluginPath, err := invoke.FindInPath(net.Network.Type, c.Path) + result, err := c.addOrGetNetwork("ADD", net.Network.Name, net.Network.CNIVersion, net, nil, rt) if err != nil { return nil, err } - net, err = injectRuntimeConfig(net, rt) - if err != nil { - return nil, err + if err = setCachedResult(result, net.Network.Name, rt); err != nil { + return nil, fmt.Errorf("failed to set network '%s' cached result: %v", net.Network.Name, err) } - return invoke.ExecPluginWithResult(pluginPath, net.Bytes, c.args("ADD", rt)) + return result, nil +} + +// GetNetwork executes the plugin with the GET command +func (c *CNIConfig) GetNetwork(net *NetworkConfig, rt *RuntimeConf) (types.Result, error) { + // GET was added in CNI spec version 0.4.0 and higher + if gtet, err := version.GreaterThanOrEqualTo(net.Network.CNIVersion, "0.4.0"); err != nil { + return nil, err + } else if !gtet { + return nil, fmt.Errorf("configuration version %q does not support the GET command", net.Network.CNIVersion) + } + + cachedResult, err := getCachedResult(net.Network.Name, net.Network.CNIVersion, rt) + if err != nil { + return nil, fmt.Errorf("failed to get network '%s' cached result: %v", net.Network.Name, err) + } + return c.addOrGetNetwork("GET", net.Network.Name, net.Network.CNIVersion, net, cachedResult, rt) } // DelNetwork executes the plugin with the DEL command func (c *CNIConfig) DelNetwork(net *NetworkConfig, rt *RuntimeConf) error { - pluginPath, err := invoke.FindInPath(net.Network.Type, c.Path) - if err != nil { + var cachedResult types.Result + + // Cached result on DEL was added in CNI spec version 0.4.0 and higher + if gtet, err := version.GreaterThanOrEqualTo(net.Network.CNIVersion, "0.4.0"); err != nil { return err + } else if gtet { + cachedResult, err = getCachedResult(net.Network.Name, net.Network.CNIVersion, rt) + if err != nil { + return fmt.Errorf("failed to get network '%s' cached result: %v", net.Network.Name, err) + } } - net, err = injectRuntimeConfig(net, rt) - if err != nil { + if err := c.delNetwork(net.Network.Name, net.Network.CNIVersion, net, cachedResult, rt); err != nil { return err } - - return invoke.ExecPluginWithoutResult(pluginPath, net.Bytes, c.args("DEL", rt)) + _ = delCachedResult(net.Network.Name, rt) + return nil } // GetVersionInfo reports which versions of the CNI spec are supported by // the given plugin. func (c *CNIConfig) GetVersionInfo(pluginType string) (version.PluginInfo, error) { - pluginPath, err := invoke.FindInPath(pluginType, c.Path) + c.ensureExec() + pluginPath, err := c.exec.FindInPath(pluginType, c.Path) if err != nil { return nil, err } - return invoke.GetVersionInfo(pluginPath) + return invoke.GetVersionInfo(pluginPath, c.exec) } // ===== diff --git a/vendor/github.com/containernetworking/cni/libcni/api_test.go b/vendor/github.com/containernetworking/cni/libcni/api_test.go index a66453db4..483720ed4 100644 --- a/vendor/github.com/containernetworking/cni/libcni/api_test.go +++ b/vendor/github.com/containernetworking/cni/libcni/api_test.go @@ -72,7 +72,7 @@ func newPluginInfo(configValue, prevResult string, injectDebugFilePath bool, res config += fmt.Sprintf(`, "prevResult": %s`, prevResult) } if injectDebugFilePath { - config += fmt.Sprintf(`, "debugFile": "%s"`, debugFilePath) + config += fmt.Sprintf(`, "debugFile": %q`, debugFilePath) } if len(capabilities) > 0 { config += `, "capabilities": {` @@ -92,7 +92,7 @@ func newPluginInfo(configValue, prevResult string, injectDebugFilePath bool, res err = json.Unmarshal([]byte(config), &newConfig) Expect(err).NotTo(HaveOccurred()) newConfig["name"] = "some-list" - newConfig["cniVersion"] = "0.3.1" + newConfig["cniVersion"] = current.ImplementedSpecVersion // Only include standard runtime config and capability args that this plugin advertises newRuntimeConfig := make(map[string]interface{}) @@ -116,13 +116,29 @@ func newPluginInfo(configValue, prevResult string, injectDebugFilePath bool, res } } +func resultCacheFilePath(cacheDirPath, netName, containerID string) string { + return filepath.Join(cacheDirPath, "results", netName+"-"+containerID) +} + var _ = Describe("Invoking plugins", func() { + var cacheDirPath string + + BeforeEach(func() { + var err error + cacheDirPath, err = ioutil.TempDir("", "cni_cachedir") + Expect(err).NotTo(HaveOccurred()) + }) + + AfterEach(func() { + Expect(os.RemoveAll(cacheDirPath)).To(Succeed()) + }) + Describe("Capabilities", func() { var ( debugFilePath string debug *noop_debug.Debug pluginConfig []byte - cniConfig libcni.CNIConfig + cniConfig *libcni.CNIConfig runtimeConfig *libcni.RuntimeConf netConfig *libcni.NetworkConfig ) @@ -136,11 +152,20 @@ var _ = Describe("Invoking plugins", func() { debug = &noop_debug.Debug{} Expect(debug.WriteDebug(debugFilePath)).To(Succeed()) - pluginConfig = []byte(`{ "type": "noop", "cniVersion": "0.3.1", "capabilities": { "portMappings": true, "somethingElse": true, "noCapability": false } }`) + pluginConfig = []byte(fmt.Sprintf(`{ + "type": "noop", + "name": "apitest", + "cniVersion": "%s", + "capabilities": { + "portMappings": true, + "somethingElse": true, + "noCapability": false + } + }`, current.ImplementedSpecVersion)) netConfig, err = libcni.ConfFromBytes(pluginConfig) Expect(err).NotTo(HaveOccurred()) - cniConfig = libcni.CNIConfig{Path: []string{filepath.Dir(pluginPaths["noop"])}} + cniConfig = libcni.NewCNIConfig([]string{filepath.Dir(pluginPaths["noop"])}, nil) runtimeConfig = &libcni.RuntimeConf{ ContainerID: "some-container-id", @@ -155,6 +180,7 @@ var _ = Describe("Invoking plugins", func() { "noCapability": true, "notAdded": []bool{true, false}, }, + CacheDir: cacheDirPath, } }) @@ -220,7 +246,7 @@ var _ = Describe("Invoking plugins", func() { debug *noop_debug.Debug cniBinPath string pluginConfig string - cniConfig libcni.CNIConfig + cniConfig *libcni.CNIConfig netConfig *libcni.NetworkConfig runtimeConfig *libcni.RuntimeConf @@ -234,7 +260,11 @@ var _ = Describe("Invoking plugins", func() { debugFilePath = debugFile.Name() debug = &noop_debug.Debug{ - ReportResult: `{ "ips": [{ "version": "4", "address": "10.1.2.3/24" }], "dns": {} }`, + ReportResult: `{ + "cniVersion": "0.4.0", + "ips": [{"version": "4", "address": "10.1.2.3/24"}], + "dns": {} + }`, } Expect(debug.WriteDebug(debugFilePath)).To(Succeed()) @@ -243,21 +273,21 @@ var _ = Describe("Invoking plugins", func() { } cniBinPath = filepath.Dir(pluginPaths["noop"]) - pluginConfig = `{ "type": "noop", "some-key": "some-value", "cniVersion": "0.3.1", "capabilities": { "portMappings": true } }` - cniConfig = libcni.CNIConfig{Path: []string{cniBinPath}} - netConfig = &libcni.NetworkConfig{ - Network: &types.NetConf{ - Type: "noop", - Capabilities: map[string]bool{ - "portMappings": true, - }, - }, - Bytes: []byte(pluginConfig), - } + pluginConfig = fmt.Sprintf(`{ + "type": "noop", + "name": "apitest", + "some-key": "some-value", + "cniVersion": "%s", + "capabilities": { "portMappings": true } + }`, current.ImplementedSpecVersion) + cniConfig = libcni.NewCNIConfig([]string{cniBinPath}, nil) + netConfig, err = libcni.ConfFromBytes([]byte(pluginConfig)) + Expect(err).NotTo(HaveOccurred()) runtimeConfig = &libcni.RuntimeConf{ ContainerID: "some-container-id", NetNS: "/some/netns/path", IfName: "some-eth0", + CacheDir: cacheDirPath, Args: [][2]string{{"DEBUG", debugFilePath}}, CapabilityArgs: map[string]interface{}{ "portMappings": portMappings, @@ -297,6 +327,7 @@ var _ = Describe("Invoking plugins", func() { Expect(err).NotTo(HaveOccurred()) Expect(result).To(Equal(¤t.Result{ + CNIVersion: current.ImplementedSpecVersion, IPs: []*current.IPConfig{ { Version: "4", @@ -313,6 +344,16 @@ var _ = Describe("Invoking plugins", func() { Expect(debug.Command).To(Equal("ADD")) Expect(debug.CmdArgs).To(Equal(expectedCmdArgs)) Expect(string(debug.CmdArgs.StdinData)).To(ContainSubstring("\"portMappings\":")) + + // Ensure the cached result matches the returned one + cacheFile := resultCacheFilePath(cacheDirPath, netConfig.Network.Name, runtimeConfig.ContainerID) + _, err = os.Stat(cacheFile) + Expect(err).NotTo(HaveOccurred()) + cachedData, err := ioutil.ReadFile(cacheFile) + Expect(err).NotTo(HaveOccurred()) + returnedData, err := json.Marshal(result) + Expect(err).NotTo(HaveOccurred()) + Expect(cachedData).To(MatchJSON(returnedData)) }) Context("when finding the plugin fails", func() { @@ -337,18 +378,231 @@ var _ = Describe("Invoking plugins", func() { Expect(err).To(MatchError("plugin error: banana")) }) }) + + Context("when the result cache directory cannot be accessed", func() { + It("returns an error", func() { + // Make the results directory inaccessble by making it a + // file instead of a directory + tmpPath := filepath.Join(cacheDirPath, "results") + err := ioutil.WriteFile(tmpPath, []byte("afdsasdfasdf"), 0600) + Expect(err).NotTo(HaveOccurred()) + + result, err := cniConfig.AddNetwork(netConfig, runtimeConfig) + Expect(result).To(BeNil()) + Expect(err).To(HaveOccurred()) + }) + }) + }) + + Describe("GetNetwork", func() { + It("executes the plugin with command GET", func() { + cacheFile := resultCacheFilePath(cacheDirPath, netConfig.Network.Name, runtimeConfig.ContainerID) + err := os.MkdirAll(filepath.Dir(cacheFile), 0700) + Expect(err).NotTo(HaveOccurred()) + cachedJson := `{ + "cniVersion": "0.4.0", + "ips": [{"version": "4", "address": "10.1.2.3/24"}], + "dns": {} + }` + err = ioutil.WriteFile(cacheFile, []byte(cachedJson), 0600) + Expect(err).NotTo(HaveOccurred()) + + r, err := cniConfig.GetNetwork(netConfig, runtimeConfig) + Expect(err).NotTo(HaveOccurred()) + + result, err := current.GetResult(r) + Expect(err).NotTo(HaveOccurred()) + + Expect(result).To(Equal(¤t.Result{ + CNIVersion: current.ImplementedSpecVersion, + IPs: []*current.IPConfig{ + { + Version: "4", + Address: net.IPNet{ + IP: net.ParseIP("10.1.2.3"), + Mask: net.IPv4Mask(255, 255, 255, 0), + }, + }, + }, + })) + + debug, err := noop_debug.ReadDebug(debugFilePath) + Expect(err).NotTo(HaveOccurred()) + Expect(debug.Command).To(Equal("GET")) + Expect(string(debug.CmdArgs.StdinData)).To(ContainSubstring("\"portMappings\":")) + + // Explicitly match stdin data as json after + // inserting the expected prevResult + var data, data2 map[string]interface{} + err = json.Unmarshal(expectedCmdArgs.StdinData, &data) + Expect(err).NotTo(HaveOccurred()) + err = json.Unmarshal([]byte(cachedJson), &data2) + Expect(err).NotTo(HaveOccurred()) + data["prevResult"] = data2 + expectedStdinJson, err := json.Marshal(data) + Expect(err).NotTo(HaveOccurred()) + Expect(debug.CmdArgs.StdinData).To(MatchJSON(expectedStdinJson)) + + debug.CmdArgs.StdinData = nil + expectedCmdArgs.StdinData = nil + Expect(debug.CmdArgs).To(Equal(expectedCmdArgs)) + }) + + Context("when finding the plugin fails", func() { + BeforeEach(func() { + netConfig.Network.Type = "does-not-exist" + }) + + It("returns the error", func() { + _, err := cniConfig.GetNetwork(netConfig, runtimeConfig) + Expect(err).To(MatchError(ContainSubstring(`failed to find plugin "does-not-exist"`))) + }) + }) + + Context("when the plugin errors", func() { + BeforeEach(func() { + debug.ReportError = "plugin error: banana" + Expect(debug.WriteDebug(debugFilePath)).To(Succeed()) + }) + It("unmarshals and returns the error", func() { + result, err := cniConfig.GetNetwork(netConfig, runtimeConfig) + Expect(result).To(BeNil()) + Expect(err).To(MatchError("plugin error: banana")) + }) + }) + + Context("when GET is called with a configuration version", func() { + var cacheFile string + + BeforeEach(func() { + cacheFile = resultCacheFilePath(cacheDirPath, netConfig.Network.Name, runtimeConfig.ContainerID) + err := os.MkdirAll(filepath.Dir(cacheFile), 0700) + Expect(err).NotTo(HaveOccurred()) + }) + + Context("less than 0.4.0", func() { + It("fails as GET is not supported before 0.4.0", func() { + // Generate plugin config with older version + pluginConfig = `{ + "type": "noop", + "name": "apitest", + "cniVersion": "0.3.1" + }` + var err error + netConfig, err = libcni.ConfFromBytes([]byte(pluginConfig)) + Expect(err).NotTo(HaveOccurred()) + _, err = cniConfig.GetNetwork(netConfig, runtimeConfig) + Expect(err).To(MatchError("configuration version \"0.3.1\" does not support the GET command")) + + debug, err := noop_debug.ReadDebug(debugFilePath) + Expect(err).NotTo(HaveOccurred()) + Expect(string(debug.CmdArgs.StdinData)).NotTo(ContainSubstring("\"prevResult\":")) + }) + }) + + Context("equal to 0.4.0", func() { + It("passes a prevResult to the plugin", func() { + err := ioutil.WriteFile(cacheFile, []byte(`{ + "cniVersion": "0.4.0", + "ips": [{"version": "4", "address": "10.1.2.3/24"}], + "dns": {} + }`), 0600) + Expect(err).NotTo(HaveOccurred()) + + _, err = cniConfig.GetNetwork(netConfig, runtimeConfig) + Expect(err).NotTo(HaveOccurred()) + debug, err := noop_debug.ReadDebug(debugFilePath) + Expect(err).NotTo(HaveOccurred()) + Expect(string(debug.CmdArgs.StdinData)).To(ContainSubstring("\"prevResult\":")) + }) + }) + }) + + Context("when the cached result", func() { + var cacheFile string + + BeforeEach(func() { + cacheFile = resultCacheFilePath(cacheDirPath, netConfig.Network.Name, runtimeConfig.ContainerID) + err := os.MkdirAll(filepath.Dir(cacheFile), 0700) + Expect(err).NotTo(HaveOccurred()) + }) + + Context("is invalid JSON", func() { + It("returns an error", func() { + err := ioutil.WriteFile(cacheFile, []byte("adfadsfasdfasfdsafaf"), 0600) + Expect(err).NotTo(HaveOccurred()) + + result, err := cniConfig.GetNetwork(netConfig, runtimeConfig) + Expect(result).To(BeNil()) + Expect(err).To(MatchError("failed to get network 'apitest' cached result: decoding version from network config: invalid character 'a' looking for beginning of value")) + }) + }) + + Context("version doesn't match the config version", func() { + It("succeeds when the cached result can be converted", func() { + err := ioutil.WriteFile(cacheFile, []byte(`{ + "cniVersion": "0.3.1", + "ips": [{"version": "4", "address": "10.1.2.3/24"}], + "dns": {} + }`), 0600) + Expect(err).NotTo(HaveOccurred()) + + _, err = cniConfig.GetNetwork(netConfig, runtimeConfig) + Expect(err).NotTo(HaveOccurred()) + }) + + It("returns an error when the cached result cannot be converted", func() { + err := ioutil.WriteFile(cacheFile, []byte(`{ + "cniVersion": "0.4567.0", + "ips": [{"version": "4", "address": "10.1.2.3/24"}], + "dns": {} + }`), 0600) + Expect(err).NotTo(HaveOccurred()) + + result, err := cniConfig.GetNetwork(netConfig, runtimeConfig) + Expect(result).To(BeNil()) + Expect(err).To(MatchError("failed to get network 'apitest' cached result: unsupported CNI result version \"0.4567.0\"")) + }) + }) + }) }) Describe("DelNetwork", func() { It("executes the plugin with command DEL", func() { - err := cniConfig.DelNetwork(netConfig, runtimeConfig) + cacheFile := resultCacheFilePath(cacheDirPath, netConfig.Network.Name, runtimeConfig.ContainerID) + err := os.MkdirAll(filepath.Dir(cacheFile), 0700) + Expect(err).NotTo(HaveOccurred()) + cachedJson := `{ + "cniVersion": "0.4.0", + "ips": [{"version": "4", "address": "10.1.2.3/24"}], + "dns": {} + }` + err = ioutil.WriteFile(cacheFile, []byte(cachedJson), 0600) + Expect(err).NotTo(HaveOccurred()) + + err = cniConfig.DelNetwork(netConfig, runtimeConfig) Expect(err).NotTo(HaveOccurred()) debug, err := noop_debug.ReadDebug(debugFilePath) Expect(err).NotTo(HaveOccurred()) Expect(debug.Command).To(Equal("DEL")) - Expect(debug.CmdArgs).To(Equal(expectedCmdArgs)) Expect(string(debug.CmdArgs.StdinData)).To(ContainSubstring("\"portMappings\":")) + + // Explicitly match stdin data as json after + // inserting the expected prevResult + var data, data2 map[string]interface{} + err = json.Unmarshal(expectedCmdArgs.StdinData, &data) + Expect(err).NotTo(HaveOccurred()) + err = json.Unmarshal([]byte(cachedJson), &data2) + Expect(err).NotTo(HaveOccurred()) + data["prevResult"] = data2 + expectedStdinJson, err := json.Marshal(data) + Expect(err).NotTo(HaveOccurred()) + Expect(debug.CmdArgs.StdinData).To(MatchJSON(expectedStdinJson)) + + debug.CmdArgs.StdinData = nil + expectedCmdArgs.StdinData = nil + Expect(debug.CmdArgs).To(Equal(expectedCmdArgs)) }) Context("when finding the plugin fails", func() { @@ -372,6 +626,135 @@ var _ = Describe("Invoking plugins", func() { Expect(err).To(MatchError("plugin error: banana")) }) }) + + Context("when DEL is called twice", func() { + var cacheFile string + + BeforeEach(func() { + cacheFile = resultCacheFilePath(cacheDirPath, netConfig.Network.Name, runtimeConfig.ContainerID) + err := os.MkdirAll(filepath.Dir(cacheFile), 0700) + Expect(err).NotTo(HaveOccurred()) + }) + + It("deletes the cached result after the first DEL", func() { + err := ioutil.WriteFile(cacheFile, []byte(`{ + "cniVersion": "0.4.0", + "ips": [{"version": "4", "address": "10.1.2.3/24"}], + "dns": {} + }`), 0600) + Expect(err).NotTo(HaveOccurred()) + + err = cniConfig.DelNetwork(netConfig, runtimeConfig) + Expect(err).NotTo(HaveOccurred()) + _, err = ioutil.ReadFile(cacheFile) + Expect(err).To(HaveOccurred()) + + err = cniConfig.DelNetwork(netConfig, runtimeConfig) + Expect(err).NotTo(HaveOccurred()) + }) + }) + + Context("when DEL is called with a configuration version", func() { + var cacheFile string + + BeforeEach(func() { + cacheFile = resultCacheFilePath(cacheDirPath, netConfig.Network.Name, runtimeConfig.ContainerID) + err := os.MkdirAll(filepath.Dir(cacheFile), 0700) + Expect(err).NotTo(HaveOccurred()) + }) + + Context("less than 0.4.0", func() { + It("does not pass a prevResult to the plugin", func() { + err := ioutil.WriteFile(cacheFile, []byte(`{ + "cniVersion": "0.3.1", + "ips": [{"version": "4", "address": "10.1.2.3/24"}], + "dns": {} + }`), 0600) + Expect(err).NotTo(HaveOccurred()) + + // Generate plugin config with older version + pluginConfig = `{ + "type": "noop", + "name": "apitest", + "cniVersion": "0.3.1" + }` + netConfig, err = libcni.ConfFromBytes([]byte(pluginConfig)) + Expect(err).NotTo(HaveOccurred()) + err = cniConfig.DelNetwork(netConfig, runtimeConfig) + Expect(err).NotTo(HaveOccurred()) + + debug, err := noop_debug.ReadDebug(debugFilePath) + Expect(err).NotTo(HaveOccurred()) + Expect(debug.Command).To(Equal("DEL")) + Expect(string(debug.CmdArgs.StdinData)).NotTo(ContainSubstring("\"prevResult\":")) + }) + }) + + Context("equal to 0.4.0", func() { + It("passes a prevResult to the plugin", func() { + err := ioutil.WriteFile(cacheFile, []byte(`{ + "cniVersion": "0.4.0", + "ips": [{"version": "4", "address": "10.1.2.3/24"}], + "dns": {} + }`), 0600) + Expect(err).NotTo(HaveOccurred()) + + err = cniConfig.DelNetwork(netConfig, runtimeConfig) + Expect(err).NotTo(HaveOccurred()) + + debug, err := noop_debug.ReadDebug(debugFilePath) + Expect(err).NotTo(HaveOccurred()) + Expect(debug.Command).To(Equal("DEL")) + Expect(string(debug.CmdArgs.StdinData)).To(ContainSubstring("\"prevResult\":")) + }) + }) + }) + + Context("when the cached result", func() { + var cacheFile string + + BeforeEach(func() { + cacheFile = resultCacheFilePath(cacheDirPath, netConfig.Network.Name, runtimeConfig.ContainerID) + err := os.MkdirAll(filepath.Dir(cacheFile), 0700) + Expect(err).NotTo(HaveOccurred()) + }) + + Context("is invalid JSON", func() { + It("returns an error", func() { + err := ioutil.WriteFile(cacheFile, []byte("adfadsfasdfasfdsafaf"), 0600) + Expect(err).NotTo(HaveOccurred()) + + err = cniConfig.DelNetwork(netConfig, runtimeConfig) + Expect(err).To(MatchError("failed to get network 'apitest' cached result: decoding version from network config: invalid character 'a' looking for beginning of value")) + }) + }) + + Context("version doesn't match the config version", func() { + It("succeeds when the cached result can be converted", func() { + err := ioutil.WriteFile(cacheFile, []byte(`{ + "cniVersion": "0.3.1", + "ips": [{"version": "4", "address": "10.1.2.3/24"}], + "dns": {} + }`), 0600) + Expect(err).NotTo(HaveOccurred()) + + err = cniConfig.DelNetwork(netConfig, runtimeConfig) + Expect(err).NotTo(HaveOccurred()) + }) + + It("returns an error when the cached result cannot be converted", func() { + err := ioutil.WriteFile(cacheFile, []byte(`{ + "cniVersion": "0.4567.0", + "ips": [{"version": "4", "address": "10.1.2.3/24"}], + "dns": {} + }`), 0600) + Expect(err).NotTo(HaveOccurred()) + + err = cniConfig.DelNetwork(netConfig, runtimeConfig) + Expect(err).To(MatchError("failed to get network 'apitest' cached result: unsupported CNI result version \"0.4567.0\"")) + }) + }) + }) }) Describe("GetVersionInfo", func() { @@ -381,7 +764,7 @@ var _ = Describe("Invoking plugins", func() { Expect(versionInfo).NotTo(BeNil()) Expect(versionInfo.SupportedVersions()).To(Equal([]string{ - "0.-42.0", "0.1.0", "0.2.0", "0.3.0", "0.3.1", + "0.-42.0", "0.1.0", "0.2.0", "0.3.0", "0.3.1", "0.4.0", })) }) @@ -398,7 +781,7 @@ var _ = Describe("Invoking plugins", func() { var ( plugins []pluginInfo cniBinPath string - cniConfig libcni.CNIConfig + cniConfig *libcni.CNIConfig netConfigList *libcni.NetworkConfigList runtimeConfig *libcni.RuntimeConf @@ -416,13 +799,14 @@ var _ = Describe("Invoking plugins", func() { } cniBinPath = filepath.Dir(pluginPaths["noop"]) - cniConfig = libcni.CNIConfig{Path: []string{cniBinPath}} + cniConfig = libcni.NewCNIConfig([]string{cniBinPath}, nil) runtimeConfig = &libcni.RuntimeConf{ ContainerID: "some-container-id", NetNS: "/some/netns/path", IfName: "some-eth0", Args: [][2]string{{"FOO", "BAR"}}, CapabilityArgs: capabilityArgs, + CacheDir: cacheDirPath, } expectedCmdArgs = skel.CmdArgs{ @@ -444,7 +828,7 @@ var _ = Describe("Invoking plugins", func() { "otherCapability": capabilityArgs["otherCapability"], } - ipResult := `{"dns":{},"ips":[{"version": "4", "address": "10.1.2.3/24"}]}` + ipResult := fmt.Sprintf(`{"cniVersion": "%s", "dns":{},"ips":[{"version": "4", "address": "10.1.2.3/24"}]}`, current.ImplementedSpecVersion) plugins = make([]pluginInfo, 3, 3) plugins[0] = newPluginInfo("some-value", "", true, ipResult, rc, []string{"portMappings", "otherCapability"}) plugins[1] = newPluginInfo("some-other-value", ipResult, true, "PASSTHROUGH", rc, []string{"otherCapability"}) @@ -452,13 +836,13 @@ var _ = Describe("Invoking plugins", func() { configList := []byte(fmt.Sprintf(`{ "name": "some-list", - "cniVersion": "0.3.1", + "cniVersion": "%s", "plugins": [ %s, %s, %s ] -}`, plugins[0].config, plugins[1].config, plugins[2].config)) +}`, current.ImplementedSpecVersion, plugins[0].config, plugins[1].config, plugins[2].config)) netConfigList, err = libcni.ConfListFromBytes(configList) Expect(err).NotTo(HaveOccurred()) @@ -479,6 +863,7 @@ var _ = Describe("Invoking plugins", func() { Expect(err).NotTo(HaveOccurred()) Expect(result).To(Equal(¤t.Result{ + CNIVersion: current.ImplementedSpecVersion, // IP4 added by first plugin IPs: []*current.IPConfig{ { @@ -507,6 +892,24 @@ var _ = Describe("Invoking plugins", func() { } }) + It("writes the correct cached result", func() { + r, err := cniConfig.AddNetworkList(netConfigList, runtimeConfig) + Expect(err).NotTo(HaveOccurred()) + + result, err := current.GetResult(r) + Expect(err).NotTo(HaveOccurred()) + + // Ensure the cached result matches the returned one + cacheFile := resultCacheFilePath(cacheDirPath, netConfigList.Name, runtimeConfig.ContainerID) + _, err = os.Stat(cacheFile) + Expect(err).NotTo(HaveOccurred()) + cachedData, err := ioutil.ReadFile(cacheFile) + Expect(err).NotTo(HaveOccurred()) + returnedData, err := json.Marshal(result) + Expect(err).NotTo(HaveOccurred()) + Expect(cachedData).To(MatchJSON(returnedData)) + }) + Context("when finding the plugin fails", func() { BeforeEach(func() { netConfigList.Plugins[1].Network.Type = "does-not-exist" @@ -529,6 +932,149 @@ var _ = Describe("Invoking plugins", func() { Expect(err).To(MatchError("plugin error: banana")) }) }) + + Context("when the result cache directory cannot be accessed", func() { + It("returns an error", func() { + // Make the results directory inaccessble by making it a + // file instead of a directory + tmpPath := filepath.Join(cacheDirPath, "results") + err := ioutil.WriteFile(tmpPath, []byte("afdsasdfasdf"), 0600) + Expect(err).NotTo(HaveOccurred()) + + result, err := cniConfig.AddNetworkList(netConfigList, runtimeConfig) + Expect(result).To(BeNil()) + Expect(err).To(HaveOccurred()) + }) + }) + }) + + Describe("GetNetworkList", func() { + It("executes all plugins with command GET and returns an intermediate result", func() { + r, err := cniConfig.GetNetworkList(netConfigList, runtimeConfig) + Expect(err).NotTo(HaveOccurred()) + + result, err := current.GetResult(r) + Expect(err).NotTo(HaveOccurred()) + + Expect(result).To(Equal(¤t.Result{ + CNIVersion: current.ImplementedSpecVersion, + // IP4 added by first plugin + IPs: []*current.IPConfig{ + { + Version: "4", + Address: net.IPNet{ + IP: net.ParseIP("10.1.2.3"), + Mask: net.IPv4Mask(255, 255, 255, 0), + }, + }, + }, + // DNS injected by last plugin + DNS: types.DNS{ + Nameservers: []string{"1.2.3.4"}, + }, + })) + + for i := 0; i < len(plugins); i++ { + debug, err := noop_debug.ReadDebug(plugins[i].debugFilePath) + Expect(err).NotTo(HaveOccurred()) + Expect(debug.Command).To(Equal("GET")) + + // Must explicitly match JSON due to dict element ordering + Expect(debug.CmdArgs.StdinData).To(MatchJSON(plugins[i].stdinData)) + debug.CmdArgs.StdinData = nil + Expect(debug.CmdArgs).To(Equal(expectedCmdArgs)) + } + }) + + Context("when the configuration version", func() { + var cacheFile string + + BeforeEach(func() { + cacheFile = resultCacheFilePath(cacheDirPath, netConfigList.Name, runtimeConfig.ContainerID) + err := os.MkdirAll(filepath.Dir(cacheFile), 0700) + Expect(err).NotTo(HaveOccurred()) + }) + + Context("is 0.4.0", func() { + It("passes a cached result to the first plugin", func() { + cachedJson := `{ + "cniVersion": "0.4.0", + "ips": [{"version": "4", "address": "10.1.2.3/24"}], + "dns": {} + }` + err := ioutil.WriteFile(cacheFile, []byte(cachedJson), 0600) + Expect(err).NotTo(HaveOccurred()) + + _, err = cniConfig.GetNetworkList(netConfigList, runtimeConfig) + Expect(err).NotTo(HaveOccurred()) + + // Match the first plugin's stdin config to the cached result JSON + debug, err := noop_debug.ReadDebug(plugins[0].debugFilePath) + Expect(err).NotTo(HaveOccurred()) + + var data map[string]interface{} + err = json.Unmarshal(debug.CmdArgs.StdinData, &data) + Expect(err).NotTo(HaveOccurred()) + stdinPrevResult, err := json.Marshal(data["prevResult"]) + Expect(err).NotTo(HaveOccurred()) + Expect(stdinPrevResult).To(MatchJSON(cachedJson)) + }) + }) + + Context("is less than 0.4.0", func() { + It("fails as GET is not supported before 0.4.0", func() { + // Set an older CNI version + confList := make(map[string]interface{}) + err := json.Unmarshal(netConfigList.Bytes, &confList) + Expect(err).NotTo(HaveOccurred()) + confList["cniVersion"] = "0.3.1" + newBytes, err := json.Marshal(confList) + Expect(err).NotTo(HaveOccurred()) + + netConfigList, err = libcni.ConfListFromBytes(newBytes) + Expect(err).NotTo(HaveOccurred()) + _, err = cniConfig.GetNetworkList(netConfigList, runtimeConfig) + Expect(err).To(MatchError("configuration version \"0.3.1\" does not support the GET command")) + }) + }) + }) + + Context("when finding the plugin fails", func() { + BeforeEach(func() { + netConfigList.Plugins[1].Network.Type = "does-not-exist" + }) + + It("returns the error", func() { + _, err := cniConfig.GetNetworkList(netConfigList, runtimeConfig) + Expect(err).To(MatchError(ContainSubstring(`failed to find plugin "does-not-exist"`))) + }) + }) + + Context("when the second plugin errors", func() { + BeforeEach(func() { + plugins[1].debug.ReportError = "plugin error: banana" + Expect(plugins[1].debug.WriteDebug(plugins[1].debugFilePath)).To(Succeed()) + }) + It("unmarshals and returns the error", func() { + result, err := cniConfig.GetNetworkList(netConfigList, runtimeConfig) + Expect(result).To(BeNil()) + Expect(err).To(MatchError("plugin error: banana")) + }) + }) + + Context("when the cached result is invalid", func() { + It("returns an error", func() { + cacheFile := resultCacheFilePath(cacheDirPath, netConfigList.Name, runtimeConfig.ContainerID) + err := os.MkdirAll(filepath.Dir(cacheFile), 0700) + Expect(err).NotTo(HaveOccurred()) + err = ioutil.WriteFile(cacheFile, []byte("adfadsfasdfasfdsafaf"), 0600) + Expect(err).NotTo(HaveOccurred()) + + result, err := cniConfig.GetNetworkList(netConfigList, runtimeConfig) + Expect(result).To(BeNil()) + Expect(err).To(MatchError("failed to get network 'some-list' cached result: decoding version from network config: invalid character 'a' looking for beginning of value")) + }) + }) }) Describe("DelNetworkList", func() { @@ -548,6 +1094,71 @@ var _ = Describe("Invoking plugins", func() { } }) + Context("when the configuration version", func() { + var cacheFile string + + BeforeEach(func() { + cacheFile = resultCacheFilePath(cacheDirPath, netConfigList.Name, runtimeConfig.ContainerID) + err := os.MkdirAll(filepath.Dir(cacheFile), 0700) + Expect(err).NotTo(HaveOccurred()) + }) + + Context("is 0.4.0", func() { + It("passes a cached result to the first plugin", func() { + cachedJson := `{ + "cniVersion": "0.4.0", + "ips": [{"version": "4", "address": "10.1.2.3/24"}], + "dns": {} + }` + err := ioutil.WriteFile(cacheFile, []byte(cachedJson), 0600) + Expect(err).NotTo(HaveOccurred()) + + err = cniConfig.DelNetworkList(netConfigList, runtimeConfig) + Expect(err).NotTo(HaveOccurred()) + + // Match the first plugin's stdin config to the cached result JSON + debug, err := noop_debug.ReadDebug(plugins[0].debugFilePath) + Expect(err).NotTo(HaveOccurred()) + + var data map[string]interface{} + err = json.Unmarshal(debug.CmdArgs.StdinData, &data) + Expect(err).NotTo(HaveOccurred()) + stdinPrevResult, err := json.Marshal(data["prevResult"]) + Expect(err).NotTo(HaveOccurred()) + Expect(stdinPrevResult).To(MatchJSON(cachedJson)) + }) + }) + + Context("is less than 0.4.0", func() { + It("does not pass a cached result to the first plugin", func() { + err := ioutil.WriteFile(cacheFile, []byte(`{ + "cniVersion": "0.3.1", + "ips": [{"version": "4", "address": "10.1.2.3/24"}], + "dns": {} + }`), 0600) + Expect(err).NotTo(HaveOccurred()) + + // Set an older CNI version + confList := make(map[string]interface{}) + err = json.Unmarshal(netConfigList.Bytes, &confList) + Expect(err).NotTo(HaveOccurred()) + confList["cniVersion"] = "0.3.1" + newBytes, err := json.Marshal(confList) + Expect(err).NotTo(HaveOccurred()) + + netConfigList, err = libcni.ConfListFromBytes(newBytes) + Expect(err).NotTo(HaveOccurred()) + err = cniConfig.DelNetworkList(netConfigList, runtimeConfig) + Expect(err).NotTo(HaveOccurred()) + + // Make sure first plugin does not receive a prevResult + debug, err := noop_debug.ReadDebug(plugins[0].debugFilePath) + Expect(err).NotTo(HaveOccurred()) + Expect(string(debug.CmdArgs.StdinData)).NotTo(ContainSubstring("\"prevResult\":")) + }) + }) + }) + Context("when finding the plugin fails", func() { BeforeEach(func() { netConfigList.Plugins[1].Network.Type = "does-not-exist" @@ -569,6 +1180,19 @@ var _ = Describe("Invoking plugins", func() { Expect(err).To(MatchError("plugin error: banana")) }) }) + + Context("when the cached result is invalid", func() { + It("returns an error", func() { + cacheFile := resultCacheFilePath(cacheDirPath, netConfigList.Name, runtimeConfig.ContainerID) + err := os.MkdirAll(filepath.Dir(cacheFile), 0700) + Expect(err).NotTo(HaveOccurred()) + err = ioutil.WriteFile(cacheFile, []byte("adfadsfasdfasfdsafaf"), 0600) + Expect(err).NotTo(HaveOccurred()) + + err = cniConfig.DelNetworkList(netConfigList, runtimeConfig) + Expect(err).To(MatchError("failed to get network 'some-list' cached result: decoding version from network config: invalid character 'a' looking for beginning of value")) + }) + }) }) }) diff --git a/vendor/github.com/containernetworking/cni/libcni/backwards_compatibility_test.go b/vendor/github.com/containernetworking/cni/libcni/backwards_compatibility_test.go index ceb9f3583..6480193ca 100644 --- a/vendor/github.com/containernetworking/cni/libcni/backwards_compatibility_test.go +++ b/vendor/github.com/containernetworking/cni/libcni/backwards_compatibility_test.go @@ -16,9 +16,11 @@ package libcni_test import ( "fmt" + "io/ioutil" "os" "os/exec" "path/filepath" + "runtime" "strings" "github.com/containernetworking/cni/libcni" @@ -29,6 +31,18 @@ import ( ) var _ = Describe("Backwards compatibility", func() { + var cacheDirPath string + + BeforeEach(func() { + var err error + cacheDirPath, err = ioutil.TempDir("", "cni_cachedir") + Expect(err).NotTo(HaveOccurred()) + }) + + AfterEach(func() { + Expect(os.RemoveAll(cacheDirPath)).To(Succeed()) + }) + It("correctly handles the response from a legacy plugin", func() { example := legacy_examples.V010 pluginPath, err := example.Build() @@ -42,9 +56,10 @@ var _ = Describe("Backwards compatibility", func() { ContainerID: "some-container-id", NetNS: "/some/netns/path", IfName: "eth0", + CacheDir: cacheDirPath, } - cniConfig := &libcni.CNIConfig{Path: []string{filepath.Dir(pluginPath)}} + cniConfig := libcni.NewCNIConfig([]string{filepath.Dir(pluginPath)}, nil) result, err := cniConfig.AddNetwork(netConf, runtimeConf) Expect(err).NotTo(HaveOccurred()) @@ -55,24 +70,23 @@ var _ = Describe("Backwards compatibility", func() { }) It("correctly handles the request from a runtime with an older libcni", func() { - // We need to be root (or have CAP_SYS_ADMIN...) - if os.Geteuid() != 0 { - Fail("must be run as root") + if runtime.GOOS == "windows" { + Skip("cannot build old runtime on windows") } - example := legacy_examples.V010_Runtime binPath, err := example.Build() Expect(err).NotTo(HaveOccurred()) for _, configName := range example.NetConfs { - configStr, ok := legacy_examples.NetConfs[configName] - if !ok { - Fail("Invalid config name " + configName) + conf, err := example.GenerateNetConf(configName) + if err != nil { + Fail("Failed to generate config name " + configName + ": " + err.Error()) } + defer conf.Cleanup() cmd := exec.Command(binPath, pluginDirs...) - cmd.Stdin = strings.NewReader(configStr) + cmd.Stdin = strings.NewReader(conf.Config) session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) Expect(err).NotTo(HaveOccurred()) diff --git a/vendor/github.com/containernetworking/cni/libcni/conf.go b/vendor/github.com/containernetworking/cni/libcni/conf.go index c7738c665..9834d715b 100644 --- a/vendor/github.com/containernetworking/cni/libcni/conf.go +++ b/vendor/github.com/containernetworking/cni/libcni/conf.go @@ -45,6 +45,9 @@ func ConfFromBytes(bytes []byte) (*NetworkConfig, error) { if err := json.Unmarshal(bytes, &conf.Network); err != nil { return nil, fmt.Errorf("error parsing configuration: %s", err) } + if conf.Network.Type == "" { + return nil, fmt.Errorf("error parsing configuration: missing 'type'") + } return conf, nil } diff --git a/vendor/github.com/containernetworking/cni/libcni/conf_test.go b/vendor/github.com/containernetworking/cni/libcni/conf_test.go index 225828e41..c931a5abd 100644 --- a/vendor/github.com/containernetworking/cni/libcni/conf_test.go +++ b/vendor/github.com/containernetworking/cni/libcni/conf_test.go @@ -37,7 +37,7 @@ var _ = Describe("Loading configuration from disk", func() { configDir, err = ioutil.TempDir("", "plugin-conf") Expect(err).NotTo(HaveOccurred()) - pluginConfig = []byte(`{ "name": "some-plugin", "some-key": "some-value" }`) + pluginConfig = []byte(`{ "name": "some-plugin", "type": "foobar", "some-key": "some-value" }`) Expect(ioutil.WriteFile(filepath.Join(configDir, "50-whatever.conf"), pluginConfig, 0600)).To(Succeed()) }) @@ -49,8 +49,11 @@ var _ = Describe("Loading configuration from disk", func() { netConfig, err := libcni.LoadConf(configDir, "some-plugin") Expect(err).NotTo(HaveOccurred()) Expect(netConfig).To(Equal(&libcni.NetworkConfig{ - Network: &types.NetConf{Name: "some-plugin"}, - Bytes: pluginConfig, + Network: &types.NetConf{ + Name: "some-plugin", + Type: "foobar", + }, + Bytes: pluginConfig, })) }) @@ -68,15 +71,18 @@ var _ = Describe("Loading configuration from disk", func() { Context("when the config file is .json extension instead of .conf", func() { BeforeEach(func() { Expect(os.Remove(configDir + "/50-whatever.conf")).To(Succeed()) - pluginConfig = []byte(`{ "name": "some-plugin", "some-key": "some-value" }`) + pluginConfig = []byte(`{ "name": "some-plugin", "some-key": "some-value", "type": "foobar" }`) Expect(ioutil.WriteFile(filepath.Join(configDir, "50-whatever.json"), pluginConfig, 0600)).To(Succeed()) }) It("finds the network config file for the plugin of the given type", func() { netConfig, err := libcni.LoadConf(configDir, "some-plugin") Expect(err).NotTo(HaveOccurred()) Expect(netConfig).To(Equal(&libcni.NetworkConfig{ - Network: &types.NetConf{Name: "some-plugin"}, - Bytes: pluginConfig, + Network: &types.NetConf{ + Name: "some-plugin", + Type: "foobar", + }, + Bytes: pluginConfig, })) }) }) @@ -149,6 +155,37 @@ var _ = Describe("Loading configuration from disk", func() { Expect(err).To(MatchError(HavePrefix(`error reading /tmp/nope/not-here: open /tmp/nope/not-here`))) }) }) + + Context("when the file is missing 'type'", func() { + var fileName, configDir string + BeforeEach(func() { + var err error + configDir, err = ioutil.TempDir("", "plugin-conf") + Expect(err).NotTo(HaveOccurred()) + + fileName = filepath.Join(configDir, "50-whatever.conf") + pluginConfig := []byte(`{ "name": "some-plugin", "some-key": "some-value" }`) + Expect(ioutil.WriteFile(fileName, pluginConfig, 0600)).To(Succeed()) + }) + + AfterEach(func() { + Expect(os.RemoveAll(configDir)).To(Succeed()) + }) + + It("returns a useful error", func() { + _, err := libcni.ConfFromFile(fileName) + Expect(err).To(MatchError(`error parsing configuration: missing 'type'`)) + }) + }) + }) + + Describe("ConfFromBytes", func() { + Context("when the config is missing 'type'", func() { + It("returns a useful error", func() { + _, err := libcni.ConfFromBytes([]byte(`{ "name": "some-plugin", "some-key": "some-value" }`)) + Expect(err).To(MatchError(`error parsing configuration: missing 'type'`)) + }) + }) }) Describe("LoadConfList", func() { @@ -251,7 +288,7 @@ var _ = Describe("Loading configuration from disk", func() { Context("when there is no config for the desired plugin list", func() { It("returns a useful error", func() { _, err := libcni.LoadConfList(configDir, "some-other-plugin") - Expect(err).To(MatchError(libcni.NotFoundError{configDir, "some-other-plugin"})) + Expect(err).To(MatchError(libcni.NotFoundError{Dir: configDir, Name: "some-other-plugin"})) }) }) @@ -304,8 +341,8 @@ var _ = Describe("Loading configuration from disk", func() { var testNetConfig *libcni.NetworkConfig BeforeEach(func() { - testNetConfig = &libcni.NetworkConfig{Network: &types.NetConf{Name: "some-plugin"}, - Bytes: []byte(`{ "name": "some-plugin" }`)} + testNetConfig = &libcni.NetworkConfig{Network: &types.NetConf{Name: "some-plugin", Type: "foobar"}, + Bytes: []byte(`{ "name": "some-plugin", "type": "foobar" }`)} }) Context("when function parameters are incorrect", func() { @@ -330,18 +367,21 @@ var _ = Describe("Loading configuration from disk", func() { Context("when new string value added", func() { It("adds the new key & value to the config", func() { - newPluginConfig := []byte(`{"name":"some-plugin","test":"test"}`) + newPluginConfig := []byte(`{"name":"some-plugin","test":"test","type":"foobar"}`) resultConfig, err := libcni.InjectConf(testNetConfig, map[string]interface{}{"test": "test"}) Expect(err).NotTo(HaveOccurred()) Expect(resultConfig).To(Equal(&libcni.NetworkConfig{ - Network: &types.NetConf{Name: "some-plugin"}, - Bytes: newPluginConfig, + Network: &types.NetConf{ + Name: "some-plugin", + Type: "foobar", + }, + Bytes: newPluginConfig, })) }) It("adds the new value for exiting key", func() { - newPluginConfig := []byte(`{"name":"some-plugin","test":"changedValue"}`) + newPluginConfig := []byte(`{"name":"some-plugin","test":"changedValue","type":"foobar"}`) resultConfig, err := libcni.InjectConf(testNetConfig, map[string]interface{}{"test": "test"}) Expect(err).NotTo(HaveOccurred()) @@ -350,13 +390,16 @@ var _ = Describe("Loading configuration from disk", func() { Expect(err).NotTo(HaveOccurred()) Expect(resultConfig).To(Equal(&libcni.NetworkConfig{ - Network: &types.NetConf{Name: "some-plugin"}, - Bytes: newPluginConfig, + Network: &types.NetConf{ + Name: "some-plugin", + Type: "foobar", + }, + Bytes: newPluginConfig, })) }) It("adds existing key & value", func() { - newPluginConfig := []byte(`{"name":"some-plugin","test":"test"}`) + newPluginConfig := []byte(`{"name":"some-plugin","test":"test","type":"foobar"}`) resultConfig, err := libcni.InjectConf(testNetConfig, map[string]interface{}{"test": "test"}) Expect(err).NotTo(HaveOccurred()) @@ -365,8 +408,11 @@ var _ = Describe("Loading configuration from disk", func() { Expect(err).NotTo(HaveOccurred()) Expect(resultConfig).To(Equal(&libcni.NetworkConfig{ - Network: &types.NetConf{Name: "some-plugin"}, - Bytes: newPluginConfig, + Network: &types.NetConf{ + Name: "some-plugin", + Type: "foobar", + }, + Bytes: newPluginConfig, })) }) @@ -397,7 +443,7 @@ var _ = Describe("ConfListFromConf", func() { var testNetConfig *libcni.NetworkConfig BeforeEach(func() { - pb := []byte(`{"name":"some-plugin","cniVersion":"0.3.1" }`) + pb := []byte(`{"name":"some-plugin","cniVersion":"0.3.1", "type":"foobar"}`) tc, err := libcni.ConfFromBytes(pb) Expect(err).NotTo(HaveOccurred()) testNetConfig = tc diff --git a/vendor/github.com/containernetworking/cni/libcni/libcni_suite_test.go b/vendor/github.com/containernetworking/cni/libcni/libcni_suite_test.go index bc4ecc5ee..057567f8a 100644 --- a/vendor/github.com/containernetworking/cni/libcni/libcni_suite_test.go +++ b/vendor/github.com/containernetworking/cni/libcni/libcni_suite_test.go @@ -15,9 +15,8 @@ package libcni_test import ( - "fmt" + "encoding/json" "path/filepath" - "strings" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -31,34 +30,29 @@ func TestLibcni(t *testing.T) { RunSpecs(t, "Libcni Suite") } -var plugins = map[string]string{ - "noop": "github.com/containernetworking/cni/plugins/test/noop", - "ptp": "github.com/containernetworking/cni/plugins/main/ptp", - "host-local": "github.com/containernetworking/cni/plugins/ipam/host-local", +var pluginPackages = map[string]string{ + "noop": "github.com/containernetworking/cni/plugins/test/noop", } var pluginPaths map[string]string var pluginDirs []string // array of plugin dirs var _ = SynchronizedBeforeSuite(func() []byte { - dirs := make([]string, 0, len(plugins)) - for name, packagePath := range plugins { + paths := map[string]string{} + for name, packagePath := range pluginPackages { execPath, err := gexec.Build(packagePath) Expect(err).NotTo(HaveOccurred()) - dirs = append(dirs, fmt.Sprintf("%s=%s", name, execPath)) + paths[name] = execPath } + crossNodeData, err := json.Marshal(paths) + Expect(err).NotTo(HaveOccurred()) - return []byte(strings.Join(dirs, ":")) + return crossNodeData }, func(crossNodeData []byte) { - pluginPaths = make(map[string]string) - for _, str := range strings.Split(string(crossNodeData), ":") { - kvs := strings.SplitN(str, "=", 2) - if len(kvs) != 2 { - Fail("Invalid inter-node data...") - } - pluginPaths[kvs[0]] = kvs[1] - pluginDirs = append(pluginDirs, filepath.Dir(kvs[1])) + Expect(json.Unmarshal(crossNodeData, &pluginPaths)).To(Succeed()) + for _, pluginPath := range pluginPaths { + pluginDirs = append(pluginDirs, filepath.Dir(pluginPath)) } }) diff --git a/vendor/github.com/containernetworking/cni/logo.png b/vendor/github.com/containernetworking/cni/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..50c54d2f524e76475b01bd8fbbc2b5b7a57fec4a GIT binary patch literal 11604 zcmY+qV{~RgyDj?0wr$&bW2a*$9ox3ej@_|svt!$~*|C$;-`@M~drpl}nl)?AdTRYy zqpBhm}hWuA%tC(y3tH8~L<%9u%`Z%}`Lx_KUVq+;~ zIRL?=#fGaZqaBctq@TLO*SPoeoO2B^uFb+~$&Hw--*?%&KN3ozA z005$8sjBIsDJRQoY;VhGXku?<%IIP1@Q)1u06lpBHEm5@42eB#ZS0(RJ@`rgi^2P^ z{U4Z#l=#0WF4p{{nsSQ7qV`Uv#2k$5jLf70u*Af~KqnJ3US%kHO&VY3E|-!C>c1_TM7^pN^QRv$2zA%ppeAF<&4*zo5^gG02h(9lRaR2Qaf9z&k6s|>pBlx+UbitDh38m zh1BFkhEV&L6YZ#92CKdt^2)+IIxBoR?F@?mj~z4*I8?4eiB@9-xpe8}rL*+>NfLd` zkUOas<$M92qb(`|p^`Sl} znLY#Tq)%~H6QbgxWEhnAa(^=L6)*SdBPVnU^2?gaDeXnvj3GWpS=Q7>vL*SVg52wyu&$oJP!*(8ovViK8^V=T z^#ad)*$yd6>`lN>0uVw!7F)K&#%J^-GcwZPY93z6M`d~37^Cm=2j=4iA@H+>dDG|i zPJ?BfXqYYp=JZvqE}W6c(Uq3@AyJfeQJyzBm$_cw^OSk7bb{QmD=)R|ItfuTl~_1H z7XSKEkAR;*=L@MjZg+42F|EO83u~VbaNN!)SVuecAPSH|hxbS7yc4EQ@sFq}F6IHD zMHap@FABOK47_Vc-+YHv3oC`|#gY0Uv7Vx6hsmw#mz))ASK!0^z|rQ5xm}A zU|MMw82LAqa=v6wAtCNTQ)>aI&N)x;o{}5VdGrd1Wn16yQz7a?50};C9weBg2mc1@ zIz8o%EnL}edPFtdK0-lw8k0J+XW6!o)xz`|k-Aox^pC%% z0`2H$I%jgjsZ=4nCbXHB*63L9%;yiLJdE~2{0|_lkPuMX8mw5u#AWSc7D^|s)`1P zkZJX&Wfi9$+~wEsO2_kz0B4A{iNjwy-$=VvnH8f=&S9TGs!uZ)4#O#!a1gBO zsD!pymARY`LHxk9N^0&KbT>jr>KBePgKcJxS++1M>0c3v*vQ8XQL%M@E<+! ziPUa6mG>T>FZa3eWq&KVsSqloS?$Yiv02wZA>wb}VvmZ;1daLP3!*%raUJXg4P*GJ zdOi=4Pg?~1_RxfjgY8t0?t&?g7jeABBGn7f{G}(R1g@p5!WG#CJXQA**5Sqtw~_~| zSH$&P%bk^xRZ|yu{i=@7E+IA4ruQ5^akG13`UA1xR-3->`BmO#jo8GGlvd8Lc7J4w zDB3BgJZ1&v^e9ey*NQQe%D_j!dM~F&v%R4X+jzon_kExwrF54V#w)r(O%&lM0?B;qH`*CzonG_4e*WItPK*PQVRx<-?!$wOG4_jN(O5_CS%RV{^me{i~b z?TpQE0JjOZM49o+yi~(ECuK%n<@(NAXaP#(8t#7l8>f1bNPDS+-+pNbOhFdysMp%n z-&jPmrtUpG?U8Gc?0$C{0i7@oighcV*04*%o7s3cJ)ezoI8hS5Z9_NcRMCCC{ojAi zst-YN?59!$$h1mQS5+qMJtLBna^l+d-H|OZ-Aovhf-24`U8gR?+%hE-lUi%O0y@7HPa>$UWu z)MGqc2}qm$u- z%WSPB-`uGQF7u145*HM!&U7d`mOJMalYatjkh8_ZX)enaZ*Y=+-g0&4{B;BU%l!6d(lOdxPK0xe^zmAa*iUAVR29yHHpL5w9hV#M}dJqUReKeXH=ePDqy#<=Kl0)w} z@T-ya9d#a>4r*LcIeYhEJllW}yf&PlDQeZR+-guy%l1UQ&*xh=ofl510?HuF;fv%; zA&;aSZ;-t%S#G+aQOZ$34knV!Vy8!0HlLolx|12%T$z|X$?wAxWXsQ6OqMO0&&s;9 z=0Y~jl(V?Fxe)xuc#-sWrpf=C3cUs!ilspv-Mp7Ug<)q0#>kRH9o!4B2)t`6ndb-= z6z;LI3$`lUPwzLC+`C+$+I`B_4CBE#a;V_{F=tPueD@N6+B#(8I;ZU#7kS*|WD1uq zwqXe&TaYCS9{O2KsyFuRuXUMmy zMtAgj5;Q<|8h+MNGuke)*{~1@_o(0*%?Ag!p~$TWeSZL(A7J8%74=6r(O3Y1u&Wc6 zctUX|=y^Xm7ewPpSoMr6U6m@|`9?XUq~GC7>9AFnCi*n&>qK6ah8vuR9OH`kj%bN_ zNM(w~4h!s3?bcTw$I^j#ACnl74;#M&H`kKg=b?l)!EDYT<>U+NSUzknu9qWQMvtqn z$_sA-)O|Kj7z4`Lf`dy7W9exp)O6Fr24G@JRU*U3&Ww_M3c2EhiXgSEskWF45?FKB zWCdc&6Vo*AAJ29x91*Zl?&FU%u7wzi(a6QnUkSV7*q_~4^77L@TjWZ6rZD8?kD~ai zx#o`!3(g`*ivOm@(9mX6U*K=8Du;sP zGD-2?Ep!sq@4UiVGjA{FlP%+5zFaR>p>As^6@7f{Q$Q{X33zw z9g?<_+3QcsMOa8DoqpeV;~iu2n><4@Iot6;Gp294RNfqkZE);w=Q5v-0rqA0JihT) zE16~4J#WvioU#K7O}MmqKkRdFIwHWx7irt}Z<4HB06pIIvGTYJ`0vt!t*!Wj=h?pr zyR78z0qZjwhcO|3>2U&j;0_sdt)NnFs_M~BZeD{B_p=U&#h5@V$T9GCBOke76}@nu z4{TBc+K&@XRS^AdwN2gKb-1#weTMa)EEw4zO27PWZ9G&XmP>zmA*k4~dG2E=WpW}V z9*o-o3_;t@oP}e3X*VJU%PmczXDXH$EDlH(>A)r(*{P2pHn}Rg2pP@CL?GF$Eukz< z&CBI3$UWqWku?qg$E5`ymum)amx?I6(VWQIgS=^tS0?EJ&xT&!#Hj4>+xMq4IuGXN zu3Ic9{Z|~c88LyKb&x%*H^$J82ttTe6~?A|3bL;;O^_@SPmE5ibY*qBZx!#rbF&J> zP8McQt^27qlPAWPO)k|Vb8#n!il~JCOGBb;GR=t{E)8}brj2&>2D-?qhq=EK{unYW zT=z6G{@ul+X7eV~^4?zs7`hhX)3~(SmWnj%dwEY4A6B)s9Zc%h;UBHM-lH+NOw2Hs zKhJCeNF8V0dgGg+(-4YN&s}sz-eNZ3{5(U|Puz>U1KW24_=CKq=%>Ypn(+BrK#NO7 zQtil>8Y55-wnHJWAc^plD(X$4WOe6|tqzO8Q&k|c;aS*1f!i6-ZkMGonfho6l zSW_V3Sy$RGowQU{@B8qJf8S(iFlhDRpQ}e1qU(p{^$}YHy#Yrn z8bc_MVXLXsI&$A&Lx+@noL|%VdijJjRhWLdG4g(+!+#kzc|UU|cP1%I{vIF7IzQgk za&h2;$NgGT_%g~_Etj@n z^@sY|ET zQT98gj4GS`_11hC(}}CilC6$8Incij7lcP&v)g~nQ=1l-U)izAu%C?Bj%{QN%6kvX z-qBo$_ylp-%7GlbTf?Zg31vH3s9yag`~Kt}=sSwP3|aH{8zh}m6UR643BoKt$BE^y zW+CJ&6yq@lW>EkLA!V8oWX}MKUR$OVSke!%oy$#n#zlV%{JiGdM$3Z?)&~2XT9O63 zqK53B(y)R6t_PD}ZzA+uPk9AhG=L@eaL3sYIW)?39e@9z2DVm1riFXJ8AQjC0{>ZD zAtlMT0_Y2eb$TPc(txR-$nzJdRu|#pWU%6HT`pS9o_&-3P0ZhRtmx~^#}QECp=0!u zQJ)}dNXU0T<%4YIaMB3zF5xiNq&FlHO(fVjj8xN$XK&*j$_E(66ArQ~`e0PtpN{e!y9+(FEK5>c|tE`0M z#fv&n5>0)VzO`cw>Lc270p?L4FhdCqN{Q6 zx=Zs6(j@|+b}ctyZVpLh7oPW{;Bw2MEgM15y>Y9SrugM4d;jde+iK!`0<3Qp68Y>X z#Cm1lW|&qxsO$U7x0Mnz9SLa8NoDWdm={ru0bt(UNp;PRXq!5EpjuX_ri2G8=-V~o zh0cGgyV2pT035n($y$4QpA}P_oXv=284a}{7`?C*YGEj_LY^nG*)VsEktrC;uX)0M z+FgA!ql@CjtHP3z995a-8K+%;R`=0e{qxkjr?&Klm%h4*sAsCylL4Q zcEi&rb0?Z0m41xt61TKLDN< zlH0tWmAl<#>7e4$V~gO#5`lgq8`AbKw%6*B;?**g2g|M*^R^14x;fZ&$AURe z2SLHJ$~dtyRhlI%(r^fb!qv^vl56Z@(rtYFQ?GX9D9Y;FEy1VqZDQIlihRaFP4)WO zgWr}QtmSVNN98t8BlEisA$a~6LT-D0D#+JDE^Tl1^L$T(YRD8SGLi?#wKeSL+eTxP zw>@nP_HDVMb`|!XTaK>kAz~c%yXVCC>{i6E&nB%v50aTUmOHT!qMWx@?5x4ktR&CC z9)g}two7GfLR7(VuCB5PFWGYMa?HwhR(EmIPBjMBqo%*-c;M-ij`iiQ za^GL#@)W>9l(`)D(Ec#4Y3F);7^d#3HV5I>nD)pYnsf&Td#+z>3S)UKw#WsAQxWtC z!!3iYN=Qs2(2{{rN)fQ5`x8;>TO@Q6u@hJL`*Ko>Sz!q`#J;Dk(qMX6rft6P%drV$ z&pu0q&nDsW{;Hx0wLm+rkj{I(@L(qSVl zpRQoMN5c+R-A1QmdYbn5m=&*VTAu#Bm?+_amS>z73l=B|diniwoJ{qNTEZ@G@7f~A z3Y!n<7>S;z4&C(7X{e?$s>Ywvdq+*ctKWHae$`p=>9U>AKsmlY1hR#-J7JtWh#Bd)ZNjj}MIgvqr2ZBO?(D>hV+*=VgZ!KR>e{yB^Gk@(O^ zPNxaaS=#6Y>(0d$ys2)wDjwgja9ADKnk)td4xdm-6&-g&Iz2hXYt`^~n0OBS&59m> zp`<^D_O;_CC&4d8a>~UEo+}(3D^L)_3w}RYk<(7CueaVX5rCnvUx2mxQ z^<@!8tz2~3h7JB!O*7H$~N~5T+=A(pljtVkWe&Q?9%(01+bm92TrXuRsG5k_UL6F&F>TG;m>S zX`ml(c8W7Me)^zhv%;cb>=b#Xrc%kF)97wBJG|eMo~%HP*i6>Df4Y2vxRri=v&A() z%WI@NhoLFz0l&Ga9~d!5OXnYy@vs|J`QA0|d4AERrm*C{(fc&u6gN;ksfZu@N4nxX zMqSkcG2A$zmGtr_t3j`x@I`t(J|4HpG6(4FygH)vPq1vy4036_-V_b$cu#HdA-w>g zy~6f5RdoH)PnSV$!>WRoK&mPeZeeiplf$e_n-$cb9fkgB^&47n;9yarTF9@qGmYcY z)lhhIr({tJp18fkxe1lw!77bj&nHV0VBE2PxG2}4j9!KltxbcErR7f`AY0KQYa~09 z8ocxy&&zhKvR^qPqPr|m<3Kv~@fUBbh{VqmJBHGLi1BC#brH27Nwxgb## z|IVVs;x!coM^2TqN=BomjGjKVE-<<#edB)dnpiEhWEl+7onKZ~eVx2qa3~JcZaCM` zt8ctC^S81(O2693{=wLdPQ8-nQSsYqGm@uzl1f6NR(GrK%*j#AG95lNR5&cA))zcB zd?dQX-OdS-iCnzMZDH#KGh46dNr(^D#?(uYoqIG(lC^CQIs zE=oGP^|pWe(4S-)?p3?*+Bx zkjOpPi@h}m!r=ik7YR_|<&JMG*o#KJ%eezCNLNgWv?CQZ1IIQssXR$To|#{c<2>e@ zNW_%ogzk9x9_+sDMbgiLTix%7n9dO&2?|!}1^hrEjihGv29FNeK~!mf0!`cH-DY9?O&M@nE7-nu3f=OU?HfKZ?Sm!bV% z2uMB{Sw)>0biuZAGmvDuN5hr%CyF!~`e;h~H7CjzBtg(nSFltWN=W4_FKHM!X&S11}_8OWhtv07&;S?MvZxKscN?UTxu-~>2TQ~4R;p5?7Q+9jC+wZ-fw=*DXu)*4wH(@70 zBYf``FpRTEeyE_U@ka)aL|hh$(}^q)p3fcNsoVAkAWntCzl1+Fz6?CE857 zxASA&LH1Zscj44r4C17@N6}PS9dwivpk4`G+UPfk$=!uJif1oO9;nc}!yDnuG=mH@@pWx*+NQ=6KRC zJ~oy=@K|>V#%;fGY)zr&C8d;&<+zDH!ERmed>Dw6U5mQ0a<$(pac!7Qh#|xP>no8k zK=l~&<|B^yJlf`nI<}x1SII9F>S=0%i|Dz(h?xDyZXDet4(ftYgoIHHnQGT{a=u{Q zL!oO01O`nE`RzziHRobL85RjQRrj~ZQdsF#6%sVgXQy)yxzFaQndo6VLTe0^TTBM(^$Q zbH1z#NdiSm^_Lgug!)@x?o_(ij7zv^JKFjRUKRC9z2AKoN~+oRO8o&L&t0HCj-9RVP zv{#g_#N4!!6L~C69y~f28=UL}h84?e=C;bSqXi6Y|#M@-gXLd0hO28tH zYO3##ziq!Tth`?<fH#{au}#twb5{M?lM>1FgLNX~aC01eka0PB09xFp@G=dsqH@#nQEns6>R zg!O{LxRG|hPQRc0Zp%@Nsvd5QQRe*oBcaV*2V|VU1hI>F)^xvo|TpokkoUenBdPo06|cF6`xQ+rBC1*(9COe(y;Q?e5Ea} zeo`U-XtbKtMFc<;_TZX6N#pa=VgCv`oSjnzV#a*Cerp*98uz)1MSp+JG=AUC#HDpV z4wWWweLs$swDzoSPn;vyLTQ~)eXWE8!~o7j=HB-QaR=LP`$;I#f4&~zzorA6En;UB ziX=#T2~)eF>6qW2(N5%q0x&SaJcH;m0o#$JRLI6c@&Dj8corXcQd(Xx^qXI;S~xi%Ao#Eh z3mHvjQkQEK&_t{oCw*M7>oWqnJeY+AWZlOCu$?u3JV3YA!_AdRpaI$Jq;;_g9=JEJQbCoC;}TQrg#h^2g1 z1of}w^m1mXTG2-EgNZ^7G7)!*hl zmc!u7l%y3u2%Uzrrh-?!M}=J8)D~B81)2XMryNg1$t}4MDA!HH9SgY-9gwsG!5)x$ z7aTHa@VjFExf=n!YI*Ky1UM#GV$Mg9k1_-?t++M4Yt9~E z#tMlksoWa992hS?!MdNh`}Yb!kRT29yok$)fuugH!b@~OPn1`&Y=8SJA}VAvi?lm; zU;I_yqu$~p@uM^j%=$|-=f6Jrim zm;z!5vD{D}s$euih%((<%!S+ZH^Bp3_dLTa;(KUm5_tSS8JGp)eyLt1K5*Bc*!#UG zXdq=ZD3)n>wdYm6g%0sX4S~MAt3}&BV^wKI0Wf783^>P*@p@x62g(i+q3=TL9id3Z$Yc55lt_r2FlLCEgr_4a>1RD~?BT=P!*% z+~LN>c7IsCgmw*T{vSPDO~VTbx03WPw_;1T`dBj$Tum;%uYlxu04vxyWfYHgHSNh@ zFZ+rW#YfH0Aq6(e3-!Ec6U!S!<~X01>D;T-F>sZN!Ebw=3|am#^x&jiNMeQgf2W@P z%70&FA;RGiWKel0Ri#mxdOBH(y_CDm32T0#IdLurLoT_Zv+;!J?9W}N0C82ULAlXX zz~FXJ{n%;-zvJ_Uvdpxr$UHu{hb?=8sZDzq=3gjiJQw+o(B3@%6yM?rcK`K(JH-D( zMfARtqP{z;^zxDIRpKXX{RvljDi9H3{HcaX{D>F1l6#3aFM@Gl}5`k41s!Q*Tx{jiep6HX@ij9Rf4$+_4mv|B8gD$WsohwI>T zKQ>>9t2D9dP&|#xJ4YhUaYf!%z|UYPYnn_SPNeTb4p>)ZZs&(4a3IfZD%tP)Hh9_u z+Y3J#OA#AA39b8_MlKjd71b%}89ZRiG?*`O`9%SSgXQFZuve>G?VbJBHGDQN#DsxvB^EygQBytb=jH<($+> z<^dBc60Rc)Fp9lkIyEYLByWC_B$Jf-~$r2$|;U1YwZlJ+w7Wok5z!NbrwuiiZGlxl+A>u;FCYDkhFa zCvc`QMX^qnV|*wX;sMJqMYPvggQO`{4h7pi)RP;bUA#QfDk;cqyh?^5!eAy|b(yHr zVRs`JjG@rn3~ou66>T!Bk{+UZt5pg!#g)SvF(R{!J5>QJ#tYK(tn(O}^7AvIgBvml zBw7h$&5qqcCcsKr68E<~Z{6{UYT`Y(&b-E8`>!$|AV2vu59{!m;L9Sp*x=ML-{{Lw zO>@L)dbP9!s-x_p3s0QL{nR`P*>ME&6+>m!!mP)S=~2FiAP|?EI=&UZUXT{Q z0_SJ_;H_4bwQjj-T`sqvJTMMY*luhgF6!B!V<&W%<(FRwvFnF~RGe@(vi+jPpAC3M zuCo3T^TabSF(;S8-YSu(0jJ^Y2>c1NQF*anzqQ}zjvRjEq?-6bAGrt~(xloRF2C?h znnz&aZ72bxR}-aP@-+S7?YbGYe9#KjCyv!4F-kqLt)%zH8bzfg_H4t z_V&O)q@00F#`;Jlw4a8cSNg_n%ahV!3&LD4XC}IJq**oS>#=cuS(|`KyEWH zcC$uNnH%2}Z<$9mSa4rTqm)0B5W&0I|L)&TR}wI}Fx=cGk1-R@-_EV(ePdTM zvy#i4E$HL)J!4aZR}1IyH0`8NV51=TGO6$*u~GxE%_xCSeXg8Mp6~Dzjn_1#O1X;~ z)RtnXcdE7GkxU4{MVnQwJZ1}1Z4UxjWy-u>b7=WOg$P*`*S<>3+Zi9;T96bDUN|rl z)cCY;_nQ#A@XJ@^31W){?no1_%s2RKNCRzHI}BX3*P*)T*TLXEoqP?D9V%C7^@Fsa z4g28w?g+0^9pdYH9RckzW#ujl>N9^y{c!_jPhrchJX``kWtdSCEpYVO7my!)g~Gj= zMkz`w+CuRM#YG7TZC?ULh;*aD)hr&iBmgt#&>wV7ja~d_v6Uo@H6!N45pe^M&|$cE znC#A5BjH&emL9C;@&oro=}9T*&gY2~#eZ*0^NE=9^vl@Pt2e7I?$nxo2e8sCfq!In zAmPRm`Sm9@JZSg;Ukoa+b$cCEXv+NL65qYgIhum}5PQF=E}awqy(8qs*>C_5quNu( zAIh?VqFLDPwF)I3IT#;Vxt@p@%WMMyMXknJFlA z{${)NCiyh5PD_ydNmHOESG!Uap5i*l1~6$2N3HtsPsxu6`^og 0 { +// return path.Join(paths[0], plugin), nil +// } +// return "", fmt.Errorf("failed to find plugin %s in paths %v", plugin, paths) +//} -func GetVersionInfo(pluginPath string) (version.PluginInfo, error) { - return defaultPluginExec.GetVersionInfo(pluginPath) -} - -var defaultPluginExec = &PluginExec{ - RawExec: &RawExec{Stderr: os.Stderr}, - VersionDecoder: &version.PluginDecoder{}, -} - -type PluginExec struct { - RawExec interface { - ExecPlugin(pluginPath string, stdinData []byte, environ []string) ([]byte, error) +func ExecPluginWithResult(pluginPath string, netconf []byte, args CNIArgs, exec Exec) (types.Result, error) { + if exec == nil { + exec = defaultExec } - VersionDecoder interface { - Decode(jsonBytes []byte) (version.PluginInfo, error) - } -} -func (e *PluginExec) WithResult(pluginPath string, netconf []byte, args CNIArgs) (types.Result, error) { - stdoutBytes, err := e.RawExec.ExecPlugin(pluginPath, netconf, args.AsEnv()) + stdoutBytes, err := exec.ExecPlugin(pluginPath, netconf, args.AsEnv()) if err != nil { return nil, err } @@ -64,8 +92,11 @@ func (e *PluginExec) WithResult(pluginPath string, netconf []byte, args CNIArgs) return version.NewResult(confVersion, stdoutBytes) } -func (e *PluginExec) WithoutResult(pluginPath string, netconf []byte, args CNIArgs) error { - _, err := e.RawExec.ExecPlugin(pluginPath, netconf, args.AsEnv()) +func ExecPluginWithoutResult(pluginPath string, netconf []byte, args CNIArgs, exec Exec) error { + if exec == nil { + exec = defaultExec + } + _, err := exec.ExecPlugin(pluginPath, netconf, args.AsEnv()) return err } @@ -73,7 +104,10 @@ func (e *PluginExec) WithoutResult(pluginPath string, netconf []byte, args CNIAr // For recent-enough plugins, it uses the information returned by the VERSION // command. For older plugins which do not recognize that command, it reports // version 0.1.0 -func (e *PluginExec) GetVersionInfo(pluginPath string) (version.PluginInfo, error) { +func GetVersionInfo(pluginPath string, exec Exec) (version.PluginInfo, error) { + if exec == nil { + exec = defaultExec + } args := &Args{ Command: "VERSION", @@ -83,7 +117,7 @@ func (e *PluginExec) GetVersionInfo(pluginPath string) (version.PluginInfo, erro Path: "dummy", } stdin := []byte(fmt.Sprintf(`{"cniVersion":%q}`, version.Current())) - stdoutBytes, err := e.RawExec.ExecPlugin(pluginPath, stdin, args.AsEnv()) + stdoutBytes, err := exec.ExecPlugin(pluginPath, stdin, args.AsEnv()) if err != nil { if err.Error() == "unknown CNI_COMMAND: VERSION" { return version.PluginSupports("0.1.0"), nil @@ -91,5 +125,19 @@ func (e *PluginExec) GetVersionInfo(pluginPath string) (version.PluginInfo, erro return nil, err } - return e.VersionDecoder.Decode(stdoutBytes) + return exec.Decode(stdoutBytes) +} + +// DefaultExec is an object that implements the Exec interface which looks +// for and executes plugins from disk. +type DefaultExec struct { + *RawExec + version.PluginDecoder +} + +// DefaultExec implements the Exec interface +var _ Exec = &DefaultExec{} + +var defaultExec = &DefaultExec{ + RawExec: &RawExec{Stderr: os.Stderr}, } diff --git a/vendor/github.com/containernetworking/cni/pkg/invoke/exec_test.go b/vendor/github.com/containernetworking/cni/pkg/invoke/exec_test.go index 33ffc2ded..c126747f2 100644 --- a/vendor/github.com/containernetworking/cni/pkg/invoke/exec_test.go +++ b/vendor/github.com/containernetworking/cni/pkg/invoke/exec_test.go @@ -29,7 +29,7 @@ import ( var _ = Describe("Executing a plugin, unit tests", func() { var ( - pluginExec *invoke.PluginExec + pluginExec invoke.Exec rawExec *fakes.RawExec versionDecoder *fakes.VersionDecoder @@ -45,7 +45,10 @@ var _ = Describe("Executing a plugin, unit tests", func() { versionDecoder = &fakes.VersionDecoder{} versionDecoder.DecodeCall.Returns.PluginInfo = version.PluginSupports("0.42.0") - pluginExec = &invoke.PluginExec{ + pluginExec = &struct { + *fakes.RawExec + *fakes.VersionDecoder + }{ RawExec: rawExec, VersionDecoder: versionDecoder, } @@ -57,7 +60,7 @@ var _ = Describe("Executing a plugin, unit tests", func() { Describe("returning a result", func() { It("unmarshals the result bytes into the Result type", func() { - r, err := pluginExec.WithResult(pluginPath, netconf, cniargs) + r, err := invoke.ExecPluginWithResult(pluginPath, netconf, cniargs, pluginExec) Expect(err).NotTo(HaveOccurred()) result, err := current.GetResult(r) @@ -67,7 +70,7 @@ var _ = Describe("Executing a plugin, unit tests", func() { }) It("passes its arguments through to the rawExec", func() { - pluginExec.WithResult(pluginPath, netconf, cniargs) + invoke.ExecPluginWithResult(pluginPath, netconf, cniargs, pluginExec) Expect(rawExec.ExecPluginCall.Received.PluginPath).To(Equal(pluginPath)) Expect(rawExec.ExecPluginCall.Received.StdinData).To(Equal(netconf)) Expect(rawExec.ExecPluginCall.Received.Environ).To(Equal([]string{"SOME=ENV"})) @@ -78,15 +81,23 @@ var _ = Describe("Executing a plugin, unit tests", func() { rawExec.ExecPluginCall.Returns.Error = errors.New("banana") }) It("returns the error", func() { - _, err := pluginExec.WithResult(pluginPath, netconf, cniargs) + _, err := invoke.ExecPluginWithResult(pluginPath, netconf, cniargs, pluginExec) Expect(err).To(MatchError("banana")) }) }) + + It("returns an error using the default exec interface", func() { + // pluginPath should not exist on-disk so we expect an error. + // This test simply tests that the default exec handler + // is run when the exec interface is nil. + _, err := invoke.ExecPluginWithResult(pluginPath, netconf, cniargs, nil) + Expect(err).To(HaveOccurred()) + }) }) Describe("without returning a result", func() { It("passes its arguments through to the rawExec", func() { - pluginExec.WithoutResult(pluginPath, netconf, cniargs) + invoke.ExecPluginWithoutResult(pluginPath, netconf, cniargs, pluginExec) Expect(rawExec.ExecPluginCall.Received.PluginPath).To(Equal(pluginPath)) Expect(rawExec.ExecPluginCall.Received.StdinData).To(Equal(netconf)) Expect(rawExec.ExecPluginCall.Received.Environ).To(Equal([]string{"SOME=ENV"})) @@ -97,10 +108,18 @@ var _ = Describe("Executing a plugin, unit tests", func() { rawExec.ExecPluginCall.Returns.Error = errors.New("banana") }) It("returns the error", func() { - err := pluginExec.WithoutResult(pluginPath, netconf, cniargs) + err := invoke.ExecPluginWithoutResult(pluginPath, netconf, cniargs, pluginExec) Expect(err).To(MatchError("banana")) }) }) + + It("returns an error using the default exec interface", func() { + // pluginPath should not exist on-disk so we expect an error. + // This test simply tests that the default exec handler + // is run when the exec interface is nil. + err := invoke.ExecPluginWithoutResult(pluginPath, netconf, cniargs, nil) + Expect(err).To(HaveOccurred()) + }) }) Describe("discovering the plugin version", func() { @@ -109,7 +128,7 @@ var _ = Describe("Executing a plugin, unit tests", func() { }) It("execs the plugin with the command VERSION", func() { - pluginExec.GetVersionInfo(pluginPath) + invoke.GetVersionInfo(pluginPath, pluginExec) Expect(rawExec.ExecPluginCall.Received.PluginPath).To(Equal(pluginPath)) Expect(rawExec.ExecPluginCall.Received.Environ).To(ContainElement("CNI_COMMAND=VERSION")) expectedStdin, _ := json.Marshal(map[string]string{"cniVersion": version.Current()}) @@ -117,7 +136,7 @@ var _ = Describe("Executing a plugin, unit tests", func() { }) It("decodes and returns the version info", func() { - versionInfo, err := pluginExec.GetVersionInfo(pluginPath) + versionInfo, err := invoke.GetVersionInfo(pluginPath, pluginExec) Expect(err).NotTo(HaveOccurred()) Expect(versionInfo.SupportedVersions()).To(Equal([]string{"0.42.0"})) Expect(versionDecoder.DecodeCall.Received.JSONBytes).To(MatchJSON(`{ "some": "version-info" }`)) @@ -128,7 +147,7 @@ var _ = Describe("Executing a plugin, unit tests", func() { rawExec.ExecPluginCall.Returns.Error = errors.New("banana") }) It("returns the error", func() { - _, err := pluginExec.GetVersionInfo(pluginPath) + _, err := invoke.GetVersionInfo(pluginPath, pluginExec) Expect(err).To(MatchError("banana")) }) }) @@ -139,13 +158,13 @@ var _ = Describe("Executing a plugin, unit tests", func() { }) It("interprets the error as a 0.1.0 version", func() { - versionInfo, err := pluginExec.GetVersionInfo(pluginPath) + versionInfo, err := invoke.GetVersionInfo(pluginPath, pluginExec) Expect(err).NotTo(HaveOccurred()) Expect(versionInfo.SupportedVersions()).To(ConsistOf("0.1.0")) }) It("sets dummy values for env vars required by very old plugins", func() { - pluginExec.GetVersionInfo(pluginPath) + invoke.GetVersionInfo(pluginPath, pluginExec) env := rawExec.ExecPluginCall.Received.Environ Expect(env).To(ContainElement("CNI_NETNS=dummy")) diff --git a/vendor/github.com/containernetworking/cni/pkg/invoke/fakes/raw_exec.go b/vendor/github.com/containernetworking/cni/pkg/invoke/fakes/raw_exec.go index 5432cdf76..4a30ec1e7 100644 --- a/vendor/github.com/containernetworking/cni/pkg/invoke/fakes/raw_exec.go +++ b/vendor/github.com/containernetworking/cni/pkg/invoke/fakes/raw_exec.go @@ -26,6 +26,16 @@ type RawExec struct { Error error } } + FindInPathCall struct { + Received struct { + Plugin string + Paths []string + } + Returns struct { + Path string + Error error + } + } } func (e *RawExec) ExecPlugin(pluginPath string, stdinData []byte, environ []string) ([]byte, error) { @@ -34,3 +44,9 @@ func (e *RawExec) ExecPlugin(pluginPath string, stdinData []byte, environ []stri e.ExecPluginCall.Received.Environ = environ return e.ExecPluginCall.Returns.ResultBytes, e.ExecPluginCall.Returns.Error } + +func (e *RawExec) FindInPath(plugin string, paths []string) (string, error) { + e.FindInPathCall.Received.Plugin = plugin + e.FindInPathCall.Received.Paths = paths + return e.FindInPathCall.Returns.Path, e.FindInPathCall.Returns.Error +} diff --git a/vendor/github.com/containernetworking/cni/pkg/invoke/get_version_integration_test.go b/vendor/github.com/containernetworking/cni/pkg/invoke/get_version_integration_test.go index 7e58a9be3..bf552362a 100644 --- a/vendor/github.com/containernetworking/cni/pkg/invoke/get_version_integration_test.go +++ b/vendor/github.com/containernetworking/cni/pkg/invoke/get_version_integration_test.go @@ -18,6 +18,7 @@ import ( "io/ioutil" "os" "path/filepath" + "runtime" "github.com/containernetworking/cni/pkg/invoke" "github.com/containernetworking/cni/pkg/version" @@ -38,6 +39,9 @@ var _ = Describe("GetVersion, integration tests", func() { pluginDir, err := ioutil.TempDir("", "plugins") Expect(err).NotTo(HaveOccurred()) pluginPath = filepath.Join(pluginDir, "test-plugin") + if runtime.GOOS == "windows" { + pluginPath += ".exe" + } }) AfterEach(func() { @@ -47,7 +51,7 @@ var _ = Describe("GetVersion, integration tests", func() { DescribeTable("correctly reporting plugin versions", func(gitRef string, pluginSource string, expectedVersions version.PluginInfo) { Expect(testhelpers.BuildAt([]byte(pluginSource), gitRef, pluginPath)).To(Succeed()) - versionInfo, err := invoke.GetVersionInfo(pluginPath) + versionInfo, err := invoke.GetVersionInfo(pluginPath, nil) Expect(err).NotTo(HaveOccurred()) Expect(versionInfo.SupportedVersions()).To(ConsistOf(expectedVersions.SupportedVersions())) @@ -68,15 +72,36 @@ var _ = Describe("GetVersion, integration tests", func() { version.PluginSupports("0.2.0", "0.999.0"), ), + Entry("historical: before GET was introduced", + git_ref_v031, plugin_source_v020_custom_versions, + version.PluginSupports("0.2.0", "0.999.0"), + ), + // this entry tracks the current behavior. Before you change it, ensure // that its previous behavior is captured in the most recent "historical" entry Entry("current", - "HEAD", plugin_source_v020_custom_versions, - version.PluginSupports("0.2.0", "0.999.0"), + "HEAD", plugin_source_v040_get, + version.PluginSupports("0.2.0", "0.4.0", "0.999.0"), ), ) }) +// A 0.4.0 plugin that supports GET +const plugin_source_v040_get = `package main + +import ( + "github.com/containernetworking/cni/pkg/skel" + "github.com/containernetworking/cni/pkg/version" + "fmt" +) + +func c(_ *skel.CmdArgs) error { fmt.Println("{}"); return nil } + +func main() { skel.PluginMain(c, c, c, version.PluginSupports("0.2.0", "0.4.0", "0.999.0"), "") } +` + +const git_ref_v031 = "909fe7d" + // a 0.2.0 plugin that can report its own versions const plugin_source_v020_custom_versions = `package main diff --git a/vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go b/vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go index d1bd860d3..a598f09c2 100644 --- a/vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go +++ b/vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec.go @@ -50,14 +50,14 @@ func pluginErr(err error, output []byte) error { if _, ok := err.(*exec.ExitError); ok { emsg := types.Error{} if perr := json.Unmarshal(output, &emsg); perr != nil { - return fmt.Errorf("netplugin failed but error parsing its diagnostic message %q: %v", string(output), perr) + emsg.Msg = fmt.Sprintf("netplugin failed but error parsing its diagnostic message %q: %v", string(output), perr) } - details := "" - if emsg.Details != "" { - details = fmt.Sprintf("; %v", emsg.Details) - } - return fmt.Errorf("%v%v", emsg.Msg, details) + return &emsg } return err } + +func (e *RawExec) FindInPath(plugin string, paths []string) (string, error) { + return FindInPath(plugin, paths) +} diff --git a/vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec_test.go b/vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec_test.go index 5d759f249..e372e2f79 100644 --- a/vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec_test.go +++ b/vendor/github.com/containernetworking/cni/pkg/invoke/raw_exec_test.go @@ -58,7 +58,7 @@ var _ = Describe("RawExec", func() { "CNI_PATH=/some/bin/path", "CNI_IFNAME=some-eth0", } - stdin = []byte(`{"some":"stdin-json", "cniVersion": "0.3.1"}`) + stdin = []byte(`{"name": "raw-exec-test", "some":"stdin-json", "cniVersion": "0.3.1"}`) execer = &invoke.RawExec{} }) diff --git a/vendor/github.com/containernetworking/cni/pkg/ip/ipmasq.go b/vendor/github.com/containernetworking/cni/pkg/ip/ipmasq.go deleted file mode 100644 index 8ee279717..000000000 --- a/vendor/github.com/containernetworking/cni/pkg/ip/ipmasq.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2015 CNI authors -// -// 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. - -package ip - -import ( - "fmt" - "net" - - "github.com/coreos/go-iptables/iptables" -) - -// SetupIPMasq installs iptables rules to masquerade traffic -// coming from ipn and going outside of it -func SetupIPMasq(ipn *net.IPNet, chain string, comment string) error { - ipt, err := iptables.New() - if err != nil { - return fmt.Errorf("failed to locate iptables: %v", err) - } - - if err = ipt.NewChain("nat", chain); err != nil { - if err.(*iptables.Error).ExitStatus() != 1 { - // TODO(eyakubovich): assumes exit status 1 implies chain exists - return err - } - } - - if err = ipt.AppendUnique("nat", chain, "-d", ipn.String(), "-j", "ACCEPT", "-m", "comment", "--comment", comment); err != nil { - return err - } - - if err = ipt.AppendUnique("nat", chain, "!", "-d", "224.0.0.0/4", "-j", "MASQUERADE", "-m", "comment", "--comment", comment); err != nil { - return err - } - - return ipt.AppendUnique("nat", "POSTROUTING", "-s", ipn.String(), "-j", chain, "-m", "comment", "--comment", comment) -} - -// TeardownIPMasq undoes the effects of SetupIPMasq -func TeardownIPMasq(ipn *net.IPNet, chain string, comment string) error { - ipt, err := iptables.New() - if err != nil { - return fmt.Errorf("failed to locate iptables: %v", err) - } - - if err = ipt.Delete("nat", "POSTROUTING", "-s", ipn.String(), "-j", chain, "-m", "comment", "--comment", comment); err != nil { - return err - } - - if err = ipt.ClearChain("nat", chain); err != nil { - return err - } - - return ipt.DeleteChain("nat", chain) -} diff --git a/vendor/github.com/containernetworking/cni/pkg/ns/ns_linux.go b/vendor/github.com/containernetworking/cni/pkg/ns/ns_linux.go deleted file mode 100644 index c9e1b4f00..000000000 --- a/vendor/github.com/containernetworking/cni/pkg/ns/ns_linux.go +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright 2015-2017 CNI authors -// -// 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. - -package ns - -import ( - "crypto/rand" - "fmt" - "os" - "path" - "runtime" - "sync" - - "golang.org/x/sys/unix" -) - -// Returns an object representing the current OS thread's network namespace -func GetCurrentNS() (NetNS, error) { - return GetNS(getCurrentThreadNetNSPath()) -} - -func getCurrentThreadNetNSPath() string { - // /proc/self/ns/net returns the namespace of the main thread, not - // of whatever thread this goroutine is running on. Make sure we - // use the thread's net namespace since the thread is switching around - return fmt.Sprintf("/proc/%d/task/%d/ns/net", os.Getpid(), unix.Gettid()) -} - -// Creates a new persistent network namespace and returns an object -// representing that namespace, without switching to it -func NewNS() (NetNS, error) { - const nsRunDir = "/var/run/netns" - - b := make([]byte, 16) - _, err := rand.Reader.Read(b) - if err != nil { - return nil, fmt.Errorf("failed to generate random netns name: %v", err) - } - - err = os.MkdirAll(nsRunDir, 0755) - if err != nil { - return nil, err - } - - // create an empty file at the mount point - nsName := fmt.Sprintf("cni-%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:]) - nsPath := path.Join(nsRunDir, nsName) - mountPointFd, err := os.Create(nsPath) - if err != nil { - return nil, err - } - mountPointFd.Close() - - // Ensure the mount point is cleaned up on errors; if the namespace - // was successfully mounted this will have no effect because the file - // is in-use - defer os.RemoveAll(nsPath) - - var wg sync.WaitGroup - wg.Add(1) - - // do namespace work in a dedicated goroutine, so that we can safely - // Lock/Unlock OSThread without upsetting the lock/unlock state of - // the caller of this function - var fd *os.File - go (func() { - defer wg.Done() - runtime.LockOSThread() - - var origNS NetNS - origNS, err = GetNS(getCurrentThreadNetNSPath()) - if err != nil { - return - } - defer origNS.Close() - - // create a new netns on the current thread - err = unix.Unshare(unix.CLONE_NEWNET) - if err != nil { - return - } - defer origNS.Set() - - // bind mount the new netns from the current thread onto the mount point - err = unix.Mount(getCurrentThreadNetNSPath(), nsPath, "none", unix.MS_BIND, "") - if err != nil { - return - } - - fd, err = os.Open(nsPath) - if err != nil { - return - } - })() - wg.Wait() - - if err != nil { - unix.Unmount(nsPath, unix.MNT_DETACH) - return nil, fmt.Errorf("failed to create namespace: %v", err) - } - - return &netNS{file: fd, mounted: true}, nil -} - -func (ns *netNS) Close() error { - if err := ns.errorIfClosed(); err != nil { - return err - } - - if err := ns.file.Close(); err != nil { - return fmt.Errorf("Failed to close %q: %v", ns.file.Name(), err) - } - ns.closed = true - - if ns.mounted { - if err := unix.Unmount(ns.file.Name(), unix.MNT_DETACH); err != nil { - return fmt.Errorf("Failed to unmount namespace %s: %v", ns.file.Name(), err) - } - if err := os.RemoveAll(ns.file.Name()); err != nil { - return fmt.Errorf("Failed to clean up namespace %s: %v", ns.file.Name(), err) - } - ns.mounted = false - } - - return nil -} - -func (ns *netNS) Set() error { - if err := ns.errorIfClosed(); err != nil { - return err - } - - if _, _, err := unix.Syscall(unix.SYS_SETNS, ns.Fd(), uintptr(unix.CLONE_NEWNET), 0); err != 0 { - return fmt.Errorf("Error switching to ns %v: %v", ns.file.Name(), err) - } - - return nil -} diff --git a/vendor/github.com/containernetworking/cni/pkg/skel/skel.go b/vendor/github.com/containernetworking/cni/pkg/skel/skel.go index 8644c25eb..e565c85d0 100644 --- a/vendor/github.com/containernetworking/cni/pkg/skel/skel.go +++ b/vendor/github.com/containernetworking/cni/pkg/skel/skel.go @@ -17,6 +17,8 @@ package skel import ( + "bytes" + "encoding/json" "fmt" "io" "io/ioutil" @@ -63,6 +65,7 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, error) { &cmd, reqForCmdEntry{ "ADD": true, + "GET": true, "DEL": true, }, }, @@ -70,8 +73,9 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, error) { "CNI_CONTAINERID", &contID, reqForCmdEntry{ - "ADD": false, - "DEL": false, + "ADD": true, + "GET": true, + "DEL": true, }, }, { @@ -79,6 +83,7 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, error) { &netns, reqForCmdEntry{ "ADD": true, + "GET": true, "DEL": false, }, }, @@ -87,6 +92,7 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, error) { &ifName, reqForCmdEntry{ "ADD": true, + "GET": true, "DEL": true, }, }, @@ -95,6 +101,7 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, error) { &args, reqForCmdEntry{ "ADD": false, + "GET": false, "DEL": false, }, }, @@ -103,6 +110,7 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, error) { &path, reqForCmdEntry{ "ADD": true, + "GET": true, "DEL": true, }, }, @@ -123,6 +131,10 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, error) { return "", nil, fmt.Errorf("required env variables missing") } + if cmd == "VERSION" { + t.Stdin = bytes.NewReader(nil) + } + stdinData, err := ioutil.ReadAll(t.Stdin) if err != nil { return "", nil, fmt.Errorf("error reading from stdin: %v", err) @@ -159,18 +171,71 @@ func (t *dispatcher) checkVersionAndCall(cmdArgs *CmdArgs, pluginVersionInfo ver Details: verErr.Details(), } } + return toCall(cmdArgs) } -func (t *dispatcher) pluginMain(cmdAdd, cmdDel func(_ *CmdArgs) error, versionInfo version.PluginInfo) *types.Error { +func validateConfig(jsonBytes []byte) error { + var conf struct { + Name string `json:"name"` + } + if err := json.Unmarshal(jsonBytes, &conf); err != nil { + return fmt.Errorf("error reading network config: %s", err) + } + if conf.Name == "" { + return fmt.Errorf("missing network name") + } + return nil +} + +func (t *dispatcher) pluginMain(cmdAdd, cmdGet, cmdDel func(_ *CmdArgs) error, versionInfo version.PluginInfo, about string) *types.Error { cmd, cmdArgs, err := t.getCmdArgsFromEnv() if err != nil { + // Print the about string to stderr when no command is set + if t.Getenv("CNI_COMMAND") == "" && about != "" { + fmt.Fprintln(t.Stderr, about) + } return createTypedError(err.Error()) } + if cmd != "VERSION" { + err = validateConfig(cmdArgs.StdinData) + if err != nil { + return createTypedError(err.Error()) + } + } + switch cmd { case "ADD": err = t.checkVersionAndCall(cmdArgs, versionInfo, cmdAdd) + case "GET": + configVersion, err := t.ConfVersionDecoder.Decode(cmdArgs.StdinData) + if err != nil { + return createTypedError(err.Error()) + } + if gtet, err := version.GreaterThanOrEqualTo(configVersion, "0.4.0"); err != nil { + return createTypedError(err.Error()) + } else if !gtet { + return &types.Error{ + Code: types.ErrIncompatibleCNIVersion, + Msg: "config version does not allow GET", + } + } + for _, pluginVersion := range versionInfo.SupportedVersions() { + gtet, err := version.GreaterThanOrEqualTo(pluginVersion, configVersion) + if err != nil { + return createTypedError(err.Error()) + } else if gtet { + if err := t.checkVersionAndCall(cmdArgs, versionInfo, cmdGet); err != nil { + return createTypedError(err.Error()) + } + return nil + } + } + return &types.Error{ + Code: types.ErrIncompatibleCNIVersion, + Msg: "plugin version does not allow GET", + } case "DEL": err = t.checkVersionAndCall(cmdArgs, versionInfo, cmdDel) case "VERSION": @@ -190,7 +255,7 @@ func (t *dispatcher) pluginMain(cmdAdd, cmdDel func(_ *CmdArgs) error, versionIn } // PluginMainWithError is the core "main" for a plugin. It accepts -// callback functions for add and del CNI commands and returns an error. +// callback functions for add, get, and del CNI commands and returns an error. // // The caller must also specify what CNI spec versions the plugin supports. // @@ -201,25 +266,28 @@ func (t *dispatcher) pluginMain(cmdAdd, cmdDel func(_ *CmdArgs) error, versionIn // // To let this package automatically handle errors and call os.Exit(1) for you, // use PluginMain() instead. -func PluginMainWithError(cmdAdd, cmdDel func(_ *CmdArgs) error, versionInfo version.PluginInfo) *types.Error { +func PluginMainWithError(cmdAdd, cmdGet, cmdDel func(_ *CmdArgs) error, versionInfo version.PluginInfo, about string) *types.Error { return (&dispatcher{ Getenv: os.Getenv, Stdin: os.Stdin, Stdout: os.Stdout, Stderr: os.Stderr, - }).pluginMain(cmdAdd, cmdDel, versionInfo) + }).pluginMain(cmdAdd, cmdGet, cmdDel, versionInfo, about) } // PluginMain is the core "main" for a plugin which includes automatic error handling. // // The caller must also specify what CNI spec versions the plugin supports. // -// When an error occurs in either cmdAdd or cmdDel, PluginMain will print the error +// The caller can specify an "about" string, which is printed on stderr +// when no CNI_COMMAND is specified. The reccomended output is "CNI plugin v" +// +// When an error occurs in either cmdAdd, cmdGet, or cmdDel, PluginMain will print the error // as JSON to stdout and call os.Exit(1). // // To have more control over error handling, use PluginMainWithError() instead. -func PluginMain(cmdAdd, cmdDel func(_ *CmdArgs) error, versionInfo version.PluginInfo) { - if e := PluginMainWithError(cmdAdd, cmdDel, versionInfo); e != nil { +func PluginMain(cmdAdd, cmdGet, cmdDel func(_ *CmdArgs) error, versionInfo version.PluginInfo, about string) { + if e := PluginMainWithError(cmdAdd, cmdGet, cmdDel, versionInfo, about); e != nil { if err := e.Print(); err != nil { log.Print("Error writing error JSON to stdout: ", err) } diff --git a/vendor/github.com/containernetworking/cni/pkg/skel/skel_test.go b/vendor/github.com/containernetworking/cni/pkg/skel/skel_test.go index ad2930841..c261f2247 100644 --- a/vendor/github.com/containernetworking/cni/pkg/skel/skel_test.go +++ b/vendor/github.com/containernetworking/cni/pkg/skel/skel_test.go @@ -17,12 +17,13 @@ package skel import ( "bytes" "errors" + "fmt" "strings" "github.com/containernetworking/cni/pkg/types" + "github.com/containernetworking/cni/pkg/types/current" "github.com/containernetworking/cni/pkg/version" - "github.com/containernetworking/cni/pkg/testutils" . "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/extensions/table" . "github.com/onsi/gomega" @@ -46,13 +47,13 @@ func (c *fakeCmd) Func(args *CmdArgs) error { var _ = Describe("dispatching to the correct callback", func() { var ( - environment map[string]string - stdinData string - stdout, stderr *bytes.Buffer - cmdAdd, cmdDel *fakeCmd - dispatch *dispatcher - expectedCmdArgs *CmdArgs - versionInfo version.PluginInfo + environment map[string]string + stdinData string + stdout, stderr *bytes.Buffer + cmdAdd, cmdGet, cmdDel *fakeCmd + dispatch *dispatcher + expectedCmdArgs *CmdArgs + versionInfo version.PluginInfo ) BeforeEach(func() { @@ -65,7 +66,7 @@ var _ = Describe("dispatching to the correct callback", func() { "CNI_PATH": "/some/cni/path", } - stdinData = `{ "some": "config", "cniVersion": "9.8.7" }` + stdinData = `{ "name":"skel-test", "some": "config", "cniVersion": "9.8.7" }` stdout = &bytes.Buffer{} stderr = &bytes.Buffer{} versionInfo = version.PluginSupports("9.8.7") @@ -76,6 +77,7 @@ var _ = Describe("dispatching to the correct callback", func() { Stderr: stderr, } cmdAdd = &fakeCmd{} + cmdGet = &fakeCmd{} cmdDel = &fakeCmd{} expectedCmdArgs = &CmdArgs{ ContainerID: "some-container-id", @@ -90,7 +92,7 @@ var _ = Describe("dispatching to the correct callback", func() { var envVarChecker = func(envVar string, isRequired bool) { delete(environment, envVar) - err := dispatch.pluginMain(cmdAdd.Func, cmdDel.Func, versionInfo) + err := dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "") if isRequired { Expect(err).To(Equal(&types.Error{ Code: 100, @@ -104,24 +106,26 @@ var _ = Describe("dispatching to the correct callback", func() { Context("when the CNI_COMMAND is ADD", func() { It("extracts env vars and stdin data and calls cmdAdd", func() { - err := dispatch.pluginMain(cmdAdd.Func, cmdDel.Func, versionInfo) + err := dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "") Expect(err).NotTo(HaveOccurred()) Expect(cmdAdd.CallCount).To(Equal(1)) + Expect(cmdGet.CallCount).To(Equal(0)) Expect(cmdDel.CallCount).To(Equal(0)) Expect(cmdAdd.Received.CmdArgs).To(Equal(expectedCmdArgs)) }) - It("does not call cmdDel", func() { - err := dispatch.pluginMain(cmdAdd.Func, cmdDel.Func, versionInfo) + It("does not call cmdGet or cmdDel", func() { + err := dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "") Expect(err).NotTo(HaveOccurred()) + Expect(cmdGet.CallCount).To(Equal(0)) Expect(cmdDel.CallCount).To(Equal(0)) }) DescribeTable("required / optional env vars", envVarChecker, Entry("command", "CNI_COMMAND", true), - Entry("container id", "CNI_CONTAINERID", false), + Entry("container id", "CNI_CONTAINERID", true), Entry("net ns", "CNI_NETNS", true), Entry("if name", "CNI_IFNAME", true), Entry("args", "CNI_ARGS", false), @@ -136,7 +140,8 @@ var _ = Describe("dispatching to the correct callback", func() { }) It("reports that all of them are missing, not just the first", func() { - Expect(dispatch.pluginMain(cmdAdd.Func, cmdDel.Func, versionInfo)).NotTo(Succeed()) + Expect(dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "")).NotTo(Succeed()) + log := stderr.String() Expect(log).To(ContainSubstring("CNI_NETNS env variable missing\n")) Expect(log).To(ContainSubstring("CNI_IFNAME env variable missing\n")) @@ -147,17 +152,18 @@ var _ = Describe("dispatching to the correct callback", func() { Context("when the stdin data is missing the required cniVersion config", func() { BeforeEach(func() { - dispatch.Stdin = strings.NewReader(`{ "some": "config" }`) + dispatch.Stdin = strings.NewReader(`{ "name": "skel-test", "some": "config" }`) }) Context("when the plugin supports version 0.1.0", func() { BeforeEach(func() { versionInfo = version.PluginSupports("0.1.0") - expectedCmdArgs.StdinData = []byte(`{ "some": "config" }`) + expectedCmdArgs.StdinData = []byte(`{ "name": "skel-test", "some": "config" }`) }) It("infers the config is 0.1.0 and calls the cmdAdd callback", func() { - err := dispatch.pluginMain(cmdAdd.Func, cmdDel.Func, versionInfo) + + err := dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "") Expect(err).NotTo(HaveOccurred()) Expect(cmdAdd.CallCount).To(Equal(1)) @@ -171,28 +177,128 @@ var _ = Describe("dispatching to the correct callback", func() { }) It("immediately returns a useful error", func() { - err := dispatch.pluginMain(cmdAdd.Func, cmdDel.Func, versionInfo) + err := dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "") Expect(err.Code).To(Equal(types.ErrIncompatibleCNIVersion)) // see https://github.com/containernetworking/cni/blob/master/SPEC.md#well-known-error-codes Expect(err.Msg).To(Equal("incompatible CNI versions")) Expect(err.Details).To(Equal(`config is "0.1.0", plugin supports ["4.3.2"]`)) }) It("does not call either callback", func() { - dispatch.pluginMain(cmdAdd.Func, cmdDel.Func, versionInfo) + dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "") Expect(cmdAdd.CallCount).To(Equal(0)) + Expect(cmdGet.CallCount).To(Equal(0)) Expect(cmdDel.CallCount).To(Equal(0)) }) }) }) }) + Context("when the CNI_COMMAND is GET", func() { + BeforeEach(func() { + environment["CNI_COMMAND"] = "GET" + }) + + It("extracts env vars and stdin data and calls cmdGet", func() { + err := dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "") + + Expect(err).NotTo(HaveOccurred()) + Expect(cmdAdd.CallCount).To(Equal(0)) + Expect(cmdGet.CallCount).To(Equal(1)) + Expect(cmdDel.CallCount).To(Equal(0)) + Expect(cmdGet.Received.CmdArgs).To(Equal(expectedCmdArgs)) + }) + + It("does not call cmdAdd or cmdDel", func() { + err := dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "") + + Expect(err).NotTo(HaveOccurred()) + Expect(cmdAdd.CallCount).To(Equal(0)) + Expect(cmdDel.CallCount).To(Equal(0)) + }) + + DescribeTable("required / optional env vars", envVarChecker, + Entry("command", "CNI_COMMAND", true), + Entry("container id", "CNI_CONTAINERID", true), + Entry("net ns", "CNI_NETNS", true), + Entry("if name", "CNI_IFNAME", true), + Entry("args", "CNI_ARGS", false), + Entry("path", "CNI_PATH", true), + ) + + Context("when multiple required env vars are missing", func() { + BeforeEach(func() { + delete(environment, "CNI_NETNS") + delete(environment, "CNI_IFNAME") + delete(environment, "CNI_PATH") + }) + + It("reports that all of them are missing, not just the first", func() { + Expect(dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "")).NotTo(Succeed()) + log := stderr.String() + Expect(log).To(ContainSubstring("CNI_NETNS env variable missing\n")) + Expect(log).To(ContainSubstring("CNI_IFNAME env variable missing\n")) + Expect(log).To(ContainSubstring("CNI_PATH env variable missing\n")) + + }) + }) + + Context("when cniVersion is less than 0.4.0", func() { + It("immediately returns a useful error", func() { + dispatch.Stdin = strings.NewReader(`{ "name": "skel-test", "cniVersion": "0.3.0", "some": "config" }`) + err := dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "") + Expect(err.Code).To(Equal(types.ErrIncompatibleCNIVersion)) // see https://github.com/containernetworking/cni/blob/master/SPEC.md#well-known-error-codes + Expect(err.Msg).To(Equal("config version does not allow GET")) + Expect(cmdAdd.CallCount).To(Equal(0)) + Expect(cmdGet.CallCount).To(Equal(0)) + Expect(cmdDel.CallCount).To(Equal(0)) + }) + }) + + Context("when plugin does not support 0.4.0", func() { + It("immediately returns a useful error", func() { + dispatch.Stdin = strings.NewReader(`{ "name": "skel-test", "cniVersion": "0.4.0", "some": "config" }`) + versionInfo = version.PluginSupports("0.1.0", "0.2.0", "0.3.0") + err := dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "") + Expect(err.Code).To(Equal(types.ErrIncompatibleCNIVersion)) // see https://github.com/containernetworking/cni/blob/master/SPEC.md#well-known-error-codes + Expect(err.Msg).To(Equal("plugin version does not allow GET")) + Expect(cmdAdd.CallCount).To(Equal(0)) + Expect(cmdGet.CallCount).To(Equal(0)) + Expect(cmdDel.CallCount).To(Equal(0)) + }) + }) + + Context("when the config has a bad version", func() { + It("immediately returns a useful error", func() { + dispatch.Stdin = strings.NewReader(`{ "cniVersion": "adsfsadf", "some": "config" }`) + versionInfo = version.PluginSupports("0.1.0", "0.2.0", "0.3.0") + err := dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "") + Expect(err.Code).To(Equal(uint(100))) + Expect(cmdAdd.CallCount).To(Equal(0)) + Expect(cmdGet.CallCount).To(Equal(0)) + Expect(cmdDel.CallCount).To(Equal(0)) + }) + }) + + Context("when the plugin has a bad version", func() { + It("immediately returns a useful error", func() { + dispatch.Stdin = strings.NewReader(`{ "cniVersion": "0.4.0", "some": "config" }`) + versionInfo = version.PluginSupports("0.1.0", "0.2.0", "adsfasdf") + err := dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "") + Expect(err.Code).To(Equal(uint(100))) + Expect(cmdAdd.CallCount).To(Equal(0)) + Expect(cmdGet.CallCount).To(Equal(0)) + Expect(cmdDel.CallCount).To(Equal(0)) + }) + }) + }) + Context("when the CNI_COMMAND is DEL", func() { BeforeEach(func() { environment["CNI_COMMAND"] = "DEL" }) It("calls cmdDel with the env vars and stdin data", func() { - err := dispatch.pluginMain(cmdAdd.Func, cmdDel.Func, versionInfo) + err := dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "") Expect(err).NotTo(HaveOccurred()) Expect(cmdDel.CallCount).To(Equal(1)) @@ -200,7 +306,7 @@ var _ = Describe("dispatching to the correct callback", func() { }) It("does not call cmdAdd", func() { - err := dispatch.pluginMain(cmdAdd.Func, cmdDel.Func, versionInfo) + err := dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "") Expect(err).NotTo(HaveOccurred()) Expect(cmdAdd.CallCount).To(Equal(0)) @@ -208,7 +314,7 @@ var _ = Describe("dispatching to the correct callback", func() { DescribeTable("required / optional env vars", envVarChecker, Entry("command", "CNI_COMMAND", true), - Entry("container id", "CNI_CONTAINERID", false), + Entry("container id", "CNI_CONTAINERID", true), Entry("net ns", "CNI_NETNS", false), Entry("if name", "CNI_IFNAME", true), Entry("args", "CNI_ARGS", false), @@ -222,17 +328,17 @@ var _ = Describe("dispatching to the correct callback", func() { }) It("prints the version to stdout", func() { - err := dispatch.pluginMain(cmdAdd.Func, cmdDel.Func, versionInfo) + err := dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "") Expect(err).NotTo(HaveOccurred()) - Expect(stdout).To(MatchJSON(`{ - "cniVersion": "0.3.1", + Expect(stdout).To(MatchJSON(fmt.Sprintf(`{ + "cniVersion": "%s", "supportedVersions": ["9.8.7"] - }`)) + }`, current.ImplementedSpecVersion))) }) It("does not call cmdAdd or cmdDel", func() { - err := dispatch.pluginMain(cmdAdd.Func, cmdDel.Func, versionInfo) + err := dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "") Expect(err).NotTo(HaveOccurred()) Expect(cmdAdd.CallCount).To(Equal(0)) @@ -248,20 +354,18 @@ var _ = Describe("dispatching to the correct callback", func() { Entry("path", "CNI_PATH", false), ) - Context("when the stdin is empty", func() { - BeforeEach(func() { - dispatch.Stdin = strings.NewReader("") - }) + It("does not read from Stdin", func() { + r := &BadReader{} + dispatch.Stdin = r - It("succeeds without error", func() { - err := dispatch.pluginMain(cmdAdd.Func, cmdDel.Func, versionInfo) + err := dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "") - Expect(err).NotTo(HaveOccurred()) - Expect(stdout).To(MatchJSON(`{ - "cniVersion": "0.3.1", - "supportedVersions": ["9.8.7"] - }`)) - }) + Expect(err).NotTo(HaveOccurred()) + Expect(r.ReadCount).To(Equal(0)) + Expect(stdout).To(MatchJSON(fmt.Sprintf(`{ + "cniVersion": "%s", + "supportedVersions": ["9.8.7"] + }`, current.ImplementedSpecVersion))) }) }) @@ -271,36 +375,42 @@ var _ = Describe("dispatching to the correct callback", func() { }) It("does not call any cmd callback", func() { - dispatch.pluginMain(cmdAdd.Func, cmdDel.Func, versionInfo) + dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "") Expect(cmdAdd.CallCount).To(Equal(0)) Expect(cmdDel.CallCount).To(Equal(0)) }) It("returns an error", func() { - err := dispatch.pluginMain(cmdAdd.Func, cmdDel.Func, versionInfo) + err := dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "") Expect(err).To(Equal(&types.Error{ Code: 100, Msg: "unknown CNI_COMMAND: NOPE", })) }) + + It("prints the about string when the command is blank", func() { + environment["CNI_COMMAND"] = "" + dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "test framework v42") + Expect(stderr.String()).To(ContainSubstring("test framework v42")) + }) }) Context("when stdin cannot be read", func() { BeforeEach(func() { - dispatch.Stdin = &testutils.BadReader{} + dispatch.Stdin = &BadReader{} }) It("does not call any cmd callback", func() { - dispatch.pluginMain(cmdAdd.Func, cmdDel.Func, versionInfo) + dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "") Expect(cmdAdd.CallCount).To(Equal(0)) Expect(cmdDel.CallCount).To(Equal(0)) }) It("wraps and returns the error", func() { - err := dispatch.pluginMain(cmdAdd.Func, cmdDel.Func, versionInfo) + err := dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "") Expect(err).To(Equal(&types.Error{ Code: 100, @@ -319,7 +429,7 @@ var _ = Describe("dispatching to the correct callback", func() { }) It("returns the error as-is", func() { - err := dispatch.pluginMain(cmdAdd.Func, cmdDel.Func, versionInfo) + err := dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "") Expect(err).To(Equal(&types.Error{ Code: 1234, @@ -334,7 +444,7 @@ var _ = Describe("dispatching to the correct callback", func() { }) It("wraps and returns the error", func() { - err := dispatch.pluginMain(cmdAdd.Func, cmdDel.Func, versionInfo) + err := dispatch.pluginMain(cmdAdd.Func, cmdGet.Func, cmdDel.Func, versionInfo, "") Expect(err).To(Equal(&types.Error{ Code: 100, @@ -344,3 +454,21 @@ var _ = Describe("dispatching to the correct callback", func() { }) }) }) + +// BadReader is an io.Reader which always errors +type BadReader struct { + Error error + ReadCount int +} + +func (r *BadReader) Read(buffer []byte) (int, error) { + r.ReadCount++ + if r.Error != nil { + return 0, r.Error + } + return 0, errors.New("banana") +} + +func (r *BadReader) Close() error { + return nil +} diff --git a/vendor/github.com/containernetworking/cni/pkg/types/020/types.go b/vendor/github.com/containernetworking/cni/pkg/types/020/types.go index 666cfe93e..2833aba78 100644 --- a/vendor/github.com/containernetworking/cni/pkg/types/020/types.go +++ b/vendor/github.com/containernetworking/cni/pkg/types/020/types.go @@ -23,9 +23,9 @@ import ( "github.com/containernetworking/cni/pkg/types" ) -const implementedSpecVersion string = "0.2.0" +const ImplementedSpecVersion string = "0.2.0" -var SupportedVersions = []string{"", "0.1.0", implementedSpecVersion} +var SupportedVersions = []string{"", "0.1.0", ImplementedSpecVersion} // Compatibility types for CNI version 0.1.0 and 0.2.0 @@ -39,7 +39,7 @@ func NewResult(data []byte) (types.Result, error) { func GetResult(r types.Result) (*Result, error) { // We expect version 0.1.0/0.2.0 results - result020, err := r.GetAsVersion(implementedSpecVersion) + result020, err := r.GetAsVersion(ImplementedSpecVersion) if err != nil { return nil, err } @@ -52,18 +52,20 @@ func GetResult(r types.Result) (*Result, error) { // Result is what gets returned from the plugin (via stdout) to the caller type Result struct { - IP4 *IPConfig `json:"ip4,omitempty"` - IP6 *IPConfig `json:"ip6,omitempty"` - DNS types.DNS `json:"dns,omitempty"` + CNIVersion string `json:"cniVersion,omitempty"` + IP4 *IPConfig `json:"ip4,omitempty"` + IP6 *IPConfig `json:"ip6,omitempty"` + DNS types.DNS `json:"dns,omitempty"` } func (r *Result) Version() string { - return implementedSpecVersion + return ImplementedSpecVersion } func (r *Result) GetAsVersion(version string) (types.Result, error) { for _, supportedVersion := range SupportedVersions { if version == supportedVersion { + r.CNIVersion = version return r, nil } } diff --git a/vendor/github.com/containernetworking/cni/pkg/types/020/types_test.go b/vendor/github.com/containernetworking/cni/pkg/types/020/types_test.go index 1bcdda735..4f08ca496 100644 --- a/vendor/github.com/containernetworking/cni/pkg/types/020/types_test.go +++ b/vendor/github.com/containernetworking/cni/pkg/types/020/types_test.go @@ -48,6 +48,7 @@ var _ = Describe("Ensures compatibility with the 0.1.0/0.2.0 spec", func() { // Set every field of the struct to ensure source compatibility res := types020.Result{ + CNIVersion: types020.ImplementedSpecVersion, IP4: &types020.IPConfig{ IP: *ipv4, Gateway: net.ParseIP("1.2.3.1"), @@ -88,6 +89,7 @@ var _ = Describe("Ensures compatibility with the 0.1.0/0.2.0 spec", func() { Expect(err).NotTo(HaveOccurred()) Expect(string(out)).To(Equal(`{ + "cniVersion": "0.2.0", "ip4": { "ip": "1.2.3.30/24", "gateway": "1.2.3.1", diff --git a/vendor/github.com/containernetworking/cni/pkg/types/args.go b/vendor/github.com/containernetworking/cni/pkg/types/args.go index 66dcf9eae..bd8640fc9 100644 --- a/vendor/github.com/containernetworking/cni/pkg/types/args.go +++ b/vendor/github.com/containernetworking/cni/pkg/types/args.go @@ -63,6 +63,12 @@ func GetKeyField(keyString string, v reflect.Value) reflect.Value { return v.Elem().FieldByName(keyString) } +// UnmarshalableArgsError is used to indicate error unmarshalling args +// from the args-string in the form "K=V;K2=V2;..." +type UnmarshalableArgsError struct { + error +} + // LoadArgs parses args from a string in the form "K=V;K2=V2;..." func LoadArgs(args string, container interface{}) error { if args == "" { @@ -85,8 +91,13 @@ func LoadArgs(args string, container interface{}) error { unknownArgs = append(unknownArgs, pair) continue } - - u := keyField.Addr().Interface().(encoding.TextUnmarshaler) + keyFieldIface := keyField.Addr().Interface() + u, ok := keyFieldIface.(encoding.TextUnmarshaler) + if !ok { + return UnmarshalableArgsError{fmt.Errorf( + "ARGS: cannot unmarshal into field '%s' - type '%s' does not implement encoding.TextUnmarshaler", + keyString, reflect.TypeOf(keyFieldIface))} + } err := u.UnmarshalText([]byte(valueString)) if err != nil { return fmt.Errorf("ARGS: error parsing value of pair %q: %v)", pair, err) diff --git a/vendor/github.com/containernetworking/cni/pkg/types/args_test.go b/vendor/github.com/containernetworking/cni/pkg/types/args_test.go index 3a53d9a42..23772ca97 100644 --- a/vendor/github.com/containernetworking/cni/pkg/types/args_test.go +++ b/vendor/github.com/containernetworking/cni/pkg/types/args_test.go @@ -118,4 +118,15 @@ var _ = Describe("LoadArgs", func() { Expect(err).NotTo(HaveOccurred()) }) }) + + Context("When known arguments are passed and cannot be unmarshalled", func() { + It("LoadArgs should fail", func() { + conf := struct { + IP IPNet + }{} + err := LoadArgs("IP=10.0.0.0/24", &conf) + Expect(err).To(HaveOccurred()) + + }) + }) }) diff --git a/vendor/github.com/containernetworking/cni/pkg/types/current/types.go b/vendor/github.com/containernetworking/cni/pkg/types/current/types.go index b89a5d3a0..92980c1a7 100644 --- a/vendor/github.com/containernetworking/cni/pkg/types/current/types.go +++ b/vendor/github.com/containernetworking/cni/pkg/types/current/types.go @@ -24,9 +24,9 @@ import ( "github.com/containernetworking/cni/pkg/types/020" ) -const implementedSpecVersion string = "0.3.1" +const ImplementedSpecVersion string = "0.4.0" -var SupportedVersions = []string{"0.3.0", implementedSpecVersion} +var SupportedVersions = []string{"0.3.0", "0.3.1", ImplementedSpecVersion} func NewResult(data []byte) (types.Result, error) { result := &Result{} @@ -37,7 +37,7 @@ func NewResult(data []byte) (types.Result, error) { } func GetResult(r types.Result) (*Result, error) { - resultCurrent, err := r.GetAsVersion(implementedSpecVersion) + resultCurrent, err := r.GetAsVersion(ImplementedSpecVersion) if err != nil { return nil, err } @@ -63,16 +63,16 @@ func convertFrom020(result types.Result) (*Result, error) { } newResult := &Result{ - DNS: oldResult.DNS, - Routes: []*types.Route{}, + CNIVersion: ImplementedSpecVersion, + DNS: oldResult.DNS, + Routes: []*types.Route{}, } if oldResult.IP4 != nil { newResult.IPs = append(newResult.IPs, &IPConfig{ - Version: "4", - Interface: -1, - Address: oldResult.IP4.IP, - Gateway: oldResult.IP4.Gateway, + Version: "4", + Address: oldResult.IP4.IP, + Gateway: oldResult.IP4.Gateway, }) for _, route := range oldResult.IP4.Routes { gw := route.GW @@ -88,10 +88,9 @@ func convertFrom020(result types.Result) (*Result, error) { if oldResult.IP6 != nil { newResult.IPs = append(newResult.IPs, &IPConfig{ - Version: "6", - Interface: -1, - Address: oldResult.IP6.IP, - Gateway: oldResult.IP6.Gateway, + Version: "6", + Address: oldResult.IP6.IP, + Gateway: oldResult.IP6.Gateway, }) for _, route := range oldResult.IP6.Routes { gw := route.GW @@ -117,6 +116,7 @@ func convertFrom030(result types.Result) (*Result, error) { if !ok { return nil, fmt.Errorf("failed to convert result") } + newResult.CNIVersion = ImplementedSpecVersion return newResult, nil } @@ -134,6 +134,7 @@ func NewResultFromResult(result types.Result) (*Result, error) { // Result is what gets returned from the plugin (via stdout) to the caller type Result struct { + CNIVersion string `json:"cniVersion,omitempty"` Interfaces []*Interface `json:"interfaces,omitempty"` IPs []*IPConfig `json:"ips,omitempty"` Routes []*types.Route `json:"routes,omitempty"` @@ -143,7 +144,8 @@ type Result struct { // Convert to the older 0.2.0 CNI spec Result type func (r *Result) convertTo020() (*types020.Result, error) { oldResult := &types020.Result{ - DNS: r.DNS, + CNIVersion: types020.ImplementedSpecVersion, + DNS: r.DNS, } for _, ip := range r.IPs { @@ -189,12 +191,13 @@ func (r *Result) convertTo020() (*types020.Result, error) { } func (r *Result) Version() string { - return implementedSpecVersion + return ImplementedSpecVersion } func (r *Result) GetAsVersion(version string) (types.Result, error) { switch version { - case "0.3.0", implementedSpecVersion: + case "0.3.0", "0.3.1", ImplementedSpecVersion: + r.CNIVersion = version return r, nil case types020.SupportedVersions[0], types020.SupportedVersions[1], types020.SupportedVersions[2]: return r.convertTo020() @@ -244,12 +247,18 @@ func (i *Interface) String() string { return fmt.Sprintf("%+v", *i) } +// Int returns a pointer to the int value passed in. Used to +// set the IPConfig.Interface field. +func Int(v int) *int { + return &v +} + // IPConfig contains values necessary to configure an IP address on an interface type IPConfig struct { // IP version, either "4" or "6" Version string // Index into Result structs Interfaces list - Interface int + Interface *int Address net.IPNet Gateway net.IP } @@ -261,7 +270,7 @@ func (i *IPConfig) String() string { // JSON (un)marshallable types type ipConfig struct { Version string `json:"version"` - Interface int `json:"interface,omitempty"` + Interface *int `json:"interface,omitempty"` Address types.IPNet `json:"address"` Gateway net.IP `json:"gateway,omitempty"` } diff --git a/vendor/github.com/containernetworking/cni/pkg/types/current/types_test.go b/vendor/github.com/containernetworking/cni/pkg/types/current/types_test.go index 9d29cf225..29bd22fab 100644 --- a/vendor/github.com/containernetworking/cni/pkg/types/current/types_test.go +++ b/vendor/github.com/containernetworking/cni/pkg/types/current/types_test.go @@ -15,6 +15,7 @@ package current_test import ( + "encoding/json" "io/ioutil" "net" "os" @@ -47,6 +48,7 @@ func testResult() *current.Result { // Set every field of the struct to ensure source compatibility return ¤t.Result{ + CNIVersion: "0.3.1", Interfaces: []*current.Interface{ { Name: "eth0", @@ -57,13 +59,13 @@ func testResult() *current.Result { IPs: []*current.IPConfig{ { Version: "4", - Interface: 0, + Interface: current.Int(0), Address: *ipv4, Gateway: net.ParseIP("1.2.3.1"), }, { Version: "6", - Interface: 0, + Interface: current.Int(0), Address: *ipv6, Gateway: net.ParseIP("abcd:1234:ffff::1"), }, @@ -85,8 +87,6 @@ var _ = Describe("Current types operations", func() { It("correctly encodes a 0.3.x Result", func() { res := testResult() - Expect(res.String()).To(Equal("Interfaces:[{Name:eth0 Mac:00:11:22:33:44:55 Sandbox:/proc/3553/ns/net}], IP:[{Version:4 Interface:0 Address:{IP:1.2.3.30 Mask:ffffff00} Gateway:1.2.3.1} {Version:6 Interface:0 Address:{IP:abcd:1234:ffff::cdde Mask:ffffffffffffffff0000000000000000} Gateway:abcd:1234:ffff::1}], Routes:[{Dst:{IP:15.5.6.0 Mask:ffffff00} GW:15.5.6.8} {Dst:{IP:1111:dddd:: Mask:ffffffffffffffffffff000000000000} GW:1111:dddd::aaaa}], DNS:{Nameservers:[1.2.3.4 1::cafe] Domain:acompany.com Search:[somedomain.com otherdomain.net] Options:[foo bar]}")) - // Redirect stdout to capture JSON result oldStdout := os.Stdout r, w, err := os.Pipe() @@ -102,7 +102,8 @@ var _ = Describe("Current types operations", func() { os.Stdout = oldStdout Expect(err).NotTo(HaveOccurred()) - Expect(string(out)).To(Equal(`{ + Expect(string(out)).To(MatchJSON(`{ + "cniVersion": "0.3.1", "interfaces": [ { "name": "eth0", @@ -113,11 +114,13 @@ var _ = Describe("Current types operations", func() { "ips": [ { "version": "4", + "interface": 0, "address": "1.2.3.30/24", "gateway": "1.2.3.1" }, { "version": "6", + "interface": 0, "address": "abcd:1234:ffff::cdde/64", "gateway": "abcd:1234:ffff::1" } @@ -171,7 +174,8 @@ var _ = Describe("Current types operations", func() { os.Stdout = oldStdout Expect(err).NotTo(HaveOccurred()) - Expect(string(out)).To(Equal(`{ + Expect(string(out)).To(MatchJSON(`{ + "cniVersion": "0.2.0", "ip4": { "ip": "1.2.3.30/24", "gateway": "1.2.3.1", @@ -207,6 +211,54 @@ var _ = Describe("Current types operations", func() { "bar" ] } +}`)) + }) + + It("correctly marshals and unmarshals interface index 0", func() { + ipc := ¤t.IPConfig{ + Version: "4", + Interface: current.Int(0), + Address: net.IPNet{ + IP: net.ParseIP("10.1.2.3"), + Mask: net.IPv4Mask(255, 255, 255, 0), + }, + } + + jsonBytes, err := json.Marshal(ipc) + Expect(err).NotTo(HaveOccurred()) + Expect(jsonBytes).To(MatchJSON(`{ + "version": "4", + "interface": 0, + "address": "10.1.2.3/24" +}`)) + + recovered := ¤t.IPConfig{} + Expect(json.Unmarshal(jsonBytes, &recovered)).To(Succeed()) + Expect(recovered).To(Equal(ipc)) + }) + + Context("when unmarshaling json fails", func() { + It("returns an error", func() { + recovered := ¤t.IPConfig{} + err := json.Unmarshal([]byte(`{"address": 5}`), &recovered) + Expect(err).To(MatchError(HavePrefix("json: cannot unmarshal"))) + }) + }) + + It("correctly marshals a missing interface index", func() { + ipc := ¤t.IPConfig{ + Version: "4", + Address: net.IPNet{ + IP: net.ParseIP("10.1.2.3"), + Mask: net.IPv4Mask(255, 255, 255, 0), + }, + } + + json, err := json.Marshal(ipc) + Expect(err).NotTo(HaveOccurred()) + Expect(json).To(MatchJSON(`{ + "version": "4", + "address": "10.1.2.3/24" }`)) }) }) diff --git a/vendor/github.com/containernetworking/cni/pkg/types/types.go b/vendor/github.com/containernetworking/cni/pkg/types/types.go index 3263015af..4684a3207 100644 --- a/vendor/github.com/containernetworking/cni/pkg/types/types.go +++ b/vendor/github.com/containernetworking/cni/pkg/types/types.go @@ -63,10 +63,12 @@ type NetConf struct { Name string `json:"name,omitempty"` Type string `json:"type,omitempty"` Capabilities map[string]bool `json:"capabilities,omitempty"` - IPAM struct { - Type string `json:"type,omitempty"` - } `json:"ipam,omitempty"` - DNS DNS `json:"dns"` + IPAM IPAM `json:"ipam,omitempty"` + DNS DNS `json:"dns"` +} + +type IPAM struct { + Type string `json:"type,omitempty"` } // NetConfList describes an ordered list of networks. @@ -136,7 +138,11 @@ type Error struct { } func (e *Error) Error() string { - return e.Msg + details := "" + if e.Details != "" { + details = fmt.Sprintf("; %v", e.Details) + } + return fmt.Sprintf("%v%v", e.Msg, details) } func (e *Error) Print() error { @@ -163,7 +169,7 @@ func (r *Route) UnmarshalJSON(data []byte) error { return nil } -func (r *Route) MarshalJSON() ([]byte, error) { +func (r Route) MarshalJSON() ([]byte, error) { rt := route{ Dst: IPNet(r.Dst), GW: r.GW, diff --git a/vendor/github.com/containernetworking/cni/pkg/types/types_test.go b/vendor/github.com/containernetworking/cni/pkg/types/types_test.go new file mode 100644 index 000000000..b9e152bfe --- /dev/null +++ b/vendor/github.com/containernetworking/cni/pkg/types/types_test.go @@ -0,0 +1,141 @@ +// Copyright 2017 CNI authors +// +// 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. + +package types_test + +import ( + "encoding/json" + "net" + + "github.com/containernetworking/cni/pkg/types" + . "github.com/onsi/ginkgo" + . "github.com/onsi/ginkgo/extensions/table" + . "github.com/onsi/gomega" +) + +var _ = Describe("Types", func() { + + Describe("ParseCIDR", func() { + DescribeTable("Parse and stringify", + func(input, expectedIP string, expectedMask int) { + ipn, err := types.ParseCIDR(input) + Expect(err).NotTo(HaveOccurred()) + Expect(ipn.String()).To(Equal(input)) + + Expect(ipn.IP.String()).To(Equal(expectedIP)) + ones, _ := ipn.Mask.Size() + Expect(ones).To(Equal(expectedMask)) + }, + Entry("ipv4", "1.2.3.4/24", "1.2.3.4", 24), + Entry("ipv6", "2001:db8::/32", "2001:db8::", 32), + ) + It("returns an error when given invalid inputs", func() { + ipn, err := types.ParseCIDR("1.2.3/45") + Expect(ipn).To(BeNil()) + Expect(err).To(MatchError("invalid CIDR address: 1.2.3/45")) + }) + }) + + Describe("custom IPNet type", func() { + It("marshals and unmarshals to JSON as a string", func() { + ipn := types.IPNet{ + IP: net.ParseIP("1.2.3.4"), + Mask: net.CIDRMask(24, 32), + } + jsonBytes, err := json.Marshal(ipn) + Expect(err).NotTo(HaveOccurred()) + Expect(jsonBytes).To(MatchJSON(`"1.2.3.4/24"`)) + + var unmarshaled types.IPNet + Expect(json.Unmarshal(jsonBytes, &unmarshaled)).To(Succeed()) + Expect(unmarshaled).To(Equal(ipn)) + }) + + Context("when the json data is not syntactically valid", func() { + Specify("UnmarshalJSON returns an error", func() { + ipn := new(types.IPNet) + err := ipn.UnmarshalJSON([]byte("1")) + Expect(err).To(MatchError("json: cannot unmarshal number into Go value of type string")) + }) + }) + + Context("when the json data is not semantically valid", func() { + Specify("UnmarshalJSON returns an error", func() { + ipn := new(types.IPNet) + err := ipn.UnmarshalJSON([]byte(`"1.2.3.4/99"`)) + Expect(err).To(MatchError("invalid CIDR address: 1.2.3.4/99")) + }) + }) + }) + + Describe("custom Route type", func() { + var example types.Route + BeforeEach(func() { + example = types.Route{ + Dst: net.IPNet{ + IP: net.ParseIP("1.2.3.0"), + Mask: net.CIDRMask(24, 32), + }, + GW: net.ParseIP("1.2.3.1"), + } + }) + + It("marshals and unmarshals to JSON", func() { + jsonBytes, err := json.Marshal(example) + Expect(err).NotTo(HaveOccurred()) + Expect(jsonBytes).To(MatchJSON(`{ "dst": "1.2.3.0/24", "gw": "1.2.3.1" }`)) + + var unmarshaled types.Route + Expect(json.Unmarshal(jsonBytes, &unmarshaled)).To(Succeed()) + Expect(unmarshaled).To(Equal(example)) + }) + + Context("when the json data is not valid", func() { + Specify("UnmarshalJSON returns an error", func() { + route := new(types.Route) + err := route.UnmarshalJSON([]byte(`{ "dst": "1.2.3.0/24", "gw": "1.2.3.x" }`)) + Expect(err).To(MatchError("invalid IP address: 1.2.3.x")) + }) + }) + + It("formats as a string with a hex mask", func() { + Expect(example.String()).To(Equal(`{Dst:{IP:1.2.3.0 Mask:ffffff00} GW:1.2.3.1}`)) + }) + }) + + Describe("Error type", func() { + var example *types.Error + BeforeEach(func() { + example = &types.Error{ + Code: 1234, + Msg: "some message", + Details: "some details", + } + }) + + Describe("Error() method (basic string)", func() { + It("returns a formatted string", func() { + Expect(example.Error()).To(Equal("some message; some details")) + }) + Context("when details are not present", func() { + BeforeEach(func() { + example.Details = "" + }) + It("returns only the message", func() { + Expect(example.Error()).To(Equal("some message")) + }) + }) + }) + }) +}) diff --git a/vendor/github.com/containernetworking/cni/pkg/version/legacy_examples/example_runtime.go b/vendor/github.com/containernetworking/cni/pkg/version/legacy_examples/example_runtime.go index a461981f2..055d7930f 100644 --- a/vendor/github.com/containernetworking/cni/pkg/version/legacy_examples/example_runtime.go +++ b/vendor/github.com/containernetworking/cni/pkg/version/legacy_examples/example_runtime.go @@ -14,6 +14,14 @@ package legacy_examples +import ( + "fmt" + "io/ioutil" + "os" + + noop_debug "github.com/containernetworking/cni/plugins/test/noop/debug" +) + // An ExampleRuntime is a small program that uses libcni to invoke a network plugin. // It should call ADD and DELETE, verifying all intermediate steps // and data structures. @@ -22,30 +30,116 @@ type ExampleRuntime struct { NetConfs []string // The network configuration names to pass } -// NetConfs are various versioned network configuration files. Examples should -// specify which version they expect -var NetConfs = map[string]string{ - "unversioned": `{ - "name": "default", - "type": "ptp", - "ipam": { - "type": "host-local", - "subnet": "10.1.2.0/24" - } -}`, - "0.1.0": `{ - "cniVersion": "0.1.0", - "name": "default", - "type": "ptp", - "ipam": { - "type": "host-local", - "subnet": "10.1.2.0/24" - } -}`, +type exampleNetConfTemplate struct { + conf string + result string } -// V010_Runtime creates a simple ptp network configuration, then -// executes libcni against the currently-built plugins. +// NetConfs are various versioned network configuration files. Examples should +// specify which version they expect +var netConfTemplates = map[string]exampleNetConfTemplate{ + "unversioned": { + conf: `{ + "name": "default", + "type": "noop", + "debugFile": "%s" +}`, + result: `{ + "ip4": { + "ip": "1.2.3.30/24", + "gateway": "1.2.3.1", + "routes": [ + { + "dst": "15.5.6.0/24", + "gw": "15.5.6.8" + } + ] + }, + "ip6": { + "ip": "abcd:1234:ffff::cdde/64", + "gateway": "abcd:1234:ffff::1", + "routes": [ + { + "dst": "1111:dddd::/80", + "gw": "1111:dddd::aaaa" + } + ] + }, + "dns":{} +}`, + }, + "0.1.0": { + conf: `{ + "cniVersion": "0.1.0", + "name": "default", + "type": "noop", + "debugFile": "%s" +}`, + result: `{ + "cniVersion": "0.1.0", + "ip4": { + "ip": "1.2.3.30/24", + "gateway": "1.2.3.1", + "routes": [ + { + "dst": "15.5.6.0/24", + "gw": "15.5.6.8" + } + ] + }, + "ip6": { + "ip": "abcd:1234:ffff::cdde/64", + "gateway": "abcd:1234:ffff::1", + "routes": [ + { + "dst": "1111:dddd::/80", + "gw": "1111:dddd::aaaa" + } + ] + }, + "dns":{} +}`, + }, +} + +func (e *ExampleRuntime) GenerateNetConf(name string) (*ExampleNetConf, error) { + template, ok := netConfTemplates[name] + if !ok { + return nil, fmt.Errorf("unknown example net config template %q", name) + } + + debugFile, err := ioutil.TempFile("", "cni_debug") + if err != nil { + return nil, fmt.Errorf("failed to create noop plugin debug file: %v", err) + } + debugFilePath := debugFile.Name() + + debug := &noop_debug.Debug{ + ReportResult: template.result, + } + if err := debug.WriteDebug(debugFilePath); err != nil { + os.Remove(debugFilePath) + return nil, fmt.Errorf("failed to write noop plugin debug file %q: %v", debugFilePath, err) + } + conf := &ExampleNetConf{ + Config: fmt.Sprintf(template.conf, debugFilePath), + debugFilePath: debugFilePath, + } + + return conf, nil +} + +type ExampleNetConf struct { + Config string + debugFilePath string +} + +func (c *ExampleNetConf) Cleanup() { + os.Remove(c.debugFilePath) +} + +// V010_Runtime creates a simple noop network configuration, then +// executes libcni against the the noop test plugin. var V010_Runtime = ExampleRuntime{ NetConfs: []string{"unversioned", "0.1.0"}, Example: Example{ @@ -56,10 +150,8 @@ var V010_Runtime = ExampleRuntime{ import ( "fmt" "io/ioutil" - "net" "os" - "github.com/containernetworking/cni/pkg/ns" "github.com/containernetworking/cni/libcni" ) @@ -87,19 +179,10 @@ func exec() int { return 1 } - targetNs, err := ns.NewNS() - if err != nil { - fmt.Printf("Could not create ns: %+v", err) - return 1 - } - defer targetNs.Close() - - ifName := "eth0" - runtimeConf := &libcni.RuntimeConf{ ContainerID: "some-container-id", - NetNS: targetNs.Path(), - IfName: ifName, + NetNS: "/some/netns/path", + IfName: "eth0", } cniConfig := &libcni.CNIConfig{Path: os.Args[1:]} @@ -111,34 +194,15 @@ func exec() int { } fmt.Printf("AddNetwork result: %+v", result) - expectedIP := result.IP4.IP - - err = targetNs.Do(func(ns.NetNS) error { - netif, err := net.InterfaceByName(ifName) - if err != nil { - return fmt.Errorf("could not retrieve interface: %v", err) - } - - addrs, err := netif.Addrs() - if err != nil { - return fmt.Errorf("could not retrieve addresses, %+v", err) - } - - found := false - for _, addr := range addrs { - if addr.String() == expectedIP.String() { - found = true - break - } - } - - if !found { - return fmt.Errorf("Far-side link did not have expected address %s", expectedIP) - } - return nil - }) - if err != nil { - fmt.Println(err) + // Validate expected results + const expectedIP4 string = "1.2.3.30/24" + if result.IP4.IP.String() != expectedIP4 { + fmt.Printf("Expected IPv4 address %q, got %q", expectedIP4, result.IP4.IP.String()) + return 3 + } + const expectedIP6 string = "abcd:1234:ffff::cdde/64" + if result.IP6.IP.String() != expectedIP6 { + fmt.Printf("Expected IPv6 address %q, got %q", expectedIP6, result.IP6.IP.String()) return 4 } @@ -148,18 +212,6 @@ func exec() int { return 5 } - err = targetNs.Do(func(ns.NetNS) error { - _, err := net.InterfaceByName(ifName) - if err == nil { - return fmt.Errorf("interface was not deleted") - } - return nil - }) - if err != nil { - fmt.Println(err) - return 6 - } - return 0 } `, diff --git a/vendor/github.com/containernetworking/cni/pkg/version/legacy_examples/examples.go b/vendor/github.com/containernetworking/cni/pkg/version/legacy_examples/examples.go index 1bf406b33..787d83dc6 100644 --- a/vendor/github.com/containernetworking/cni/pkg/version/legacy_examples/examples.go +++ b/vendor/github.com/containernetworking/cni/pkg/version/legacy_examples/examples.go @@ -20,6 +20,7 @@ import ( "io/ioutil" "net" "path/filepath" + "runtime" "sync" "github.com/containernetworking/cni/pkg/types" @@ -61,6 +62,9 @@ func (e Example) Build() (string, error) { } outBinPath := filepath.Join(buildDir, e.Name) + if runtime.GOOS == "windows" { + outBinPath += ".exe" + } if err := testhelpers.BuildAt([]byte(e.PluginSource), e.CNIRepoGitRef, outBinPath); err != nil { return "", err diff --git a/vendor/github.com/containernetworking/cni/pkg/version/legacy_examples/legacy_examples_test.go b/vendor/github.com/containernetworking/cni/pkg/version/legacy_examples/legacy_examples_test.go index 411510565..3490eda49 100644 --- a/vendor/github.com/containernetworking/cni/pkg/version/legacy_examples/legacy_examples_test.go +++ b/vendor/github.com/containernetworking/cni/pkg/version/legacy_examples/legacy_examples_test.go @@ -17,6 +17,7 @@ package legacy_examples_test import ( "os" "path/filepath" + "runtime" "github.com/containernetworking/cni/pkg/version/legacy_examples" . "github.com/onsi/ginkgo" @@ -29,7 +30,11 @@ var _ = Describe("The v0.1.0 Example", func() { pluginPath, err := example.Build() Expect(err).NotTo(HaveOccurred()) - Expect(filepath.Base(pluginPath)).To(Equal(example.Name)) + expectedBaseName := example.Name + if runtime.GOOS == "windows" { + expectedBaseName += ".exe" + } + Expect(filepath.Base(pluginPath)).To(Equal(expectedBaseName)) Expect(os.RemoveAll(pluginPath)).To(Succeed()) }) diff --git a/vendor/github.com/containernetworking/cni/pkg/version/plugin.go b/vendor/github.com/containernetworking/cni/pkg/version/plugin.go index 8a4672810..612335a81 100644 --- a/vendor/github.com/containernetworking/cni/pkg/version/plugin.go +++ b/vendor/github.com/containernetworking/cni/pkg/version/plugin.go @@ -18,6 +18,8 @@ import ( "encoding/json" "fmt" "io" + "strconv" + "strings" ) // PluginInfo reports information about CNI versioning @@ -79,3 +81,60 @@ func (*PluginDecoder) Decode(jsonBytes []byte) (PluginInfo, error) { } return &info, nil } + +// ParseVersion parses a version string like "3.0.1" or "0.4.5" into major, +// minor, and micro numbers or returns an error +func ParseVersion(version string) (int, int, int, error) { + var major, minor, micro int + parts := strings.Split(version, ".") + if len(parts) == 0 || len(parts) >= 4 { + return -1, -1, -1, fmt.Errorf("invalid version %q: too many or too few parts", version) + } + + major, err := strconv.Atoi(parts[0]) + if err != nil { + return -1, -1, -1, fmt.Errorf("failed to convert major version part %q: %v", parts[0], err) + } + + if len(parts) >= 2 { + minor, err = strconv.Atoi(parts[1]) + if err != nil { + return -1, -1, -1, fmt.Errorf("failed to convert minor version part %q: %v", parts[1], err) + } + } + + if len(parts) >= 3 { + micro, err = strconv.Atoi(parts[2]) + if err != nil { + return -1, -1, -1, fmt.Errorf("failed to convert micro version part %q: %v", parts[2], err) + } + } + + return major, minor, micro, nil +} + +// GreaterThanOrEqualTo takes two string versions, parses them into major/minor/micro +// nubmers, and compares them to determine whether the first version is greater +// than or equal to the second +func GreaterThanOrEqualTo(version, otherVersion string) (bool, error) { + firstMajor, firstMinor, firstMicro, err := ParseVersion(version) + if err != nil { + return false, err + } + + secondMajor, secondMinor, secondMicro, err := ParseVersion(otherVersion) + if err != nil { + return false, err + } + + if firstMajor > secondMajor { + return true, nil + } else if firstMajor == secondMajor { + if firstMinor > secondMinor { + return true, nil + } else if firstMinor == secondMinor && firstMicro >= secondMicro { + return true, nil + } + } + return false, nil +} diff --git a/vendor/github.com/containernetworking/cni/pkg/version/plugin_test.go b/vendor/github.com/containernetworking/cni/pkg/version/plugin_test.go index 124288fd4..bf25085d3 100644 --- a/vendor/github.com/containernetworking/cni/pkg/version/plugin_test.go +++ b/vendor/github.com/containernetworking/cni/pkg/version/plugin_test.go @@ -82,4 +82,60 @@ var _ = Describe("Decoding versions reported by a plugin", func() { }) }) + Describe("ParseVersion", func() { + It("parses a valid version correctly", func() { + major, minor, micro, err := version.ParseVersion("1.2.3") + Expect(err).NotTo(HaveOccurred()) + Expect(major).To(Equal(1)) + Expect(minor).To(Equal(2)) + Expect(micro).To(Equal(3)) + }) + + It("returns an error for malformed versions", func() { + badVersions := []string{"asdfasdf", "asdf.", ".asdfas", "asdf.adsf.", "0.", "..", "1.2.3.4.5"} + for _, v := range badVersions { + _, _, _, err := version.ParseVersion(v) + Expect(err).To(HaveOccurred()) + } + }) + }) + + Describe("GreaterThanOrEqualTo", func() { + It("correctly compares versions", func() { + versions := [][2]string{ + {"1.2.34", "1.2.14"}, + {"2.5.4", "2.4.4"}, + {"1.2.3", "0.2.3"}, + {"0.4.0", "0.3.1"}, + } + for _, v := range versions { + // Make sure the first is greater than the second + gt, err := version.GreaterThanOrEqualTo(v[0], v[1]) + Expect(err).NotTo(HaveOccurred()) + Expect(gt).To(Equal(true)) + + // And the opposite + gt, err = version.GreaterThanOrEqualTo(v[1], v[0]) + Expect(err).NotTo(HaveOccurred()) + Expect(gt).To(Equal(false)) + } + }) + + It("returns true when versions are the same", func() { + gt, err := version.GreaterThanOrEqualTo("1.2.3", "1.2.3") + Expect(err).NotTo(HaveOccurred()) + Expect(gt).To(Equal(true)) + }) + + It("returns an error for malformed versions", func() { + versions := [][2]string{ + {"1.2.34", "asdadf"}, + {"adsfad", "2.5.4"}, + } + for _, v := range versions { + _, err := version.GreaterThanOrEqualTo(v[0], v[1]) + Expect(err).To(HaveOccurred()) + } + }) + }) }) diff --git a/vendor/github.com/containernetworking/cni/pkg/version/testhelpers/testhelpers_test.go b/vendor/github.com/containernetworking/cni/pkg/version/testhelpers/testhelpers_test.go index 3473cd595..4fe070f73 100644 --- a/vendor/github.com/containernetworking/cni/pkg/version/testhelpers/testhelpers_test.go +++ b/vendor/github.com/containernetworking/cni/pkg/version/testhelpers/testhelpers_test.go @@ -18,6 +18,7 @@ import ( "os" "os/exec" "path/filepath" + "runtime" "github.com/containernetworking/cni/pkg/version/testhelpers" . "github.com/onsi/ginkgo" @@ -46,6 +47,9 @@ func main() { skel.PluginMain(c, c) } outputDir, err = ioutil.TempDir("", "bin") Expect(err).NotTo(HaveOccurred()) outputFilePath = filepath.Join(outputDir, "some-binary") + if runtime.GOOS == "windows" { + outputFilePath += ".exe" + } }) AfterEach(func() { diff --git a/vendor/github.com/containernetworking/cni/pkg/version/version.go b/vendor/github.com/containernetworking/cni/pkg/version/version.go index efe8ea871..c8e46d55b 100644 --- a/vendor/github.com/containernetworking/cni/pkg/version/version.go +++ b/vendor/github.com/containernetworking/cni/pkg/version/version.go @@ -24,7 +24,7 @@ import ( // Current reports the version of the CNI spec implemented by this library func Current() string { - return "0.3.1" + return "0.4.0" } // Legacy PluginInfo describes a plugin that is backwards compatible with the @@ -35,7 +35,7 @@ func Current() string { // Any future CNI spec versions which meet this definition should be added to // this list. var Legacy = PluginSupports("0.1.0", "0.2.0") -var All = PluginSupports("0.1.0", "0.2.0", "0.3.0", "0.3.1") +var All = PluginSupports("0.1.0", "0.2.0", "0.3.0", "0.3.1", "0.4.0") var resultFactories = []struct { supportedVersions []string diff --git a/vendor/github.com/containernetworking/cni/plugins/ipam/host-local/backend/allocator/allocator.go b/vendor/github.com/containernetworking/cni/plugins/ipam/host-local/backend/allocator/allocator.go deleted file mode 100644 index c3211fc2d..000000000 --- a/vendor/github.com/containernetworking/cni/plugins/ipam/host-local/backend/allocator/allocator.go +++ /dev/null @@ -1,277 +0,0 @@ -// Copyright 2015 CNI authors -// -// 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. - -package allocator - -import ( - "fmt" - "log" - "net" - "os" - - "github.com/containernetworking/cni/pkg/ip" - "github.com/containernetworking/cni/pkg/types" - "github.com/containernetworking/cni/pkg/types/current" - "github.com/containernetworking/cni/plugins/ipam/host-local/backend" -) - -type IPAllocator struct { - // start is inclusive and may be allocated - start net.IP - // end is inclusive and may be allocated - end net.IP - conf *IPAMConfig - store backend.Store -} - -func NewIPAllocator(conf *IPAMConfig, store backend.Store) (*IPAllocator, error) { - // Can't create an allocator for a network with no addresses, eg - // a /32 or /31 - ones, masklen := conf.Subnet.Mask.Size() - if ones > masklen-2 { - return nil, fmt.Errorf("Network %v too small to allocate from", conf.Subnet) - } - - var ( - start net.IP - end net.IP - err error - ) - start, end, err = networkRange((*net.IPNet)(&conf.Subnet)) - if err != nil { - return nil, err - } - - // skip the .0 address - start = ip.NextIP(start) - - if conf.RangeStart != nil { - if err := validateRangeIP(conf.RangeStart, (*net.IPNet)(&conf.Subnet), nil, nil); err != nil { - return nil, err - } - start = conf.RangeStart - } - if conf.RangeEnd != nil { - if err := validateRangeIP(conf.RangeEnd, (*net.IPNet)(&conf.Subnet), start, nil); err != nil { - return nil, err - } - end = conf.RangeEnd - } - return &IPAllocator{start, end, conf, store}, nil -} - -func canonicalizeIP(ip net.IP) (net.IP, error) { - if ip.To4() != nil { - return ip.To4(), nil - } else if ip.To16() != nil { - return ip.To16(), nil - } - return nil, fmt.Errorf("IP %s not v4 nor v6", ip) -} - -// Ensures @ip is within @ipnet, and (if given) inclusive of @start and @end -func validateRangeIP(ip net.IP, ipnet *net.IPNet, start net.IP, end net.IP) error { - var err error - - // Make sure we can compare IPv4 addresses directly - ip, err = canonicalizeIP(ip) - if err != nil { - return err - } - - if !ipnet.Contains(ip) { - return fmt.Errorf("%s not in network: %s", ip, ipnet) - } - - if start != nil { - start, err = canonicalizeIP(start) - if err != nil { - return err - } - if len(ip) != len(start) { - return fmt.Errorf("%s %d not same size IP address as start %s %d", ip, len(ip), start, len(start)) - } - for i := 0; i < len(ip); i++ { - if ip[i] > start[i] { - break - } else if ip[i] < start[i] { - return fmt.Errorf("%s outside of network %s with start %s", ip, ipnet, start) - } - } - } - - if end != nil { - end, err = canonicalizeIP(end) - if err != nil { - return err - } - if len(ip) != len(end) { - return fmt.Errorf("%s %d not same size IP address as end %s %d", ip, len(ip), end, len(end)) - } - for i := 0; i < len(ip); i++ { - if ip[i] < end[i] { - break - } else if ip[i] > end[i] { - return fmt.Errorf("%s outside of network %s with end %s", ip, ipnet, end) - } - } - } - return nil -} - -// Returns newly allocated IP along with its config -func (a *IPAllocator) Get(id string) (*current.IPConfig, []*types.Route, error) { - a.store.Lock() - defer a.store.Unlock() - - gw := a.conf.Gateway - if gw == nil { - gw = ip.NextIP(a.conf.Subnet.IP) - } - - var requestedIP net.IP - if a.conf.Args != nil { - requestedIP = a.conf.Args.IP - } - - if requestedIP != nil { - if gw != nil && gw.Equal(a.conf.Args.IP) { - return nil, nil, fmt.Errorf("requested IP must differ gateway IP") - } - - subnet := net.IPNet{ - IP: a.conf.Subnet.IP, - Mask: a.conf.Subnet.Mask, - } - err := validateRangeIP(requestedIP, &subnet, a.start, a.end) - if err != nil { - return nil, nil, err - } - - reserved, err := a.store.Reserve(id, requestedIP) - if err != nil { - return nil, nil, err - } - - if reserved { - ipConfig := ¤t.IPConfig{ - Version: "4", - Address: net.IPNet{IP: requestedIP, Mask: a.conf.Subnet.Mask}, - Gateway: gw, - } - routes := convertRoutesToCurrent(a.conf.Routes) - return ipConfig, routes, nil - } - return nil, nil, fmt.Errorf("requested IP address %q is not available in network: %s", requestedIP, a.conf.Name) - } - - startIP, endIP := a.getSearchRange() - for cur := startIP; ; cur = a.nextIP(cur) { - // don't allocate gateway IP - if gw != nil && cur.Equal(gw) { - continue - } - - reserved, err := a.store.Reserve(id, cur) - if err != nil { - return nil, nil, err - } - if reserved { - ipConfig := ¤t.IPConfig{ - Version: "4", - Address: net.IPNet{IP: cur, Mask: a.conf.Subnet.Mask}, - Gateway: gw, - } - routes := convertRoutesToCurrent(a.conf.Routes) - return ipConfig, routes, nil - } - // break here to complete the loop - if cur.Equal(endIP) { - break - } - } - return nil, nil, fmt.Errorf("no IP addresses available in network: %s", a.conf.Name) -} - -// Releases all IPs allocated for the container with given ID -func (a *IPAllocator) Release(id string) error { - a.store.Lock() - defer a.store.Unlock() - - return a.store.ReleaseByID(id) -} - -// Return the start and end IP addresses of a given subnet, excluding -// the broadcast address (eg, 192.168.1.255) -func networkRange(ipnet *net.IPNet) (net.IP, net.IP, error) { - if ipnet.IP == nil { - return nil, nil, fmt.Errorf("missing field %q in IPAM configuration", "subnet") - } - ip, err := canonicalizeIP(ipnet.IP) - if err != nil { - return nil, nil, fmt.Errorf("IP not v4 nor v6") - } - - if len(ip) != len(ipnet.Mask) { - return nil, nil, fmt.Errorf("IPNet IP and Mask version mismatch") - } - - var end net.IP - for i := 0; i < len(ip); i++ { - end = append(end, ip[i]|^ipnet.Mask[i]) - } - - // Exclude the broadcast address for IPv4 - if ip.To4() != nil { - end[3]-- - } - - return ipnet.IP, end, nil -} - -// nextIP returns the next ip of curIP within ipallocator's subnet -func (a *IPAllocator) nextIP(curIP net.IP) net.IP { - if curIP.Equal(a.end) { - return a.start - } - return ip.NextIP(curIP) -} - -// getSearchRange returns the start and end ip based on the last reserved ip -func (a *IPAllocator) getSearchRange() (net.IP, net.IP) { - var startIP net.IP - var endIP net.IP - startFromLastReservedIP := false - lastReservedIP, err := a.store.LastReservedIP() - if err != nil && !os.IsNotExist(err) { - log.Printf("Error retriving last reserved ip: %v", err) - } else if lastReservedIP != nil { - subnet := net.IPNet{ - IP: a.conf.Subnet.IP, - Mask: a.conf.Subnet.Mask, - } - err := validateRangeIP(lastReservedIP, &subnet, a.start, a.end) - if err == nil { - startFromLastReservedIP = true - } - } - if startFromLastReservedIP { - startIP = a.nextIP(lastReservedIP) - endIP = lastReservedIP - } else { - startIP = a.start - endIP = a.end - } - return startIP, endIP -} diff --git a/vendor/github.com/containernetworking/cni/plugins/ipam/host-local/backend/allocator/allocator_test.go b/vendor/github.com/containernetworking/cni/plugins/ipam/host-local/backend/allocator/allocator_test.go deleted file mode 100644 index 147fe2592..000000000 --- a/vendor/github.com/containernetworking/cni/plugins/ipam/host-local/backend/allocator/allocator_test.go +++ /dev/null @@ -1,356 +0,0 @@ -// Copyright 2016 CNI authors -// -// 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. - -package allocator - -import ( - "fmt" - "github.com/containernetworking/cni/pkg/types" - "github.com/containernetworking/cni/pkg/types/current" - fakestore "github.com/containernetworking/cni/plugins/ipam/host-local/backend/testing" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "net" -) - -type AllocatorTestCase struct { - subnet string - ipmap map[string]string - expectResult string - lastIP string -} - -func (t AllocatorTestCase) run() (*current.IPConfig, []*types.Route, error) { - subnet, err := types.ParseCIDR(t.subnet) - if err != nil { - return nil, nil, err - } - - conf := IPAMConfig{ - Name: "test", - Type: "host-local", - Subnet: types.IPNet{IP: subnet.IP, Mask: subnet.Mask}, - } - store := fakestore.NewFakeStore(t.ipmap, net.ParseIP(t.lastIP)) - alloc, err := NewIPAllocator(&conf, store) - if err != nil { - return nil, nil, err - } - res, routes, err := alloc.Get("ID") - if err != nil { - return nil, nil, err - } - - return res, routes, nil -} - -var _ = Describe("host-local ip allocator", func() { - Context("when has free ip", func() { - It("should allocate ips in round robin", func() { - testCases := []AllocatorTestCase{ - // fresh start - { - subnet: "10.0.0.0/29", - ipmap: map[string]string{}, - expectResult: "10.0.0.2", - lastIP: "", - }, - { - subnet: "10.0.0.0/30", - ipmap: map[string]string{}, - expectResult: "10.0.0.2", - lastIP: "", - }, - { - subnet: "10.0.0.0/29", - ipmap: map[string]string{ - "10.0.0.2": "id", - }, - expectResult: "10.0.0.3", - lastIP: "", - }, - // next ip of last reserved ip - { - subnet: "10.0.0.0/29", - ipmap: map[string]string{}, - expectResult: "10.0.0.6", - lastIP: "10.0.0.5", - }, - { - subnet: "10.0.0.0/29", - ipmap: map[string]string{ - "10.0.0.4": "id", - "10.0.0.5": "id", - }, - expectResult: "10.0.0.6", - lastIP: "10.0.0.3", - }, - // round robin to the beginning - { - subnet: "10.0.0.0/29", - ipmap: map[string]string{ - "10.0.0.6": "id", - }, - expectResult: "10.0.0.2", - lastIP: "10.0.0.5", - }, - // lastIP is out of range - { - subnet: "10.0.0.0/29", - ipmap: map[string]string{ - "10.0.0.2": "id", - }, - expectResult: "10.0.0.3", - lastIP: "10.0.0.128", - }, - // wrap around and reserve lastIP - { - subnet: "10.0.0.0/29", - ipmap: map[string]string{ - "10.0.0.2": "id", - "10.0.0.4": "id", - "10.0.0.5": "id", - "10.0.0.6": "id", - }, - expectResult: "10.0.0.3", - lastIP: "10.0.0.3", - }, - } - - for _, tc := range testCases { - res, _, err := tc.run() - Expect(err).ToNot(HaveOccurred()) - Expect(res.Address.IP.String()).To(Equal(tc.expectResult)) - } - }) - - It("should not allocate the broadcast address", func() { - subnet, err := types.ParseCIDR("192.168.1.0/24") - Expect(err).ToNot(HaveOccurred()) - - conf := IPAMConfig{ - Name: "test", - Type: "host-local", - Subnet: types.IPNet{IP: subnet.IP, Mask: subnet.Mask}, - } - store := fakestore.NewFakeStore(map[string]string{}, net.ParseIP("")) - alloc, err := NewIPAllocator(&conf, store) - Expect(err).ToNot(HaveOccurred()) - - for i := 1; i < 254; i++ { - res, _, err := alloc.Get("ID") - Expect(err).ToNot(HaveOccurred()) - // i+1 because the gateway address is skipped - s := fmt.Sprintf("192.168.1.%d/24", i+1) - Expect(s).To(Equal(res.Address.String())) - } - - _, _, err = alloc.Get("ID") - Expect(err).To(HaveOccurred()) - }) - - It("should allocate RangeStart first", func() { - subnet, err := types.ParseCIDR("192.168.1.0/24") - Expect(err).ToNot(HaveOccurred()) - - conf := IPAMConfig{ - Name: "test", - Type: "host-local", - Subnet: types.IPNet{IP: subnet.IP, Mask: subnet.Mask}, - RangeStart: net.ParseIP("192.168.1.10"), - } - store := fakestore.NewFakeStore(map[string]string{}, net.ParseIP("")) - alloc, err := NewIPAllocator(&conf, store) - Expect(err).ToNot(HaveOccurred()) - - res, _, err := alloc.Get("ID") - Expect(err).ToNot(HaveOccurred()) - Expect(res.Address.String()).To(Equal("192.168.1.10/24")) - - res, _, err = alloc.Get("ID") - Expect(err).ToNot(HaveOccurred()) - Expect(res.Address.String()).To(Equal("192.168.1.11/24")) - }) - - It("should allocate RangeEnd but not past RangeEnd", func() { - subnet, err := types.ParseCIDR("192.168.1.0/24") - Expect(err).ToNot(HaveOccurred()) - - conf := IPAMConfig{ - Name: "test", - Type: "host-local", - Subnet: types.IPNet{IP: subnet.IP, Mask: subnet.Mask}, - RangeEnd: net.ParseIP("192.168.1.5"), - } - store := fakestore.NewFakeStore(map[string]string{}, net.ParseIP("")) - alloc, err := NewIPAllocator(&conf, store) - Expect(err).ToNot(HaveOccurred()) - - for i := 1; i < 5; i++ { - res, _, err := alloc.Get("ID") - Expect(err).ToNot(HaveOccurred()) - // i+1 because the gateway address is skipped - Expect(res.Address.String()).To(Equal(fmt.Sprintf("192.168.1.%d/24", i+1))) - } - - _, _, err = alloc.Get("ID") - Expect(err).To(HaveOccurred()) - }) - - Context("when requesting a specific IP", func() { - It("must allocate the requested IP", func() { - subnet, err := types.ParseCIDR("10.0.0.0/29") - Expect(err).ToNot(HaveOccurred()) - requestedIP := net.ParseIP("10.0.0.2") - ipmap := map[string]string{} - conf := IPAMConfig{ - Name: "test", - Type: "host-local", - Subnet: types.IPNet{IP: subnet.IP, Mask: subnet.Mask}, - Args: &IPAMArgs{IP: requestedIP}, - } - store := fakestore.NewFakeStore(ipmap, nil) - alloc, _ := NewIPAllocator(&conf, store) - res, _, err := alloc.Get("ID") - Expect(err).ToNot(HaveOccurred()) - Expect(res.Address.IP.String()).To(Equal(requestedIP.String())) - }) - - It("must return an error when the requested IP is after RangeEnd", func() { - subnet, err := types.ParseCIDR("192.168.1.0/24") - Expect(err).ToNot(HaveOccurred()) - ipmap := map[string]string{} - conf := IPAMConfig{ - Name: "test", - Type: "host-local", - Subnet: types.IPNet{IP: subnet.IP, Mask: subnet.Mask}, - Args: &IPAMArgs{IP: net.ParseIP("192.168.1.50")}, - RangeEnd: net.ParseIP("192.168.1.20"), - } - store := fakestore.NewFakeStore(ipmap, nil) - alloc, _ := NewIPAllocator(&conf, store) - _, _, err = alloc.Get("ID") - Expect(err).To(HaveOccurred()) - }) - - It("must return an error when the requested IP is before RangeStart", func() { - subnet, err := types.ParseCIDR("192.168.1.0/24") - Expect(err).ToNot(HaveOccurred()) - ipmap := map[string]string{} - conf := IPAMConfig{ - Name: "test", - Type: "host-local", - Subnet: types.IPNet{IP: subnet.IP, Mask: subnet.Mask}, - Args: &IPAMArgs{IP: net.ParseIP("192.168.1.3")}, - RangeStart: net.ParseIP("192.168.1.10"), - } - store := fakestore.NewFakeStore(ipmap, nil) - alloc, _ := NewIPAllocator(&conf, store) - _, _, err = alloc.Get("ID") - Expect(err).To(HaveOccurred()) - }) - }) - - It("RangeStart must be in the given subnet", func() { - subnet, err := types.ParseCIDR("192.168.1.0/24") - Expect(err).ToNot(HaveOccurred()) - - conf := IPAMConfig{ - Name: "test", - Type: "host-local", - Subnet: types.IPNet{IP: subnet.IP, Mask: subnet.Mask}, - RangeStart: net.ParseIP("10.0.0.1"), - } - store := fakestore.NewFakeStore(map[string]string{}, net.ParseIP("")) - _, err = NewIPAllocator(&conf, store) - Expect(err).To(HaveOccurred()) - }) - - It("RangeEnd must be in the given subnet", func() { - subnet, err := types.ParseCIDR("192.168.1.0/24") - Expect(err).ToNot(HaveOccurred()) - - conf := IPAMConfig{ - Name: "test", - Type: "host-local", - Subnet: types.IPNet{IP: subnet.IP, Mask: subnet.Mask}, - RangeEnd: net.ParseIP("10.0.0.1"), - } - store := fakestore.NewFakeStore(map[string]string{}, net.ParseIP("")) - _, err = NewIPAllocator(&conf, store) - Expect(err).To(HaveOccurred()) - }) - - It("RangeEnd must be after RangeStart in the given subnet", func() { - subnet, err := types.ParseCIDR("192.168.1.0/24") - Expect(err).ToNot(HaveOccurred()) - - conf := IPAMConfig{ - Name: "test", - Type: "host-local", - Subnet: types.IPNet{IP: subnet.IP, Mask: subnet.Mask}, - RangeStart: net.ParseIP("192.168.1.10"), - RangeEnd: net.ParseIP("192.168.1.3"), - } - store := fakestore.NewFakeStore(map[string]string{}, net.ParseIP("")) - _, err = NewIPAllocator(&conf, store) - Expect(err).To(HaveOccurred()) - }) - }) - - Context("when out of ips", func() { - It("returns a meaningful error", func() { - testCases := []AllocatorTestCase{ - { - subnet: "10.0.0.0/30", - ipmap: map[string]string{ - "10.0.0.2": "id", - "10.0.0.3": "id", - }, - }, - { - subnet: "10.0.0.0/29", - ipmap: map[string]string{ - "10.0.0.2": "id", - "10.0.0.3": "id", - "10.0.0.4": "id", - "10.0.0.5": "id", - "10.0.0.6": "id", - "10.0.0.7": "id", - }, - }, - } - for _, tc := range testCases { - _, _, err := tc.run() - Expect(err).To(MatchError("no IP addresses available in network: test")) - } - }) - }) - - Context("when given an invalid subnet", func() { - It("returns a meaningful error", func() { - subnet, err := types.ParseCIDR("192.168.1.0/31") - Expect(err).ToNot(HaveOccurred()) - - conf := IPAMConfig{ - Name: "test", - Type: "host-local", - Subnet: types.IPNet{IP: subnet.IP, Mask: subnet.Mask}, - } - store := fakestore.NewFakeStore(map[string]string{}, net.ParseIP("")) - _, err = NewIPAllocator(&conf, store) - Expect(err).To(HaveOccurred()) - }) - }) -}) diff --git a/vendor/github.com/containernetworking/cni/plugins/ipam/host-local/backend/allocator/config.go b/vendor/github.com/containernetworking/cni/plugins/ipam/host-local/backend/allocator/config.go deleted file mode 100644 index 8c0044893..000000000 --- a/vendor/github.com/containernetworking/cni/plugins/ipam/host-local/backend/allocator/config.go +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2015 CNI authors -// -// 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. - -package allocator - -import ( - "encoding/json" - "fmt" - "net" - - "github.com/containernetworking/cni/pkg/types" -) - -// IPAMConfig represents the IP related network configuration. -type IPAMConfig struct { - Name string - Type string `json:"type"` - RangeStart net.IP `json:"rangeStart"` - RangeEnd net.IP `json:"rangeEnd"` - Subnet types.IPNet `json:"subnet"` - Gateway net.IP `json:"gateway"` - Routes []types.Route `json:"routes"` - DataDir string `json:"dataDir"` - ResolvConf string `json:"resolvConf"` - Args *IPAMArgs `json:"-"` -} - -type IPAMArgs struct { - types.CommonArgs - IP net.IP `json:"ip,omitempty"` -} - -type Net struct { - Name string `json:"name"` - CNIVersion string `json:"cniVersion"` - IPAM *IPAMConfig `json:"ipam"` -} - -// NewIPAMConfig creates a NetworkConfig from the given network name. -func LoadIPAMConfig(bytes []byte, args string) (*IPAMConfig, string, error) { - n := Net{} - if err := json.Unmarshal(bytes, &n); err != nil { - return nil, "", err - } - - if n.IPAM == nil { - return nil, "", fmt.Errorf("IPAM config missing 'ipam' key") - } - - if args != "" { - n.IPAM.Args = &IPAMArgs{} - err := types.LoadArgs(args, n.IPAM.Args) - if err != nil { - return nil, "", err - } - } - - // Copy net name into IPAM so not to drag Net struct around - n.IPAM.Name = n.Name - - return n.IPAM, n.CNIVersion, nil -} - -func convertRoutesToCurrent(routes []types.Route) []*types.Route { - var currentRoutes []*types.Route - for _, r := range routes { - currentRoutes = append(currentRoutes, &types.Route{ - Dst: r.Dst, - GW: r.GW, - }) - } - return currentRoutes -} diff --git a/vendor/github.com/containernetworking/cni/plugins/ipam/host-local/host_local_test.go b/vendor/github.com/containernetworking/cni/plugins/ipam/host-local/host_local_test.go deleted file mode 100644 index f1578d092..000000000 --- a/vendor/github.com/containernetworking/cni/plugins/ipam/host-local/host_local_test.go +++ /dev/null @@ -1,292 +0,0 @@ -// Copyright 2016 CNI authors -// -// 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. - -package main - -import ( - "fmt" - "io/ioutil" - "net" - "os" - "path/filepath" - "strings" - - "github.com/containernetworking/cni/pkg/skel" - "github.com/containernetworking/cni/pkg/testutils" - "github.com/containernetworking/cni/pkg/types" - "github.com/containernetworking/cni/pkg/types/020" - "github.com/containernetworking/cni/pkg/types/current" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -var _ = Describe("host-local Operations", func() { - It("allocates and releases an address with ADD/DEL", func() { - const ifname string = "eth0" - const nspath string = "/some/where" - - tmpDir, err := ioutil.TempDir("", "host_local_artifacts") - Expect(err).NotTo(HaveOccurred()) - defer os.RemoveAll(tmpDir) - - err = ioutil.WriteFile(filepath.Join(tmpDir, "resolv.conf"), []byte("nameserver 192.0.2.3"), 0644) - Expect(err).NotTo(HaveOccurred()) - - conf := fmt.Sprintf(`{ - "cniVersion": "0.3.1", - "name": "mynet", - "type": "ipvlan", - "master": "foo0", - "ipam": { - "type": "host-local", - "subnet": "10.1.2.0/24", - "dataDir": "%s", - "resolvConf": "%s/resolv.conf" - } -}`, tmpDir, tmpDir) - - args := &skel.CmdArgs{ - ContainerID: "dummy", - Netns: nspath, - IfName: ifname, - StdinData: []byte(conf), - } - - // Allocate the IP - r, raw, err := testutils.CmdAddWithResult(nspath, ifname, []byte(conf), func() error { - return cmdAdd(args) - }) - Expect(err).NotTo(HaveOccurred()) - Expect(strings.Index(string(raw), "\"version\":")).Should(BeNumerically(">", 0)) - - result, err := current.GetResult(r) - Expect(err).NotTo(HaveOccurred()) - - expectedAddress, err := types.ParseCIDR("10.1.2.2/24") - Expect(err).NotTo(HaveOccurred()) - Expect(len(result.IPs)).To(Equal(1)) - expectedAddress.IP = expectedAddress.IP.To16() - Expect(result.IPs[0].Address).To(Equal(*expectedAddress)) - Expect(result.IPs[0].Gateway).To(Equal(net.ParseIP("10.1.2.1"))) - - ipFilePath := filepath.Join(tmpDir, "mynet", "10.1.2.2") - contents, err := ioutil.ReadFile(ipFilePath) - Expect(err).NotTo(HaveOccurred()) - Expect(string(contents)).To(Equal("dummy")) - - lastFilePath := filepath.Join(tmpDir, "mynet", "last_reserved_ip") - contents, err = ioutil.ReadFile(lastFilePath) - Expect(err).NotTo(HaveOccurred()) - Expect(string(contents)).To(Equal("10.1.2.2")) - - // Release the IP - err = testutils.CmdDelWithResult(nspath, ifname, func() error { - return cmdDel(args) - }) - Expect(err).NotTo(HaveOccurred()) - - _, err = os.Stat(ipFilePath) - Expect(err).To(HaveOccurred()) - }) - - It("doesn't error when passed an unknown ID on DEL", func() { - const ifname string = "eth0" - const nspath string = "/some/where" - - tmpDir, err := ioutil.TempDir("", "host_local_artifacts") - Expect(err).NotTo(HaveOccurred()) - defer os.RemoveAll(tmpDir) - - conf := fmt.Sprintf(`{ - "cniVersion": "0.3.0", - "name": "mynet", - "type": "ipvlan", - "master": "foo0", - "ipam": { - "type": "host-local", - "subnet": "10.1.2.0/24", - "dataDir": "%s" - } -}`, tmpDir) - - args := &skel.CmdArgs{ - ContainerID: "dummy", - Netns: nspath, - IfName: ifname, - StdinData: []byte(conf), - } - - // Release the IP - err = testutils.CmdDelWithResult(nspath, ifname, func() error { - return cmdDel(args) - }) - Expect(err).NotTo(HaveOccurred()) - }) - - It("allocates and releases an address with ADD/DEL and 0.1.0 config", func() { - const ifname string = "eth0" - const nspath string = "/some/where" - - tmpDir, err := ioutil.TempDir("", "host_local_artifacts") - Expect(err).NotTo(HaveOccurred()) - defer os.RemoveAll(tmpDir) - - err = ioutil.WriteFile(filepath.Join(tmpDir, "resolv.conf"), []byte("nameserver 192.0.2.3"), 0644) - Expect(err).NotTo(HaveOccurred()) - - conf := fmt.Sprintf(`{ - "cniVersion": "0.1.0", - "name": "mynet", - "type": "ipvlan", - "master": "foo0", - "ipam": { - "type": "host-local", - "subnet": "10.1.2.0/24", - "dataDir": "%s", - "resolvConf": "%s/resolv.conf" - } -}`, tmpDir, tmpDir) - - args := &skel.CmdArgs{ - ContainerID: "dummy", - Netns: nspath, - IfName: ifname, - StdinData: []byte(conf), - } - - // Allocate the IP - r, raw, err := testutils.CmdAddWithResult(nspath, ifname, []byte(conf), func() error { - return cmdAdd(args) - }) - Expect(err).NotTo(HaveOccurred()) - Expect(strings.Index(string(raw), "\"ip4\":")).Should(BeNumerically(">", 0)) - - result, err := types020.GetResult(r) - Expect(err).NotTo(HaveOccurred()) - - expectedAddress, err := types.ParseCIDR("10.1.2.2/24") - Expect(err).NotTo(HaveOccurred()) - expectedAddress.IP = expectedAddress.IP.To16() - Expect(result.IP4.IP).To(Equal(*expectedAddress)) - Expect(result.IP4.Gateway).To(Equal(net.ParseIP("10.1.2.1"))) - - ipFilePath := filepath.Join(tmpDir, "mynet", "10.1.2.2") - contents, err := ioutil.ReadFile(ipFilePath) - Expect(err).NotTo(HaveOccurred()) - Expect(string(contents)).To(Equal("dummy")) - - lastFilePath := filepath.Join(tmpDir, "mynet", "last_reserved_ip") - contents, err = ioutil.ReadFile(lastFilePath) - Expect(err).NotTo(HaveOccurred()) - Expect(string(contents)).To(Equal("10.1.2.2")) - - Expect(result.DNS).To(Equal(types.DNS{Nameservers: []string{"192.0.2.3"}})) - - // Release the IP - err = testutils.CmdDelWithResult(nspath, ifname, func() error { - return cmdDel(args) - }) - Expect(err).NotTo(HaveOccurred()) - - _, err = os.Stat(ipFilePath) - Expect(err).To(HaveOccurred()) - }) - - It("ignores whitespace in disk files", func() { - const ifname string = "eth0" - const nspath string = "/some/where" - - tmpDir, err := ioutil.TempDir("", "host_local_artifacts") - Expect(err).NotTo(HaveOccurred()) - defer os.RemoveAll(tmpDir) - - conf := fmt.Sprintf(`{ - "cniVersion": "0.3.1", - "name": "mynet", - "type": "ipvlan", - "master": "foo0", - "ipam": { - "type": "host-local", - "subnet": "10.1.2.0/24", - "dataDir": "%s" - } -}`, tmpDir) - - args := &skel.CmdArgs{ - ContainerID: " dummy\n ", - Netns: nspath, - IfName: ifname, - StdinData: []byte(conf), - } - - // Allocate the IP - r, _, err := testutils.CmdAddWithResult(nspath, ifname, []byte(conf), func() error { - return cmdAdd(args) - }) - Expect(err).NotTo(HaveOccurred()) - - result, err := current.GetResult(r) - Expect(err).NotTo(HaveOccurred()) - - ipFilePath := filepath.Join(tmpDir, "mynet", result.IPs[0].Address.IP.String()) - contents, err := ioutil.ReadFile(ipFilePath) - Expect(err).NotTo(HaveOccurred()) - Expect(string(contents)).To(Equal("dummy")) - - // Release the IP - err = testutils.CmdDelWithResult(nspath, ifname, func() error { - return cmdDel(args) - }) - Expect(err).NotTo(HaveOccurred()) - - _, err = os.Stat(ipFilePath) - Expect(err).To(HaveOccurred()) - }) - - It("does not output an error message upon initial subnet creation", func() { - const ifname string = "eth0" - const nspath string = "/some/where" - - tmpDir, err := ioutil.TempDir("", "host_local_artifacts") - Expect(err).NotTo(HaveOccurred()) - defer os.RemoveAll(tmpDir) - - conf := fmt.Sprintf(`{ - "cniVersion": "0.2.0", - "name": "mynet", - "type": "ipvlan", - "master": "foo0", - "ipam": { - "type": "host-local", - "subnet": "10.1.2.0/24", - "dataDir": "%s" - } -}`, tmpDir) - - args := &skel.CmdArgs{ - ContainerID: "testing", - Netns: nspath, - IfName: ifname, - StdinData: []byte(conf), - } - - // Allocate the IP - _, out, err := testutils.CmdAddWithResult(nspath, ifname, []byte(conf), func() error { - return cmdAdd(args) - }) - Expect(err).NotTo(HaveOccurred()) - Expect(strings.Index(string(out), "Error retriving last reserved ip")).To(Equal(-1)) - }) -}) diff --git a/vendor/github.com/containernetworking/cni/plugins/ipam/host-local/main.go b/vendor/github.com/containernetworking/cni/plugins/ipam/host-local/main.go deleted file mode 100644 index 2f77912bd..000000000 --- a/vendor/github.com/containernetworking/cni/plugins/ipam/host-local/main.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2015 CNI authors -// -// 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. - -package main - -import ( - "github.com/containernetworking/cni/plugins/ipam/host-local/backend/allocator" - "github.com/containernetworking/cni/plugins/ipam/host-local/backend/disk" - - "github.com/containernetworking/cni/pkg/skel" - "github.com/containernetworking/cni/pkg/types" - "github.com/containernetworking/cni/pkg/types/current" - "github.com/containernetworking/cni/pkg/version" -) - -func main() { - skel.PluginMain(cmdAdd, cmdDel, version.All) -} - -func cmdAdd(args *skel.CmdArgs) error { - ipamConf, confVersion, err := allocator.LoadIPAMConfig(args.StdinData, args.Args) - if err != nil { - return err - } - - result := ¤t.Result{} - - if ipamConf.ResolvConf != "" { - dns, err := parseResolvConf(ipamConf.ResolvConf) - if err != nil { - return err - } - result.DNS = *dns - } - - store, err := disk.New(ipamConf.Name, ipamConf.DataDir) - if err != nil { - return err - } - defer store.Close() - - allocator, err := allocator.NewIPAllocator(ipamConf, store) - if err != nil { - return err - } - - ipConf, routes, err := allocator.Get(args.ContainerID) - if err != nil { - return err - } - result.IPs = []*current.IPConfig{ipConf} - result.Routes = routes - - return types.PrintResult(result, confVersion) -} - -func cmdDel(args *skel.CmdArgs) error { - ipamConf, _, err := allocator.LoadIPAMConfig(args.StdinData, args.Args) - if err != nil { - return err - } - - store, err := disk.New(ipamConf.Name, ipamConf.DataDir) - if err != nil { - return err - } - defer store.Close() - - ipAllocator, err := allocator.NewIPAllocator(ipamConf, store) - if err != nil { - return err - } - - return ipAllocator.Release(args.ContainerID) -} diff --git a/vendor/github.com/containernetworking/cni/plugins/main/bridge/bridge_test.go b/vendor/github.com/containernetworking/cni/plugins/main/bridge/bridge_test.go deleted file mode 100644 index 65f083b73..000000000 --- a/vendor/github.com/containernetworking/cni/plugins/main/bridge/bridge_test.go +++ /dev/null @@ -1,529 +0,0 @@ -// Copyright 2015 CNI authors -// -// 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. - -package main - -import ( - "fmt" - "net" - "strings" - "syscall" - - "github.com/containernetworking/cni/pkg/ns" - "github.com/containernetworking/cni/pkg/skel" - "github.com/containernetworking/cni/pkg/testutils" - "github.com/containernetworking/cni/pkg/types" - "github.com/containernetworking/cni/pkg/types/020" - "github.com/containernetworking/cni/pkg/types/current" - - "github.com/containernetworking/cni/pkg/utils/hwaddr" - - "github.com/vishvananda/netlink" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -func checkBridgeConfig03x(version string, originalNS ns.NetNS) { - const BRNAME = "cni0" - const IFNAME = "eth0" - - gwaddr, subnet, err := net.ParseCIDR("10.1.2.1/24") - Expect(err).NotTo(HaveOccurred()) - - conf := fmt.Sprintf(`{ - "cniVersion": "%s", - "name": "mynet", - "type": "bridge", - "bridge": "%s", - "isDefaultGateway": true, - "ipMasq": false, - "ipam": { - "type": "host-local", - "subnet": "%s" - } -}`, version, BRNAME, subnet.String()) - - targetNs, err := ns.NewNS() - Expect(err).NotTo(HaveOccurred()) - defer targetNs.Close() - - args := &skel.CmdArgs{ - ContainerID: "dummy", - Netns: targetNs.Path(), - IfName: IFNAME, - StdinData: []byte(conf), - } - - var result *current.Result - err = originalNS.Do(func(ns.NetNS) error { - defer GinkgoRecover() - - r, raw, err := testutils.CmdAddWithResult(targetNs.Path(), IFNAME, []byte(conf), func() error { - return cmdAdd(args) - }) - Expect(err).NotTo(HaveOccurred()) - Expect(strings.Index(string(raw), "\"interfaces\":")).Should(BeNumerically(">", 0)) - - result, err = current.GetResult(r) - Expect(err).NotTo(HaveOccurred()) - - Expect(len(result.Interfaces)).To(Equal(3)) - Expect(result.Interfaces[0].Name).To(Equal(BRNAME)) - Expect(result.Interfaces[2].Name).To(Equal(IFNAME)) - - // Make sure bridge link exists - link, err := netlink.LinkByName(result.Interfaces[0].Name) - Expect(err).NotTo(HaveOccurred()) - Expect(link.Attrs().Name).To(Equal(BRNAME)) - Expect(link).To(BeAssignableToTypeOf(&netlink.Bridge{})) - Expect(link.Attrs().HardwareAddr.String()).To(Equal(result.Interfaces[0].Mac)) - hwAddr := fmt.Sprintf("%s", link.Attrs().HardwareAddr) - Expect(hwAddr).To(HavePrefix(hwaddr.PrivateMACPrefixString)) - - // Ensure bridge has gateway address - addrs, err := netlink.AddrList(link, syscall.AF_INET) - Expect(err).NotTo(HaveOccurred()) - Expect(len(addrs)).To(BeNumerically(">", 0)) - found := false - subnetPrefix, subnetBits := subnet.Mask.Size() - for _, a := range addrs { - aPrefix, aBits := a.IPNet.Mask.Size() - if a.IPNet.IP.Equal(gwaddr) && aPrefix == subnetPrefix && aBits == subnetBits { - found = true - break - } - } - Expect(found).To(Equal(true)) - - // Check for the veth link in the main namespace - links, err := netlink.LinkList() - Expect(err).NotTo(HaveOccurred()) - Expect(len(links)).To(Equal(3)) // Bridge, veth, and loopback - - link, err = netlink.LinkByName(result.Interfaces[1].Name) - Expect(err).NotTo(HaveOccurred()) - Expect(link).To(BeAssignableToTypeOf(&netlink.Veth{})) - return nil - }) - Expect(err).NotTo(HaveOccurred()) - - // Find the veth peer in the container namespace and the default route - err = targetNs.Do(func(ns.NetNS) error { - defer GinkgoRecover() - - link, err := netlink.LinkByName(IFNAME) - Expect(err).NotTo(HaveOccurred()) - Expect(link.Attrs().Name).To(Equal(IFNAME)) - Expect(link).To(BeAssignableToTypeOf(&netlink.Veth{})) - - addrs, err := netlink.AddrList(link, syscall.AF_INET) - Expect(err).NotTo(HaveOccurred()) - Expect(len(addrs)).To(Equal(1)) - - hwAddr := fmt.Sprintf("%s", link.Attrs().HardwareAddr) - Expect(hwAddr).To(HavePrefix(hwaddr.PrivateMACPrefixString)) - - // Ensure the default route - routes, err := netlink.RouteList(link, 0) - Expect(err).NotTo(HaveOccurred()) - - var defaultRouteFound bool - for _, route := range routes { - defaultRouteFound = (route.Dst == nil && route.Src == nil && route.Gw.Equal(gwaddr)) - if defaultRouteFound { - break - } - } - Expect(defaultRouteFound).To(Equal(true)) - - return nil - }) - Expect(err).NotTo(HaveOccurred()) - - err = originalNS.Do(func(ns.NetNS) error { - defer GinkgoRecover() - - err := testutils.CmdDelWithResult(targetNs.Path(), IFNAME, func() error { - return cmdDel(args) - }) - Expect(err).NotTo(HaveOccurred()) - return nil - }) - Expect(err).NotTo(HaveOccurred()) - - // Make sure the host veth has been deleted - err = targetNs.Do(func(ns.NetNS) error { - defer GinkgoRecover() - - link, err := netlink.LinkByName(IFNAME) - Expect(err).To(HaveOccurred()) - Expect(link).To(BeNil()) - return nil - }) - Expect(err).NotTo(HaveOccurred()) - - // Make sure the container veth has been deleted - err = originalNS.Do(func(ns.NetNS) error { - defer GinkgoRecover() - - link, err := netlink.LinkByName(result.Interfaces[1].Name) - Expect(err).To(HaveOccurred()) - Expect(link).To(BeNil()) - return nil - }) -} - -var _ = Describe("bridge Operations", func() { - var originalNS ns.NetNS - - BeforeEach(func() { - // Create a new NetNS so we don't modify the host - var err error - originalNS, err = ns.NewNS() - Expect(err).NotTo(HaveOccurred()) - }) - - AfterEach(func() { - Expect(originalNS.Close()).To(Succeed()) - }) - - It("creates a bridge", func() { - const IFNAME = "bridge0" - - conf := &NetConf{ - NetConf: types.NetConf{ - CNIVersion: "0.3.1", - Name: "testConfig", - Type: "bridge", - }, - BrName: IFNAME, - IsGW: false, - IPMasq: false, - MTU: 5000, - } - - err := originalNS.Do(func(ns.NetNS) error { - defer GinkgoRecover() - - bridge, _, err := setupBridge(conf) - Expect(err).NotTo(HaveOccurred()) - Expect(bridge.Attrs().Name).To(Equal(IFNAME)) - - // Double check that the link was added - link, err := netlink.LinkByName(IFNAME) - Expect(err).NotTo(HaveOccurred()) - Expect(link.Attrs().Name).To(Equal(IFNAME)) - return nil - }) - Expect(err).NotTo(HaveOccurred()) - }) - - It("handles an existing bridge", func() { - const IFNAME = "bridge0" - - err := originalNS.Do(func(ns.NetNS) error { - defer GinkgoRecover() - - err := netlink.LinkAdd(&netlink.Bridge{ - LinkAttrs: netlink.LinkAttrs{ - Name: IFNAME, - }, - }) - Expect(err).NotTo(HaveOccurred()) - link, err := netlink.LinkByName(IFNAME) - Expect(err).NotTo(HaveOccurred()) - Expect(link.Attrs().Name).To(Equal(IFNAME)) - ifindex := link.Attrs().Index - - conf := &NetConf{ - NetConf: types.NetConf{ - CNIVersion: "0.3.1", - Name: "testConfig", - Type: "bridge", - }, - BrName: IFNAME, - IsGW: false, - IPMasq: false, - } - - bridge, _, err := setupBridge(conf) - Expect(err).NotTo(HaveOccurred()) - Expect(bridge.Attrs().Name).To(Equal(IFNAME)) - Expect(bridge.Attrs().Index).To(Equal(ifindex)) - - // Double check that the link has the same ifindex - link, err = netlink.LinkByName(IFNAME) - Expect(err).NotTo(HaveOccurred()) - Expect(link.Attrs().Name).To(Equal(IFNAME)) - Expect(link.Attrs().Index).To(Equal(ifindex)) - return nil - }) - Expect(err).NotTo(HaveOccurred()) - }) - - It("configures and deconfigures a bridge and veth with default route with ADD/DEL for 0.3.0 config", func() { - checkBridgeConfig03x("0.3.0", originalNS) - }) - - It("configures and deconfigures a bridge and veth with default route with ADD/DEL for 0.3.1 config", func() { - checkBridgeConfig03x("0.3.1", originalNS) - }) - - It("deconfigures an unconfigured bridge with DEL", func() { - const BRNAME = "cni0" - const IFNAME = "eth0" - - _, subnet, err := net.ParseCIDR("10.1.2.1/24") - Expect(err).NotTo(HaveOccurred()) - - conf := fmt.Sprintf(`{ - "cniVersion": "0.3.0", - "name": "mynet", - "type": "bridge", - "bridge": "%s", - "isDefaultGateway": true, - "ipMasq": false, - "ipam": { - "type": "host-local", - "subnet": "%s" - } -}`, BRNAME, subnet.String()) - - targetNs, err := ns.NewNS() - Expect(err).NotTo(HaveOccurred()) - defer targetNs.Close() - - args := &skel.CmdArgs{ - ContainerID: "dummy", - Netns: targetNs.Path(), - IfName: IFNAME, - StdinData: []byte(conf), - } - - err = originalNS.Do(func(ns.NetNS) error { - defer GinkgoRecover() - - err := testutils.CmdDelWithResult(targetNs.Path(), IFNAME, func() error { - return cmdDel(args) - }) - Expect(err).NotTo(HaveOccurred()) - return nil - }) - Expect(err).NotTo(HaveOccurred()) - }) - - It("configures and deconfigures a bridge and veth with default route with ADD/DEL for 0.1.0 config", func() { - const BRNAME = "cni0" - const IFNAME = "eth0" - - gwaddr, subnet, err := net.ParseCIDR("10.1.2.1/24") - Expect(err).NotTo(HaveOccurred()) - - conf := fmt.Sprintf(`{ - "cniVersion": "0.1.0", - "name": "mynet", - "type": "bridge", - "bridge": "%s", - "isDefaultGateway": true, - "ipMasq": false, - "ipam": { - "type": "host-local", - "subnet": "%s" - } -}`, BRNAME, subnet.String()) - - targetNs, err := ns.NewNS() - Expect(err).NotTo(HaveOccurred()) - defer targetNs.Close() - - args := &skel.CmdArgs{ - ContainerID: "dummy", - Netns: targetNs.Path(), - IfName: IFNAME, - StdinData: []byte(conf), - } - - var result *types020.Result - err = originalNS.Do(func(ns.NetNS) error { - defer GinkgoRecover() - - r, raw, err := testutils.CmdAddWithResult(targetNs.Path(), IFNAME, []byte(conf), func() error { - return cmdAdd(args) - }) - Expect(err).NotTo(HaveOccurred()) - Expect(strings.Index(string(raw), "\"ip4\":")).Should(BeNumerically(">", 0)) - - // We expect a version 0.1.0 result - result, err = types020.GetResult(r) - Expect(err).NotTo(HaveOccurred()) - - // Make sure bridge link exists - link, err := netlink.LinkByName(BRNAME) - Expect(err).NotTo(HaveOccurred()) - Expect(link.Attrs().Name).To(Equal(BRNAME)) - Expect(link).To(BeAssignableToTypeOf(&netlink.Bridge{})) - hwAddr := fmt.Sprintf("%s", link.Attrs().HardwareAddr) - Expect(hwAddr).To(HavePrefix(hwaddr.PrivateMACPrefixString)) - - // Ensure bridge has gateway address - addrs, err := netlink.AddrList(link, syscall.AF_INET) - Expect(err).NotTo(HaveOccurred()) - Expect(len(addrs)).To(BeNumerically(">", 0)) - found := false - subnetPrefix, subnetBits := subnet.Mask.Size() - for _, a := range addrs { - aPrefix, aBits := a.IPNet.Mask.Size() - if a.IPNet.IP.Equal(gwaddr) && aPrefix == subnetPrefix && aBits == subnetBits { - found = true - break - } - } - Expect(found).To(Equal(true)) - - // Check for the veth link in the main namespace; can't - // check the for the specific link since version 0.1.0 - // doesn't report interfaces - links, err := netlink.LinkList() - Expect(err).NotTo(HaveOccurred()) - Expect(len(links)).To(Equal(3)) // Bridge, veth, and loopback - return nil - }) - Expect(err).NotTo(HaveOccurred()) - - // Find the veth peer in the container namespace and the default route - err = targetNs.Do(func(ns.NetNS) error { - defer GinkgoRecover() - - link, err := netlink.LinkByName(IFNAME) - Expect(err).NotTo(HaveOccurred()) - Expect(link.Attrs().Name).To(Equal(IFNAME)) - Expect(link).To(BeAssignableToTypeOf(&netlink.Veth{})) - - addrs, err := netlink.AddrList(link, syscall.AF_INET) - Expect(err).NotTo(HaveOccurred()) - Expect(len(addrs)).To(Equal(1)) - - hwAddr := fmt.Sprintf("%s", link.Attrs().HardwareAddr) - Expect(hwAddr).To(HavePrefix(hwaddr.PrivateMACPrefixString)) - - // Ensure the default route - routes, err := netlink.RouteList(link, 0) - Expect(err).NotTo(HaveOccurred()) - - var defaultRouteFound bool - for _, route := range routes { - defaultRouteFound = (route.Dst == nil && route.Src == nil && route.Gw.Equal(gwaddr)) - if defaultRouteFound { - break - } - } - Expect(defaultRouteFound).To(Equal(true)) - - return nil - }) - Expect(err).NotTo(HaveOccurred()) - - err = originalNS.Do(func(ns.NetNS) error { - defer GinkgoRecover() - - err := testutils.CmdDelWithResult(targetNs.Path(), IFNAME, func() error { - return cmdDel(args) - }) - Expect(err).NotTo(HaveOccurred()) - return nil - }) - Expect(err).NotTo(HaveOccurred()) - - // Make sure the container veth has been deleted; cannot check - // host veth as version 0.1.0 can't report its name - err = originalNS.Do(func(ns.NetNS) error { - defer GinkgoRecover() - - link, err := netlink.LinkByName(IFNAME) - Expect(err).To(HaveOccurred()) - Expect(link).To(BeNil()) - return nil - }) - }) - - It("ensure bridge address", func() { - const IFNAME = "bridge0" - const EXPECTED_IP = "10.0.0.0/8" - const CHANGED_EXPECTED_IP = "10.1.2.3/16" - - conf := &NetConf{ - NetConf: types.NetConf{ - CNIVersion: "0.3.1", - Name: "testConfig", - Type: "bridge", - }, - BrName: IFNAME, - IsGW: true, - IPMasq: false, - MTU: 5000, - } - - gwnFirst := &net.IPNet{ - IP: net.IPv4(10, 0, 0, 0), - Mask: net.CIDRMask(8, 32), - } - - gwnSecond := &net.IPNet{ - IP: net.IPv4(10, 1, 2, 3), - Mask: net.CIDRMask(16, 32), - } - - err := originalNS.Do(func(ns.NetNS) error { - defer GinkgoRecover() - - bridge, _, err := setupBridge(conf) - Expect(err).NotTo(HaveOccurred()) - // Check if ForceAddress has default value - Expect(conf.ForceAddress).To(Equal(false)) - - err = ensureBridgeAddr(bridge, gwnFirst, conf.ForceAddress) - Expect(err).NotTo(HaveOccurred()) - - //Check if IP address is set correctly - addrs, err := netlink.AddrList(bridge, syscall.AF_INET) - Expect(len(addrs)).To(Equal(1)) - addr := addrs[0].IPNet.String() - Expect(addr).To(Equal(EXPECTED_IP)) - - //The bridge IP address has been changed. Error expected when ForceAddress is set to false. - err = ensureBridgeAddr(bridge, gwnSecond, false) - Expect(err).To(HaveOccurred()) - - //The IP address should stay the same. - addrs, err = netlink.AddrList(bridge, syscall.AF_INET) - Expect(len(addrs)).To(Equal(1)) - addr = addrs[0].IPNet.String() - Expect(addr).To(Equal(EXPECTED_IP)) - - //Reconfigure IP when ForceAddress is set to true and IP address has been changed. - err = ensureBridgeAddr(bridge, gwnSecond, true) - Expect(err).NotTo(HaveOccurred()) - - //Retrieve the IP address after reconfiguration - addrs, err = netlink.AddrList(bridge, syscall.AF_INET) - Expect(len(addrs)).To(Equal(1)) - addr = addrs[0].IPNet.String() - Expect(addr).To(Equal(CHANGED_EXPECTED_IP)) - - return nil - }) - Expect(err).NotTo(HaveOccurred()) - }) -}) diff --git a/vendor/github.com/containernetworking/cni/plugins/test/noop/main.go b/vendor/github.com/containernetworking/cni/plugins/test/noop/main.go index a79f117b4..f2da357b6 100644 --- a/vendor/github.com/containernetworking/cni/plugins/test/noop/main.go +++ b/vendor/github.com/containernetworking/cni/plugins/test/noop/main.go @@ -121,19 +121,25 @@ func debugBehavior(args *skel.CmdArgs, command string) error { if debug.ReportError != "" { return errors.New(debug.ReportError) } else if debug.ReportResult == "PASSTHROUGH" || debug.ReportResult == "INJECT-DNS" { + prevResult := netConf.PrevResult if debug.ReportResult == "INJECT-DNS" { - newResult, err := current.NewResultFromResult(netConf.PrevResult) + prevResult, err = current.NewResultFromResult(netConf.PrevResult) if err != nil { return err } - newResult.DNS.Nameservers = []string{"1.2.3.4"} - netConf.PrevResult = newResult + prevResult.DNS.Nameservers = []string{"1.2.3.4"} } - newResult, err := json.Marshal(netConf.PrevResult) + + // Must print the prevResult as the CNIVersion of the config + newResult, err := prevResult.GetAsVersion(netConf.CNIVersion) + if err != nil { + return fmt.Errorf("failed to convert result to config %q: %v", netConf.CNIVersion, err) + } + resultBytes, err := json.Marshal(newResult) if err != nil { return fmt.Errorf("failed to marshal new result: %v", err) } - os.Stdout.WriteString(string(newResult)) + os.Stdout.WriteString(string(resultBytes)) } else { os.Stdout.WriteString(debug.ReportResult) } @@ -142,7 +148,7 @@ func debugBehavior(args *skel.CmdArgs, command string) error { } func debugGetSupportedVersions(stdinData []byte) []string { - vers := []string{"0.-42.0", "0.1.0", "0.2.0", "0.3.0", "0.3.1"} + vers := []string{"0.-42.0", "0.1.0", "0.2.0", "0.3.0", "0.3.1", "0.4.0"} cniArgs := os.Getenv("CNI_ARGS") if cniArgs == "" { return vers @@ -167,6 +173,10 @@ func cmdAdd(args *skel.CmdArgs) error { return debugBehavior(args, "ADD") } +func cmdGet(args *skel.CmdArgs) error { + return debugBehavior(args, "GET") +} + func cmdDel(args *skel.CmdArgs) error { return debugBehavior(args, "DEL") } @@ -202,5 +212,5 @@ func main() { } supportedVersions := debugGetSupportedVersions(stdinData) - skel.PluginMain(cmdAdd, cmdDel, version.PluginSupports(supportedVersions...)) + skel.PluginMain(cmdAdd, cmdGet, cmdDel, version.PluginSupports(supportedVersions...), "CNI nnop plugin v0.7.0") } diff --git a/vendor/github.com/containernetworking/cni/plugins/test/noop/noop_test.go b/vendor/github.com/containernetworking/cni/plugins/test/noop/noop_test.go index 880869b0c..683d99f48 100644 --- a/vendor/github.com/containernetworking/cni/plugins/test/noop/noop_test.go +++ b/vendor/github.com/containernetworking/cni/plugins/test/noop/noop_test.go @@ -42,7 +42,7 @@ var _ = Describe("No-op plugin", func() { BeforeEach(func() { debug = &noop_debug.Debug{ ReportResult: reportResult, - ReportVersionSupport: []string{"0.1.0", "0.2.0", "0.3.0", "0.3.1"}, + ReportVersionSupport: []string{"0.1.0", "0.2.0", "0.3.0", "0.3.1", "0.4.0"}, } debugFile, err := ioutil.TempFile("", "cni_debug") @@ -64,14 +64,15 @@ var _ = Describe("No-op plugin", func() { // Keep this last "CNI_ARGS=" + args, } - cmd.Stdin = strings.NewReader(`{"some":"stdin-json", "cniVersion": "0.3.1"}`) + stdinData := `{"name": "noop-test", "some":"stdin-json", "cniVersion": "0.3.1"}` + cmd.Stdin = strings.NewReader(stdinData) expectedCmdArgs = skel.CmdArgs{ ContainerID: "some-container-id", Netns: "/some/netns/path", IfName: "some-eth0", Args: args, Path: "/some/bin/path", - StdinData: []byte(`{"some":"stdin-json", "cniVersion": "0.3.1"}`), + StdinData: []byte(stdinData), } }) @@ -96,11 +97,12 @@ var _ = Describe("No-op plugin", func() { Eventually(session).Should(gexec.Exit(2)) }) - It("pass previous result through when ReportResult is PASSTHROUGH", func() { + It("pass previous result 0.3.1 through when ReportResult is PASSTHROUGH", func() { debug = &noop_debug.Debug{ReportResult: "PASSTHROUGH"} Expect(debug.WriteDebug(debugFileName)).To(Succeed()) cmd.Stdin = strings.NewReader(`{ + "name":"noop-test", "some":"stdin-json", "cniVersion": "0.3.1", "prevResult": { @@ -110,7 +112,25 @@ var _ = Describe("No-op plugin", func() { session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) Expect(err).NotTo(HaveOccurred()) Eventually(session).Should(gexec.Exit(0)) - Expect(session.Out.Contents()).To(MatchJSON(`{"ips": [{"version": "4", "address": "10.1.2.15/24"}], "dns": {}}`)) + Expect(session.Out.Contents()).To(MatchJSON(`{"cniVersion": "0.3.1", "ips": [{"version": "4", "address": "10.1.2.15/24"}], "dns": {}}`)) + }) + + It("pass previous result 0.4.0 through when ReportResult is PASSTHROUGH", func() { + debug = &noop_debug.Debug{ReportResult: "PASSTHROUGH"} + Expect(debug.WriteDebug(debugFileName)).To(Succeed()) + + cmd.Stdin = strings.NewReader(`{ + "name":"noop-test", + "some":"stdin-json", + "cniVersion": "0.4.0", + "prevResult": { + "ips": [{"version": "4", "address": "10.1.2.15/24"}] + } +}`) + session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) + Expect(err).NotTo(HaveOccurred()) + Eventually(session).Should(gexec.Exit(0)) + Expect(session.Out.Contents()).To(MatchJSON(`{"cniVersion": "0.4.0", "ips": [{"version": "4", "address": "10.1.2.15/24"}], "dns": {}}`)) }) It("injects DNS into previous result when ReportResult is INJECT-DNS", func() { @@ -118,9 +138,11 @@ var _ = Describe("No-op plugin", func() { Expect(debug.WriteDebug(debugFileName)).To(Succeed()) cmd.Stdin = strings.NewReader(`{ + "name":"noop-test", "some":"stdin-json", - "cniVersion": "0.3.1", + "cniVersion": "0.4.0", "prevResult": { + "cniVersion": "0.3.1", "ips": [{"version": "4", "address": "10.1.2.3/24"}], "dns": {} } @@ -130,6 +152,7 @@ var _ = Describe("No-op plugin", func() { Expect(err).NotTo(HaveOccurred()) Eventually(session).Should(gexec.Exit(0)) Expect(session.Out.Contents()).To(MatchJSON(`{ + "cniVersion": "0.4.0", "ips": [{"version": "4", "address": "10.1.2.3/24"}], "dns": {"nameservers": ["1.2.3.4"]} }`)) @@ -139,7 +162,7 @@ var _ = Describe("No-op plugin", func() { // Remove the DEBUG option from CNI_ARGS and regular args newArgs := "FOO=BAR" cmd.Env[len(cmd.Env)-1] = "CNI_ARGS=" + newArgs - newStdin := fmt.Sprintf(`{"some":"stdin-json", "cniVersion": "0.3.1", "debugFile": "%s"}`, debugFileName) + newStdin := fmt.Sprintf(`{"name":"noop-test", "some": "stdin-json", "cniVersion": "0.4.0", "debugFile": %q}`, debugFileName) cmd.Stdin = strings.NewReader(newStdin) expectedCmdArgs.Args = newArgs expectedCmdArgs.StdinData = []byte(newStdin) diff --git a/vendor/github.com/containernetworking/cni/scripts/docker-run.sh b/vendor/github.com/containernetworking/cni/scripts/docker-run.sh index 6271dd28d..a8e12795f 100755 --- a/vendor/github.com/containernetworking/cni/scripts/docker-run.sh +++ b/vendor/github.com/containernetworking/cni/scripts/docker-run.sh @@ -13,7 +13,7 @@ netnspath=/proc/$pid/ns/net function cleanup() { ./exec-plugins.sh del $contid $netnspath - docker kill $contid >/dev/null + docker rm -f $contid >/dev/null } trap cleanup EXIT diff --git a/vendor/github.com/containernetworking/cni/scripts/release-with-rkt.sh b/vendor/github.com/containernetworking/cni/scripts/release-with-rkt.sh deleted file mode 100755 index dbc3551dc..000000000 --- a/vendor/github.com/containernetworking/cni/scripts/release-with-rkt.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash -set -xe - -SRC_DIR="${SRC_DIR:-$PWD}" - -FEDORA_INSTALL="dnf install -y golang tar xz bzip2 gzip sudo iproute wget" -FEDORA_IMAGE="docker://fedora:23" -ACBUILD_URL="https://github.com/appc/acbuild/releases/download/v0.2.2/acbuild.tar.gz" -ACBUILD="acbuild --debug" -BUILDFLAGS="-a --ldflags '-extldflags \"-static\"'" - -TAG=$(git describe --exact-match --abbrev=0) || TAG=$(git describe) -RELEASE_DIR=release-${TAG} -OUTPUT_DIR=bin - -rm -Rf ${SRC_DIR}/${RELEASE_DIR} -mkdir -p ${SRC_DIR}/${RELEASE_DIR} - -sudo -E rkt run \ - --volume rslvconf,kind=host,source=/etc/resolv.conf \ - --mount volume=rslvconf,target=/etc/resolv.conf \ - --volume src-dir,kind=host,source=$SRC_DIR \ - --mount volume=src-dir,target=/opt/src \ - --interactive \ - --insecure-options=image \ - ${FEDORA_IMAGE} \ - --exec /bin/bash \ - -- -xe -c "\ - ${FEDORA_INSTALL}; cd /opt/src; umask 0022; - for arch in amd64 arm arm64 ppc64le s390x; do \ - CGO_ENABLED=0 GOARCH=\$arch ./build ${BUILDFLAGS}; \ - for format in txz tbz2 tgz; do \ - FILENAME=cni-\$arch-${TAG}.\$format; \ - FILEPATH=${RELEASE_DIR}/\$FILENAME; \ - tar -C ${OUTPUT_DIR} --owner=0 --group=0 -caf \$FILEPATH .; \ - if [ \"\$arch\" == \"amd64\" ]; then \ - cp \$FILEPATH ${RELEASE_DIR}/cni-${TAG}.\$format; \ - fi; \ - done; \ - done; \ - wget -O - ${ACBUILD_URL} | tar -C /usr/bin -xzvf -; \ - ${ACBUILD} begin; \ - ${ACBUILD} set-name coreos.com/cni; \ - ${ACBUILD} label add version ${TAG}; \ - ${ACBUILD} copy --to-dir ${OUTPUT_DIR} /opt/cni/; \ - ${ACBUILD} write ${RELEASE_DIR}/cni-${TAG}.aci; \ - ${ACBUILD} end; \ - pushd ${RELEASE_DIR}; for f in \$(ls); do sha1sum \$f > \$f.sha1; done; popd; \ - chown -R ${UID} ${OUTPUT_DIR} ${RELEASE_DIR}; \ - :" diff --git a/vendor/github.com/containernetworking/cni/scripts/release.sh b/vendor/github.com/containernetworking/cni/scripts/release.sh new file mode 100755 index 000000000..d3cef5671 --- /dev/null +++ b/vendor/github.com/containernetworking/cni/scripts/release.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +set -xe + +SRC_DIR="${SRC_DIR:-$PWD}" +BUILDFLAGS="-a --ldflags '-extldflags \"-static\"'" + +TAG=$(git describe --tags --dirty) +RELEASE_DIR=release-${TAG} + +OUTPUT_DIR=bin + +# Always clean first +rm -Rf ${SRC_DIR}/${RELEASE_DIR} +mkdir -p ${SRC_DIR}/${RELEASE_DIR} +mkdir -p ${OUTPUT_DIR} + +docker run -i -v ${SRC_DIR}:/opt/src --rm golang:1.8-alpine \ +/bin/sh -xe -c "\ + apk --no-cache add bash tar; + cd /opt/src; umask 0022; + for arch in amd64 arm arm64 ppc64le s390x; do \ + rm -f ${OUTPUT_DIR}/* ; \ + CGO_ENABLED=0 GOARCH=\$arch ./build.sh ${BUILDFLAGS}; \ + for format in tgz; do \ + FILENAME=cni-\$arch-${TAG}.\$format; \ + FILEPATH=${RELEASE_DIR}/\$FILENAME; \ + tar -C ${OUTPUT_DIR} --owner=0 --group=0 -caf \$FILEPATH .; \ + if [ \"\$arch\" == \"amd64\" ]; then \ + cp \$FILEPATH ${RELEASE_DIR}/cni-${TAG}.\$format; \ + fi; \ + done; \ + done; + cd ${RELEASE_DIR}; + for f in *.tgz; do sha1sum \$f > \$f.sha1; done; + for f in *.tgz; do sha256sum \$f > \$f.sha256; done; + for f in *.tgz; do sha512sum \$f > \$f.sha512; done; + cd .. + chown -R ${UID} ${OUTPUT_DIR} ${RELEASE_DIR}" diff --git a/vendor/github.com/containernetworking/cni/test.sh b/vendor/github.com/containernetworking/cni/test.sh index 3da1669db..ba27e0bed 100755 --- a/vendor/github.com/containernetworking/cni/test.sh +++ b/vendor/github.com/containernetworking/cni/test.sh @@ -1,73 +1,46 @@ #!/usr/bin/env bash -# -# Run all CNI tests -# ./test -# ./test -v -# -# Run tests for one package -# PKG=./plugins/ipam/dhcp ./test -# -set -e +set -euo pipefail -source ./build.sh - -TESTABLE="libcni plugins/ipam/dhcp plugins/ipam/host-local plugins/ipam/host-local/backend/allocator plugins/main/loopback pkg/invoke pkg/ns pkg/skel pkg/types pkg/types/current pkg/types/020 pkg/utils plugins/main/ipvlan plugins/main/macvlan plugins/main/bridge plugins/main/ptp plugins/test/noop pkg/utils/hwaddr pkg/ip pkg/version pkg/version/testhelpers plugins/meta/flannel pkg/ipam" -FORMATTABLE="$TESTABLE pkg/testutils plugins/meta/flannel plugins/meta/tuning" - -# user has not provided PKG override -if [ -z "$PKG" ]; then - TEST=$TESTABLE - FMT=$FORMATTABLE - -# user has provided PKG override -else - # strip out slashes and dots from PKG=./foo/ - TEST=${PKG//\//} - TEST=${TEST//./} - - # only run gofmt on packages provided by user - FMT="$TEST" -fi - -# split TEST into an array and prepend REPO_PATH to each local package -split=(${TEST// / }) -TEST=${split[@]/#/${REPO_PATH}/} +# switch into the repo root directory +cd "$(dirname $0)" echo -n "Running tests " function testrun { - sudo -E bash -c "umask 0; PATH=$GOROOT/bin:$(pwd)/bin:$PATH go test -covermode set $@" + bash -c "umask 0; PATH=$PATH go test $@" } -if [ ! -z "${COVERALLS}" ]; then +if [ ! -z "${COVERALLS:-""}" ]; then + # coverage profile only works per-package + PKGS="$(go list ./... | xargs echo)" echo "with coverage profile generation..." i=0 - for t in ${TEST}; do - testrun "-coverprofile ${i}.coverprofile ${t}" + for t in ${PKGS}; do + testrun "-covermode set -coverprofile ${i}.coverprofile ${t}" i=$((i+1)) done gover - goveralls -service=travis-ci -coverprofile=gover.coverprofile -repotoken=$COVERALLS_TOKEN + goveralls -service=travis-ci -coverprofile=gover.coverprofile else echo "without coverage profile generation..." - testrun "${TEST}" + testrun "./..." fi echo "Checking gofmt..." -fmtRes=$(gofmt -l $FMT) +fmtRes=$(go fmt ./...) if [ -n "${fmtRes}" ]; then - echo -e "gofmt checking failed:\n${fmtRes}" + echo -e "go fmt checking failed:\n${fmtRes}" exit 255 fi echo "Checking govet..." -vetRes=$(go vet $TEST) +vetRes=$(go vet ./...) if [ -n "${vetRes}" ]; then - echo -e "govet checking failed:\n${vetRes}" + echo -e "go vet checking failed:\n${vetRes}" exit 255 fi echo "Checking license header..." licRes=$( - for file in $(find . -type f -iname '*.go' ! -path './vendor/*'); do + for file in $(find . -type f -iname '*.go'); do head -n1 "${file}" | grep -Eq "(Copyright|generated)" || echo -e " ${file}" done ) @@ -76,5 +49,4 @@ if [ -n "${licRes}" ]; then exit 255 fi - echo "Success" diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/coreos/go-systemd/activation/listeners.go b/vendor/github.com/containernetworking/cni/vendor/github.com/coreos/go-systemd/activation/listeners.go deleted file mode 100644 index a30cb8939..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/coreos/go-systemd/activation/listeners.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// 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. - -package activation - -import ( - "net" -) - -// Listeners returns a slice containing a net.Listener for each matching socket type -// passed to this process. -// -// The order of the file descriptors is preserved in the returned slice. -// Nil values are used to fill any gaps. For example if systemd were to return file descriptors -// corresponding with "udp, tcp, tcp", then the slice would contain {nil, net.Listener, net.Listener} -func Listeners(unsetEnv bool) ([]net.Listener, error) { - files := Files(unsetEnv) - listeners := make([]net.Listener, len(files)) - - for i, f := range files { - if pc, err := net.FileListener(f); err == nil { - listeners[i] = pc - } - } - return listeners, nil -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/bootstrap_command.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/bootstrap_command.go deleted file mode 100644 index d804fe00c..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/bootstrap_command.go +++ /dev/null @@ -1,182 +0,0 @@ -package main - -import ( - "bytes" - "flag" - "fmt" - "os" - "path/filepath" - "strings" - "text/template" - - "go/build" - - "github.com/onsi/ginkgo/ginkgo/nodot" -) - -func BuildBootstrapCommand() *Command { - var agouti, noDot bool - flagSet := flag.NewFlagSet("bootstrap", flag.ExitOnError) - flagSet.BoolVar(&agouti, "agouti", false, "If set, bootstrap will generate a bootstrap file for writing Agouti tests") - flagSet.BoolVar(&noDot, "nodot", false, "If set, bootstrap will generate a bootstrap file that does not . import ginkgo and gomega") - - return &Command{ - Name: "bootstrap", - FlagSet: flagSet, - UsageCommand: "ginkgo bootstrap ", - Usage: []string{ - "Bootstrap a test suite for the current package", - "Accepts the following flags:", - }, - Command: func(args []string, additionalArgs []string) { - generateBootstrap(agouti, noDot) - }, - } -} - -var bootstrapText = `package {{.Package}}_test - -import ( - {{.GinkgoImport}} - {{.GomegaImport}} - - "testing" -) - -func Test{{.FormattedName}}(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "{{.FormattedName}} Suite") -} -` - -var agoutiBootstrapText = `package {{.Package}}_test - -import ( - {{.GinkgoImport}} - {{.GomegaImport}} - "github.com/sclevine/agouti" - - "testing" -) - -func Test{{.FormattedName}}(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "{{.FormattedName}} Suite") -} - -var agoutiDriver *agouti.WebDriver - -var _ = BeforeSuite(func() { - // Choose a WebDriver: - - agoutiDriver = agouti.PhantomJS() - // agoutiDriver = agouti.Selenium() - // agoutiDriver = agouti.ChromeDriver() - - Expect(agoutiDriver.Start()).To(Succeed()) -}) - -var _ = AfterSuite(func() { - Expect(agoutiDriver.Stop()).To(Succeed()) -}) -` - -type bootstrapData struct { - Package string - FormattedName string - GinkgoImport string - GomegaImport string -} - -func getPackageAndFormattedName() (string, string, string) { - path, err := os.Getwd() - if err != nil { - complainAndQuit("Could not get current working directory: \n" + err.Error()) - } - - dirName := strings.Replace(filepath.Base(path), "-", "_", -1) - dirName = strings.Replace(dirName, " ", "_", -1) - - pkg, err := build.ImportDir(path, 0) - packageName := pkg.Name - if err != nil { - packageName = dirName - } - - formattedName := prettifyPackageName(filepath.Base(path)) - return packageName, dirName, formattedName -} - -func prettifyPackageName(name string) string { - name = strings.Replace(name, "-", " ", -1) - name = strings.Replace(name, "_", " ", -1) - name = strings.Title(name) - name = strings.Replace(name, " ", "", -1) - return name -} - -func fileExists(path string) bool { - _, err := os.Stat(path) - if err == nil { - return true - } - return false -} - -func generateBootstrap(agouti bool, noDot bool) { - packageName, bootstrapFilePrefix, formattedName := getPackageAndFormattedName() - data := bootstrapData{ - Package: packageName, - FormattedName: formattedName, - GinkgoImport: `. "github.com/onsi/ginkgo"`, - GomegaImport: `. "github.com/onsi/gomega"`, - } - - if noDot { - data.GinkgoImport = `"github.com/onsi/ginkgo"` - data.GomegaImport = `"github.com/onsi/gomega"` - } - - targetFile := fmt.Sprintf("%s_suite_test.go", bootstrapFilePrefix) - if fileExists(targetFile) { - fmt.Printf("%s already exists.\n\n", targetFile) - os.Exit(1) - } else { - fmt.Printf("Generating ginkgo test suite bootstrap for %s in:\n\t%s\n", packageName, targetFile) - } - - f, err := os.Create(targetFile) - if err != nil { - complainAndQuit("Could not create file: " + err.Error()) - panic(err.Error()) - } - defer f.Close() - - var templateText string - if agouti { - templateText = agoutiBootstrapText - } else { - templateText = bootstrapText - } - - bootstrapTemplate, err := template.New("bootstrap").Parse(templateText) - if err != nil { - panic(err.Error()) - } - - buf := &bytes.Buffer{} - bootstrapTemplate.Execute(buf, data) - - if noDot { - contents, err := nodot.ApplyNoDot(buf.Bytes()) - if err != nil { - complainAndQuit("Failed to import nodot declarations: " + err.Error()) - } - fmt.Println("To update the nodot declarations in the future, switch to this directory and run:\n\tginkgo nodot") - buf = bytes.NewBuffer(contents) - } - - buf.WriteTo(f) - - goFmt(targetFile) -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/build_command.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/build_command.go deleted file mode 100644 index bbba8a1b4..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/build_command.go +++ /dev/null @@ -1,68 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "os" - "path/filepath" - - "github.com/onsi/ginkgo/ginkgo/interrupthandler" - "github.com/onsi/ginkgo/ginkgo/testrunner" -) - -func BuildBuildCommand() *Command { - commandFlags := NewBuildCommandFlags(flag.NewFlagSet("build", flag.ExitOnError)) - interruptHandler := interrupthandler.NewInterruptHandler() - builder := &SpecBuilder{ - commandFlags: commandFlags, - interruptHandler: interruptHandler, - } - - return &Command{ - Name: "build", - FlagSet: commandFlags.FlagSet, - UsageCommand: "ginkgo build ", - Usage: []string{ - "Build the passed in (or the package in the current directory if left blank).", - "Accepts the following flags:", - }, - Command: builder.BuildSpecs, - } -} - -type SpecBuilder struct { - commandFlags *RunWatchAndBuildCommandFlags - interruptHandler *interrupthandler.InterruptHandler -} - -func (r *SpecBuilder) BuildSpecs(args []string, additionalArgs []string) { - r.commandFlags.computeNodes() - - suites, _ := findSuites(args, r.commandFlags.Recurse, r.commandFlags.SkipPackage, false) - - if len(suites) == 0 { - complainAndQuit("Found no test suites") - } - - passed := true - for _, suite := range suites { - runner := testrunner.New(suite, 1, false, r.commandFlags.Race, r.commandFlags.Cover, r.commandFlags.CoverPkg, r.commandFlags.Tags, nil) - fmt.Printf("Compiling %s...\n", suite.PackageName) - - path, _ := filepath.Abs(filepath.Join(suite.Path, fmt.Sprintf("%s.test", suite.PackageName))) - err := runner.CompileTo(path) - if err != nil { - fmt.Println(err.Error()) - passed = false - } else { - fmt.Printf(" compiled %s.test\n", suite.PackageName) - } - - runner.CleanUp() - } - - if passed { - os.Exit(0) - } - os.Exit(1) -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/ginkgo_ast_nodes.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/ginkgo_ast_nodes.go deleted file mode 100644 index 02e2b3b32..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/ginkgo_ast_nodes.go +++ /dev/null @@ -1,123 +0,0 @@ -package convert - -import ( - "fmt" - "go/ast" - "strings" - "unicode" -) - -/* - * Creates a func init() node - */ -func createVarUnderscoreBlock() *ast.ValueSpec { - valueSpec := &ast.ValueSpec{} - object := &ast.Object{Kind: 4, Name: "_", Decl: valueSpec, Data: 0} - ident := &ast.Ident{Name: "_", Obj: object} - valueSpec.Names = append(valueSpec.Names, ident) - return valueSpec -} - -/* - * Creates a Describe("Testing with ginkgo", func() { }) node - */ -func createDescribeBlock() *ast.CallExpr { - blockStatement := &ast.BlockStmt{List: []ast.Stmt{}} - - fieldList := &ast.FieldList{} - funcType := &ast.FuncType{Params: fieldList} - funcLit := &ast.FuncLit{Type: funcType, Body: blockStatement} - basicLit := &ast.BasicLit{Kind: 9, Value: "\"Testing with Ginkgo\""} - describeIdent := &ast.Ident{Name: "Describe"} - return &ast.CallExpr{Fun: describeIdent, Args: []ast.Expr{basicLit, funcLit}} -} - -/* - * Convenience function to return the name of the *testing.T param - * for a Test function that will be rewritten. This is useful because - * we will want to replace the usage of this named *testing.T inside the - * body of the function with a GinktoT. - */ -func namedTestingTArg(node *ast.FuncDecl) string { - return node.Type.Params.List[0].Names[0].Name // *exhale* -} - -/* - * Convenience function to return the block statement node for a Describe statement - */ -func blockStatementFromDescribe(desc *ast.CallExpr) *ast.BlockStmt { - var funcLit *ast.FuncLit - var found = false - - for _, node := range desc.Args { - switch node := node.(type) { - case *ast.FuncLit: - found = true - funcLit = node - break - } - } - - if !found { - panic("Error finding ast.FuncLit inside describe statement. Somebody done goofed.") - } - - return funcLit.Body -} - -/* convenience function for creating an It("TestNameHere") - * with all the body of the test function inside the anonymous - * func passed to It() - */ -func createItStatementForTestFunc(testFunc *ast.FuncDecl) *ast.ExprStmt { - blockStatement := &ast.BlockStmt{List: testFunc.Body.List} - fieldList := &ast.FieldList{} - funcType := &ast.FuncType{Params: fieldList} - funcLit := &ast.FuncLit{Type: funcType, Body: blockStatement} - - testName := rewriteTestName(testFunc.Name.Name) - basicLit := &ast.BasicLit{Kind: 9, Value: fmt.Sprintf("\"%s\"", testName)} - itBlockIdent := &ast.Ident{Name: "It"} - callExpr := &ast.CallExpr{Fun: itBlockIdent, Args: []ast.Expr{basicLit, funcLit}} - return &ast.ExprStmt{X: callExpr} -} - -/* -* rewrite test names to be human readable -* eg: rewrites "TestSomethingAmazing" as "something amazing" - */ -func rewriteTestName(testName string) string { - nameComponents := []string{} - currentString := "" - indexOfTest := strings.Index(testName, "Test") - if indexOfTest != 0 { - return testName - } - - testName = strings.Replace(testName, "Test", "", 1) - first, rest := testName[0], testName[1:] - testName = string(unicode.ToLower(rune(first))) + rest - - for _, rune := range testName { - if unicode.IsUpper(rune) { - nameComponents = append(nameComponents, currentString) - currentString = string(unicode.ToLower(rune)) - } else { - currentString += string(rune) - } - } - - return strings.Join(append(nameComponents, currentString), " ") -} - -func newGinkgoTFromIdent(ident *ast.Ident) *ast.CallExpr { - return &ast.CallExpr{ - Lparen: ident.NamePos + 1, - Rparen: ident.NamePos + 2, - Fun: &ast.Ident{Name: "GinkgoT"}, - } -} - -func newGinkgoTInterface() *ast.Ident { - return &ast.Ident{Name: "GinkgoTInterface"} -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/import.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/import.go deleted file mode 100644 index e226196f7..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/import.go +++ /dev/null @@ -1,91 +0,0 @@ -package convert - -import ( - "errors" - "fmt" - "go/ast" -) - -/* - * Given the root node of an AST, returns the node containing the - * import statements for the file. - */ -func importsForRootNode(rootNode *ast.File) (imports *ast.GenDecl, err error) { - for _, declaration := range rootNode.Decls { - decl, ok := declaration.(*ast.GenDecl) - if !ok || len(decl.Specs) == 0 { - continue - } - - _, ok = decl.Specs[0].(*ast.ImportSpec) - if ok { - imports = decl - return - } - } - - err = errors.New(fmt.Sprintf("Could not find imports for root node:\n\t%#v\n", rootNode)) - return -} - -/* - * Removes "testing" import, if present - */ -func removeTestingImport(rootNode *ast.File) { - importDecl, err := importsForRootNode(rootNode) - if err != nil { - panic(err.Error()) - } - - var index int - for i, importSpec := range importDecl.Specs { - importSpec := importSpec.(*ast.ImportSpec) - if importSpec.Path.Value == "\"testing\"" { - index = i - break - } - } - - importDecl.Specs = append(importDecl.Specs[:index], importDecl.Specs[index+1:]...) -} - -/* - * Adds import statements for onsi/ginkgo, if missing - */ -func addGinkgoImports(rootNode *ast.File) { - importDecl, err := importsForRootNode(rootNode) - if err != nil { - panic(err.Error()) - } - - if len(importDecl.Specs) == 0 { - // TODO: might need to create a import decl here - panic("unimplemented : expected to find an imports block") - } - - needsGinkgo := true - for _, importSpec := range importDecl.Specs { - importSpec, ok := importSpec.(*ast.ImportSpec) - if !ok { - continue - } - - if importSpec.Path.Value == "\"github.com/onsi/ginkgo\"" { - needsGinkgo = false - } - } - - if needsGinkgo { - importDecl.Specs = append(importDecl.Specs, createImport(".", "\"github.com/onsi/ginkgo\"")) - } -} - -/* - * convenience function to create an import statement - */ -func createImport(name, path string) *ast.ImportSpec { - return &ast.ImportSpec{ - Name: &ast.Ident{Name: name}, - Path: &ast.BasicLit{Kind: 9, Value: path}, - } -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/package_rewriter.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/package_rewriter.go deleted file mode 100644 index ed09c460d..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/package_rewriter.go +++ /dev/null @@ -1,127 +0,0 @@ -package convert - -import ( - "fmt" - "go/build" - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "regexp" -) - -/* - * RewritePackage takes a name (eg: my-package/tools), finds its test files using - * Go's build package, and then rewrites them. A ginkgo test suite file will - * also be added for this package, and all of its child packages. - */ -func RewritePackage(packageName string) { - pkg, err := packageWithName(packageName) - if err != nil { - panic(fmt.Sprintf("unexpected error reading package: '%s'\n%s\n", packageName, err.Error())) - } - - for _, filename := range findTestsInPackage(pkg) { - rewriteTestsInFile(filename) - } - return -} - -/* - * Given a package, findTestsInPackage reads the test files in the directory, - * and then recurses on each child package, returning a slice of all test files - * found in this process. - */ -func findTestsInPackage(pkg *build.Package) (testfiles []string) { - for _, file := range append(pkg.TestGoFiles, pkg.XTestGoFiles...) { - testfiles = append(testfiles, filepath.Join(pkg.Dir, file)) - } - - dirFiles, err := ioutil.ReadDir(pkg.Dir) - if err != nil { - panic(fmt.Sprintf("unexpected error reading dir: '%s'\n%s\n", pkg.Dir, err.Error())) - } - - re := regexp.MustCompile(`^[._]`) - - for _, file := range dirFiles { - if !file.IsDir() { - continue - } - - if re.Match([]byte(file.Name())) { - continue - } - - packageName := filepath.Join(pkg.ImportPath, file.Name()) - subPackage, err := packageWithName(packageName) - if err != nil { - panic(fmt.Sprintf("unexpected error reading package: '%s'\n%s\n", packageName, err.Error())) - } - - testfiles = append(testfiles, findTestsInPackage(subPackage)...) - } - - addGinkgoSuiteForPackage(pkg) - goFmtPackage(pkg) - return -} - -/* - * Shells out to `ginkgo bootstrap` to create a test suite file - */ -func addGinkgoSuiteForPackage(pkg *build.Package) { - originalDir, err := os.Getwd() - if err != nil { - panic(err) - } - - suite_test_file := filepath.Join(pkg.Dir, pkg.Name+"_suite_test.go") - - _, err = os.Stat(suite_test_file) - if err == nil { - return // test file already exists, this should be a no-op - } - - err = os.Chdir(pkg.Dir) - if err != nil { - panic(err) - } - - output, err := exec.Command("ginkgo", "bootstrap").Output() - - if err != nil { - panic(fmt.Sprintf("error running 'ginkgo bootstrap'.\nstdout: %s\n%s\n", output, err.Error())) - } - - err = os.Chdir(originalDir) - if err != nil { - panic(err) - } -} - -/* - * Shells out to `go fmt` to format the package - */ -func goFmtPackage(pkg *build.Package) { - output, err := exec.Command("go", "fmt", pkg.ImportPath).Output() - - if err != nil { - fmt.Printf("Warning: Error running 'go fmt %s'.\nstdout: %s\n%s\n", pkg.ImportPath, output, err.Error()) - } -} - -/* - * Attempts to return a package with its test files already read. - * The ImportMode arg to build.Import lets you specify if you want go to read the - * buildable go files inside the package, but it fails if the package has no go files - */ -func packageWithName(name string) (pkg *build.Package, err error) { - pkg, err = build.Default.Import(name, ".", build.ImportMode(0)) - if err == nil { - return - } - - pkg, err = build.Default.Import(name, ".", build.ImportMode(1)) - return -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/test_finder.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/test_finder.go deleted file mode 100644 index b33595c9a..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/test_finder.go +++ /dev/null @@ -1,56 +0,0 @@ -package convert - -import ( - "go/ast" - "regexp" -) - -/* - * Given a root node, walks its top level statements and returns - * points to function nodes to rewrite as It statements. - * These functions, according to Go testing convention, must be named - * TestWithCamelCasedName and receive a single *testing.T argument. - */ -func findTestFuncs(rootNode *ast.File) (testsToRewrite []*ast.FuncDecl) { - testNameRegexp := regexp.MustCompile("^Test[0-9A-Z].+") - - ast.Inspect(rootNode, func(node ast.Node) bool { - if node == nil { - return false - } - - switch node := node.(type) { - case *ast.FuncDecl: - matches := testNameRegexp.MatchString(node.Name.Name) - - if matches && receivesTestingT(node) { - testsToRewrite = append(testsToRewrite, node) - } - } - - return true - }) - - return -} - -/* - * convenience function that looks at args to a function and determines if its - * params include an argument of type *testing.T - */ -func receivesTestingT(node *ast.FuncDecl) bool { - if len(node.Type.Params.List) != 1 { - return false - } - - base, ok := node.Type.Params.List[0].Type.(*ast.StarExpr) - if !ok { - return false - } - - intermediate := base.X.(*ast.SelectorExpr) - isTestingPackage := intermediate.X.(*ast.Ident).Name == "testing" - isTestingT := intermediate.Sel.Name == "T" - - return isTestingPackage && isTestingT -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/testfile_rewriter.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/testfile_rewriter.go deleted file mode 100644 index 4b001a7db..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/testfile_rewriter.go +++ /dev/null @@ -1,163 +0,0 @@ -package convert - -import ( - "bytes" - "fmt" - "go/ast" - "go/format" - "go/parser" - "go/token" - "io/ioutil" - "os" -) - -/* - * Given a file path, rewrites any tests in the Ginkgo format. - * First, we parse the AST, and update the imports declaration. - * Then, we walk the first child elements in the file, returning tests to rewrite. - * A top level init func is declared, with a single Describe func inside. - * Then the test functions to rewrite are inserted as It statements inside the Describe. - * Finally we walk the rest of the file, replacing other usages of *testing.T - * Once that is complete, we write the AST back out again to its file. - */ -func rewriteTestsInFile(pathToFile string) { - fileSet := token.NewFileSet() - rootNode, err := parser.ParseFile(fileSet, pathToFile, nil, 0) - if err != nil { - panic(fmt.Sprintf("Error parsing test file '%s':\n%s\n", pathToFile, err.Error())) - } - - addGinkgoImports(rootNode) - removeTestingImport(rootNode) - - varUnderscoreBlock := createVarUnderscoreBlock() - describeBlock := createDescribeBlock() - varUnderscoreBlock.Values = []ast.Expr{describeBlock} - - for _, testFunc := range findTestFuncs(rootNode) { - rewriteTestFuncAsItStatement(testFunc, rootNode, describeBlock) - } - - underscoreDecl := &ast.GenDecl{ - Tok: 85, // gah, magick numbers are needed to make this work - TokPos: 14, // this tricks Go into writing "var _ = Describe" - Specs: []ast.Spec{varUnderscoreBlock}, - } - - imports := rootNode.Decls[0] - tail := rootNode.Decls[1:] - rootNode.Decls = append(append([]ast.Decl{imports}, underscoreDecl), tail...) - rewriteOtherFuncsToUseGinkgoT(rootNode.Decls) - walkNodesInRootNodeReplacingTestingT(rootNode) - - var buffer bytes.Buffer - if err = format.Node(&buffer, fileSet, rootNode); err != nil { - panic(fmt.Sprintf("Error formatting ast node after rewriting tests.\n%s\n", err.Error())) - } - - fileInfo, err := os.Stat(pathToFile) - if err != nil { - panic(fmt.Sprintf("Error stat'ing file: %s\n", pathToFile)) - } - - ioutil.WriteFile(pathToFile, buffer.Bytes(), fileInfo.Mode()) - return -} - -/* - * Given a test func named TestDoesSomethingNeat, rewrites it as - * It("does something neat", func() { __test_body_here__ }) and adds it - * to the Describe's list of statements - */ -func rewriteTestFuncAsItStatement(testFunc *ast.FuncDecl, rootNode *ast.File, describe *ast.CallExpr) { - var funcIndex int = -1 - for index, child := range rootNode.Decls { - if child == testFunc { - funcIndex = index - break - } - } - - if funcIndex < 0 { - panic(fmt.Sprintf("Assert failed: Error finding index for test node %s\n", testFunc.Name.Name)) - } - - var block *ast.BlockStmt = blockStatementFromDescribe(describe) - block.List = append(block.List, createItStatementForTestFunc(testFunc)) - replaceTestingTsWithGinkgoT(block, namedTestingTArg(testFunc)) - - // remove the old test func from the root node's declarations - rootNode.Decls = append(rootNode.Decls[:funcIndex], rootNode.Decls[funcIndex+1:]...) - return -} - -/* - * walks nodes inside of a test func's statements and replaces the usage of - * it's named *testing.T param with GinkgoT's - */ -func replaceTestingTsWithGinkgoT(statementsBlock *ast.BlockStmt, testingT string) { - ast.Inspect(statementsBlock, func(node ast.Node) bool { - if node == nil { - return false - } - - keyValueExpr, ok := node.(*ast.KeyValueExpr) - if ok { - replaceNamedTestingTsInKeyValueExpression(keyValueExpr, testingT) - return true - } - - funcLiteral, ok := node.(*ast.FuncLit) - if ok { - replaceTypeDeclTestingTsInFuncLiteral(funcLiteral) - return true - } - - callExpr, ok := node.(*ast.CallExpr) - if !ok { - return true - } - replaceTestingTsInArgsLists(callExpr, testingT) - - funCall, ok := callExpr.Fun.(*ast.SelectorExpr) - if ok { - replaceTestingTsMethodCalls(funCall, testingT) - } - - return true - }) -} - -/* - * rewrite t.Fail() or any other *testing.T method by replacing with T().Fail() - * This function receives a selector expression (eg: t.Fail()) and - * the name of the *testing.T param from the function declaration. Rewrites the - * selector expression in place if the target was a *testing.T - */ -func replaceTestingTsMethodCalls(selectorExpr *ast.SelectorExpr, testingT string) { - ident, ok := selectorExpr.X.(*ast.Ident) - if !ok { - return - } - - if ident.Name == testingT { - selectorExpr.X = newGinkgoTFromIdent(ident) - } -} - -/* - * replaces usages of a named *testing.T param inside of a call expression - * with a new GinkgoT object - */ -func replaceTestingTsInArgsLists(callExpr *ast.CallExpr, testingT string) { - for index, arg := range callExpr.Args { - ident, ok := arg.(*ast.Ident) - if !ok { - continue - } - - if ident.Name == testingT { - callExpr.Args[index] = newGinkgoTFromIdent(ident) - } - } -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/testing_t_rewriter.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/testing_t_rewriter.go deleted file mode 100644 index 418cdc4e5..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert/testing_t_rewriter.go +++ /dev/null @@ -1,130 +0,0 @@ -package convert - -import ( - "go/ast" -) - -/* - * Rewrites any other top level funcs that receive a *testing.T param - */ -func rewriteOtherFuncsToUseGinkgoT(declarations []ast.Decl) { - for _, decl := range declarations { - decl, ok := decl.(*ast.FuncDecl) - if !ok { - continue - } - - for _, param := range decl.Type.Params.List { - starExpr, ok := param.Type.(*ast.StarExpr) - if !ok { - continue - } - - selectorExpr, ok := starExpr.X.(*ast.SelectorExpr) - if !ok { - continue - } - - xIdent, ok := selectorExpr.X.(*ast.Ident) - if !ok || xIdent.Name != "testing" { - continue - } - - if selectorExpr.Sel.Name != "T" { - continue - } - - param.Type = newGinkgoTInterface() - } - } -} - -/* - * Walks all of the nodes in the file, replacing *testing.T in struct - * and func literal nodes. eg: - * type foo struct { *testing.T } - * var bar = func(t *testing.T) { } - */ -func walkNodesInRootNodeReplacingTestingT(rootNode *ast.File) { - ast.Inspect(rootNode, func(node ast.Node) bool { - if node == nil { - return false - } - - switch node := node.(type) { - case *ast.StructType: - replaceTestingTsInStructType(node) - case *ast.FuncLit: - replaceTypeDeclTestingTsInFuncLiteral(node) - } - - return true - }) -} - -/* - * replaces named *testing.T inside a composite literal - */ -func replaceNamedTestingTsInKeyValueExpression(kve *ast.KeyValueExpr, testingT string) { - ident, ok := kve.Value.(*ast.Ident) - if !ok { - return - } - - if ident.Name == testingT { - kve.Value = newGinkgoTFromIdent(ident) - } -} - -/* - * replaces *testing.T params in a func literal with GinkgoT - */ -func replaceTypeDeclTestingTsInFuncLiteral(functionLiteral *ast.FuncLit) { - for _, arg := range functionLiteral.Type.Params.List { - starExpr, ok := arg.Type.(*ast.StarExpr) - if !ok { - continue - } - - selectorExpr, ok := starExpr.X.(*ast.SelectorExpr) - if !ok { - continue - } - - target, ok := selectorExpr.X.(*ast.Ident) - if !ok { - continue - } - - if target.Name == "testing" && selectorExpr.Sel.Name == "T" { - arg.Type = newGinkgoTInterface() - } - } -} - -/* - * Replaces *testing.T types inside of a struct declaration with a GinkgoT - * eg: type foo struct { *testing.T } - */ -func replaceTestingTsInStructType(structType *ast.StructType) { - for _, field := range structType.Fields.List { - starExpr, ok := field.Type.(*ast.StarExpr) - if !ok { - continue - } - - selectorExpr, ok := starExpr.X.(*ast.SelectorExpr) - if !ok { - continue - } - - xIdent, ok := selectorExpr.X.(*ast.Ident) - if !ok { - continue - } - - if xIdent.Name == "testing" && selectorExpr.Sel.Name == "T" { - field.Type = newGinkgoTInterface() - } - } -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert_command.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert_command.go deleted file mode 100644 index 89e60d393..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/convert_command.go +++ /dev/null @@ -1,44 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "github.com/onsi/ginkgo/ginkgo/convert" - "os" -) - -func BuildConvertCommand() *Command { - return &Command{ - Name: "convert", - FlagSet: flag.NewFlagSet("convert", flag.ExitOnError), - UsageCommand: "ginkgo convert /path/to/package", - Usage: []string{ - "Convert the package at the passed in path from an XUnit-style test to a Ginkgo-style test", - }, - Command: convertPackage, - } -} - -func convertPackage(args []string, additionalArgs []string) { - if len(args) != 1 { - println(fmt.Sprintf("usage: ginkgo convert /path/to/your/package")) - os.Exit(1) - } - - defer func() { - err := recover() - if err != nil { - switch err := err.(type) { - case error: - println(err.Error()) - case string: - println(err) - default: - println(fmt.Sprintf("unexpected error: %#v", err)) - } - os.Exit(1) - } - }() - - convert.RewritePackage(args[0]) -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/generate_command.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/generate_command.go deleted file mode 100644 index 7dd3b4da2..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/generate_command.go +++ /dev/null @@ -1,164 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "os" - "path/filepath" - "strings" - "text/template" -) - -func BuildGenerateCommand() *Command { - var agouti, noDot bool - flagSet := flag.NewFlagSet("generate", flag.ExitOnError) - flagSet.BoolVar(&agouti, "agouti", false, "If set, generate will generate a test file for writing Agouti tests") - flagSet.BoolVar(&noDot, "nodot", false, "If set, generate will generate a test file that does not . import ginkgo and gomega") - - return &Command{ - Name: "generate", - FlagSet: flagSet, - UsageCommand: "ginkgo generate ", - Usage: []string{ - "Generate a test file named filename_test.go", - "If the optional argument is omitted, a file named after the package in the current directory will be created.", - "Accepts the following flags:", - }, - Command: func(args []string, additionalArgs []string) { - generateSpec(args, agouti, noDot) - }, - } -} - -var specText = `package {{.Package}}_test - -import ( - . "{{.PackageImportPath}}" - - {{if .IncludeImports}}. "github.com/onsi/ginkgo"{{end}} - {{if .IncludeImports}}. "github.com/onsi/gomega"{{end}} -) - -var _ = Describe("{{.Subject}}", func() { - -}) -` - -var agoutiSpecText = `package {{.Package}}_test - -import ( - . "{{.PackageImportPath}}" - - {{if .IncludeImports}}. "github.com/onsi/ginkgo"{{end}} - {{if .IncludeImports}}. "github.com/onsi/gomega"{{end}} - . "github.com/sclevine/agouti/matchers" - "github.com/sclevine/agouti" -) - -var _ = Describe("{{.Subject}}", func() { - var page *agouti.Page - - BeforeEach(func() { - var err error - page, err = agoutiDriver.NewPage() - Expect(err).NotTo(HaveOccurred()) - }) - - AfterEach(func() { - Expect(page.Destroy()).To(Succeed()) - }) -}) -` - -type specData struct { - Package string - Subject string - PackageImportPath string - IncludeImports bool -} - -func generateSpec(args []string, agouti, noDot bool) { - if len(args) == 0 { - err := generateSpecForSubject("", agouti, noDot) - if err != nil { - fmt.Println(err.Error()) - fmt.Println("") - os.Exit(1) - } - fmt.Println("") - return - } - - var failed bool - for _, arg := range args { - err := generateSpecForSubject(arg, agouti, noDot) - if err != nil { - failed = true - fmt.Println(err.Error()) - } - } - fmt.Println("") - if failed { - os.Exit(1) - } -} - -func generateSpecForSubject(subject string, agouti, noDot bool) error { - packageName, specFilePrefix, formattedName := getPackageAndFormattedName() - if subject != "" { - subject = strings.Split(subject, ".go")[0] - subject = strings.Split(subject, "_test")[0] - specFilePrefix = subject - formattedName = prettifyPackageName(subject) - } - - data := specData{ - Package: packageName, - Subject: formattedName, - PackageImportPath: getPackageImportPath(), - IncludeImports: !noDot, - } - - targetFile := fmt.Sprintf("%s_test.go", specFilePrefix) - if fileExists(targetFile) { - return fmt.Errorf("%s already exists.", targetFile) - } else { - fmt.Printf("Generating ginkgo test for %s in:\n %s\n", data.Subject, targetFile) - } - - f, err := os.Create(targetFile) - if err != nil { - return err - } - defer f.Close() - - var templateText string - if agouti { - templateText = agoutiSpecText - } else { - templateText = specText - } - - specTemplate, err := template.New("spec").Parse(templateText) - if err != nil { - return err - } - - specTemplate.Execute(f, data) - goFmt(targetFile) - return nil -} - -func getPackageImportPath() string { - workingDir, err := os.Getwd() - if err != nil { - panic(err.Error()) - } - sep := string(filepath.Separator) - paths := strings.Split(workingDir, sep+"src"+sep) - if len(paths) == 1 { - fmt.Printf("\nCouldn't identify package import path.\n\n\tginkgo generate\n\nMust be run within a package directory under $GOPATH/src/...\nYou're going to have to change UNKNOWN_PACKAGE_PATH in the generated file...\n\n") - return "UNKNOWN_PACKAGE_PATH" - } - return filepath.ToSlash(paths[len(paths)-1]) -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/help_command.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/help_command.go deleted file mode 100644 index a42d4f8aa..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/help_command.go +++ /dev/null @@ -1,31 +0,0 @@ -package main - -import ( - "flag" - "fmt" -) - -func BuildHelpCommand() *Command { - return &Command{ - Name: "help", - FlagSet: flag.NewFlagSet("help", flag.ExitOnError), - UsageCommand: "ginkgo help ", - Usage: []string{ - "Print usage information. If a command is passed in, print usage information just for that command.", - }, - Command: printHelp, - } -} - -func printHelp(args []string, additionalArgs []string) { - if len(args) == 0 { - usage() - } else { - command, found := commandMatching(args[0]) - if !found { - complainAndQuit(fmt.Sprintf("Unknown command: %s", args[0])) - } - - usageForCommand(command, true) - } -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/interrupthandler/interrupt_handler.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/interrupthandler/interrupt_handler.go deleted file mode 100644 index c15db0b02..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/interrupthandler/interrupt_handler.go +++ /dev/null @@ -1,52 +0,0 @@ -package interrupthandler - -import ( - "os" - "os/signal" - "sync" - "syscall" -) - -type InterruptHandler struct { - interruptCount int - lock *sync.Mutex - C chan bool -} - -func NewInterruptHandler() *InterruptHandler { - h := &InterruptHandler{ - lock: &sync.Mutex{}, - C: make(chan bool, 0), - } - - go h.handleInterrupt() - SwallowSigQuit() - - return h -} - -func (h *InterruptHandler) WasInterrupted() bool { - h.lock.Lock() - defer h.lock.Unlock() - - return h.interruptCount > 0 -} - -func (h *InterruptHandler) handleInterrupt() { - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt, syscall.SIGTERM) - - <-c - signal.Stop(c) - - h.lock.Lock() - h.interruptCount++ - if h.interruptCount == 1 { - close(h.C) - } else if h.interruptCount > 5 { - os.Exit(1) - } - h.lock.Unlock() - - go h.handleInterrupt() -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/interrupthandler/sigquit_swallower_unix.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/interrupthandler/sigquit_swallower_unix.go deleted file mode 100644 index 14c94210e..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/interrupthandler/sigquit_swallower_unix.go +++ /dev/null @@ -1,14 +0,0 @@ -// +build freebsd openbsd netbsd dragonfly darwin linux - -package interrupthandler - -import ( - "os" - "os/signal" - "syscall" -) - -func SwallowSigQuit() { - c := make(chan os.Signal, 1024) - signal.Notify(c, syscall.SIGQUIT) -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/interrupthandler/sigquit_swallower_windows.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/interrupthandler/sigquit_swallower_windows.go deleted file mode 100644 index 7f4a50e19..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/interrupthandler/sigquit_swallower_windows.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build windows - -package interrupthandler - -func SwallowSigQuit() { - //noop -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/main.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/main.go deleted file mode 100644 index b031b8082..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/main.go +++ /dev/null @@ -1,291 +0,0 @@ -/* -The Ginkgo CLI - -The Ginkgo CLI is fully documented [here](http://onsi.github.io/ginkgo/#the_ginkgo_cli) - -You can also learn more by running: - - ginkgo help - -Here are some of the more commonly used commands: - -To install: - - go install github.com/onsi/ginkgo/ginkgo - -To run tests: - - ginkgo - -To run tests in all subdirectories: - - ginkgo -r - -To run tests in particular packages: - - ginkgo /path/to/package /path/to/another/package - -To pass arguments/flags to your tests: - - ginkgo -- - -To run tests in parallel - - ginkgo -p - -this will automatically detect the optimal number of nodes to use. Alternatively, you can specify the number of nodes with: - - ginkgo -nodes=N - -(note that you don't need to provide -p in this case). - -By default the Ginkgo CLI will spin up a server that the individual test processes send test output to. The CLI aggregates this output and then presents coherent test output, one test at a time, as each test completes. -An alternative is to have the parallel nodes run and stream interleaved output back. This useful for debugging, particularly in contexts where tests hang/fail to start. To get this interleaved output: - - ginkgo -nodes=N -stream=true - -On windows, the default value for stream is true. - -By default, when running multiple tests (with -r or a list of packages) Ginkgo will abort when a test fails. To have Ginkgo run subsequent test suites instead you can: - - ginkgo -keepGoing - -To monitor packages and rerun tests when changes occur: - - ginkgo watch <-r> - -passing `ginkgo watch` the `-r` flag will recursively detect all test suites under the current directory and monitor them. -`watch` does not detect *new* packages. Moreover, changes in package X only rerun the tests for package X, tests for packages -that depend on X are not rerun. - -[OSX & Linux only] To receive (desktop) notifications when a test run completes: - - ginkgo -notify - -this is particularly useful with `ginkgo watch`. Notifications are currently only supported on OS X and require that you `brew install terminal-notifier` - -Sometimes (to suss out race conditions/flakey tests, for example) you want to keep running a test suite until it fails. You can do this with: - - ginkgo -untilItFails - -To bootstrap a test suite: - - ginkgo bootstrap - -To generate a test file: - - ginkgo generate - -To bootstrap/generate test files without using "." imports: - - ginkgo bootstrap --nodot - ginkgo generate --nodot - -this will explicitly export all the identifiers in Ginkgo and Gomega allowing you to rename them to avoid collisions. When you pull to the latest Ginkgo/Gomega you'll want to run - - ginkgo nodot - -to refresh this list and pull in any new identifiers. In particular, this will pull in any new Gomega matchers that get added. - -To convert an existing XUnit style test suite to a Ginkgo-style test suite: - - ginkgo convert . - -To unfocus tests: - - ginkgo unfocus - -or - - ginkgo blur - -To compile a test suite: - - ginkgo build - -will output an executable file named `package.test`. This can be run directly or by invoking - - ginkgo - -To print out Ginkgo's version: - - ginkgo version - -To get more help: - - ginkgo help -*/ -package main - -import ( - "flag" - "fmt" - "os" - "os/exec" - "strings" - - "github.com/onsi/ginkgo/config" - "github.com/onsi/ginkgo/ginkgo/testsuite" -) - -const greenColor = "\x1b[32m" -const redColor = "\x1b[91m" -const defaultStyle = "\x1b[0m" -const lightGrayColor = "\x1b[37m" - -type Command struct { - Name string - AltName string - FlagSet *flag.FlagSet - Usage []string - UsageCommand string - Command func(args []string, additionalArgs []string) - SuppressFlagDocumentation bool - FlagDocSubstitute []string -} - -func (c *Command) Matches(name string) bool { - return c.Name == name || (c.AltName != "" && c.AltName == name) -} - -func (c *Command) Run(args []string, additionalArgs []string) { - c.FlagSet.Parse(args) - c.Command(c.FlagSet.Args(), additionalArgs) -} - -var DefaultCommand *Command -var Commands []*Command - -func init() { - DefaultCommand = BuildRunCommand() - Commands = append(Commands, BuildWatchCommand()) - Commands = append(Commands, BuildBuildCommand()) - Commands = append(Commands, BuildBootstrapCommand()) - Commands = append(Commands, BuildGenerateCommand()) - Commands = append(Commands, BuildNodotCommand()) - Commands = append(Commands, BuildConvertCommand()) - Commands = append(Commands, BuildUnfocusCommand()) - Commands = append(Commands, BuildVersionCommand()) - Commands = append(Commands, BuildHelpCommand()) -} - -func main() { - args := []string{} - additionalArgs := []string{} - - foundDelimiter := false - - for _, arg := range os.Args[1:] { - if !foundDelimiter { - if arg == "--" { - foundDelimiter = true - continue - } - } - - if foundDelimiter { - additionalArgs = append(additionalArgs, arg) - } else { - args = append(args, arg) - } - } - - if len(args) > 0 { - commandToRun, found := commandMatching(args[0]) - if found { - commandToRun.Run(args[1:], additionalArgs) - return - } - } - - DefaultCommand.Run(args, additionalArgs) -} - -func commandMatching(name string) (*Command, bool) { - for _, command := range Commands { - if command.Matches(name) { - return command, true - } - } - return nil, false -} - -func usage() { - fmt.Fprintf(os.Stderr, "Ginkgo Version %s\n\n", config.VERSION) - usageForCommand(DefaultCommand, false) - for _, command := range Commands { - fmt.Fprintf(os.Stderr, "\n") - usageForCommand(command, false) - } -} - -func usageForCommand(command *Command, longForm bool) { - fmt.Fprintf(os.Stderr, "%s\n%s\n", command.UsageCommand, strings.Repeat("-", len(command.UsageCommand))) - fmt.Fprintf(os.Stderr, "%s\n", strings.Join(command.Usage, "\n")) - if command.SuppressFlagDocumentation && !longForm { - fmt.Fprintf(os.Stderr, "%s\n", strings.Join(command.FlagDocSubstitute, "\n ")) - } else { - command.FlagSet.PrintDefaults() - } -} - -func complainAndQuit(complaint string) { - fmt.Fprintf(os.Stderr, "%s\nFor usage instructions:\n\tginkgo help\n", complaint) - os.Exit(1) -} - -func findSuites(args []string, recurse bool, skipPackage string, allowPrecompiled bool) ([]testsuite.TestSuite, []string) { - suites := []testsuite.TestSuite{} - - if len(args) > 0 { - for _, arg := range args { - if allowPrecompiled { - suite, err := testsuite.PrecompiledTestSuite(arg) - if err == nil { - suites = append(suites, suite) - continue - } - } - suites = append(suites, testsuite.SuitesInDir(arg, recurse)...) - } - } else { - suites = testsuite.SuitesInDir(".", recurse) - } - - skippedPackages := []string{} - if skipPackage != "" { - skipFilters := strings.Split(skipPackage, ",") - filteredSuites := []testsuite.TestSuite{} - for _, suite := range suites { - skip := false - for _, skipFilter := range skipFilters { - if strings.Contains(suite.Path, skipFilter) { - skip = true - break - } - } - if skip { - skippedPackages = append(skippedPackages, suite.Path) - } else { - filteredSuites = append(filteredSuites, suite) - } - } - suites = filteredSuites - } - - return suites, skippedPackages -} - -func goFmt(path string) { - err := exec.Command("go", "fmt", path).Run() - if err != nil { - complainAndQuit("Could not fmt: " + err.Error()) - } -} - -func pluralizedWord(singular, plural string, count int) string { - if count == 1 { - return singular - } - return plural -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/nodot/nodot.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/nodot/nodot.go deleted file mode 100644 index 3f7237c60..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/nodot/nodot.go +++ /dev/null @@ -1,194 +0,0 @@ -package nodot - -import ( - "fmt" - "go/ast" - "go/build" - "go/parser" - "go/token" - "path/filepath" - "strings" -) - -func ApplyNoDot(data []byte) ([]byte, error) { - sections, err := generateNodotSections() - if err != nil { - return nil, err - } - - for _, section := range sections { - data = section.createOrUpdateIn(data) - } - - return data, nil -} - -type nodotSection struct { - name string - pkg string - declarations []string - types []string -} - -func (s nodotSection) createOrUpdateIn(data []byte) []byte { - renames := map[string]string{} - - contents := string(data) - - lines := strings.Split(contents, "\n") - - comment := "// Declarations for " + s.name - - newLines := []string{} - for _, line := range lines { - if line == comment { - continue - } - - words := strings.Split(line, " ") - lastWord := words[len(words)-1] - - if s.containsDeclarationOrType(lastWord) { - renames[lastWord] = words[1] - continue - } - - newLines = append(newLines, line) - } - - if len(newLines[len(newLines)-1]) > 0 { - newLines = append(newLines, "") - } - - newLines = append(newLines, comment) - - for _, typ := range s.types { - name, ok := renames[s.prefix(typ)] - if !ok { - name = typ - } - newLines = append(newLines, fmt.Sprintf("type %s %s", name, s.prefix(typ))) - } - - for _, decl := range s.declarations { - name, ok := renames[s.prefix(decl)] - if !ok { - name = decl - } - newLines = append(newLines, fmt.Sprintf("var %s = %s", name, s.prefix(decl))) - } - - newLines = append(newLines, "") - - newContents := strings.Join(newLines, "\n") - - return []byte(newContents) -} - -func (s nodotSection) prefix(declOrType string) string { - return s.pkg + "." + declOrType -} - -func (s nodotSection) containsDeclarationOrType(word string) bool { - for _, declaration := range s.declarations { - if s.prefix(declaration) == word { - return true - } - } - - for _, typ := range s.types { - if s.prefix(typ) == word { - return true - } - } - - return false -} - -func generateNodotSections() ([]nodotSection, error) { - sections := []nodotSection{} - - declarations, err := getExportedDeclerationsForPackage("github.com/onsi/ginkgo", "ginkgo_dsl.go", "GINKGO_VERSION", "GINKGO_PANIC") - if err != nil { - return nil, err - } - sections = append(sections, nodotSection{ - name: "Ginkgo DSL", - pkg: "ginkgo", - declarations: declarations, - types: []string{"Done", "Benchmarker"}, - }) - - declarations, err = getExportedDeclerationsForPackage("github.com/onsi/gomega", "gomega_dsl.go", "GOMEGA_VERSION") - if err != nil { - return nil, err - } - sections = append(sections, nodotSection{ - name: "Gomega DSL", - pkg: "gomega", - declarations: declarations, - }) - - declarations, err = getExportedDeclerationsForPackage("github.com/onsi/gomega", "matchers.go") - if err != nil { - return nil, err - } - sections = append(sections, nodotSection{ - name: "Gomega Matchers", - pkg: "gomega", - declarations: declarations, - }) - - return sections, nil -} - -func getExportedDeclerationsForPackage(pkgPath string, filename string, blacklist ...string) ([]string, error) { - pkg, err := build.Import(pkgPath, ".", 0) - if err != nil { - return []string{}, err - } - - declarations, err := getExportedDeclarationsForFile(filepath.Join(pkg.Dir, filename)) - if err != nil { - return []string{}, err - } - - blacklistLookup := map[string]bool{} - for _, declaration := range blacklist { - blacklistLookup[declaration] = true - } - - filteredDeclarations := []string{} - for _, declaration := range declarations { - if blacklistLookup[declaration] { - continue - } - filteredDeclarations = append(filteredDeclarations, declaration) - } - - return filteredDeclarations, nil -} - -func getExportedDeclarationsForFile(path string) ([]string, error) { - fset := token.NewFileSet() - tree, err := parser.ParseFile(fset, path, nil, 0) - if err != nil { - return []string{}, err - } - - declarations := []string{} - ast.FileExports(tree) - for _, decl := range tree.Decls { - switch x := decl.(type) { - case *ast.GenDecl: - switch s := x.Specs[0].(type) { - case *ast.ValueSpec: - declarations = append(declarations, s.Names[0].Name) - } - case *ast.FuncDecl: - declarations = append(declarations, x.Name.Name) - } - } - - return declarations, nil -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/nodot_command.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/nodot_command.go deleted file mode 100644 index 212235bae..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/nodot_command.go +++ /dev/null @@ -1,76 +0,0 @@ -package main - -import ( - "bufio" - "flag" - "github.com/onsi/ginkgo/ginkgo/nodot" - "io/ioutil" - "os" - "path/filepath" - "regexp" -) - -func BuildNodotCommand() *Command { - return &Command{ - Name: "nodot", - FlagSet: flag.NewFlagSet("bootstrap", flag.ExitOnError), - UsageCommand: "ginkgo nodot", - Usage: []string{ - "Update the nodot declarations in your test suite", - "Any missing declarations (from, say, a recently added matcher) will be added to your bootstrap file.", - "If you've renamed a declaration, that name will be honored and not overwritten.", - }, - Command: updateNodot, - } -} - -func updateNodot(args []string, additionalArgs []string) { - suiteFile, perm := findSuiteFile() - - data, err := ioutil.ReadFile(suiteFile) - if err != nil { - complainAndQuit("Failed to update nodot declarations: " + err.Error()) - } - - content, err := nodot.ApplyNoDot(data) - if err != nil { - complainAndQuit("Failed to update nodot declarations: " + err.Error()) - } - ioutil.WriteFile(suiteFile, content, perm) - - goFmt(suiteFile) -} - -func findSuiteFile() (string, os.FileMode) { - workingDir, err := os.Getwd() - if err != nil { - complainAndQuit("Could not find suite file for nodot: " + err.Error()) - } - - files, err := ioutil.ReadDir(workingDir) - if err != nil { - complainAndQuit("Could not find suite file for nodot: " + err.Error()) - } - - re := regexp.MustCompile(`RunSpecs\(|RunSpecsWithDefaultAndCustomReporters\(|RunSpecsWithCustomReporters\(`) - - for _, file := range files { - if file.IsDir() { - continue - } - path := filepath.Join(workingDir, file.Name()) - f, err := os.Open(path) - if err != nil { - complainAndQuit("Could not find suite file for nodot: " + err.Error()) - } - defer f.Close() - - if re.MatchReader(bufio.NewReader(f)) { - return path, file.Mode() - } - } - - complainAndQuit("Could not find a suite file for nodot: you need a bootstrap file that call's Ginkgo's RunSpecs() command.\nTry running ginkgo bootstrap first.") - - return "", 0 -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/notifications.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/notifications.go deleted file mode 100644 index 368d61fb3..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/notifications.go +++ /dev/null @@ -1,141 +0,0 @@ -package main - -import ( - "fmt" - "os" - "os/exec" - "regexp" - "runtime" - "strings" - - "github.com/onsi/ginkgo/config" - "github.com/onsi/ginkgo/ginkgo/testsuite" -) - -type Notifier struct { - commandFlags *RunWatchAndBuildCommandFlags -} - -func NewNotifier(commandFlags *RunWatchAndBuildCommandFlags) *Notifier { - return &Notifier{ - commandFlags: commandFlags, - } -} - -func (n *Notifier) VerifyNotificationsAreAvailable() { - if n.commandFlags.Notify { - onLinux := (runtime.GOOS == "linux") - onOSX := (runtime.GOOS == "darwin") - if onOSX { - - _, err := exec.LookPath("terminal-notifier") - if err != nil { - fmt.Printf(`--notify requires terminal-notifier, which you don't seem to have installed. - -OSX: - -To remedy this: - - brew install terminal-notifier - -To learn more about terminal-notifier: - - https://github.com/alloy/terminal-notifier -`) - os.Exit(1) - } - - } else if onLinux { - - _, err := exec.LookPath("notify-send") - if err != nil { - fmt.Printf(`--notify requires terminal-notifier or notify-send, which you don't seem to have installed. - -Linux: - -Download and install notify-send for your distribution -`) - os.Exit(1) - } - - } - } -} - -func (n *Notifier) SendSuiteCompletionNotification(suite testsuite.TestSuite, suitePassed bool) { - if suitePassed { - n.SendNotification("Ginkgo [PASS]", fmt.Sprintf(`Test suite for "%s" passed.`, suite.PackageName)) - } else { - n.SendNotification("Ginkgo [FAIL]", fmt.Sprintf(`Test suite for "%s" failed.`, suite.PackageName)) - } -} - -func (n *Notifier) SendNotification(title string, subtitle string) { - - if n.commandFlags.Notify { - onLinux := (runtime.GOOS == "linux") - onOSX := (runtime.GOOS == "darwin") - - if onOSX { - - _, err := exec.LookPath("terminal-notifier") - if err == nil { - args := []string{"-title", title, "-subtitle", subtitle, "-group", "com.onsi.ginkgo"} - terminal := os.Getenv("TERM_PROGRAM") - if terminal == "iTerm.app" { - args = append(args, "-activate", "com.googlecode.iterm2") - } else if terminal == "Apple_Terminal" { - args = append(args, "-activate", "com.apple.Terminal") - } - - exec.Command("terminal-notifier", args...).Run() - } - - } else if onLinux { - - _, err := exec.LookPath("notify-send") - if err == nil { - args := []string{"-a", "ginkgo", title, subtitle} - exec.Command("notify-send", args...).Run() - } - - } - } -} - -func (n *Notifier) RunCommand(suite testsuite.TestSuite, suitePassed bool) { - - command := n.commandFlags.AfterSuiteHook - if command != "" { - - // Allow for string replacement to pass input to the command - passed := "[FAIL]" - if suitePassed { - passed = "[PASS]" - } - command = strings.Replace(command, "(ginkgo-suite-passed)", passed, -1) - command = strings.Replace(command, "(ginkgo-suite-name)", suite.PackageName, -1) - - // Must break command into parts - splitArgs := regexp.MustCompile(`'.+'|".+"|\S+`) - parts := splitArgs.FindAllString(command, -1) - - output, err := exec.Command(parts[0], parts[1:]...).CombinedOutput() - if err != nil { - fmt.Println("Post-suite command failed:") - if config.DefaultReporterConfig.NoColor { - fmt.Printf("\t%s\n", output) - } else { - fmt.Printf("\t%s%s%s\n", redColor, string(output), defaultStyle) - } - n.SendNotification("Ginkgo [ERROR]", fmt.Sprintf(`After suite command "%s" failed`, n.commandFlags.AfterSuiteHook)) - } else { - fmt.Println("Post-suite command succeeded:") - if config.DefaultReporterConfig.NoColor { - fmt.Printf("\t%s\n", output) - } else { - fmt.Printf("\t%s%s%s\n", greenColor, string(output), defaultStyle) - } - } - } -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/run_command.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/run_command.go deleted file mode 100644 index c5cf2775f..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/run_command.go +++ /dev/null @@ -1,192 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "math/rand" - "os" - "time" - - "github.com/onsi/ginkgo/config" - "github.com/onsi/ginkgo/ginkgo/interrupthandler" - "github.com/onsi/ginkgo/ginkgo/testrunner" - "github.com/onsi/ginkgo/types" -) - -func BuildRunCommand() *Command { - commandFlags := NewRunCommandFlags(flag.NewFlagSet("ginkgo", flag.ExitOnError)) - notifier := NewNotifier(commandFlags) - interruptHandler := interrupthandler.NewInterruptHandler() - runner := &SpecRunner{ - commandFlags: commandFlags, - notifier: notifier, - interruptHandler: interruptHandler, - suiteRunner: NewSuiteRunner(notifier, interruptHandler), - } - - return &Command{ - Name: "", - FlagSet: commandFlags.FlagSet, - UsageCommand: "ginkgo -- ", - Usage: []string{ - "Run the tests in the passed in (or the package in the current directory if left blank).", - "Any arguments after -- will be passed to the test.", - "Accepts the following flags:", - }, - Command: runner.RunSpecs, - } -} - -type SpecRunner struct { - commandFlags *RunWatchAndBuildCommandFlags - notifier *Notifier - interruptHandler *interrupthandler.InterruptHandler - suiteRunner *SuiteRunner -} - -func (r *SpecRunner) RunSpecs(args []string, additionalArgs []string) { - r.commandFlags.computeNodes() - r.notifier.VerifyNotificationsAreAvailable() - - suites, skippedPackages := findSuites(args, r.commandFlags.Recurse, r.commandFlags.SkipPackage, true) - if len(skippedPackages) > 0 { - fmt.Println("Will skip:") - for _, skippedPackage := range skippedPackages { - fmt.Println(" " + skippedPackage) - } - } - - if len(skippedPackages) > 0 && len(suites) == 0 { - fmt.Println("All tests skipped! Exiting...") - os.Exit(0) - } - - if len(suites) == 0 { - complainAndQuit("Found no test suites") - } - - r.ComputeSuccinctMode(len(suites)) - - t := time.Now() - - runners := []*testrunner.TestRunner{} - for _, suite := range suites { - runners = append(runners, testrunner.New(suite, r.commandFlags.NumCPU, r.commandFlags.ParallelStream, r.commandFlags.Race, r.commandFlags.Cover, r.commandFlags.CoverPkg, r.commandFlags.Tags, additionalArgs)) - } - - numSuites := 0 - runResult := testrunner.PassingRunResult() - if r.commandFlags.UntilItFails { - iteration := 0 - for { - r.UpdateSeed() - randomizedRunners := r.randomizeOrder(runners) - runResult, numSuites = r.suiteRunner.RunSuites(randomizedRunners, r.commandFlags.NumCompilers, r.commandFlags.KeepGoing, nil) - iteration++ - - if r.interruptHandler.WasInterrupted() { - break - } - - if runResult.Passed { - fmt.Printf("\nAll tests passed...\nWill keep running them until they fail.\nThis was attempt #%d\n%s\n", iteration, orcMessage(iteration)) - } else { - fmt.Printf("\nTests failed on attempt #%d\n\n", iteration) - break - } - } - } else { - randomizedRunners := r.randomizeOrder(runners) - runResult, numSuites = r.suiteRunner.RunSuites(randomizedRunners, r.commandFlags.NumCompilers, r.commandFlags.KeepGoing, nil) - } - - for _, runner := range runners { - runner.CleanUp() - } - - fmt.Printf("\nGinkgo ran %d %s in %s\n", numSuites, pluralizedWord("suite", "suites", numSuites), time.Since(t)) - - if runResult.Passed { - if runResult.HasProgrammaticFocus { - fmt.Printf("Test Suite Passed\n") - fmt.Printf("Detected Programmatic Focus - setting exit status to %d\n", types.GINKGO_FOCUS_EXIT_CODE) - os.Exit(types.GINKGO_FOCUS_EXIT_CODE) - } else { - fmt.Printf("Test Suite Passed\n") - os.Exit(0) - } - } else { - fmt.Printf("Test Suite Failed\n") - os.Exit(1) - } -} - -func (r *SpecRunner) ComputeSuccinctMode(numSuites int) { - if config.DefaultReporterConfig.Verbose { - config.DefaultReporterConfig.Succinct = false - return - } - - if numSuites == 1 { - return - } - - if numSuites > 1 && !r.commandFlags.wasSet("succinct") { - config.DefaultReporterConfig.Succinct = true - } -} - -func (r *SpecRunner) UpdateSeed() { - if !r.commandFlags.wasSet("seed") { - config.GinkgoConfig.RandomSeed = time.Now().Unix() - } -} - -func (r *SpecRunner) randomizeOrder(runners []*testrunner.TestRunner) []*testrunner.TestRunner { - if !r.commandFlags.RandomizeSuites { - return runners - } - - if len(runners) <= 1 { - return runners - } - - randomizedRunners := make([]*testrunner.TestRunner, len(runners)) - randomizer := rand.New(rand.NewSource(config.GinkgoConfig.RandomSeed)) - permutation := randomizer.Perm(len(runners)) - for i, j := range permutation { - randomizedRunners[i] = runners[j] - } - return randomizedRunners -} - -func orcMessage(iteration int) string { - if iteration < 10 { - return "" - } else if iteration < 30 { - return []string{ - "If at first you succeed...", - "...try, try again.", - "Looking good!", - "Still good...", - "I think your tests are fine....", - "Yep, still passing", - "Here we go again...", - "Even the gophers are getting bored", - "Did you try -race?", - "Maybe you should stop now?", - "I'm getting tired...", - "What if I just made you a sandwich?", - "Hit ^C, hit ^C, please hit ^C", - "Make it stop. Please!", - "Come on! Enough is enough!", - "Dave, this conversation can serve no purpose anymore. Goodbye.", - "Just what do you think you're doing, Dave? ", - "I, Sisyphus", - "Insanity: doing the same thing over and over again and expecting different results. -Einstein", - "I guess Einstein never tried to churn butter", - }[iteration-10] + "\n" - } else { - return "No, seriously... you can probably stop now.\n" - } -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/run_watch_and_build_command_flags.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/run_watch_and_build_command_flags.go deleted file mode 100644 index e6bcf367e..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/run_watch_and_build_command_flags.go +++ /dev/null @@ -1,121 +0,0 @@ -package main - -import ( - "flag" - "runtime" - - "github.com/onsi/ginkgo/config" -) - -type RunWatchAndBuildCommandFlags struct { - Recurse bool - Race bool - Cover bool - CoverPkg string - SkipPackage string - Tags string - - //for run and watch commands - NumCPU int - NumCompilers int - ParallelStream bool - Notify bool - AfterSuiteHook string - AutoNodes bool - - //only for run command - KeepGoing bool - UntilItFails bool - RandomizeSuites bool - - //only for watch command - Depth int - - FlagSet *flag.FlagSet -} - -const runMode = 1 -const watchMode = 2 -const buildMode = 3 - -func NewRunCommandFlags(flagSet *flag.FlagSet) *RunWatchAndBuildCommandFlags { - c := &RunWatchAndBuildCommandFlags{ - FlagSet: flagSet, - } - c.flags(runMode) - return c -} - -func NewWatchCommandFlags(flagSet *flag.FlagSet) *RunWatchAndBuildCommandFlags { - c := &RunWatchAndBuildCommandFlags{ - FlagSet: flagSet, - } - c.flags(watchMode) - return c -} - -func NewBuildCommandFlags(flagSet *flag.FlagSet) *RunWatchAndBuildCommandFlags { - c := &RunWatchAndBuildCommandFlags{ - FlagSet: flagSet, - } - c.flags(buildMode) - return c -} - -func (c *RunWatchAndBuildCommandFlags) wasSet(flagName string) bool { - wasSet := false - c.FlagSet.Visit(func(f *flag.Flag) { - if f.Name == flagName { - wasSet = true - } - }) - - return wasSet -} - -func (c *RunWatchAndBuildCommandFlags) computeNodes() { - if c.wasSet("nodes") { - return - } - if c.AutoNodes { - switch n := runtime.NumCPU(); { - case n <= 4: - c.NumCPU = n - default: - c.NumCPU = n - 1 - } - } -} - -func (c *RunWatchAndBuildCommandFlags) flags(mode int) { - onWindows := (runtime.GOOS == "windows") - - c.FlagSet.BoolVar(&(c.Recurse), "r", false, "Find and run test suites under the current directory recursively") - c.FlagSet.BoolVar(&(c.Race), "race", false, "Run tests with race detection enabled") - c.FlagSet.BoolVar(&(c.Cover), "cover", false, "Run tests with coverage analysis, will generate coverage profiles with the package name in the current directory") - c.FlagSet.StringVar(&(c.CoverPkg), "coverpkg", "", "Run tests with coverage on the given external modules") - c.FlagSet.StringVar(&(c.SkipPackage), "skipPackage", "", "A comma-separated list of package names to be skipped. If any part of the package's path matches, that package is ignored.") - c.FlagSet.StringVar(&(c.Tags), "tags", "", "A list of build tags to consider satisfied during the build") - - if mode == runMode || mode == watchMode { - config.Flags(c.FlagSet, "", false) - c.FlagSet.IntVar(&(c.NumCPU), "nodes", 1, "The number of parallel test nodes to run") - c.FlagSet.IntVar(&(c.NumCompilers), "compilers", 0, "The number of concurrent compilations to run (0 will autodetect)") - c.FlagSet.BoolVar(&(c.AutoNodes), "p", false, "Run in parallel with auto-detected number of nodes") - c.FlagSet.BoolVar(&(c.ParallelStream), "stream", onWindows, "stream parallel test output in real time: less coherent, but useful for debugging") - if !onWindows { - c.FlagSet.BoolVar(&(c.Notify), "notify", false, "Send desktop notifications when a test run completes") - } - c.FlagSet.StringVar(&(c.AfterSuiteHook), "afterSuiteHook", "", "Run a command when a suite test run completes") - } - - if mode == runMode { - c.FlagSet.BoolVar(&(c.KeepGoing), "keepGoing", false, "When true, failures from earlier test suites do not prevent later test suites from running") - c.FlagSet.BoolVar(&(c.UntilItFails), "untilItFails", false, "When true, Ginkgo will keep rerunning tests until a failure occurs") - c.FlagSet.BoolVar(&(c.RandomizeSuites), "randomizeSuites", false, "When true, Ginkgo will randomize the order in which test suites run") - } - - if mode == watchMode { - c.FlagSet.IntVar(&(c.Depth), "depth", 1, "Ginkgo will watch dependencies down to this depth in the dependency tree") - } -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/suite_runner.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/suite_runner.go deleted file mode 100644 index 7d56e5f78..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/suite_runner.go +++ /dev/null @@ -1,172 +0,0 @@ -package main - -import ( - "fmt" - "runtime" - "sync" - - "github.com/onsi/ginkgo/config" - "github.com/onsi/ginkgo/ginkgo/interrupthandler" - "github.com/onsi/ginkgo/ginkgo/testrunner" - "github.com/onsi/ginkgo/ginkgo/testsuite" -) - -type compilationInput struct { - runner *testrunner.TestRunner - result chan compilationOutput -} - -type compilationOutput struct { - runner *testrunner.TestRunner - err error -} - -type SuiteRunner struct { - notifier *Notifier - interruptHandler *interrupthandler.InterruptHandler -} - -func NewSuiteRunner(notifier *Notifier, interruptHandler *interrupthandler.InterruptHandler) *SuiteRunner { - return &SuiteRunner{ - notifier: notifier, - interruptHandler: interruptHandler, - } -} - -func (r *SuiteRunner) compileInParallel(runners []*testrunner.TestRunner, numCompilers int, willCompile func(suite testsuite.TestSuite)) chan compilationOutput { - //we return this to the consumer, it will return each runner in order as it compiles - compilationOutputs := make(chan compilationOutput, len(runners)) - - //an array of channels - the nth runner's compilation output is sent to the nth channel in this array - //we read from these channels in order to ensure we run the suites in order - orderedCompilationOutputs := []chan compilationOutput{} - for _ = range runners { - orderedCompilationOutputs = append(orderedCompilationOutputs, make(chan compilationOutput, 1)) - } - - //we're going to spin up numCompilers compilers - they're going to run concurrently and will consume this channel - //we prefill the channel then close it, this ensures we compile things in the correct order - workPool := make(chan compilationInput, len(runners)) - for i, runner := range runners { - workPool <- compilationInput{runner, orderedCompilationOutputs[i]} - } - close(workPool) - - //pick a reasonable numCompilers - if numCompilers == 0 { - numCompilers = runtime.NumCPU() - } - - //a WaitGroup to help us wait for all compilers to shut down - wg := &sync.WaitGroup{} - wg.Add(numCompilers) - - //spin up the concurrent compilers - for i := 0; i < numCompilers; i++ { - go func() { - defer wg.Done() - for input := range workPool { - if r.interruptHandler.WasInterrupted() { - return - } - - if willCompile != nil { - willCompile(input.runner.Suite) - } - - //We retry because Go sometimes steps on itself when multiple compiles happen in parallel. This is ugly, but should help resolve flakiness... - var err error - retries := 0 - for retries <= 5 { - if r.interruptHandler.WasInterrupted() { - return - } - if err = input.runner.Compile(); err == nil { - break - } - retries++ - } - - input.result <- compilationOutput{input.runner, err} - } - }() - } - - //read from the compilation output channels *in order* and send them to the caller - //close the compilationOutputs channel to tell the caller we're done - go func() { - defer close(compilationOutputs) - for _, orderedCompilationOutput := range orderedCompilationOutputs { - select { - case compilationOutput := <-orderedCompilationOutput: - compilationOutputs <- compilationOutput - case <-r.interruptHandler.C: - //interrupt detected, wait for the compilers to shut down then bail - //this ensure we clean up after ourselves as we don't leave any compilation processes running - wg.Wait() - return - } - } - }() - - return compilationOutputs -} - -func (r *SuiteRunner) RunSuites(runners []*testrunner.TestRunner, numCompilers int, keepGoing bool, willCompile func(suite testsuite.TestSuite)) (testrunner.RunResult, int) { - runResult := testrunner.PassingRunResult() - - compilationOutputs := r.compileInParallel(runners, numCompilers, willCompile) - - numSuitesThatRan := 0 - suitesThatFailed := []testsuite.TestSuite{} - for compilationOutput := range compilationOutputs { - if compilationOutput.err != nil { - fmt.Print(compilationOutput.err.Error()) - } - numSuitesThatRan++ - suiteRunResult := testrunner.FailingRunResult() - if compilationOutput.err == nil { - suiteRunResult = compilationOutput.runner.Run() - } - r.notifier.SendSuiteCompletionNotification(compilationOutput.runner.Suite, suiteRunResult.Passed) - r.notifier.RunCommand(compilationOutput.runner.Suite, suiteRunResult.Passed) - runResult = runResult.Merge(suiteRunResult) - if !suiteRunResult.Passed { - suitesThatFailed = append(suitesThatFailed, compilationOutput.runner.Suite) - if !keepGoing { - break - } - } - if numSuitesThatRan < len(runners) && !config.DefaultReporterConfig.Succinct { - fmt.Println("") - } - } - - if keepGoing && !runResult.Passed { - r.listFailedSuites(suitesThatFailed) - } - - return runResult, numSuitesThatRan -} - -func (r *SuiteRunner) listFailedSuites(suitesThatFailed []testsuite.TestSuite) { - fmt.Println("") - fmt.Println("There were failures detected in the following suites:") - - maxPackageNameLength := 0 - for _, suite := range suitesThatFailed { - if len(suite.PackageName) > maxPackageNameLength { - maxPackageNameLength = len(suite.PackageName) - } - } - - packageNameFormatter := fmt.Sprintf("%%%ds", maxPackageNameLength) - - for _, suite := range suitesThatFailed { - if config.DefaultReporterConfig.NoColor { - fmt.Printf("\t"+packageNameFormatter+" %s\n", suite.PackageName, suite.Path) - } else { - fmt.Printf("\t%s"+packageNameFormatter+"%s %s%s%s\n", redColor, suite.PackageName, defaultStyle, lightGrayColor, suite.Path, defaultStyle) - } - } -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/testrunner/log_writer.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/testrunner/log_writer.go deleted file mode 100644 index a73a6e379..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/testrunner/log_writer.go +++ /dev/null @@ -1,52 +0,0 @@ -package testrunner - -import ( - "bytes" - "fmt" - "io" - "log" - "strings" - "sync" -) - -type logWriter struct { - buffer *bytes.Buffer - lock *sync.Mutex - log *log.Logger -} - -func newLogWriter(target io.Writer, node int) *logWriter { - return &logWriter{ - buffer: &bytes.Buffer{}, - lock: &sync.Mutex{}, - log: log.New(target, fmt.Sprintf("[%d] ", node), 0), - } -} - -func (w *logWriter) Write(data []byte) (n int, err error) { - w.lock.Lock() - defer w.lock.Unlock() - - w.buffer.Write(data) - contents := w.buffer.String() - - lines := strings.Split(contents, "\n") - for _, line := range lines[0 : len(lines)-1] { - w.log.Println(line) - } - - w.buffer.Reset() - w.buffer.Write([]byte(lines[len(lines)-1])) - return len(data), nil -} - -func (w *logWriter) Close() error { - w.lock.Lock() - defer w.lock.Unlock() - - if w.buffer.Len() > 0 { - w.log.Println(w.buffer.String()) - } - - return nil -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/testrunner/run_result.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/testrunner/run_result.go deleted file mode 100644 index 5d472acb8..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/testrunner/run_result.go +++ /dev/null @@ -1,27 +0,0 @@ -package testrunner - -type RunResult struct { - Passed bool - HasProgrammaticFocus bool -} - -func PassingRunResult() RunResult { - return RunResult{ - Passed: true, - HasProgrammaticFocus: false, - } -} - -func FailingRunResult() RunResult { - return RunResult{ - Passed: false, - HasProgrammaticFocus: false, - } -} - -func (r RunResult) Merge(o RunResult) RunResult { - return RunResult{ - Passed: r.Passed && o.Passed, - HasProgrammaticFocus: r.HasProgrammaticFocus || o.HasProgrammaticFocus, - } -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/testrunner/test_runner.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/testrunner/test_runner.go deleted file mode 100644 index a1e47ba18..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/testrunner/test_runner.go +++ /dev/null @@ -1,460 +0,0 @@ -package testrunner - -import ( - "bytes" - "fmt" - "io" - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "regexp" - "strconv" - "strings" - "syscall" - "time" - - "github.com/onsi/ginkgo/config" - "github.com/onsi/ginkgo/ginkgo/testsuite" - "github.com/onsi/ginkgo/internal/remote" - "github.com/onsi/ginkgo/reporters/stenographer" - "github.com/onsi/ginkgo/types" -) - -type TestRunner struct { - Suite testsuite.TestSuite - - compiled bool - compilationTargetPath string - - numCPU int - parallelStream bool - race bool - cover bool - coverPkg string - tags string - additionalArgs []string -} - -func New(suite testsuite.TestSuite, numCPU int, parallelStream bool, race bool, cover bool, coverPkg string, tags string, additionalArgs []string) *TestRunner { - runner := &TestRunner{ - Suite: suite, - numCPU: numCPU, - parallelStream: parallelStream, - race: race, - cover: cover, - coverPkg: coverPkg, - tags: tags, - additionalArgs: additionalArgs, - } - - if !suite.Precompiled { - dir, err := ioutil.TempDir("", "ginkgo") - if err != nil { - panic(fmt.Sprintf("coulnd't create temporary directory... might be time to rm -rf:\n%s", err.Error())) - } - runner.compilationTargetPath = filepath.Join(dir, suite.PackageName+".test") - } - - return runner -} - -func (t *TestRunner) Compile() error { - return t.CompileTo(t.compilationTargetPath) -} - -func (t *TestRunner) CompileTo(path string) error { - if t.compiled { - return nil - } - - if t.Suite.Precompiled { - return nil - } - - args := []string{"test", "-c", "-i", "-o", path} - if t.race { - args = append(args, "-race") - } - if t.cover || t.coverPkg != "" { - args = append(args, "-cover", "-covermode=atomic") - } - if t.coverPkg != "" { - args = append(args, fmt.Sprintf("-coverpkg=%s", t.coverPkg)) - } - if t.tags != "" { - args = append(args, fmt.Sprintf("-tags=%s", t.tags)) - } - - cmd := exec.Command("go", args...) - - cmd.Dir = t.Suite.Path - - output, err := cmd.CombinedOutput() - - if err != nil { - fixedOutput := fixCompilationOutput(string(output), t.Suite.Path) - if len(output) > 0 { - return fmt.Errorf("Failed to compile %s:\n\n%s", t.Suite.PackageName, fixedOutput) - } - return fmt.Errorf("Failed to compile %s", t.Suite.PackageName) - } - - if fileExists(path) == false { - compiledFile := filepath.Join(t.Suite.Path, t.Suite.PackageName+".test") - if fileExists(compiledFile) { - // seems like we are on an old go version that does not support the -o flag on go test - // move the compiled test file to the desired location by hand - err = os.Rename(compiledFile, path) - if err != nil { - // We cannot move the file, perhaps because the source and destination - // are on different partitions. We can copy the file, however. - err = copyFile(compiledFile, path) - if err != nil { - return fmt.Errorf("Failed to copy compiled file: %s", err) - } - } - } else { - return fmt.Errorf("Failed to compile %s: output file %q could not be found", t.Suite.PackageName, path) - } - } - - t.compiled = true - - return nil -} - -func fileExists(path string) bool { - _, err := os.Stat(path) - return err == nil || os.IsNotExist(err) == false -} - -// copyFile copies the contents of the file named src to the file named -// by dst. The file will be created if it does not already exist. If the -// destination file exists, all it's contents will be replaced by the contents -// of the source file. -func copyFile(src, dst string) error { - srcInfo, err := os.Stat(src) - if err != nil { - return err - } - mode := srcInfo.Mode() - - in, err := os.Open(src) - if err != nil { - return err - } - - defer in.Close() - - out, err := os.Create(dst) - if err != nil { - return err - } - - defer func() { - closeErr := out.Close() - if err == nil { - err = closeErr - } - }() - - _, err = io.Copy(out, in) - if err != nil { - return err - } - - err = out.Sync() - if err != nil { - return err - } - - return out.Chmod(mode) -} - -/* -go test -c -i spits package.test out into the cwd. there's no way to change this. - -to make sure it doesn't generate conflicting .test files in the cwd, Compile() must switch the cwd to the test package. - -unfortunately, this causes go test's compile output to be expressed *relative to the test package* instead of the cwd. - -this makes it hard to reason about what failed, and also prevents iterm's Cmd+click from working. - -fixCompilationOutput..... rewrites the output to fix the paths. - -yeah...... -*/ -func fixCompilationOutput(output string, relToPath string) string { - re := regexp.MustCompile(`^(\S.*\.go)\:\d+\:`) - lines := strings.Split(output, "\n") - for i, line := range lines { - indices := re.FindStringSubmatchIndex(line) - if len(indices) == 0 { - continue - } - - path := line[indices[2]:indices[3]] - path = filepath.Join(relToPath, path) - lines[i] = path + line[indices[3]:] - } - return strings.Join(lines, "\n") -} - -func (t *TestRunner) Run() RunResult { - if t.Suite.IsGinkgo { - if t.numCPU > 1 { - if t.parallelStream { - return t.runAndStreamParallelGinkgoSuite() - } else { - return t.runParallelGinkgoSuite() - } - } else { - return t.runSerialGinkgoSuite() - } - } else { - return t.runGoTestSuite() - } -} - -func (t *TestRunner) CleanUp() { - if t.Suite.Precompiled { - return - } - os.RemoveAll(filepath.Dir(t.compilationTargetPath)) -} - -func (t *TestRunner) runSerialGinkgoSuite() RunResult { - ginkgoArgs := config.BuildFlagArgs("ginkgo", config.GinkgoConfig, config.DefaultReporterConfig) - return t.run(t.cmd(ginkgoArgs, os.Stdout, 1), nil) -} - -func (t *TestRunner) runGoTestSuite() RunResult { - return t.run(t.cmd([]string{"-test.v"}, os.Stdout, 1), nil) -} - -func (t *TestRunner) runAndStreamParallelGinkgoSuite() RunResult { - completions := make(chan RunResult) - writers := make([]*logWriter, t.numCPU) - - server, err := remote.NewServer(t.numCPU) - if err != nil { - panic("Failed to start parallel spec server") - } - - server.Start() - defer server.Close() - - for cpu := 0; cpu < t.numCPU; cpu++ { - config.GinkgoConfig.ParallelNode = cpu + 1 - config.GinkgoConfig.ParallelTotal = t.numCPU - config.GinkgoConfig.SyncHost = server.Address() - - ginkgoArgs := config.BuildFlagArgs("ginkgo", config.GinkgoConfig, config.DefaultReporterConfig) - - writers[cpu] = newLogWriter(os.Stdout, cpu+1) - - cmd := t.cmd(ginkgoArgs, writers[cpu], cpu+1) - - server.RegisterAlive(cpu+1, func() bool { - if cmd.ProcessState == nil { - return true - } - return !cmd.ProcessState.Exited() - }) - - go t.run(cmd, completions) - } - - res := PassingRunResult() - - for cpu := 0; cpu < t.numCPU; cpu++ { - res = res.Merge(<-completions) - } - - for _, writer := range writers { - writer.Close() - } - - os.Stdout.Sync() - - if t.cover || t.coverPkg != "" { - t.combineCoverprofiles() - } - - return res -} - -func (t *TestRunner) runParallelGinkgoSuite() RunResult { - result := make(chan bool) - completions := make(chan RunResult) - writers := make([]*logWriter, t.numCPU) - reports := make([]*bytes.Buffer, t.numCPU) - - stenographer := stenographer.New(!config.DefaultReporterConfig.NoColor) - aggregator := remote.NewAggregator(t.numCPU, result, config.DefaultReporterConfig, stenographer) - - server, err := remote.NewServer(t.numCPU) - if err != nil { - panic("Failed to start parallel spec server") - } - server.RegisterReporters(aggregator) - server.Start() - defer server.Close() - - for cpu := 0; cpu < t.numCPU; cpu++ { - config.GinkgoConfig.ParallelNode = cpu + 1 - config.GinkgoConfig.ParallelTotal = t.numCPU - config.GinkgoConfig.SyncHost = server.Address() - config.GinkgoConfig.StreamHost = server.Address() - - ginkgoArgs := config.BuildFlagArgs("ginkgo", config.GinkgoConfig, config.DefaultReporterConfig) - - reports[cpu] = &bytes.Buffer{} - writers[cpu] = newLogWriter(reports[cpu], cpu+1) - - cmd := t.cmd(ginkgoArgs, writers[cpu], cpu+1) - - server.RegisterAlive(cpu+1, func() bool { - if cmd.ProcessState == nil { - return true - } - return !cmd.ProcessState.Exited() - }) - - go t.run(cmd, completions) - } - - res := PassingRunResult() - - for cpu := 0; cpu < t.numCPU; cpu++ { - res = res.Merge(<-completions) - } - - //all test processes are done, at this point - //we should be able to wait for the aggregator to tell us that it's done - - select { - case <-result: - fmt.Println("") - case <-time.After(time.Second): - //the aggregator never got back to us! something must have gone wrong - fmt.Println(` - ------------------------------------------------------------------- - | | - | Ginkgo timed out waiting for all parallel nodes to report back! | - | | - ------------------------------------------------------------------- -`) - - os.Stdout.Sync() - - for _, writer := range writers { - writer.Close() - } - - for _, report := range reports { - fmt.Print(report.String()) - } - - os.Stdout.Sync() - } - - if t.cover || t.coverPkg != "" { - t.combineCoverprofiles() - } - - return res -} - -func (t *TestRunner) cmd(ginkgoArgs []string, stream io.Writer, node int) *exec.Cmd { - args := []string{"--test.timeout=24h"} - if t.cover || t.coverPkg != "" { - coverprofile := "--test.coverprofile=" + t.Suite.PackageName + ".coverprofile" - if t.numCPU > 1 { - coverprofile = fmt.Sprintf("%s.%d", coverprofile, node) - } - args = append(args, coverprofile) - } - - args = append(args, ginkgoArgs...) - args = append(args, t.additionalArgs...) - - path := t.compilationTargetPath - if t.Suite.Precompiled { - path, _ = filepath.Abs(filepath.Join(t.Suite.Path, fmt.Sprintf("%s.test", t.Suite.PackageName))) - } - - cmd := exec.Command(path, args...) - - cmd.Dir = t.Suite.Path - cmd.Stderr = stream - cmd.Stdout = stream - - return cmd -} - -func (t *TestRunner) run(cmd *exec.Cmd, completions chan RunResult) RunResult { - var res RunResult - - defer func() { - if completions != nil { - completions <- res - } - }() - - err := cmd.Start() - if err != nil { - fmt.Printf("Failed to run test suite!\n\t%s", err.Error()) - return res - } - - cmd.Wait() - exitStatus := cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus() - res.Passed = (exitStatus == 0) || (exitStatus == types.GINKGO_FOCUS_EXIT_CODE) - res.HasProgrammaticFocus = (exitStatus == types.GINKGO_FOCUS_EXIT_CODE) - - return res -} - -func (t *TestRunner) combineCoverprofiles() { - profiles := []string{} - for cpu := 1; cpu <= t.numCPU; cpu++ { - coverFile := fmt.Sprintf("%s.coverprofile.%d", t.Suite.PackageName, cpu) - coverFile = filepath.Join(t.Suite.Path, coverFile) - coverProfile, err := ioutil.ReadFile(coverFile) - os.Remove(coverFile) - - if err == nil { - profiles = append(profiles, string(coverProfile)) - } - } - - if len(profiles) != t.numCPU { - return - } - - lines := map[string]int{} - lineOrder := []string{} - for i, coverProfile := range profiles { - for _, line := range strings.Split(string(coverProfile), "\n")[1:] { - if len(line) == 0 { - continue - } - components := strings.Split(line, " ") - count, _ := strconv.Atoi(components[len(components)-1]) - prefix := strings.Join(components[0:len(components)-1], " ") - lines[prefix] += count - if i == 0 { - lineOrder = append(lineOrder, prefix) - } - } - } - - output := []string{"mode: atomic"} - for _, line := range lineOrder { - output = append(output, fmt.Sprintf("%s %d", line, lines[line])) - } - finalOutput := strings.Join(output, "\n") - ioutil.WriteFile(filepath.Join(t.Suite.Path, fmt.Sprintf("%s.coverprofile", t.Suite.PackageName)), []byte(finalOutput), 0666) -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/testsuite/test_suite.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/testsuite/test_suite.go deleted file mode 100644 index cc7d2f453..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/testsuite/test_suite.go +++ /dev/null @@ -1,106 +0,0 @@ -package testsuite - -import ( - "errors" - "io/ioutil" - "os" - "path/filepath" - "regexp" - "strings" -) - -type TestSuite struct { - Path string - PackageName string - IsGinkgo bool - Precompiled bool -} - -func PrecompiledTestSuite(path string) (TestSuite, error) { - info, err := os.Stat(path) - if err != nil { - return TestSuite{}, err - } - - if info.IsDir() { - return TestSuite{}, errors.New("this is a directory, not a file") - } - - if filepath.Ext(path) != ".test" { - return TestSuite{}, errors.New("this is not a .test binary") - } - - if info.Mode()&0111 == 0 { - return TestSuite{}, errors.New("this is not executable") - } - - dir := relPath(filepath.Dir(path)) - packageName := strings.TrimSuffix(filepath.Base(path), filepath.Ext(path)) - - return TestSuite{ - Path: dir, - PackageName: packageName, - IsGinkgo: true, - Precompiled: true, - }, nil -} - -func SuitesInDir(dir string, recurse bool) []TestSuite { - suites := []TestSuite{} - files, _ := ioutil.ReadDir(dir) - re := regexp.MustCompile(`_test\.go$`) - for _, file := range files { - if !file.IsDir() && re.Match([]byte(file.Name())) { - suites = append(suites, New(dir, files)) - break - } - } - - if recurse { - re = regexp.MustCompile(`^[._]`) - for _, file := range files { - if file.IsDir() && !re.Match([]byte(file.Name())) { - suites = append(suites, SuitesInDir(dir+"/"+file.Name(), recurse)...) - } - } - } - - return suites -} - -func relPath(dir string) string { - dir, _ = filepath.Abs(dir) - cwd, _ := os.Getwd() - dir, _ = filepath.Rel(cwd, filepath.Clean(dir)) - dir = "." + string(filepath.Separator) + dir - return dir -} - -func New(dir string, files []os.FileInfo) TestSuite { - return TestSuite{ - Path: relPath(dir), - PackageName: packageNameForSuite(dir), - IsGinkgo: filesHaveGinkgoSuite(dir, files), - } -} - -func packageNameForSuite(dir string) string { - path, _ := filepath.Abs(dir) - return filepath.Base(path) -} - -func filesHaveGinkgoSuite(dir string, files []os.FileInfo) bool { - reTestFile := regexp.MustCompile(`_test\.go$`) - reGinkgo := regexp.MustCompile(`package ginkgo|\/ginkgo"`) - - for _, file := range files { - if !file.IsDir() && reTestFile.Match([]byte(file.Name())) { - contents, _ := ioutil.ReadFile(dir + "/" + file.Name()) - if reGinkgo.Match(contents) { - return true - } - } - } - - return false -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/unfocus_command.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/unfocus_command.go deleted file mode 100644 index 683c3a998..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/unfocus_command.go +++ /dev/null @@ -1,38 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "os/exec" -) - -func BuildUnfocusCommand() *Command { - return &Command{ - Name: "unfocus", - AltName: "blur", - FlagSet: flag.NewFlagSet("unfocus", flag.ExitOnError), - UsageCommand: "ginkgo unfocus (or ginkgo blur)", - Usage: []string{ - "Recursively unfocuses any focused tests under the current directory", - }, - Command: unfocusSpecs, - } -} - -func unfocusSpecs([]string, []string) { - unfocus("Describe") - unfocus("Context") - unfocus("It") - unfocus("Measure") - unfocus("DescribeTable") - unfocus("Entry") -} - -func unfocus(component string) { - fmt.Printf("Removing F%s...\n", component) - cmd := exec.Command("gofmt", fmt.Sprintf("-r=F%s -> %s", component, component), "-w", ".") - out, _ := cmd.CombinedOutput() - if string(out) != "" { - println(string(out)) - } -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/version_command.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/version_command.go deleted file mode 100644 index cdca3a348..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/version_command.go +++ /dev/null @@ -1,23 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "github.com/onsi/ginkgo/config" -) - -func BuildVersionCommand() *Command { - return &Command{ - Name: "version", - FlagSet: flag.NewFlagSet("version", flag.ExitOnError), - UsageCommand: "ginkgo version", - Usage: []string{ - "Print Ginkgo's version", - }, - Command: printVersion, - } -} - -func printVersion([]string, []string) { - fmt.Printf("Ginkgo Version %s\n", config.VERSION) -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/delta.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/delta.go deleted file mode 100644 index 6c485c5b1..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/delta.go +++ /dev/null @@ -1,22 +0,0 @@ -package watch - -import "sort" - -type Delta struct { - ModifiedPackages []string - - NewSuites []*Suite - RemovedSuites []*Suite - modifiedSuites []*Suite -} - -type DescendingByDelta []*Suite - -func (a DescendingByDelta) Len() int { return len(a) } -func (a DescendingByDelta) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a DescendingByDelta) Less(i, j int) bool { return a[i].Delta() > a[j].Delta() } - -func (d Delta) ModifiedSuites() []*Suite { - sort.Sort(DescendingByDelta(d.modifiedSuites)) - return d.modifiedSuites -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/delta_tracker.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/delta_tracker.go deleted file mode 100644 index 452c07e4d..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/delta_tracker.go +++ /dev/null @@ -1,71 +0,0 @@ -package watch - -import ( - "fmt" - - "github.com/onsi/ginkgo/ginkgo/testsuite" -) - -type SuiteErrors map[testsuite.TestSuite]error - -type DeltaTracker struct { - maxDepth int - suites map[string]*Suite - packageHashes *PackageHashes -} - -func NewDeltaTracker(maxDepth int) *DeltaTracker { - return &DeltaTracker{ - maxDepth: maxDepth, - packageHashes: NewPackageHashes(), - suites: map[string]*Suite{}, - } -} - -func (d *DeltaTracker) Delta(suites []testsuite.TestSuite) (delta Delta, errors SuiteErrors) { - errors = SuiteErrors{} - delta.ModifiedPackages = d.packageHashes.CheckForChanges() - - providedSuitePaths := map[string]bool{} - for _, suite := range suites { - providedSuitePaths[suite.Path] = true - } - - d.packageHashes.StartTrackingUsage() - - for _, suite := range d.suites { - if providedSuitePaths[suite.Suite.Path] { - if suite.Delta() > 0 { - delta.modifiedSuites = append(delta.modifiedSuites, suite) - } - } else { - delta.RemovedSuites = append(delta.RemovedSuites, suite) - } - } - - d.packageHashes.StopTrackingUsageAndPrune() - - for _, suite := range suites { - _, ok := d.suites[suite.Path] - if !ok { - s, err := NewSuite(suite, d.maxDepth, d.packageHashes) - if err != nil { - errors[suite] = err - continue - } - d.suites[suite.Path] = s - delta.NewSuites = append(delta.NewSuites, s) - } - } - - return delta, errors -} - -func (d *DeltaTracker) WillRun(suite testsuite.TestSuite) error { - s, ok := d.suites[suite.Path] - if !ok { - return fmt.Errorf("unknown suite %s", suite.Path) - } - - return s.MarkAsRunAndRecomputedDependencies(d.maxDepth) -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/dependencies.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/dependencies.go deleted file mode 100644 index 82c25face..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/dependencies.go +++ /dev/null @@ -1,91 +0,0 @@ -package watch - -import ( - "go/build" - "regexp" -) - -var ginkgoAndGomegaFilter = regexp.MustCompile(`github\.com/onsi/ginkgo|github\.com/onsi/gomega`) - -type Dependencies struct { - deps map[string]int -} - -func NewDependencies(path string, maxDepth int) (Dependencies, error) { - d := Dependencies{ - deps: map[string]int{}, - } - - if maxDepth == 0 { - return d, nil - } - - err := d.seedWithDepsForPackageAtPath(path) - if err != nil { - return d, err - } - - for depth := 1; depth < maxDepth; depth++ { - n := len(d.deps) - d.addDepsForDepth(depth) - if n == len(d.deps) { - break - } - } - - return d, nil -} - -func (d Dependencies) Dependencies() map[string]int { - return d.deps -} - -func (d Dependencies) seedWithDepsForPackageAtPath(path string) error { - pkg, err := build.ImportDir(path, 0) - if err != nil { - return err - } - - d.resolveAndAdd(pkg.Imports, 1) - d.resolveAndAdd(pkg.TestImports, 1) - d.resolveAndAdd(pkg.XTestImports, 1) - - delete(d.deps, pkg.Dir) - return nil -} - -func (d Dependencies) addDepsForDepth(depth int) { - for dep, depDepth := range d.deps { - if depDepth == depth { - d.addDepsForDep(dep, depth+1) - } - } -} - -func (d Dependencies) addDepsForDep(dep string, depth int) { - pkg, err := build.ImportDir(dep, 0) - if err != nil { - println(err.Error()) - return - } - d.resolveAndAdd(pkg.Imports, depth) -} - -func (d Dependencies) resolveAndAdd(deps []string, depth int) { - for _, dep := range deps { - pkg, err := build.Import(dep, ".", 0) - if err != nil { - continue - } - if pkg.Goroot == false && !ginkgoAndGomegaFilter.Match([]byte(pkg.Dir)) { - d.addDepIfNotPresent(pkg.Dir, depth) - } - } -} - -func (d Dependencies) addDepIfNotPresent(dep string, depth int) { - _, ok := d.deps[dep] - if !ok { - d.deps[dep] = depth - } -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/package_hash.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/package_hash.go deleted file mode 100644 index eaf357c24..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/package_hash.go +++ /dev/null @@ -1,103 +0,0 @@ -package watch - -import ( - "fmt" - "io/ioutil" - "os" - "regexp" - "time" -) - -var goRegExp = regexp.MustCompile(`\.go$`) -var goTestRegExp = regexp.MustCompile(`_test\.go$`) - -type PackageHash struct { - CodeModifiedTime time.Time - TestModifiedTime time.Time - Deleted bool - - path string - codeHash string - testHash string -} - -func NewPackageHash(path string) *PackageHash { - p := &PackageHash{ - path: path, - } - - p.codeHash, _, p.testHash, _, p.Deleted = p.computeHashes() - - return p -} - -func (p *PackageHash) CheckForChanges() bool { - codeHash, codeModifiedTime, testHash, testModifiedTime, deleted := p.computeHashes() - - if deleted { - if p.Deleted == false { - t := time.Now() - p.CodeModifiedTime = t - p.TestModifiedTime = t - } - p.Deleted = true - return true - } - - modified := false - p.Deleted = false - - if p.codeHash != codeHash { - p.CodeModifiedTime = codeModifiedTime - modified = true - } - if p.testHash != testHash { - p.TestModifiedTime = testModifiedTime - modified = true - } - - p.codeHash = codeHash - p.testHash = testHash - return modified -} - -func (p *PackageHash) computeHashes() (codeHash string, codeModifiedTime time.Time, testHash string, testModifiedTime time.Time, deleted bool) { - infos, err := ioutil.ReadDir(p.path) - - if err != nil { - deleted = true - return - } - - for _, info := range infos { - if info.IsDir() { - continue - } - - if goTestRegExp.Match([]byte(info.Name())) { - testHash += p.hashForFileInfo(info) - if info.ModTime().After(testModifiedTime) { - testModifiedTime = info.ModTime() - } - continue - } - - if goRegExp.Match([]byte(info.Name())) { - codeHash += p.hashForFileInfo(info) - if info.ModTime().After(codeModifiedTime) { - codeModifiedTime = info.ModTime() - } - } - } - - testHash += codeHash - if codeModifiedTime.After(testModifiedTime) { - testModifiedTime = codeModifiedTime - } - - return -} - -func (p *PackageHash) hashForFileInfo(info os.FileInfo) string { - return fmt.Sprintf("%s_%d_%d", info.Name(), info.Size(), info.ModTime().UnixNano()) -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/package_hashes.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/package_hashes.go deleted file mode 100644 index 262eaa847..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/package_hashes.go +++ /dev/null @@ -1,82 +0,0 @@ -package watch - -import ( - "path/filepath" - "sync" -) - -type PackageHashes struct { - PackageHashes map[string]*PackageHash - usedPaths map[string]bool - lock *sync.Mutex -} - -func NewPackageHashes() *PackageHashes { - return &PackageHashes{ - PackageHashes: map[string]*PackageHash{}, - usedPaths: nil, - lock: &sync.Mutex{}, - } -} - -func (p *PackageHashes) CheckForChanges() []string { - p.lock.Lock() - defer p.lock.Unlock() - - modified := []string{} - - for _, packageHash := range p.PackageHashes { - if packageHash.CheckForChanges() { - modified = append(modified, packageHash.path) - } - } - - return modified -} - -func (p *PackageHashes) Add(path string) *PackageHash { - p.lock.Lock() - defer p.lock.Unlock() - - path, _ = filepath.Abs(path) - _, ok := p.PackageHashes[path] - if !ok { - p.PackageHashes[path] = NewPackageHash(path) - } - - if p.usedPaths != nil { - p.usedPaths[path] = true - } - return p.PackageHashes[path] -} - -func (p *PackageHashes) Get(path string) *PackageHash { - p.lock.Lock() - defer p.lock.Unlock() - - path, _ = filepath.Abs(path) - if p.usedPaths != nil { - p.usedPaths[path] = true - } - return p.PackageHashes[path] -} - -func (p *PackageHashes) StartTrackingUsage() { - p.lock.Lock() - defer p.lock.Unlock() - - p.usedPaths = map[string]bool{} -} - -func (p *PackageHashes) StopTrackingUsageAndPrune() { - p.lock.Lock() - defer p.lock.Unlock() - - for path := range p.PackageHashes { - if !p.usedPaths[path] { - delete(p.PackageHashes, path) - } - } - - p.usedPaths = nil -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/suite.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/suite.go deleted file mode 100644 index 5deaba7cb..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch/suite.go +++ /dev/null @@ -1,87 +0,0 @@ -package watch - -import ( - "fmt" - "math" - "time" - - "github.com/onsi/ginkgo/ginkgo/testsuite" -) - -type Suite struct { - Suite testsuite.TestSuite - RunTime time.Time - Dependencies Dependencies - - sharedPackageHashes *PackageHashes -} - -func NewSuite(suite testsuite.TestSuite, maxDepth int, sharedPackageHashes *PackageHashes) (*Suite, error) { - deps, err := NewDependencies(suite.Path, maxDepth) - if err != nil { - return nil, err - } - - sharedPackageHashes.Add(suite.Path) - for dep := range deps.Dependencies() { - sharedPackageHashes.Add(dep) - } - - return &Suite{ - Suite: suite, - Dependencies: deps, - - sharedPackageHashes: sharedPackageHashes, - }, nil -} - -func (s *Suite) Delta() float64 { - delta := s.delta(s.Suite.Path, true, 0) * 1000 - for dep, depth := range s.Dependencies.Dependencies() { - delta += s.delta(dep, false, depth) - } - return delta -} - -func (s *Suite) MarkAsRunAndRecomputedDependencies(maxDepth int) error { - s.RunTime = time.Now() - - deps, err := NewDependencies(s.Suite.Path, maxDepth) - if err != nil { - return err - } - - s.sharedPackageHashes.Add(s.Suite.Path) - for dep := range deps.Dependencies() { - s.sharedPackageHashes.Add(dep) - } - - s.Dependencies = deps - - return nil -} - -func (s *Suite) Description() string { - numDeps := len(s.Dependencies.Dependencies()) - pluralizer := "ies" - if numDeps == 1 { - pluralizer = "y" - } - return fmt.Sprintf("%s [%d dependenc%s]", s.Suite.Path, numDeps, pluralizer) -} - -func (s *Suite) delta(packagePath string, includeTests bool, depth int) float64 { - return math.Max(float64(s.dt(packagePath, includeTests)), 0) / float64(depth+1) -} - -func (s *Suite) dt(packagePath string, includeTests bool) time.Duration { - packageHash := s.sharedPackageHashes.Get(packagePath) - var modifiedTime time.Time - if includeTests { - modifiedTime = packageHash.TestModifiedTime - } else { - modifiedTime = packageHash.CodeModifiedTime - } - - return modifiedTime.Sub(s.RunTime) -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch_command.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch_command.go deleted file mode 100644 index 03ea01258..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/ginkgo/watch_command.go +++ /dev/null @@ -1,172 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "time" - - "github.com/onsi/ginkgo/config" - "github.com/onsi/ginkgo/ginkgo/interrupthandler" - "github.com/onsi/ginkgo/ginkgo/testrunner" - "github.com/onsi/ginkgo/ginkgo/testsuite" - "github.com/onsi/ginkgo/ginkgo/watch" -) - -func BuildWatchCommand() *Command { - commandFlags := NewWatchCommandFlags(flag.NewFlagSet("watch", flag.ExitOnError)) - interruptHandler := interrupthandler.NewInterruptHandler() - notifier := NewNotifier(commandFlags) - watcher := &SpecWatcher{ - commandFlags: commandFlags, - notifier: notifier, - interruptHandler: interruptHandler, - suiteRunner: NewSuiteRunner(notifier, interruptHandler), - } - - return &Command{ - Name: "watch", - FlagSet: commandFlags.FlagSet, - UsageCommand: "ginkgo watch -- ", - Usage: []string{ - "Watches the tests in the passed in and runs them when changes occur.", - "Any arguments after -- will be passed to the test.", - }, - Command: watcher.WatchSpecs, - SuppressFlagDocumentation: true, - FlagDocSubstitute: []string{ - "Accepts all the flags that the ginkgo command accepts except for --keepGoing and --untilItFails", - }, - } -} - -type SpecWatcher struct { - commandFlags *RunWatchAndBuildCommandFlags - notifier *Notifier - interruptHandler *interrupthandler.InterruptHandler - suiteRunner *SuiteRunner -} - -func (w *SpecWatcher) WatchSpecs(args []string, additionalArgs []string) { - w.commandFlags.computeNodes() - w.notifier.VerifyNotificationsAreAvailable() - - w.WatchSuites(args, additionalArgs) -} - -func (w *SpecWatcher) runnersForSuites(suites []testsuite.TestSuite, additionalArgs []string) []*testrunner.TestRunner { - runners := []*testrunner.TestRunner{} - - for _, suite := range suites { - runners = append(runners, testrunner.New(suite, w.commandFlags.NumCPU, w.commandFlags.ParallelStream, w.commandFlags.Race, w.commandFlags.Cover, w.commandFlags.CoverPkg, w.commandFlags.Tags, additionalArgs)) - } - - return runners -} - -func (w *SpecWatcher) WatchSuites(args []string, additionalArgs []string) { - suites, _ := findSuites(args, w.commandFlags.Recurse, w.commandFlags.SkipPackage, false) - - if len(suites) == 0 { - complainAndQuit("Found no test suites") - } - - fmt.Printf("Identified %d test %s. Locating dependencies to a depth of %d (this may take a while)...\n", len(suites), pluralizedWord("suite", "suites", len(suites)), w.commandFlags.Depth) - deltaTracker := watch.NewDeltaTracker(w.commandFlags.Depth) - delta, errors := deltaTracker.Delta(suites) - - fmt.Printf("Watching %d %s:\n", len(delta.NewSuites), pluralizedWord("suite", "suites", len(delta.NewSuites))) - for _, suite := range delta.NewSuites { - fmt.Println(" " + suite.Description()) - } - - for suite, err := range errors { - fmt.Printf("Failed to watch %s: %s\n", suite.PackageName, err) - } - - if len(suites) == 1 { - runners := w.runnersForSuites(suites, additionalArgs) - w.suiteRunner.RunSuites(runners, w.commandFlags.NumCompilers, true, nil) - runners[0].CleanUp() - } - - ticker := time.NewTicker(time.Second) - - for { - select { - case <-ticker.C: - suites, _ := findSuites(args, w.commandFlags.Recurse, w.commandFlags.SkipPackage, false) - delta, _ := deltaTracker.Delta(suites) - - suitesToRun := []testsuite.TestSuite{} - - if len(delta.NewSuites) > 0 { - fmt.Printf(greenColor+"Detected %d new %s:\n"+defaultStyle, len(delta.NewSuites), pluralizedWord("suite", "suites", len(delta.NewSuites))) - for _, suite := range delta.NewSuites { - suitesToRun = append(suitesToRun, suite.Suite) - fmt.Println(" " + suite.Description()) - } - } - - modifiedSuites := delta.ModifiedSuites() - if len(modifiedSuites) > 0 { - fmt.Println(greenColor + "\nDetected changes in:" + defaultStyle) - for _, pkg := range delta.ModifiedPackages { - fmt.Println(" " + pkg) - } - fmt.Printf(greenColor+"Will run %d %s:\n"+defaultStyle, len(modifiedSuites), pluralizedWord("suite", "suites", len(modifiedSuites))) - for _, suite := range modifiedSuites { - suitesToRun = append(suitesToRun, suite.Suite) - fmt.Println(" " + suite.Description()) - } - fmt.Println("") - } - - if len(suitesToRun) > 0 { - w.UpdateSeed() - w.ComputeSuccinctMode(len(suitesToRun)) - runners := w.runnersForSuites(suitesToRun, additionalArgs) - result, _ := w.suiteRunner.RunSuites(runners, w.commandFlags.NumCompilers, true, func(suite testsuite.TestSuite) { - deltaTracker.WillRun(suite) - }) - for _, runner := range runners { - runner.CleanUp() - } - if !w.interruptHandler.WasInterrupted() { - color := redColor - if result.Passed { - color = greenColor - } - fmt.Println(color + "\nDone. Resuming watch..." + defaultStyle) - } - } - - case <-w.interruptHandler.C: - return - } - } -} - -func (w *SpecWatcher) ComputeSuccinctMode(numSuites int) { - if config.DefaultReporterConfig.Verbose { - config.DefaultReporterConfig.Succinct = false - return - } - - if w.commandFlags.wasSet("succinct") { - return - } - - if numSuites == 1 { - config.DefaultReporterConfig.Succinct = false - } - - if numSuites > 1 { - config.DefaultReporterConfig.Succinct = true - } -} - -func (w *SpecWatcher) UpdateSeed() { - if !w.commandFlags.wasSet("seed") { - config.GinkgoConfig.RandomSeed = time.Now().Unix() - } -} diff --git a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/integration/integration.go b/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/integration/integration.go deleted file mode 100644 index 76ab1b728..000000000 --- a/vendor/github.com/containernetworking/cni/vendor/github.com/onsi/ginkgo/integration/integration.go +++ /dev/null @@ -1 +0,0 @@ -package integration diff --git a/vendor/github.com/containernetworking/plugins/.appveyor.yml b/vendor/github.com/containernetworking/plugins/.appveyor.yml new file mode 100644 index 000000000..ea06455d3 --- /dev/null +++ b/vendor/github.com/containernetworking/plugins/.appveyor.yml @@ -0,0 +1,28 @@ +clone_folder: c:\gopath\src\github.com\containernetworking\plugins + +environment: + GOPATH: c:\gopath + +install: + - echo %PATH% + - echo %GOPATH% + - set PATH=%GOPATH%\bin;c:\go\bin;%PATH% + - go version + - go env + +build: off + +test_script: + - ps: | + go list ./... | Select-String -Pattern (Get-Content "./plugins/linux_only.txt") -NotMatch > "to_test.txt" + echo "Will test:" + Get-Content "to_test.txt" + foreach ($pkg in Get-Content "to_test.txt") { + if ($pkg) { + echo $pkg + go test -v $pkg + if ($LastExitCode -ne 0) { + throw "test failed" + } + } + } diff --git a/vendor/github.com/containernetworking/plugins/.gitignore b/vendor/github.com/containernetworking/plugins/.gitignore new file mode 100644 index 000000000..b33641168 --- /dev/null +++ b/vendor/github.com/containernetworking/plugins/.gitignore @@ -0,0 +1,30 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof + +bin/ +gopath/ +.vagrant + +/release-* diff --git a/vendor/github.com/containernetworking/plugins/.travis.yml b/vendor/github.com/containernetworking/plugins/.travis.yml new file mode 100644 index 000000000..e6ab0e99e --- /dev/null +++ b/vendor/github.com/containernetworking/plugins/.travis.yml @@ -0,0 +1,38 @@ +language: go +sudo: required +dist: trusty + +go: + - 1.9.x + - 1.10.x + +env: + global: + - PATH=$GOROOT/bin:$GOPATH/bin:$PATH + matrix: + - TARGET=amd64 + - TARGET=arm + - TARGET=arm64 + - TARGET=ppc64le + - TARGET=s390x + +matrix: + fast_finish: true + +install: + - go get github.com/onsi/ginkgo/ginkgo + - go get github.com/containernetworking/cni/cnitool + +script: + - | + if [ "${TARGET}" == "amd64" ]; then + GOARCH="${TARGET}" ./test.sh + else + GOARCH="${TARGET}" ./build.sh + fi + +notifications: + email: false + +git: + depth: 9999999 diff --git a/vendor/github.com/containernetworking/plugins/CONTRIBUTING.md b/vendor/github.com/containernetworking/plugins/CONTRIBUTING.md new file mode 100644 index 000000000..0108d70e2 --- /dev/null +++ b/vendor/github.com/containernetworking/plugins/CONTRIBUTING.md @@ -0,0 +1,134 @@ +# How to Contribute + +CNI is [Apache 2.0 licensed](LICENSE) and accepts contributions via GitHub +pull requests. This document outlines some of the conventions on development +workflow, commit message formatting, contact points and other resources to make +it easier to get your contribution accepted. + +We gratefully welcome improvements to documentation as well as to code. + +# Certificate of Origin + +By contributing to this project you agree to the Developer Certificate of +Origin (DCO). This document was created by the Linux Kernel community and is a +simple statement that you, as a contributor, have the legal right to make the +contribution. See the [DCO](DCO) file for details. + +# Email and Chat + +The project uses the the cni-dev email list and IRC chat: +- Email: [cni-dev](https://groups.google.com/forum/#!forum/cni-dev) +- IRC: #[containernetworking](irc://irc.freenode.org:6667/#containernetworking) channel on freenode.org + +Please avoid emailing maintainers found in the MAINTAINERS file directly. They +are very busy and read the mailing lists. + +## Getting Started + +- Fork the repository on GitHub +- Read the [README](README.md) for build and test instructions +- Play with the project, submit bugs, submit pull requests! + +## Contribution workflow + +This is a rough outline of how to prepare a contribution: + +- Create a topic branch from where you want to base your work (usually branched from master). +- Make commits of logical units. +- Make sure your commit messages are in the proper format (see below). +- Push your changes to a topic branch in your fork of the repository. +- If you changed code: + - add automated tests to cover your changes, using the [Ginkgo](http://onsi.github.io/ginkgo/) & [Gomega](http://onsi.github.io/gomega/) style + - if the package did not previously have any test coverage, add it to the list + of `TESTABLE` packages in the `test.sh` script. + - run the full test script and ensure it passes +- Make sure any new code files have a license header (this is now enforced by automated tests) +- Submit a pull request to the original repository. + +## How to run the test suite +We generally require test coverage of any new features or bug fixes. + +Here's how you can run the test suite on any system (even Mac or Windows) using + [Vagrant](https://www.vagrantup.com/) and a hypervisor of your choice: + +First, ensure that you have the [CNI repo](https://github.com/containernetworking/cni) and this repo (plugins) cloned side-by-side: +```bash +cd ~/workspace +git clone https://github.com/containernetworking/cni +git clone https://github.com/containernetworking/plugins +``` + +Next, boot the virtual machine and SSH in to run the tests: + +```bash +vagrant up +vagrant ssh +# you're now in a shell in a virtual machine +sudo su +cd /go/src/github.com/containernetworking/plugins + +# to run the full test suite +./test.sh + +# to focus on a particular test suite +cd plugins/main/loopback +go test +``` + +# Acceptance policy + +These things will make a PR more likely to be accepted: + + * a well-described requirement + * tests for new code + * tests for old code! + * new code and tests follow the conventions in old code and tests + * a good commit message (see below) + +In general, we will merge a PR once two maintainers have endorsed it. +Trivial changes (e.g., corrections to spelling) may get waved through. +For substantial changes, more people may become involved, and you might get asked to resubmit the PR or divide the changes into more than one PR. + +### Format of the Commit Message + +We follow a rough convention for commit messages that is designed to answer two +questions: what changed and why. The subject line should feature the what and +the body of the commit should describe the why. + +``` +scripts: add the test-cluster command + +this uses tmux to setup a test cluster that you can easily kill and +start for debugging. + +Fixes #38 +``` + +The format can be described more formally as follows: + +``` +: + + + +