blob: 10149178ce6bff30baf0d1fbac4356f11b7400f5 [file] [log] [blame]
Filip Tehlar229f5fc2022-08-09 14:44:47 +00001package main
2
3import (
4 "context"
5 "encoding/json"
6 "fmt"
7 "os"
8 "os/exec"
9 "os/signal"
10
11 "git.fd.io/govpp.git/api"
12)
13
14type CfgTable map[string]func([]string) *ActionResult
15
16var cfgTable CfgTable
17
18type ConfFn func(context.Context, api.Connection) error
19
20func newVppContext() (context.Context, context.CancelFunc) {
21 ctx, cancel := signal.NotifyContext(
22 context.Background(),
23 os.Interrupt,
24 )
25 return ctx, cancel
26}
27
28func Vppcli(runDir, command string) (string, error) {
29 cmd := exec.Command("vppctl", "-s", fmt.Sprintf("%s/var/run/vpp/cli.sock", runDir), command)
30 o, err := cmd.CombinedOutput()
31 if err != nil {
32 fmt.Printf("failed to execute command: '%v'.\n", err)
33 }
34 fmt.Printf("Command output %s", string(o))
35 return string(o), err
36}
37
38func exitOnErrCh(ctx context.Context, cancel context.CancelFunc, errCh <-chan error) {
39 // If we already have an error, log it and exit
40 select {
41 case err := <-errCh:
42 fmt.Printf("%v", err)
43 default:
44 }
45 go func(ctx context.Context, errCh <-chan error) {
46 <-errCh
47 cancel()
48 }(ctx, errCh)
49}
50
51func writeSyncFile(res *ActionResult) error {
52 syncFile := "/tmp/sync/rc"
53
54 var jsonRes JsonResult
55
56 jsonRes.ErrOutput = res.ErrOutput
57 jsonRes.StdOutput = res.StdOutput
58 if res.Err != nil {
59 jsonRes.Code = 1
60 jsonRes.Desc = fmt.Sprintf("%s :%v", res.Desc, res.Err)
61 } else {
62 jsonRes.Code = 0
63 }
64
65 str, err := json.Marshal(jsonRes)
66 if err != nil {
67 return fmt.Errorf("error marshaling json result data! %v", err)
68 }
69
70 _, err = os.Open(syncFile)
71 if err != nil {
72 // expecting the file does not exist
73 f, e := os.Create(syncFile)
74 if e != nil {
75 return fmt.Errorf("failed to open sync file")
76 }
77 defer f.Close()
78 f.Write([]byte(str))
79 } else {
80 return fmt.Errorf("sync file exists, delete the file frst")
81 }
82 return nil
83}
84
85func NewActionResult(err error, opts ...ActionResultOptionFn) *ActionResult {
86 res := &ActionResult{
87 Err: err,
88 }
89 for _, o := range opts {
90 o(res)
91 }
92 return res
93}
94
95type ActionResultOptionFn func(res *ActionResult)
96
97func ActionResultWithDesc(s string) ActionResultOptionFn {
98 return func(res *ActionResult) {
99 res.Desc = s
100 }
101}
102
103func ActionResultWithStderr(s string) ActionResultOptionFn {
104 return func(res *ActionResult) {
105 res.ErrOutput = s
106 }
107}
108
109func ActionResultWithStdout(s string) ActionResultOptionFn {
110 return func(res *ActionResult) {
111 res.ErrOutput = s
112 }
113}
114
115func OkResult() *ActionResult {
116 return NewActionResult(nil)
117}
118
119func reg(key string, fn func([]string) *ActionResult) {
120 cfgTable[key] = fn
121}
122
123func processArgs() *ActionResult {
124 fn := cfgTable[os.Args[1]]
125 if fn == nil {
126 return NewActionResult(fmt.Errorf("internal: no config found for %s", os.Args[1]))
127 }
128 return fn(os.Args)
129}
130
131func main() {
132 if len(os.Args) == 0 {
133 fmt.Println("args required")
134 return
135 }
136
137 if os.Args[1] == "rm" {
138 topology, err := LoadTopology(TopologyDir, os.Args[2])
139 if err != nil {
140 fmt.Printf("falied to load topologies: %v\n", err)
141 os.Exit(1)
142 }
143 topology.Unconfigure()
144 os.Exit(0)
145 }
146
147 RegisterActions()
148
149 var err error
150 res := processArgs()
151 err = writeSyncFile(res)
152 if err != nil {
153 fmt.Printf("failed to write to sync file: %v\n", err)
154 }
155}