update go-cni/for cni update fixing plugins that don't respond with version

Signed-off-by: Mike Brown <brownwm@us.ibm.com>
This commit is contained in:
Mike Brown
2022-06-01 12:51:30 -05:00
parent 5bc2d2e429
commit e3b4d750db
8 changed files with 91 additions and 15 deletions

View File

@@ -31,12 +31,10 @@ help: ## this help
test: ## run tests, except integration tests and tests that require root
$(Q)go test -v -race $(EXTRA_TESTFLAGS) -count=1 ./...
integration: ## run integration test
integration: bin/integration.test ## run integration test
$(Q)bin/integration.test -test.v -test.count=1 -test.root $(EXTRA_TESTFLAGS) -test.parallel $(TESTFLAGS_PARALLEL)
FORCE:
bin/integration.test: FORCE ## build integration test binary into bin
bin/integration.test: ## build integration test binary into bin
$(Q)cd ./integration && go test -race -c . -o ../bin/integration.test
clean: ## clean up binaries

View File

@@ -33,6 +33,8 @@ import (
type CNI interface {
// Setup setup the network for the namespace
Setup(ctx context.Context, id string, path string, opts ...NamespaceOpts) (*Result, error)
// SetupSerially sets up each of the network interfaces for the namespace in serial
SetupSerially(ctx context.Context, id string, path string, opts ...NamespaceOpts) (*Result, error)
// Remove tears down the network of the namespace.
Remove(ctx context.Context, id string, path string, opts ...NamespaceOpts) error
// Check checks if the network is still in desired state
@@ -165,6 +167,34 @@ func (c *libcni) Setup(ctx context.Context, id string, path string, opts ...Name
return c.createResult(result)
}
// SetupSerially setups the network in the namespace and returns a Result
func (c *libcni) SetupSerially(ctx context.Context, id string, path string, opts ...NamespaceOpts) (*Result, error) {
if err := c.Status(); err != nil {
return nil, err
}
ns, err := newNamespace(id, path, opts...)
if err != nil {
return nil, err
}
result, err := c.attachNetworksSerially(ctx, ns)
if err != nil {
return nil, err
}
return c.createResult(result)
}
func (c *libcni) attachNetworksSerially(ctx context.Context, ns *Namespace) ([]*types100.Result, error) {
var results []*types100.Result
for _, network := range c.Networks() {
r, err := network.Attach(ctx, ns)
if err != nil {
return nil, err
}
results = append(results, r)
}
return results, nil
}
type asynchAttachResult struct {
index int
res *types100.Result

View File

@@ -16,6 +16,7 @@ package invoke
import (
"context"
"encoding/json"
"fmt"
"os"
@@ -33,6 +34,43 @@ type Exec interface {
Decode(jsonBytes []byte) (version.PluginInfo, error)
}
// Plugin must return result in same version as specified in netconf; but
// for backwards compatibility reasons if the result version is empty use
// config version (rather than technically correct 0.1.0).
// https://github.com/containernetworking/cni/issues/895
func fixupResultVersion(netconf, result []byte) (string, []byte, error) {
versionDecoder := &version.ConfigDecoder{}
confVersion, err := versionDecoder.Decode(netconf)
if err != nil {
return "", nil, err
}
var rawResult map[string]interface{}
if err := json.Unmarshal(result, &rawResult); err != nil {
return "", nil, fmt.Errorf("failed to unmarshal raw result: %w", err)
}
// Manually decode Result version; we need to know whether its cniVersion
// is empty, while built-in decoders (correctly) substitute 0.1.0 for an
// empty version per the CNI spec.
if resultVerRaw, ok := rawResult["cniVersion"]; ok {
resultVer, ok := resultVerRaw.(string)
if ok && resultVer != "" {
return resultVer, result, nil
}
}
// If the cniVersion is not present or empty, assume the result is
// the same CNI spec version as the config
rawResult["cniVersion"] = confVersion
newBytes, err := json.Marshal(rawResult)
if err != nil {
return "", nil, fmt.Errorf("failed to remarshal fixed result: %w", err)
}
return confVersion, newBytes, nil
}
// For example, a testcase could pass an instance of the following fakeExec
// object to ExecPluginWithResult() to verify the incoming stdin and environment
// and provide a tailored response:
@@ -84,7 +122,12 @@ func ExecPluginWithResult(ctx context.Context, pluginPath string, netconf []byte
return nil, err
}
return create.CreateFromBytes(stdoutBytes)
resultVersion, fixedBytes, err := fixupResultVersion(netconf, stdoutBytes)
if err != nil {
return nil, err
}
return create.Create(resultVersion, fixedBytes)
}
func ExecPluginWithoutResult(ctx context.Context, pluginPath string, netconf []byte, args CNIArgs, exec Exec) error {

4
vendor/modules.txt vendored
View File

@@ -104,7 +104,7 @@ github.com/containerd/continuity/testutil/loopback
# github.com/containerd/fifo v1.0.0
## explicit; go 1.13
github.com/containerd/fifo
# github.com/containerd/go-cni v1.1.5
# github.com/containerd/go-cni v1.1.6
## explicit; go 1.17
github.com/containerd/go-cni
# github.com/containerd/go-runc v1.0.0
@@ -128,7 +128,7 @@ github.com/containerd/typeurl
## explicit; go 1.16
github.com/containerd/zfs
github.com/containerd/zfs/plugin
# github.com/containernetworking/cni v1.1.0
# github.com/containernetworking/cni v1.1.1
## explicit; go 1.14
github.com/containernetworking/cni/libcni
github.com/containernetworking/cni/pkg/invoke