6 "github.com/edwarnicke/exechelper"
9 const vppConfigTemplate = `unix {
11 log %[1]s/var/log/vpp/vpp.log
14 runtime-dir %[1]s/var/run
27 socket-name %[1]s/var/run/vpp/api.sock
31 socket-name %[1]s/var/run/vpp/stats.sock
35 plugin unittest_plugin.so { enable }
36 plugin dpdk_plugin.so { disable }
37 plugin crypto_aesni_plugin.so { enable }
38 plugin quic_plugin.so { enable }
44 defaultCliSocketFilePath = "/var/run/vpp/cli.sock"
47 type VppInstance struct {
53 type VppConfig struct {
55 CliSocketFilePath string
58 func (vc *VppConfig) getTemplate() string {
59 return fmt.Sprintf(vppConfigTemplate, "%[1]s", vc.CliSocketFilePath)
62 func (vpp *VppInstance) set2VethsServer() {
63 vpp.actionFuncName = "Configure2Veths"
64 vpp.config.Variant = "srv"
67 func (vpp *VppInstance) set2VethsClient() {
68 vpp.actionFuncName = "Configure2Veths"
69 vpp.config.Variant = "cln"
72 func (vpp *VppInstance) setVppProxy() {
73 vpp.actionFuncName = "ConfigureVppProxy"
76 func (vpp *VppInstance) setEnvoyProxy() {
77 vpp.actionFuncName = "ConfigureEnvoyProxy"
80 func (vpp *VppInstance) setCliSocket(filePath string) {
81 vpp.config.CliSocketFilePath = filePath
84 func (vpp *VppInstance) getCliSocket() string {
85 return fmt.Sprintf("%s%s", vpp.container.workDir, vpp.config.CliSocketFilePath)
88 func (vpp *VppInstance) start() error {
89 if vpp.actionFuncName == "" {
90 return fmt.Errorf("vpp start failed: action function name must not be blank")
93 serializedConfig, err := serializeVppConfig(vpp.config)
95 return fmt.Errorf("serialize vpp config: %v", err)
97 args := fmt.Sprintf("%s '%s'", vpp.actionFuncName, serializedConfig)
98 _, err = vpp.container.execAction(args)
100 return fmt.Errorf("vpp start failed: %s", err)
106 func (vpp *VppInstance) vppctl(command string) (string, error) {
107 cliExecCommand := fmt.Sprintf("docker exec --detach=false %[1]s vppctl -s %[2]s %[3]s",
108 vpp.container.name, vpp.getCliSocket(), command)
109 output, err := exechelper.CombinedOutput(cliExecCommand)
111 return "", fmt.Errorf("vppctl failed: %s", err)
114 return string(output), nil
117 func NewVppInstance(c *Container) *VppInstance {
118 var vppConfig VppConfig
119 vppConfig.CliSocketFilePath = defaultCliSocketFilePath
120 vpp := new(VppInstance)
122 vpp.config = vppConfig
126 func serializeVppConfig(vppConfig VppConfig) (string, error) {
127 serializedConfig, err := json.Marshal(vppConfig)
129 return "", fmt.Errorf("vpp start failed: serializing configuration failed: %s", err)
131 return string(serializedConfig), nil
134 func deserializeVppConfig(input string) (VppConfig, error) {
135 var vppConfig VppConfig
136 err := json.Unmarshal([]byte(input), &vppConfig)
138 // Since input is not a valid JSON it is going be used as a variant value
139 // for compatibility reasons
140 vppConfig.Variant = input
141 vppConfig.CliSocketFilePath = defaultCliSocketFilePath
143 return vppConfig, nil