Merge "Code cleanup"
[ovn4nfv-k8s-plugin.git] / cmd / ovn4nfvk8s / ovn4nfvk8s.go
1 package main
2
3 import (
4         "fmt"
5         "io/ioutil"
6         "os"
7         "os/signal"
8         "syscall"
9
10         "github.com/sirupsen/logrus"
11         "github.com/urfave/cli"
12
13         kexec "k8s.io/utils/exec"
14
15         "ovn4nfv-k8s-plugin/internal/pkg/config"
16         "ovn4nfv-k8s-plugin/internal/pkg/factory"
17         "ovn4nfv-k8s-plugin/internal/pkg/ovn"
18         "ovn4nfv-k8s-plugin/internal/pkg/util"
19 )
20
21 func main() {
22         c := cli.NewApp()
23         c.Name = "ovn4nfvk8s"
24         c.Usage = "run ovn4nfvk8s to start pod watchers"
25         c.Flags = append([]cli.Flag{
26                 // Daemon file
27                 cli.StringFlag{
28                         Name:  "pidfile",
29                         Usage: "Name of file that will hold the ovn4nfvk8s pid (optional)",
30                 },
31         }, config.Flags...)
32         c.Action = func(c *cli.Context) error {
33                 return runOvnKube(c)
34         }
35
36         if err := c.Run(os.Args); err != nil {
37                 logrus.Fatal(err)
38         }
39 }
40
41 func delPidfile(pidfile string) {
42         if pidfile != "" {
43                 if _, err := os.Stat(pidfile); err == nil {
44                         if err := os.Remove(pidfile); err != nil {
45                                 logrus.Errorf("%s delete failed: %v", pidfile, err)
46                         }
47                 }
48         }
49 }
50
51 func runOvnKube(ctx *cli.Context) error {
52         exec := kexec.New()
53         _, err := config.InitConfig(ctx)
54         if err != nil {
55                 return err
56         }
57         pidfile := ctx.String("pidfile")
58
59         c := make(chan os.Signal, 2)
60         signal.Notify(c, os.Interrupt, syscall.SIGTERM)
61         go func() {
62                 <-c
63                 delPidfile(pidfile)
64                 os.Exit(1)
65         }()
66
67         defer delPidfile(pidfile)
68
69         if pidfile != "" {
70                 // need to test if already there
71                 _, err := os.Stat(pidfile)
72
73                 // Create if it doesn't exist, else exit with error
74                 if os.IsNotExist(err) {
75                         if err := ioutil.WriteFile(pidfile, []byte(fmt.Sprintf("%d", os.Getpid())), 0644); err != nil {
76                                 logrus.Errorf("failed to write pidfile %s (%v). Ignoring..", pidfile, err)
77                         }
78                 } else {
79                         // get the pid and see if it exists
80                         pid, err := ioutil.ReadFile(pidfile)
81                         if err != nil {
82                                 logrus.Errorf("pidfile %s exists but can't be read", pidfile)
83                                 return err
84                         }
85                         _, err1 := os.Stat("/proc/" + string(pid[:]) + "/cmdline")
86                         if os.IsNotExist(err1) {
87                                 // Left over pid from dead process
88                                 if err := ioutil.WriteFile(pidfile, []byte(fmt.Sprintf("%d", os.Getpid())), 0644); err != nil {
89                                         logrus.Errorf("failed to write pidfile %s (%v). Ignoring..", pidfile, err)
90                                 }
91                         } else {
92                                 logrus.Errorf("pidfile %s exists and ovn4nfvk8s is running", pidfile)
93                                 os.Exit(1)
94                         }
95                 }
96         }
97
98         if err = util.SetExec(exec); err != nil {
99                 logrus.Errorf("Failed to initialize exec helper: %v", err)
100                 return err
101         }
102
103         clientset, err := config.NewClientset(&config.Kubernetes)
104         if err != nil {
105                 panic(err.Error())
106         }
107
108         // Create distributed router and gateway for the deployment
109         err = ovn.SetupMaster("ovn4nfv-master")
110         if err != nil {
111                 logrus.Errorf(err.Error())
112                 panic(err.Error())
113         }
114         // create factory and start the ovn controller
115         stopChan := make(chan struct{})
116         factory, err := factory.NewWatchFactory(clientset, stopChan)
117         if err != nil {
118                 panic(err.Error)
119         }
120
121         ovnController := ovn.NewOvnController(clientset, factory)
122         if err := ovnController.Run(); err != nil {
123                 logrus.Errorf(err.Error())
124                 panic(err.Error())
125         }
126         // run forever
127         select {}
128
129         return nil
130 }