in network.go [326:382]
func (cniConf CNIConfiguration) invokeCNI(ctx context.Context, logger *log.Entry) (*types.Result, error, []func() error) {
var cleanupFuncs []func() error
cniPlugin := libcni.NewCNIConfigWithCacheDir(cniConf.BinPath, cniConf.CacheDir, nil)
networkConf := cniConf.NetworkConfig
var err error
if networkConf == nil {
networkConf, err = libcni.LoadConfList(cniConf.ConfDir, cniConf.NetworkName)
if err != nil {
return nil, errors.Wrapf(err, "failed to load CNI configuration from dir %q for network %q",
cniConf.ConfDir, cniConf.NetworkName), cleanupFuncs
}
}
runtimeConf := cniConf.asCNIRuntimeConf()
delNetworkFunc := func() error {
err := cniPlugin.DelNetworkList(ctx, networkConf, runtimeConf)
if err != nil {
return errors.Wrapf(err, "failed to delete CNI network list %q", cniConf.NetworkName)
}
return nil
}
// Try deleting the network in case it already exists, which can happen if there is
// a crash before cleanup from a previous invocations. If it doesn't exist,
// well-behaved CNI plugins should treat this as a no-op without returning an error
// (resulting also in a nil error here).
// We can be reasonably sure any previous VM that was using this network is gone due
// to earlier validation that the VM's socket path does not already exists.
err = delNetworkFunc()
if err != nil {
errMsg := fmt.Sprintf("failed to delete pre-existing CNI network %+v", cniConf)
// We are checking Force parameter to choose, should we fail with error
// or continue execution with just logging error
if !cniConf.Force {
// something actually went wrong deleting the network, return an error and Force wasn't used so we don't
// try to create a new network on top of a possibly half-deleted previous one.
return nil, errors.Wrap(err, errMsg), cleanupFuncs
}
logger.Error(err, errMsg)
}
// Append cleanup of the network list before calling AddNetworkList to handle
// case where AddNetworkList fails but leaves intermediate resources around like
// devices and ip allocations.
cleanupFuncs = append(cleanupFuncs, delNetworkFunc)
cniResult, err := cniPlugin.AddNetworkList(ctx, networkConf, runtimeConf)
if err != nil {
return nil, errors.Wrap(err, "failed to create CNI network"), cleanupFuncs
}
return &cniResult, nil, cleanupFuncs
}