func (etcd *etcdPlugin) NewBrokerWithAtomic(keyPrefix string) keyval.BytesBrokerWithAtomic {
	return etcd.conn.NewBroker(keyPrefix).(keyval.BytesBrokerWithAtomic)
}
NewBrokerWithAtomic creates new instance of prefixed (byte-oriented) broker with atomic operations.
package main
import (
	"context"
	"net"
	"os"
	"os/signal"
	"syscall"
	"time"
	"github.com/namsral/flag"
	"google.golang.org/grpc"
	"go.ligato.io/cn-infra/v2/config"
	"go.ligato.io/cn-infra/v2/db/keyval"
	"go.ligato.io/cn-infra/v2/db/keyval/bolt"
	"go.ligato.io/cn-infra/v2/db/keyval/etcd"
	"go.ligato.io/cn-infra/v2/db/keyval/kvproto"
	"go.ligato.io/cn-infra/v2/exec/processmanager"
	"go.ligato.io/cn-infra/v2/exec/processmanager/status"
	"go.ligato.io/cn-infra/v2/logging"
	"go.ligato.io/cn-infra/v2/logging/logrus"
	"go.ligato.io/cn-infra/v2/servicelabel"
	"github.com/contiv/vpp/cmd/contiv-stn/model/stn"
	"github.com/contiv/vpp/pkg/pci"
	"github.com/contiv/vpp/plugins/contivconf"
	"github.com/contiv/vpp/plugins/controller"
	"github.com/contiv/vpp/plugins/nodesync"
	"github.com/contiv/vpp/plugins/nodesync/vppnode"
)
const (
	vppProcessName       = "vpp"
	defaultVppBinaryPath = "/usr/bin/vpp"
	vppStartupConfigPath = "/etc/vpp/contiv-vswitch.conf"
	agentProcessName       = "contiv-agent"
	defaultAgentBinaryPath = "/usr/bin/contiv-agent"
	defaultEtcdCfgFile     = "/etc/etcd/etcd.conf"
	defaultBoltCfgFile     = "/etc/vpp-agent/bolt.conf"
	defaultStnServerSocket = "/var/run/contiv/stn.sock"
	defaultCNISocketFile   = "/var/run/contiv/cni.sock"
	etcdConnectionRetries = 2  
	vmxnet3PreferredDriver = "vfio-pci"  
)
var (
	vppBinaryPath   = flag.String("vpp-bin", defaultVppBinaryPath, "location of the VPP binary")
	agentBinaryPath = flag.String("agent-bin", defaultAgentBinaryPath, "location of the Contiv Agent binary")
	etcdCfgFile     = flag.String("etcd-config", defaultEtcdCfgFile, "location of the ETCD config file")
	boltCfgFile     = flag.String("bolt-config", defaultBoltCfgFile, "location of the Bolt config file")
	stnServerSocket = flag.String("stn-server-socket", defaultStnServerSocket, "socket file where STN GRPC server listens for connections")
	crashDebugEnabled = os.Getenv("CRASH_DEBUG_ENABLED") != ""  
)
var logger logging.Logger  
func init() {
	logger = logrus.NewLogger("contiv-init")
	logger.SetOutput(os.Stdout)
	logger.SetLevel(logging.DebugLevel)
}
func stealNIC(nicName string, useDHCP bool) (*stn.STNReply, error) {
	logger.Debugf("Stealing the NIC: %s", nicName)
	conn, err := stnGrpcConnect()
	if err != nil {
		return nil, err
	}
	defer conn.Close()
	c := stn.NewSTNClient(conn)
	reply, err := c.StealInterface(context.Background(), &stn.STNRequest{
		InterfaceName: nicName,
		DhcpEnabled:   useDHCP,
	})
	if err != nil {
		logger.Errorf("Error by executing STN GRPC: %v", err)
		return nil, err
	}
	logger.Debug(reply)
	return reply, nil
}
func releaseNIC(nicName string, useDHCP bool) error {
	logger.Debugf("Releasing the NIC: %s", nicName)
	conn, err := stnGrpcConnect()
	if err != nil {
		return err
	}
	defer conn.Close()
	c := stn.NewSTNClient(conn)
	reply, err := c.ReleaseInterface(context.Background(), &stn.STNRequest{
		InterfaceName: nicName,
		DhcpEnabled:   useDHCP,
	})
	if err != nil {
		logger.Errorf("Error by executing STN GRPC: %v", err)
		return err
	}
	logger.Debug(reply)
	return nil
}
func stnGrpcConnect() (*grpc.ClientConn, error) {
	dialer := grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) {
		return net.DialTimeout("unix", addr, timeout)
	})
	conn, err := grpc.Dial(*stnServerSocket, grpc.WithInsecure(), dialer)
	if err != nil {
		logger.Errorf("Unable to connect to STN GRPC: %v", err)
		return nil, err
	}
	return conn, nil
}
type etcdPlugin struct {
	*kvproto.ProtoWrapper
	conn *etcd.BytesConnectionEtcd
}
func (etcd *etcdPlugin) OnConnect(callback func() error) {
	callback()
}
func (etcd *etcdPlugin) Disabled() bool {
	return false
}
func (etcd *etcdPlugin) String() string {
	return "etcd-plugin-simple"
}