aboutsummaryrefslogtreecommitdiffstats
path: root/cmd/ovn4nfvk8s/ovn4nfvk8s.go
blob: d097558db970260f6330aaf35304c90d5eb87113 (plain)
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
125
126
127
128
129
130
131
132
package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"os/signal"
	"syscall"

	"github.com/sirupsen/logrus"
	"github.com/urfave/cli"

	kexec "k8s.io/utils/exec"

	"ovn4nfv-k8s-plugin/internal/pkg/config"
	"ovn4nfv-k8s-plugin/internal/pkg/factory"
	"ovn4nfv-k8s-plugin/internal/pkg/ovn"
	"ovn4nfv-k8s-plugin/internal/pkg/util"
)

func main() {
	c := cli.NewApp()
	c.Name = "ovn4nfvk8s"
	c.Usage = "run ovn4nfvk8s to start pod watchers"
	c.Version = config.Version
	c.Flags = append([]cli.Flag{
		// Daemon file
		cli.StringFlag{
			Name:  "pidfile",
			Usage: "Name of file that will hold the ovn4nfvk8s pid (optional)",
		},
	}, config.Flags...)
	c.Action = func(c *cli.Context) error {
		return runOvnKube(c)
	}

	if err := c.Run(os.Args); err != nil {
		logrus.Fatal(err)
	}
}

func delPidfile(pidfile string) {
	if pidfile != "" {
		if _, err := os.Stat(pidfile); err == nil {
			if err := os.Remove(pidfile); err != nil {
				logrus.Errorf("%s delete failed: %v", pidfile, err)
			}
		}
	}
}

func runOvnKube(ctx *cli.Context) error {
	fmt.Println("ovn4nfvk8s started")
	exec := kexec.New()
	_, err := config.InitConfig(ctx, exec, nil)
	if err != nil {
		return err
	}
	pidfile := ctx.String("pidfile")

	c := make(chan os.Signal, 2)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	go func() {
		<-c
		delPidfile(pidfile)
		os.Exit(1)
	}()

	defer delPidfile(pidfile)

	if pidfile != "" {
		// need to test if already there
		_, err := os.Stat(pidfile)

		// Create if it doesn't exist, else exit with error
		if os.IsNotExist(err) {
			if err := ioutil.WriteFile(pidfile, []byte(fmt.Sprintf("%d", os.Getpid())), 0644); err != nil {
				logrus.Errorf("failed to write pidfile %s (%v). Ignoring..", pidfile, err)
			}
		} else {
			// get the pid and see if it exists
			pid, err := ioutil.ReadFile(pidfile)
			if err != nil {
				logrus.Errorf("pidfile %s exists but can't be read", pidfile)
				return err
			}
			_, err1 := os.Stat("/proc/" + string(pid[:]) + "/cmdline")
			if os.IsNotExist(err1) {
				// Left over pid from dead process
				if err := ioutil.WriteFile(pidfile, []byte(fmt.Sprintf("%d", os.Getpid())), 0644); err != nil {
					logrus.Errorf("failed to write pidfile %s (%v). Ignoring..", pidfile, err)
				}
			} else {
				logrus.Errorf("pidfile %s exists and ovn4nfvk8s is running", pidfile)
				os.Exit(1)
			}
		}
	}

	if err = util.SetExec(exec); err != nil {
		logrus.Errorf("Failed to initialize exec helper: %v", err)
		return err
	}

	clientset, err := config.NewClientset(&config.Kubernetes)
	if err != nil {
		panic(err.Error())
	}

	// Create distributed router and gateway for the deployment
	err = ovn.SetupMaster("ovn4nfv-master")
	if err != nil {
		logrus.Errorf(err.Error())
		panic(err.Error())
	}
	// create factory and start the ovn controller
	stopChan := make(chan struct{})
	factory, err := factory.NewWatchFactory(clientset, stopChan)
	if err != nil {
		panic(err.Error)
	}

	ovnController := ovn.NewOvnController(clientset, factory)
	if err := ovnController.Run(); err != nil {
		logrus.Errorf(err.Error())
		panic(err.Error())
	}
	// run forever
	select {}

	return nil
}