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)
94 args := fmt.Sprintf("%s '%s'", vpp.actionFuncName, serializedConfig)
95 _, err = vpp.container.execAction(args)
97 return fmt.Errorf("vpp start failed: %s", err)
103 func (vpp *VppInstance) vppctl(command string) (string, error) {
104 cliExecCommand := fmt.Sprintf("docker exec --detach=false %[1]s vppctl -s %[2]s %[3]s",
105 vpp.container.name, vpp.getCliSocket(), command)
106 output, err := exechelper.CombinedOutput(cliExecCommand)
108 return "", fmt.Errorf("vppctl failed: %s", err)
111 return string(output), nil
114 func NewVppInstance(c *Container) *VppInstance {
115 var vppConfig VppConfig
116 vppConfig.CliSocketFilePath = defaultCliSocketFilePath
117 vpp := new(VppInstance)
119 vpp.config = vppConfig
123 func serializeVppConfig(vppConfig VppConfig) (string, error) {
124 serializedConfig, err := json.Marshal(vppConfig)
126 return "", fmt.Errorf("vpp start failed: serializing configuration failed: %s", err)
128 return string(serializedConfig), nil
131 func deserializeVppConfig(input string) (VppConfig, error) {
132 var vppConfig VppConfig
133 err := json.Unmarshal([]byte(input), &vppConfig)
135 // Since input is not a valid JSON it is going be used as a variant value
136 // for compatibility reasons
137 vppConfig.Variant = input
138 vppConfig.CliSocketFilePath = defaultCliSocketFilePath
140 return vppConfig, nil