Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package cni for openSUSE:Factory checked in at 2026-09-08 16:58:15 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/cni (Old) and /work/SRC/openSUSE:Factory/.cni.new.1265 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "cni" Tue Sep 8 16:58:15 2026 rev:23 rq:1376337 version:1.3.1 Changes: -------- --- /work/SRC/openSUSE:Factory/cni/cni.changes 2025-04-22 17:28:48.100389091 +0200 +++ /work/SRC/openSUSE:Factory/.cni.new.1265/cni.changes 2026-09-08 17:01:56.757571397 +0200 @@ -1,0 +2,20 @@ +Mon Sep 07 04:57:18 UTC 2026 - Bharti Gautam <[email protected]> + +- Update to version 1.3.1: + * pkg/invoke: add OpenTelemetry trace context propagation + * docs: Fix broken link to "Version considerations" in SPEC.md + * README: change meeting to 10:00 US/East. + * Update test expectations to tolerate error + * Tolerate invalid cni cache for DelNetwork + * spec: update number of specifically defined terms + * moving meeting to bi-weekly + * Fix golangci and ci lint error + * Add exec error when stderr is present + * Update my email + * refactor: cni-tool with cobra + * update MAINTAINERS + * Clarify some language around `DEL` and `prevResult` + * remove archived 3rd party plugins + * Add error codes for STATUS verb to `types.go` and `SPEC.md` + +------------------------------------------------------------------- Old: ---- cni-1.3.0.obscpio New: ---- cni-1.3.1.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ cni.spec ++++++ --- /var/tmp/diff_new_pack.LdBSQ4/_old 2026-09-08 17:01:57.990622937 +0200 +++ /var/tmp/diff_new_pack.LdBSQ4/_new 2026-09-08 17:01:57.993623063 +0200 @@ -1,7 +1,7 @@ # # spec file for package cni # -# Copyright (c) 2023 SUSE LLC +# Copyright (c) 2026 SUSE LLC and contributors # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -22,7 +22,7 @@ %define cni_bin_dir %{_libexecdir}/cni %define cni_doc_dir %{_docdir}/cni Name: cni -Version: 1.3.0 +Version: 1.3.1 Release: 0 Summary: Container Network Interface - networking for Linux containers License: Apache-2.0 @@ -34,8 +34,8 @@ BuildRequires: golang-packaging BuildRequires: shadow BuildRequires: systemd-rpm-macros -BuildRequires: golang(API) >= 1.21 BuildRequires: zstd +BuildRequires: golang(API) >= 1.21 Requires(post): %fillup_prereq Recommends: cni-plugins %{?systemd_requires} ++++++ _service ++++++ --- /var/tmp/diff_new_pack.LdBSQ4/_old 2026-09-08 17:01:58.050625445 +0200 +++ /var/tmp/diff_new_pack.LdBSQ4/_new 2026-09-08 17:01:58.053625571 +0200 @@ -2,7 +2,7 @@ <service name="obs_scm" mode="manual"> <param name="url">https://github.com/containernetworking/cni.git</param> <param name="scm">git</param> - <param name="revision">v1.3.0</param> + <param name="revision">v1.3.1</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> <!-- filter out spec-vN.M.O tags --> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.LdBSQ4/_old 2026-09-08 17:01:58.084626867 +0200 +++ /var/tmp/diff_new_pack.LdBSQ4/_new 2026-09-08 17:01:58.089627076 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/containernetworking/cni.git</param> - <param name="changesrevision">a28faab92684aed3af64d5085733c34550ce9877</param></service></servicedata> + <param name="changesrevision">3f51e8803ebbdba0ebeed735b42137e4c7302403</param></service></servicedata> (No newline at EOF) ++++++ cni-1.3.0.obscpio -> cni-1.3.1.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cni-1.3.0/.golangci.yml new/cni-1.3.1/.golangci.yml --- old/cni-1.3.0/.golangci.yml 2025-04-07 17:37:53.000000000 +0200 +++ new/cni-1.3.1/.golangci.yml 2026-08-13 02:47:07.000000000 +0200 @@ -1,30 +1,42 @@ +version: "2" + linters: enable: - contextcheck - - errcheck - errorlint - - gci - ginkgolinter - gocritic - - gofumpt - - govet - - ineffassign - misspell - nolintlint - nonamedreturns - predeclared - - staticcheck - - typecheck - unconvert - - unused - whitespace + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + paths: + - third_party$ + - builtin$ + - examples$ -linters-settings: - gci: - sections: - - standard - - default - - prefix(github.com/containernetworking) - -run: - timeout: 5m +formatters: + enable: + - gci + - gofumpt + settings: + gci: + sections: + - standard + - default + - prefix(github.com/containernetworking) + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cni-1.3.0/MAINTAINERS new/cni-1.3.1/MAINTAINERS --- old/cni-1.3.0/MAINTAINERS 2025-04-07 17:37:53.000000000 +0200 +++ new/cni-1.3.1/MAINTAINERS 2026-08-13 02:47:07.000000000 +0200 @@ -1,10 +1,14 @@ Bruce Ma <[email protected]> (@mars1024) Casey Callendrello <[email protected]> (@squeed) -Dan Williams <[email protected]> (@dcbw) -Matt Dupre <[email protected]> (@matthewdupre) Michael Cambria <[email protected]> (@mccv1r0) Michael Zappa <[email protected]> (@MikeZappa87) -Piotr Skamruk <[email protected]> (@jellonek) -Tomofumi Hayashi <[email protected]> (@s1061123) +Tomofumi Hayashi <[email protected]> (@s1061123) Lionel Jouin <[email protected]> (@LionelJouin) -Ben Leggett <[email protected]> (@bleggett) +Ben Leggett <[email protected]> (@bleggett) +Marcelo Guerrero <[email protected]> (@mlguerrero12) +Doug Smith <[email protected]> (@dougbtv) + +Emeritus: +Dan Williams <[email protected]> (@dcbw) +Matt Dupre <[email protected]> (@matthewdupre) +Piotr Skamruk <[email protected]> (@jellonek) \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cni-1.3.0/README.md new/cni-1.3.1/README.md --- old/cni-1.3.0/README.md 2025-04-07 17:37:53.000000000 +0200 +++ new/cni-1.3.1/README.md 2026-08-13 02:47:07.000000000 +0200 @@ -29,7 +29,7 @@ We welcome contributions, including [bug reports](https://github.com/containernetworking/cni/issues), and code and documentation improvements. If you intend to contribute to code or documentation, please read [CONTRIBUTING.md](CONTRIBUTING.md). Also see the [contact section](#contact) in this README. -The CNI project has a [weekly meeting](https://meet.jit.si/CNIMaintainersMeeting). It takes place Mondays at 11:00 US/Eastern. All are welcome to join. +The CNI project has a [biweekly meeting](https://calendar.google.com/calendar/event?action=TEMPLATE&tmeid=Yzg1NDlibnA5Y2c0Nm5scDI4ZG5udWpmY2JfMjAyNTEwMTNUMTQwMDAwWiAyMmM0NjU1ZjFjMjkzZTg0NDRhNTU2OTVmNDIxODg3MDgwYzc1OWU0YTQ1MjVhYmQ2NTFmYmI2MGVlYTc2YzE5QGc&tmsrc=22c4655f1c293e8444a55695f421887080c759e4a4525abd651fbb60eea76c19%40group.calendar.google.com&scp=ALL) on [jitsi](https://meet.jit.si/CNIMaintainersMeeting) ([notes](https://github.com/containernetworking/meeting-notes)). It takes place Mondays at 10:00 US/Eastern. All are welcome to join. ## Why develop CNI? @@ -40,7 +40,6 @@ ## Who is using CNI? ### Container runtimes -- [rkt - container engine](https://coreos.com/blog/rkt-cni-networking.html) - [Kubernetes - a system to simplify container operations](https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/) - [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) @@ -51,16 +50,13 @@ ### 3rd party plugins - [Project Calico - a layer 3 virtual network](https://github.com/projectcalico/calico) -- [Weave - a multi-host Docker network](https://github.com/weaveworks/weave) - [Contiv Networking - policy networking for various use cases](https://github.com/contiv/netplugin) - [SR-IOV](https://github.com/hustcat/sriov-cni) -- [Cilium - BPF & XDP for containers](https://github.com/cilium/cilium) -- [Infoblox - enterprise IP address management for containers](https://github.com/infobloxopen/cni-infoblox) +- [Cilium - eBPF & XDP for containers](https://github.com/cilium/cilium) - [Multus - a Multi plugin](https://github.com/k8snetworkplumbingwg/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) @@ -69,13 +65,11 @@ - [Juniper Contrail](https://www.juniper.net/cloud) / [TungstenFabric](https://tungstenfabric.io) - Provides overlay SDN solution, delivering multicloud networking, hybrid cloud networking, simultaneous overlay-underlay support, network policy enforcement, network isolation, service chaining and flexible load balancing - [Knitter - a CNI plugin supporting multiple networking for Kubernetes](https://github.com/ZTE/Knitter) - [DANM - a CNI-compliant networking solution for TelCo workloads running on Kubernetes](https://github.com/nokia/danm) -- [VMware NSX – a CNI plugin that enables automated NSX L2/L3 networking and L4/L7 Load Balancing; network isolation at the pod, node, and cluster level; and zero-trust security policy for your Kubernetes cluster.](https://docs.vmware.com/en/VMware-NSX-T/2.2/com.vmware.nsxt.ncp_kubernetes.doc/GUID-6AFA724E-BB62-4693-B95C-321E8DDEA7E1.html) - [cni-route-override - a meta CNI plugin that override route information](https://github.com/redhat-nfvpe/cni-route-override) - [Terway - a collection of CNI Plugins based on alibaba cloud VPC/ECS network product](https://github.com/AliyunContainerService/terway) - [Cisco ACI CNI - for on-prem and cloud container networking with consistent policy and security model.](https://github.com/noironetworks/aci-containers) - [Kube-OVN - a CNI plugin that bases on OVN/OVS and provides advanced features like subnet, static ip, ACL, QoS, etc.](https://github.com/kubeovn/kube-ovn) - [Project Antrea - an Open vSwitch k8s CNI](https://github.com/vmware-tanzu/antrea) -- [OVN4NFV-K8S-Plugin - a OVN based CNI controller plugin to provide cloud native based Service function chaining (SFC), Multiple OVN overlay networking](https://github.com/opnfv/ovn4nfv-k8s-plugin) - [Azure CNI - a CNI plugin that natively extends Azure Virtual Networks to containers](https://github.com/Azure/azure-container-networking) - [Hybridnet - a CNI plugin designed for hybrid clouds which provides both overlay and underlay networking for containers in one or more clusters. Overlay and underlay containers can run on the same node and have cluster-wide bidirectional network connectivity.](https://github.com/alibaba/hybridnet) - [Spiderpool - An IP Address Management (IPAM) CNI plugin of Kubernetes for managing static ip for underlay network](https://github.com/spidernet-io/spiderpool) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cni-1.3.0/SPEC.md new/cni-1.3.1/SPEC.md --- old/cni-1.3.0/SPEC.md 2025-04-07 17:37:53.000000000 +0200 +++ new/cni-1.3.1/SPEC.md 2026-08-13 02:47:07.000000000 +0200 @@ -69,7 +69,7 @@ This document proposes a generic plugin-based networking solution for application containers on Linux, the _Container Networking Interface_, or _CNI_. -For the purposes of this proposal, we define three terms very specifically: +For the purposes of this proposal, we define four terms very specifically: - _container_ is a network isolation domain, though the actual isolation technology is not defined by the specification. This could be a [network namespace][namespaces] or a virtual machine, for example. - _network_ refers to a group of endpoints 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. - _runtime_ is the program responsible for executing CNI plugins. @@ -108,7 +108,7 @@ A network configuration consists of a JSON object with the following keys: - `cniVersion` (string): [Semantic Version 2.0](https://semver.org) of CNI specification to which this configuration list and all the individual configurations conform. Currently "1.1.0" -- `cniVersions` (string list): List of all CNI versions which this configuration supports. See [version selection](#version-selection) below. +- `cniVersions` (string list): List of all CNI versions which this configuration supports. See [version selection](#version-considerations) below. - `name` (string): Network name. This should be unique across all network configurations on a host (or other administrative domain). Must start with an alphanumeric character, optionally followed by any combination of one or more alphanumeric characters, underscore, dot (.) or hyphen (-). Must not contain characters disallowed in file paths. - `disableCheck` (boolean): Either `true` or `false`. If `disableCheck` is `true`, runtimes must not call `CHECK` for this network configuration list. This allows an administrator to prevent `CHECK`ing where a combination of plugins is known to return spurious errors. - `disableGC` (boolean): Either `true` or `false`. If `disableGC` is `true`, runtimes must not call `GC` for this network configuration list. This allows an administrator to prevent `GC`ing when it is known that garbage collection may have undesired effects (e.g. shared configuration between multiple runtimes). @@ -268,7 +268,10 @@ - delete the interface defined by `CNI_IFNAME` inside the container at `CNI_NETNS`, or - undo any modifications applied in the plugin's `ADD` functionality -Plugins should generally complete a `DEL` action without error even if some resources are missing. For example, an IPAM plugin should generally release an IP allocation and return success even if the container network namespace no longer exists, unless that network namespace is critical for IPAM management. While DHCP may usually send a 'release' message on the container network interface, since DHCP leases have a lifetime this release action would not be considered critical and no error should be returned if this action fails. For another example, the `bridge` plugin should delegate the DEL action to the IPAM plugin and clean up its own resources even if the container network namespace and/or container network interface no longer exist. +A `prevResult` must be supplied to CNI plugins as part of a `DEL` command. For the first plugin in the `DEL` command plugin chain, this `prevResult` will be the final result of the previous `ADD` command. +Plugins should still return without error if `prevResult` is empty for a `DEL` command, however. + +`DEL` command invocations are always considered best-effort - plugins should always complete a `DEL` action without error to the fullest extent possible, even if some resources or state are missing. For example, an IPAM plugin should generally release an IP allocation and return success even if the container network namespace no longer exists, unless that network namespace is critical for IPAM management. While DHCP may usually send a 'release' message on the container network interface, since DHCP leases have a lifetime this release action would not be considered critical and no error should be returned if this action fails. For another example, the `bridge` plugin should delegate the DEL action to the IPAM plugin and clean up its own resources even if the container network namespace and/or container network interface no longer exist. Plugins MUST accept multiple `DEL` calls for the same (`CNI_CONTAINERID`, `CNI_IFNAME`) pair, and return success if the interface in question, or any modifications added, are missing. @@ -648,6 +651,8 @@ `6`|Failed to decode content. For example, failed to unmarshal network config from bytes or failed to decode version info from string. `7`|Invalid network config. If some validations on network configs do not pass, this error will be raised. `11`|Try again later. If the plugin detects some transient condition that should clear up, it can use this code to notify the runtime it should re-try the operation later. + `50`|The plugin is not available (i.e. cannot service `ADD` requests) + `51`|The plugin is not available, and existing containers in the network may have limited connectivity. In addition, stderr can be used for unstructured output such as logs. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cni-1.3.0/cnitool/README.md new/cni-1.3.1/cnitool/README.md --- old/cni-1.3.0/cnitool/README.md 2025-04-07 17:37:53.000000000 +0200 +++ new/cni-1.3.1/cnitool/README.md 2026-08-13 02:47:07.000000000 +0200 @@ -1,7 +1,7 @@ # cnitool `cnitool` is a simple program that executes a CNI configuration. It will -add or remove an interface in an already-created network namespace. +add, check, remove, gc, or get status of an interface in an already-created network namespace. ## Environment Variables @@ -9,15 +9,42 @@ directory. It defaults to `/etc/cni/net.d`. The `cnitool` searches for CNI configuration files in this directory according to the following priorities: 1. Search files with the extension `*.conflist`, representing a list of plugin configurations. - 2. If there are no `*.conflist` files in the directory, search files with the extension `*.conf` or `*.json`, + 2. If there are no `*.conflist` files in the directory, search files with the extension `*.conf` or `*.json`, representing a single plugin configuration. - + It loads all the CNI configuration files in this directory and if it finds a CNI configuration with the `network name` given to the cnitool it returns the corresponding CNI configuration, else it returns `nil`. * `CNI_PATH`: For a given CNI configuration `cnitool` will search for the corresponding CNI plugin in this path. +* `CNI_ARGS`: Optional arguments in the format "KEY1=VALUE1;KEY2=VALUE2;..." passed to the CNI plugin. +* `CAP_ARGS`: Optional capability arguments in JSON format passed to the CNI plugin. +* `CNI_IFNAME`: Interface name to be configured. Defaults to "eth0" if not specified. + +## Command Line Usage + +```bash +cnitool: CNI Tool for managing network interfaces in a network namespace + +Usage: + cnitool [command] + +Available Commands: + add Add network interface to a network namespace + check Check network interface in a network namespace + completion Generate the autocompletion script for the specified shell + del Delete network interface from a network namespace + gc Garbage collect network interfaces + help Help about any command + status Get status of network interfaces + +Flags: + -h, --help help for cnitool + -i, --ifname string Interface name (defaults to env var CNI_IFNAME or 'eth0') + +Use "cnitool [command] --help" for more information about a command. +``` ## Example invocation diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cni-1.3.0/cnitool/cmd/add.go new/cni-1.3.1/cnitool/cmd/add.go --- old/cni-1.3.0/cnitool/cmd/add.go 1970-01-01 01:00:00.000000000 +0100 +++ new/cni-1.3.1/cnitool/cmd/add.go 2026-08-13 02:47:07.000000000 +0200 @@ -0,0 +1,51 @@ +// 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 cmd + +import ( + "context" + + "github.com/spf13/cobra" +) + +// addCmd represents the add command +var addCmd = &cobra.Command{ + Use: "add <network-name> <netns>", + Short: "Add network interface to a network namespace", + Long: `Add network interface to a network namespace. +This command will create a new network interface and add it to the specified network namespace.`, + Args: cobra.MinimumNArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + netconf, rt, err := setupRuntimeConfig(cmd, args) + if err != nil { + return err + } + + cninet := getCNIConfig() + result, err := cninet.AddNetworkList(context.TODO(), netconf, rt) + if err != nil { + return err + } + + if result != nil { + _ = result.Print() + } + return nil + }, +} + +func init() { + rootCmd.AddCommand(addCmd) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cni-1.3.0/cnitool/cmd/check.go new/cni-1.3.1/cnitool/cmd/check.go --- old/cni-1.3.0/cnitool/cmd/check.go 1970-01-01 01:00:00.000000000 +0100 +++ new/cni-1.3.1/cnitool/cmd/check.go 2026-08-13 02:47:07.000000000 +0200 @@ -0,0 +1,43 @@ +// 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 cmd + +import ( + "context" + + "github.com/spf13/cobra" +) + +// checkCmd represents the check command +var checkCmd = &cobra.Command{ + Use: "check <network-name> <netns>", + Short: "Check network interface in a network namespace", + Long: `Check network interface in a network namespace. +This command will check if the network interface is properly configured in the specified network namespace.`, + Args: cobra.MinimumNArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + netconf, rt, err := setupRuntimeConfig(cmd, args) + if err != nil { + return err + } + + cninet := getCNIConfig() + return cninet.CheckNetworkList(context.TODO(), netconf, rt) + }, +} + +func init() { + rootCmd.AddCommand(checkCmd) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cni-1.3.0/cnitool/cmd/del.go new/cni-1.3.1/cnitool/cmd/del.go --- old/cni-1.3.0/cnitool/cmd/del.go 1970-01-01 01:00:00.000000000 +0100 +++ new/cni-1.3.1/cnitool/cmd/del.go 2026-08-13 02:47:07.000000000 +0200 @@ -0,0 +1,43 @@ +// 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 cmd + +import ( + "context" + + "github.com/spf13/cobra" +) + +// delCmd represents the del command +var delCmd = &cobra.Command{ + Use: "del <network-name> <netns>", + Short: "Delete network interface from a network namespace", + Long: `Delete network interface from a network namespace. +This command will remove the network interface from the specified network namespace.`, + Args: cobra.MinimumNArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + netconf, rt, err := setupRuntimeConfig(cmd, args) + if err != nil { + return err + } + + cninet := getCNIConfig() + return cninet.DelNetworkList(context.TODO(), netconf, rt) + }, +} + +func init() { + rootCmd.AddCommand(delCmd) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cni-1.3.0/cnitool/cmd/gc.go new/cni-1.3.1/cnitool/cmd/gc.go --- old/cni-1.3.0/cnitool/cmd/gc.go 1970-01-01 01:00:00.000000000 +0100 +++ new/cni-1.3.1/cnitool/cmd/gc.go 2026-08-13 02:47:07.000000000 +0200 @@ -0,0 +1,44 @@ +// 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 cmd + +import ( + "context" + + "github.com/spf13/cobra" +) + +// gcCmd represents the gc command +var gcCmd = &cobra.Command{ + Use: "gc <network-name> <netns>", + Short: "Garbage collect network interfaces", + Long: `Garbage collect network interfaces. +This command will clean up unused network interfaces in the specified network namespace.`, + Args: cobra.MinimumNArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + netconf, _, err := setupRuntimeConfig(cmd, args) + if err != nil { + return err + } + + cninet := getCNIConfig() + // Currently just invoke GC without args, hence all network interface should be GC'ed! + return cninet.GCNetworkList(context.TODO(), netconf, nil) + }, +} + +func init() { + rootCmd.AddCommand(gcCmd) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cni-1.3.0/cnitool/cmd/root.go new/cni-1.3.1/cnitool/cmd/root.go --- old/cni-1.3.0/cnitool/cmd/root.go 1970-01-01 01:00:00.000000000 +0100 +++ new/cni-1.3.1/cnitool/cmd/root.go 2026-08-13 02:47:07.000000000 +0200 @@ -0,0 +1,155 @@ +// 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 cmd + +import ( + "crypto/sha512" + "encoding/json" + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/spf13/cobra" + + "github.com/containernetworking/cni/libcni" +) + +// Protocol parameters are passed to the plugins via OS environment variables. +const ( + EnvCNIPath = "CNI_PATH" + EnvNetDir = "NETCONFPATH" + EnvCapabilityArgs = "CAP_ARGS" + EnvCNIArgs = "CNI_ARGS" + EnvCNIIfname = "CNI_IFNAME" + + DefaultNetDir = "/etc/cni/net.d" +) + +var ( + // Used for flags + netName string + netNS string + ifName string + + rootCmd = &cobra.Command{ + Use: "cnitool", + Short: "CNI Tool for managing network interfaces in a network namespace", + Long: `CNI Tool is a simple program that executes a CNI configuration. +It will add, check, remove, gc, or get status of an interface in an already-created network namespace.`, + } +) + +// Execute executes the root command. +func Execute() error { + return rootCmd.Execute() +} + +func init() { + // Global flags + rootCmd.PersistentFlags().StringVarP(&ifName, "ifname", "i", "", "Interface name (defaults to env var CNI_IFNAME or 'eth0')") +} + +// parseArgs parses CNI_ARGS environment variable into key-value pairs +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 +} + +// setupRuntimeConfig prepares the runtime configuration for CNI operations +func setupRuntimeConfig(cmd *cobra.Command, args []string) (*libcni.NetworkConfigList, *libcni.RuntimeConf, error) { + if len(args) < 2 { + return nil, nil, fmt.Errorf("network name and namespace are required") + } + + netName = args[0] + netNS = args[1] + + // Get network configuration directory + netdir := os.Getenv(EnvNetDir) + if netdir == "" { + netdir = DefaultNetDir + } + + // Load network configuration + netconf, err := libcni.LoadNetworkConf(netdir, netName) + if err != nil { + return nil, nil, err + } + + // Parse capability arguments + var capabilityArgs map[string]interface{} + capabilityArgsValue := os.Getenv(EnvCapabilityArgs) + if len(capabilityArgsValue) > 0 { + if err = json.Unmarshal([]byte(capabilityArgsValue), &capabilityArgs); err != nil { + return nil, nil, err + } + } + + // Parse CNI arguments + var cniArgs [][2]string + args_env := os.Getenv(EnvCNIArgs) + if len(args_env) > 0 { + cniArgs, err = parseArgs(args_env) + if err != nil { + return nil, nil, err + } + } + + // Get interface name from flag or environment variable + if ifName == "" { + ifName, _ = os.LookupEnv(EnvCNIIfname) + if ifName == "" { + ifName = "eth0" + } + } + + // Get absolute path of network namespace + netNS, err = filepath.Abs(netNS) + if err != nil { + return nil, nil, err + } + + // Generate the containerid by hashing the netns path + s := sha512.Sum512([]byte(netNS)) + containerID := fmt.Sprintf("cnitool-%x", s[:10]) + + // Create runtime configuration + rt := &libcni.RuntimeConf{ + ContainerID: containerID, + NetNS: netNS, + IfName: ifName, + Args: cniArgs, + CapabilityArgs: capabilityArgs, + } + + return netconf, rt, nil +} + +// getCNIConfig returns a CNI configuration +func getCNIConfig() *libcni.CNIConfig { + return libcni.NewCNIConfig(filepath.SplitList(os.Getenv(EnvCNIPath)), nil) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cni-1.3.0/cnitool/cmd/status.go new/cni-1.3.1/cnitool/cmd/status.go --- old/cni-1.3.0/cnitool/cmd/status.go 1970-01-01 01:00:00.000000000 +0100 +++ new/cni-1.3.1/cnitool/cmd/status.go 2026-08-13 02:47:07.000000000 +0200 @@ -0,0 +1,43 @@ +// 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 cmd + +import ( + "context" + + "github.com/spf13/cobra" +) + +// statusCmd represents the status command +var statusCmd = &cobra.Command{ + Use: "status <network-name> <netns>", + Short: "Get status of network interfaces", + Long: `Get status of network interfaces. +This command will retrieve the status of network interfaces in the specified network namespace.`, + Args: cobra.MinimumNArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + netconf, _, err := setupRuntimeConfig(cmd, args) + if err != nil { + return err + } + + cninet := getCNIConfig() + return cninet.GetStatusNetworkList(context.TODO(), netconf) + }, +} + +func init() { + rootCmd.AddCommand(statusCmd) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cni-1.3.0/cnitool/cnitool.go new/cni-1.3.1/cnitool/cnitool.go --- old/cni-1.3.0/cnitool/cnitool.go 2025-04-07 17:37:53.000000000 +0200 +++ new/cni-1.3.1/cnitool/cnitool.go 1970-01-01 01:00:00.000000000 +0100 @@ -1,156 +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 ( - "context" - "crypto/sha512" - "encoding/json" - "fmt" - "os" - "path/filepath" - "strings" - - "github.com/containernetworking/cni/libcni" -) - -// Protocol parameters are passed to the plugins via OS environment variables. -const ( - EnvCNIPath = "CNI_PATH" - EnvNetDir = "NETCONFPATH" - EnvCapabilityArgs = "CAP_ARGS" - EnvCNIArgs = "CNI_ARGS" - EnvCNIIfname = "CNI_IFNAME" - - DefaultNetDir = "/etc/cni/net.d" - - CmdAdd = "add" - CmdCheck = "check" - CmdDel = "del" - CmdGC = "gc" - CmdStatus = "status" -) - -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) < 4 { - usage() - } - - netdir := os.Getenv(EnvNetDir) - if netdir == "" { - netdir = DefaultNetDir - } - netconf, err := libcni.LoadNetworkConf(netdir, os.Args[2]) - if err != nil { - exit(err) - } - - 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) - } - } - - ifName, ok := os.LookupEnv(EnvCNIIfname) - if !ok { - ifName = "eth0" - } - - 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: containerID, - NetNS: netns, - IfName: ifName, - Args: cniArgs, - CapabilityArgs: capabilityArgs, - } - - switch os.Args[1] { - case CmdAdd: - result, err := cninet.AddNetworkList(context.TODO(), netconf, rt) - if result != nil { - _ = result.Print() - } - exit(err) - case CmdCheck: - err := cninet.CheckNetworkList(context.TODO(), netconf, rt) - exit(err) - case CmdDel: - exit(cninet.DelNetworkList(context.TODO(), netconf, rt)) - case CmdGC: - // Currently just invoke GC without args, hence all network interface should be GC'ed! - exit(cninet.GCNetworkList(context.TODO(), netconf, nil)) - case CmdStatus: - exit(cninet.GetStatusNetworkList(context.TODO(), netconf)) - } -} - -func usage() { - exe := filepath.Base(os.Args[0]) - - fmt.Fprintf(os.Stderr, "%s: Add, check, remove, gc or status network interfaces from a network namespace\n", exe) - fmt.Fprintf(os.Stderr, " %s add <net> <netns>\n", exe) - fmt.Fprintf(os.Stderr, " %s check <net> <netns>\n", exe) - fmt.Fprintf(os.Stderr, " %s del <net> <netns>\n", exe) - fmt.Fprintf(os.Stderr, " %s gc <net> <netns>\n", exe) - fmt.Fprintf(os.Stderr, " %s status <net> <netns>\n", exe) - os.Exit(1) -} - -func exit(err error) { - if err != nil { - fmt.Fprintf(os.Stderr, "%s\n", err) - os.Exit(1) - } - os.Exit(0) -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cni-1.3.0/cnitool/main.go new/cni-1.3.1/cnitool/main.go --- old/cni-1.3.0/cnitool/main.go 1970-01-01 01:00:00.000000000 +0100 +++ new/cni-1.3.1/cnitool/main.go 2026-08-13 02:47:07.000000000 +0200 @@ -0,0 +1,29 @@ +// 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" + "os" + + "github.com/containernetworking/cni/cnitool/cmd" +) + +func main() { + if err := cmd.Execute(); err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) + os.Exit(1) + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cni-1.3.0/go.mod new/cni-1.3.1/go.mod --- old/cni-1.3.0/go.mod 2025-04-07 17:37:53.000000000 +0200 +++ new/cni-1.3.1/go.mod 2026-08-13 02:47:07.000000000 +0200 @@ -5,14 +5,19 @@ require ( github.com/onsi/ginkgo/v2 v2.20.1 github.com/onsi/gomega v1.34.1 + github.com/spf13/cobra v1.9.1 github.com/vishvananda/netns v0.0.4 + go.opentelemetry.io/otel v1.29.0 + go.opentelemetry.io/otel/trace v1.29.0 ) require ( - github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/logr v1.4.3 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect - github.com/google/go-cmp v0.6.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/spf13/pflag v1.0.6 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/net v0.28.0 // indirect golang.org/x/sys v0.23.0 // indirect diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cni-1.3.0/go.sum new/cni-1.3.1/go.sum --- old/cni-1.3.0/go.sum 2025-04-07 17:37:53.000000000 +0200 +++ new/cni-1.3.1/go.sum 2026-08-13 02:47:07.000000000 +0200 @@ -1,23 +1,39 @@ +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/onsi/ginkgo/v2 v2.20.1 h1:YlVIbqct+ZmnEph770q9Q7NVAz4wwIiVNahee6JyUzo= github.com/onsi/ginkgo/v2 v2.20.1/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= +github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= +github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= +go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= +go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= +go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc= +go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= +go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4= +go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cni-1.3.0/libcni/api.go new/cni-1.3.1/libcni/api.go --- old/cni-1.3.0/libcni/api.go 2025-04-07 17:37:53.000000000 +0200 +++ new/cni-1.3.1/libcni/api.go 2026-08-13 02:47:07.000000000 +0200 @@ -663,9 +663,9 @@ if gtet, err := version.GreaterThanOrEqualTo(net.Network.CNIVersion, "0.4.0"); err != nil { return err } else if gtet { - cachedResult, err = c.getCachedResult(net.Network.Name, net.Network.CNIVersion, rt) - if err != nil { - return fmt.Errorf("failed to get network %q cached result: %w", net.Network.Name, err) + if cachedResult, err = c.getCachedResult(net.Network.Name, net.Network.CNIVersion, rt); err != nil { + _ = c.cacheDel(net.Network.Name, rt) + cachedResult = nil } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cni-1.3.0/libcni/api_test.go new/cni-1.3.1/libcni/api_test.go --- old/cni-1.3.0/libcni/api_test.go 2025-04-07 17:37:53.000000000 +0200 +++ new/cni-1.3.1/libcni/api_test.go 2026-08-13 02:47:07.000000000 +0200 @@ -837,12 +837,12 @@ }) Context("result is invalid JSON", func() { - It("returns an error", func() { + It("tolerates the error", func() { err := os.WriteFile(cacheFile, []byte("adfadsfasdfasfdsafaf"), 0o600) Expect(err).NotTo(HaveOccurred()) err = cniConfig.DelNetwork(ctx, 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")) + Expect(err).NotTo(HaveOccurred()) }) }) @@ -859,7 +859,7 @@ Expect(err).NotTo(HaveOccurred()) }) - It("returns an error when the cached result cannot be converted", func() { + It("tolerates the error when the cached result cannot be converted", func() { err := os.WriteFile(cacheFile, []byte(`{ "cniVersion": "0.4567.0", "ips": [{"version": "4", "address": "10.1.2.3/24"}], @@ -868,7 +868,7 @@ Expect(err).NotTo(HaveOccurred()) err = cniConfig.DelNetwork(ctx, netConfig, runtimeConfig) - Expect(err).To(MatchError("failed to get network \"apitest\" cached result: unsupported CNI result version \"0.4567.0\"")) + Expect(err).NotTo(HaveOccurred()) }) }) }) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cni-1.3.0/pkg/invoke/raw_exec.go new/cni-1.3.1/pkg/invoke/raw_exec.go --- old/cni-1.3.0/pkg/invoke/raw_exec.go 2025-04-07 17:37:53.000000000 +0200 +++ new/cni-1.3.1/pkg/invoke/raw_exec.go 2026-08-13 02:47:07.000000000 +0200 @@ -25,6 +25,9 @@ "time" "github.com/containernetworking/cni/pkg/types" + "go.opentelemetry.io/otel/baggage" + "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/trace" ) type RawExec struct { @@ -35,7 +38,7 @@ stdout := &bytes.Buffer{} stderr := &bytes.Buffer{} c := exec.CommandContext(ctx, pluginPath) - c.Env = environ + c.Env = injectTraceContext(ctx, environ) c.Stdin = bytes.NewBuffer(stdinData) c.Stdout = stdout c.Stderr = stderr @@ -69,13 +72,42 @@ return stdout.Bytes(), nil } +// injectTraceContext will add OpenTelemetry trace context to the environment variables based on +// https://github.com/open-telemetry/opentelemetry-specification/blob/main/oteps/0258-env-context-baggage-carriers.md +func injectTraceContext(ctx context.Context, environ []string) []string { + sc := trace.SpanContextFromContext(ctx) + if !sc.IsValid() { + return environ + } + + ctx = trace.ContextWithRemoteSpanContext(ctx, sc) + mc := propagation.MapCarrier{} + (propagation.TraceContext{}).Inject(ctx, mc) + + // Currently, both traceparent and tracestate are not exported variables, + // https://github.com/open-telemetry/opentelemetry-go/blob/bcf8234d0c9c48b626cad85367a3681f3fc0c0fd/propagation/trace_context.go#L18-L19 + // so we have to use the string literals here. + if traceparent := mc.Get("traceparent"); traceparent != "" { + environ = append(environ, "TRACEPARENT"+"="+traceparent) + } + + if tracestate := mc.Get("tracestate"); tracestate != "" { + environ = append(environ, "TRACESTATE"+"="+tracestate) + } + + if envBaggage := baggage.FromContext(ctx).String(); envBaggage != "" { + environ = append(environ, "BAGGAGE"+"="+envBaggage) + } + return environ +} + func (e *RawExec) pluginErr(err error, stdout, stderr []byte) error { emsg := types.Error{} if len(stdout) == 0 { if len(stderr) == 0 { emsg.Msg = fmt.Sprintf("netplugin failed with no error message: %v", err) } else { - emsg.Msg = fmt.Sprintf("netplugin failed: %q", string(stderr)) + emsg.Msg = fmt.Sprintf("netplugin failed: %q: %v", string(stderr), err) } } else if perr := json.Unmarshal(stdout, &emsg); perr != nil { emsg.Msg = fmt.Sprintf("netplugin failed but error parsing its diagnostic message %q: %v", string(stdout), perr) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cni-1.3.0/pkg/invoke/raw_exec_test.go new/cni-1.3.1/pkg/invoke/raw_exec_test.go --- old/cni-1.3.0/pkg/invoke/raw_exec_test.go 2025-04-07 17:37:53.000000000 +0200 +++ new/cni-1.3.1/pkg/invoke/raw_exec_test.go 2026-08-13 02:47:07.000000000 +0200 @@ -122,7 +122,7 @@ Expect(debug.WriteDebug(debugFileName)).To(Succeed()) _, err := execer.ExecPlugin(ctx, pathToPlugin, stdin, environ) Expect(err).To(HaveOccurred()) - Expect(err).To(MatchError(`netplugin failed: "some stderr message"`)) + Expect(err).To(MatchError(`netplugin failed: "some stderr message": exit status 1`)) }) }) }) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cni-1.3.0/pkg/types/types.go new/cni-1.3.1/pkg/types/types.go --- old/cni-1.3.0/pkg/types/types.go 2025-04-07 17:37:53.000000000 +0200 +++ new/cni-1.3.1/pkg/types/types.go 2026-08-13 02:47:07.000000000 +0200 @@ -229,7 +229,7 @@ } // Well known error codes -// see https://github.com/containernetworking/cni/blob/main/SPEC.md#well-known-error-codes +// see https://github.com/containernetworking/cni/blob/main/SPEC.md#error const ( ErrUnknown uint = iota // 0 ErrIncompatibleCNIVersion // 1 @@ -241,6 +241,8 @@ ErrInvalidNetworkConfig // 7 ErrInvalidNetNS // 8 ErrTryAgainLater uint = 11 + ErrPluginNotAvailable uint = 50 + ErrLimitedConnectivity uint = 51 ErrInternal uint = 999 ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cni-1.3.0/pkg/version/version.go new/cni-1.3.1/pkg/version/version.go --- old/cni-1.3.0/pkg/version/version.go 2025-04-07 17:37:53.000000000 +0200 +++ new/cni-1.3.1/pkg/version/version.go 2026-08-13 02:47:07.000000000 +0200 @@ -39,13 +39,13 @@ All = PluginSupports("0.1.0", "0.2.0", "0.3.0", "0.3.1", "0.4.0", "1.0.0", "1.1.0") ) -// VersionsFrom returns a list of versions starting from min, inclusive -func VersionsStartingFrom(min string) PluginInfo { +// VersionsFrom returns a list of versions starting from minVer, inclusive +func VersionsStartingFrom(minVer string) PluginInfo { out := []string{} // cheat, just assume ordered ok := false for _, v := range All.SupportedVersions() { - if !ok && v == min { + if !ok && v == minVer { ok = true } if ok { ++++++ cni.obsinfo ++++++ --- /var/tmp/diff_new_pack.LdBSQ4/_old 2026-09-08 17:01:58.307636188 +0200 +++ /var/tmp/diff_new_pack.LdBSQ4/_new 2026-09-08 17:01:58.310636313 +0200 @@ -1,5 +1,5 @@ name: cni -version: 1.3.0 -mtime: 1744040273 -commit: a28faab92684aed3af64d5085733c34550ce9877 +version: 1.3.1 +mtime: 1786582027 +commit: 3f51e8803ebbdba0ebeed735b42137e4c7302403 ++++++ vendor.tar.gz ++++++ ++++ 18675 lines of diff (skipped)
