blob: 15524b826c22abaa0747efe161a788f9e6f93c87 [file] [log] [blame]
Maros Ondrejicka11a03e92022-12-01 09:56:37 +01001package main
2
3import (
Maros Ondrejicka11a03e92022-12-01 09:56:37 +01004 "encoding/json"
Filip Tehlarf3ee2b62023-01-09 12:07:09 +01005 "fmt"
Maros Ondrejicka11a03e92022-12-01 09:56:37 +01006 "github.com/edwarnicke/exechelper"
7)
8
9const vppConfigTemplate = `unix {
10 nodaemon
11 log %[1]s/var/log/vpp/vpp.log
12 full-coredump
13 cli-listen %[1]s%[2]s
14 runtime-dir %[1]s/var/run
15 gid vpp
16}
17
18api-trace {
19 on
20}
21
22api-segment {
23 gid vpp
24}
25
26socksvr {
27 socket-name %[1]s/var/run/vpp/api.sock
28}
29
30statseg {
31 socket-name %[1]s/var/run/vpp/stats.sock
32}
33
34plugins {
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 }
39}
40
41`
42
Maros Ondrejickadb823ed2022-12-14 16:30:04 +010043const (
44 defaultCliSocketFilePath = "/var/run/vpp/cli.sock"
45)
46
Maros Ondrejicka11a03e92022-12-01 09:56:37 +010047type VppInstance struct {
Filip Tehlarf3ee2b62023-01-09 12:07:09 +010048 container *Container
49 config VppConfig
Maros Ondrejicka11a03e92022-12-01 09:56:37 +010050 actionFuncName string
51}
52
53type VppConfig struct {
Filip Tehlarf3ee2b62023-01-09 12:07:09 +010054 Variant string
Maros Ondrejicka11a03e92022-12-01 09:56:37 +010055 CliSocketFilePath string
56}
57
58func (vc *VppConfig) getTemplate() string {
59 return fmt.Sprintf(vppConfigTemplate, "%[1]s", vc.CliSocketFilePath)
60}
61
62func (vpp *VppInstance) set2VethsServer() {
63 vpp.actionFuncName = "Configure2Veths"
64 vpp.config.Variant = "srv"
65}
66
67func (vpp *VppInstance) set2VethsClient() {
68 vpp.actionFuncName = "Configure2Veths"
69 vpp.config.Variant = "cln"
70}
71
Maros Ondrejickadb823ed2022-12-14 16:30:04 +010072func (vpp *VppInstance) setVppProxy() {
73 vpp.actionFuncName = "ConfigureVppProxy"
74}
75
76func (vpp *VppInstance) setEnvoyProxy() {
77 vpp.actionFuncName = "ConfigureEnvoyProxy"
78}
79
Maros Ondrejicka11a03e92022-12-01 09:56:37 +010080func (vpp *VppInstance) setCliSocket(filePath string) {
81 vpp.config.CliSocketFilePath = filePath
82}
83
84func (vpp *VppInstance) getCliSocket() string {
Maros Ondrejickadb823ed2022-12-14 16:30:04 +010085 return fmt.Sprintf("%s%s", vpp.container.workDir, vpp.config.CliSocketFilePath)
Maros Ondrejicka11a03e92022-12-01 09:56:37 +010086}
87
88func (vpp *VppInstance) start() error {
Maros Ondrejicka11a03e92022-12-01 09:56:37 +010089 if vpp.actionFuncName == "" {
90 return fmt.Errorf("vpp start failed: action function name must not be blank")
91 }
92
Maros Ondrejickadb823ed2022-12-14 16:30:04 +010093 serializedConfig, err := serializeVppConfig(vpp.config)
94 args := fmt.Sprintf("%s '%s'", vpp.actionFuncName, serializedConfig)
95 _, err = vpp.container.execAction(args)
Maros Ondrejicka11a03e92022-12-01 09:56:37 +010096 if err != nil {
97 return fmt.Errorf("vpp start failed: %s", err)
98 }
99
100 return nil
101}
102
103func (vpp *VppInstance) vppctl(command string) (string, error) {
Maros Ondrejickadb823ed2022-12-14 16:30:04 +0100104 cliExecCommand := fmt.Sprintf("docker exec --detach=false %[1]s vppctl -s %[2]s %[3]s",
Maros Ondrejicka11a03e92022-12-01 09:56:37 +0100105 vpp.container.name, vpp.getCliSocket(), command)
Maros Ondrejickadb823ed2022-12-14 16:30:04 +0100106 output, err := exechelper.CombinedOutput(cliExecCommand)
Maros Ondrejicka11a03e92022-12-01 09:56:37 +0100107 if err != nil {
108 return "", fmt.Errorf("vppctl failed: %s", err)
109 }
110
111 return string(output), nil
112}
113
114func NewVppInstance(c *Container) *VppInstance {
Maros Ondrejickadb823ed2022-12-14 16:30:04 +0100115 var vppConfig VppConfig
116 vppConfig.CliSocketFilePath = defaultCliSocketFilePath
Maros Ondrejicka11a03e92022-12-01 09:56:37 +0100117 vpp := new(VppInstance)
118 vpp.container = c
Maros Ondrejickadb823ed2022-12-14 16:30:04 +0100119 vpp.config = vppConfig
Maros Ondrejicka11a03e92022-12-01 09:56:37 +0100120 return vpp
121}
122
Maros Ondrejickadb823ed2022-12-14 16:30:04 +0100123func serializeVppConfig(vppConfig VppConfig) (string, error) {
124 serializedConfig, err := json.Marshal(vppConfig)
125 if err != nil {
126 return "", fmt.Errorf("vpp start failed: serializing configuration failed: %s", err)
127 }
128 return string(serializedConfig), nil
129}
130
131func deserializeVppConfig(input string) (VppConfig, error) {
Maros Ondrejicka11a03e92022-12-01 09:56:37 +0100132 var vppConfig VppConfig
133 err := json.Unmarshal([]byte(input), &vppConfig)
134 if err != nil {
Maros Ondrejickadb823ed2022-12-14 16:30:04 +0100135 // Since input is not a valid JSON it is going be used as a variant value
Maros Ondrejicka11a03e92022-12-01 09:56:37 +0100136 // for compatibility reasons
137 vppConfig.Variant = input
Maros Ondrejickadb823ed2022-12-14 16:30:04 +0100138 vppConfig.CliSocketFilePath = defaultCliSocketFilePath
Maros Ondrejicka11a03e92022-12-01 09:56:37 +0100139 }
140 return vppConfig, nil
141}