blob: 8fa1458767d60c81b2d772980a871fbf8a8819fc [file] [log] [blame]
Filip Tehlar229f5fc2022-08-09 14:44:47 +00001package main
2
3import (
4 "context"
5 "encoding/json"
6 "fmt"
7 "os"
Filip Tehlar229f5fc2022-08-09 14:44:47 +00008 "os/signal"
Filip Tehlar1a9dc752022-11-22 12:49:22 +01009 "reflect"
Filip Tehlar229f5fc2022-08-09 14:44:47 +000010)
11
Filip Tehlar1a9dc752022-11-22 12:49:22 +010012var actions Actions
Filip Tehlar229f5fc2022-08-09 14:44:47 +000013
14func newVppContext() (context.Context, context.CancelFunc) {
15 ctx, cancel := signal.NotifyContext(
16 context.Background(),
17 os.Interrupt,
18 )
19 return ctx, cancel
20}
21
Filip Tehlar229f5fc2022-08-09 14:44:47 +000022func exitOnErrCh(ctx context.Context, cancel context.CancelFunc, errCh <-chan error) {
23 // If we already have an error, log it and exit
24 select {
25 case err := <-errCh:
26 fmt.Printf("%v", err)
27 default:
28 }
29 go func(ctx context.Context, errCh <-chan error) {
30 <-errCh
31 cancel()
32 }(ctx, errCh)
33}
34
35func writeSyncFile(res *ActionResult) error {
36 syncFile := "/tmp/sync/rc"
37
38 var jsonRes JsonResult
39
40 jsonRes.ErrOutput = res.ErrOutput
41 jsonRes.StdOutput = res.StdOutput
42 if res.Err != nil {
43 jsonRes.Code = 1
44 jsonRes.Desc = fmt.Sprintf("%s :%v", res.Desc, res.Err)
45 } else {
46 jsonRes.Code = 0
47 }
48
49 str, err := json.Marshal(jsonRes)
50 if err != nil {
51 return fmt.Errorf("error marshaling json result data! %v", err)
52 }
53
54 _, err = os.Open(syncFile)
55 if err != nil {
56 // expecting the file does not exist
57 f, e := os.Create(syncFile)
58 if e != nil {
59 return fmt.Errorf("failed to open sync file")
60 }
61 defer f.Close()
62 f.Write([]byte(str))
63 } else {
Maros Ondrejicka0db15752022-10-12 22:58:01 +020064 return fmt.Errorf("sync file exists, delete the file first")
Filip Tehlar229f5fc2022-08-09 14:44:47 +000065 }
66 return nil
67}
68
69func NewActionResult(err error, opts ...ActionResultOptionFn) *ActionResult {
70 res := &ActionResult{
71 Err: err,
72 }
73 for _, o := range opts {
74 o(res)
75 }
76 return res
77}
78
79type ActionResultOptionFn func(res *ActionResult)
80
81func ActionResultWithDesc(s string) ActionResultOptionFn {
82 return func(res *ActionResult) {
83 res.Desc = s
84 }
85}
86
87func ActionResultWithStderr(s string) ActionResultOptionFn {
88 return func(res *ActionResult) {
89 res.ErrOutput = s
90 }
91}
92
93func ActionResultWithStdout(s string) ActionResultOptionFn {
94 return func(res *ActionResult) {
Maros Ondrejicka0db15752022-10-12 22:58:01 +020095 res.StdOutput = s
Filip Tehlar229f5fc2022-08-09 14:44:47 +000096 }
97}
98
99func OkResult() *ActionResult {
100 return NewActionResult(nil)
101}
102
Filip Tehlar229f5fc2022-08-09 14:44:47 +0000103func processArgs() *ActionResult {
Filip Tehlar1a9dc752022-11-22 12:49:22 +0100104 nArgs := len(os.Args) - 1 // skip program name
105 if nArgs < 1 {
106 return NewActionResult(fmt.Errorf("internal: no action specified!"))
Filip Tehlar229f5fc2022-08-09 14:44:47 +0000107 }
Filip Tehlar1a9dc752022-11-22 12:49:22 +0100108 action := os.Args[1]
109 methodValue := reflect.ValueOf(&actions).MethodByName(action)
110 if !methodValue.IsValid() {
111 return NewActionResult(fmt.Errorf("internal unknown action %s!", action))
112 }
113 methodIface := methodValue.Interface()
114 fn := methodIface.(func([]string) *ActionResult)
Filip Tehlar229f5fc2022-08-09 14:44:47 +0000115 return fn(os.Args)
116}
117
118func main() {
119 if len(os.Args) == 0 {
120 fmt.Println("args required")
121 return
122 }
123
124 if os.Args[1] == "rm" {
Maros Ondrejickadb823ed2022-12-14 16:30:04 +0100125 topology, err := LoadTopology(NetworkTopologyDir, os.Args[2])
Filip Tehlar229f5fc2022-08-09 14:44:47 +0000126 if err != nil {
127 fmt.Printf("falied to load topologies: %v\n", err)
128 os.Exit(1)
129 }
130 topology.Unconfigure()
131 os.Exit(0)
132 }
133
Filip Tehlar229f5fc2022-08-09 14:44:47 +0000134 var err error
135 res := processArgs()
136 err = writeSyncFile(res)
137 if err != nil {
138 fmt.Printf("failed to write to sync file: %v\n", err)
139 }
140}