1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
package main
import (
"fmt"
"encoding/json"
"github.com/edwarnicke/exechelper"
)
const vppConfigTemplate = `unix {
nodaemon
log %[1]s/var/log/vpp/vpp.log
full-coredump
cli-listen %[1]s%[2]s
runtime-dir %[1]s/var/run
gid vpp
}
api-trace {
on
}
api-segment {
gid vpp
}
socksvr {
socket-name %[1]s/var/run/vpp/api.sock
}
statseg {
socket-name %[1]s/var/run/vpp/stats.sock
}
plugins {
plugin unittest_plugin.so { enable }
plugin dpdk_plugin.so { disable }
plugin crypto_aesni_plugin.so { enable }
plugin quic_plugin.so { enable }
}
`
type VppInstance struct {
container *Container
config VppConfig
actionFuncName string
}
type VppConfig struct {
Variant string
CliSocketFilePath string
}
func (vc *VppConfig) getTemplate() string {
return fmt.Sprintf(vppConfigTemplate, "%[1]s", vc.CliSocketFilePath)
}
func (vpp *VppInstance) set2VethsServer() {
vpp.actionFuncName = "Configure2Veths"
vpp.config.Variant = "srv"
}
func (vpp *VppInstance) set2VethsClient() {
vpp.actionFuncName = "Configure2Veths"
vpp.config.Variant = "cln"
}
func (vpp *VppInstance) setCliSocket(filePath string) {
vpp.config.CliSocketFilePath = filePath
}
func (vpp *VppInstance) getCliSocket() string {
return fmt.Sprintf("/tmp/%s/%s", vpp.actionFuncName, vpp.config.CliSocketFilePath)
}
func (vpp *VppInstance) start() error {
if vpp.config.Variant == "" {
return fmt.Errorf("vpp start failed: variant must not be blank")
}
if vpp.actionFuncName == "" {
return fmt.Errorf("vpp start failed: action function name must not be blank")
}
serializedConfig, err := json.Marshal(vpp.config)
if err != nil {
return fmt.Errorf("vpp start failed: serializing configuration failed: %s", err)
}
args := fmt.Sprintf("%s '%s'", vpp.actionFuncName, string(serializedConfig))
_, err = hstExec(args, vpp.container.name)
if err != nil {
return fmt.Errorf("vpp start failed: %s", err)
}
return nil
}
func (vpp *VppInstance) vppctl(command string) (string, error) {
dockerExecCommand := fmt.Sprintf("docker exec --detach=false %[1]s vppctl -s %[2]s %[3]s",
vpp.container.name, vpp.getCliSocket(), command)
output, err := exechelper.CombinedOutput(dockerExecCommand)
if err != nil {
return "", fmt.Errorf("vppctl failed: %s", err)
}
return string(output), nil
}
func NewVppInstance(c *Container) *VppInstance {
vpp := new(VppInstance)
vpp.container = c
return vpp
}
func DeserializeVppConfig(input string) (VppConfig, error) {
var vppConfig VppConfig
err := json.Unmarshal([]byte(input), &vppConfig)
if err != nil {
// Since input is not a valid JSON it is going be used as variant value
// for compatibility reasons
vppConfig.Variant = input
vppConfig.CliSocketFilePath = "/var/run/vpp/cli.sock"
}
return vppConfig, nil
}
|