@@ -17,6 +17,7 @@ package main
17
17
import (
18
18
"flag"
19
19
"fmt"
20
+ "net"
20
21
"os"
21
22
"reflect"
22
23
"strings"
@@ -29,6 +30,12 @@ import (
29
30
"github.com/k8snetworkplumbingwg/ovs-cni/pkg/marker"
30
31
)
31
32
33
+ const (
34
+ UnixSocketType = "unix"
35
+ TcpSocketType = "tcp"
36
+ SocketConnectionTimeout = time .Minute
37
+ )
38
+
32
39
func main () {
33
40
nodeName := flag .String ("node-name" , "" , "name of kubernetes node" )
34
41
ovsSocket := flag .String ("ovs-socket" , "" , "address of openvswitch database connection" )
@@ -54,38 +61,16 @@ func main() {
54
61
if * ovsSocket == "" {
55
62
glog .Fatal ("ovs-socket must be set" )
56
63
}
57
-
58
- var socketType , path string
59
- ovsSocketTokens := strings .Split (* ovsSocket , ":" )
60
- if len (ovsSocketTokens ) < 2 {
61
- /*
62
- * ovsSocket should consist of comma separated socket type and socket
63
- * detail. If no socket type is specified, it is assumed to be a unix
64
- * domain socket, for backwards compatibility.
65
- */
66
- socketType = "unix"
67
- path = * ovsSocket
68
- } else {
69
- socketType = ovsSocketTokens [0 ]
70
- path = ovsSocketTokens [1 ]
64
+ socketType , address , err := parseOvsSocket (ovsSocket )
65
+ if err != nil {
66
+ glog .Fatalf ("Failed to parse ovs socket: %v" , err )
71
67
}
72
-
73
- if socketType == "unix" {
74
- for {
75
- _ , err := os .Stat (path )
76
- if err == nil {
77
- glog .Info ("Found the OVS socket" )
78
- break
79
- } else if os .IsNotExist (err ) {
80
- glog .Infof ("Given ovs-socket %q was not found, waiting for the socket to appear" , path )
81
- time .Sleep (time .Minute )
82
- } else {
83
- glog .Fatalf ("Failed opening the OVS socket with: %v" , err )
84
- }
85
- }
68
+ if err = validateOvsSocketConnection (socketType , address ); err != nil {
69
+ glog .Fatal ("Failed to connect to ovs: %v" , err )
86
70
}
71
+ endpoint := fmt .Sprintf ("%s:%s" , socketType , address )
87
72
88
- markerApp , err := marker .NewMarker (* nodeName , socketType + ":" + path )
73
+ markerApp , err := marker .NewMarker (* nodeName , endpoint )
89
74
if err != nil {
90
75
glog .Fatalf ("Failed to create a new marker object: %v" , err )
91
76
}
@@ -137,3 +122,90 @@ func keepAlive(healthCheckFile string, healthCheckInterval int) {
137
122
138
123
}, time .Duration (healthCheckInterval )* time .Second )
139
124
}
125
+
126
+ /*
127
+ takes an OVS socket string and returns the socket
128
+ type, address, and any parsing error.
129
+ */
130
+ func parseOvsSocket (ovsSocket * string ) (string , string , error ) {
131
+ var socketType , address string
132
+ ovsSocketTokens := strings .Split (* ovsSocket , ":" )
133
+ if len (ovsSocketTokens ) < 2 {
134
+ /*
135
+ * ovsSocket should consist of comma separated socket type and socket
136
+ * detail. If no socket type is specified, it is assumed to be a unix
137
+ * domain socket, for backwards compatibility.
138
+ */
139
+ socketType = UnixSocketType
140
+ address = * ovsSocket
141
+ } else {
142
+ socketType = ovsSocketTokens [0 ]
143
+ if socketType == TcpSocketType {
144
+ if len (ovsSocketTokens ) != 3 {
145
+ return "" , "" , fmt .Errorf ("failed to parse OVS %s socket, must be in this format %s:<host>:<port>" , socketType , socketType )
146
+ }
147
+ address = fmt .Sprintf ("%s:%s" , ovsSocketTokens [1 ], ovsSocketTokens [2 ])
148
+ } else {
149
+ // unix socket
150
+ socketType = UnixSocketType
151
+ address = ovsSocketTokens [1 ]
152
+ }
153
+ }
154
+ return socketType , address , nil
155
+ }
156
+
157
+ func validateOvsSocketConnection (socketType , address string ) error {
158
+ validator , err := getOvsSocketValidator (socketType )
159
+ if err != nil {
160
+ return err
161
+ }
162
+ return validator (address )
163
+ }
164
+
165
+ func getOvsSocketValidator (socketType string ) (func (string ) error , error ) {
166
+ switch socketType {
167
+ case UnixSocketType :
168
+ return validateOvsUnixConnection , nil
169
+ case TcpSocketType :
170
+ return validateOvsTcpConnection , nil
171
+ default :
172
+ return nil , fmt .Errorf ("unsupported ovs socket type: %s" , socketType )
173
+ }
174
+ }
175
+
176
+ func validateOvsUnixConnection (address string ) error {
177
+ for {
178
+ _ , err := os .Stat (address )
179
+ if err == nil {
180
+ glog .Info ("Found the OVS socket" )
181
+ break
182
+ } else if os .IsNotExist (err ) {
183
+ glog .Infof ("Given ovs-socket %q was not found, waiting for the socket to appear" , address )
184
+ time .Sleep (SocketConnectionTimeout )
185
+ } else {
186
+ return fmt .Errorf ("failed opening the OVS socket with: %v" , err )
187
+ }
188
+ }
189
+ return nil
190
+ }
191
+
192
+ func validateOvsTcpConnection (address string ) error {
193
+ conn , err := net .DialTimeout (TcpSocketType , address , SocketConnectionTimeout )
194
+ if err == nil {
195
+ glog .Info ("Successfully connected to TCP socket" )
196
+ conn .Close ()
197
+ return nil
198
+ }
199
+
200
+ if netErr , ok := err .(net.Error ); ok && netErr .Timeout () {
201
+ return fmt .Errorf ("connection to %s timed out" , address )
202
+ } else if opErr , ok := err .(* net.OpError ); ok {
203
+ if opErr .Op == "dial" {
204
+ return fmt .Errorf ("connection to %s failed: %v" , address , err )
205
+ } else {
206
+ return fmt .Errorf ("unexpected error when connecting to %s: %v" , address , err )
207
+ }
208
+ } else {
209
+ return fmt .Errorf ("unexpected error when connecting to %s: %v" , address , err )
210
+ }
211
+ }
0 commit comments