9
9
"net"
10
10
"net/http"
11
11
"os"
12
- "path"
12
+ "path/filepath "
13
13
"strings"
14
14
15
15
"github.com/golang/glog"
@@ -44,9 +44,21 @@ import (
44
44
// removed and re-created with 0700 permissions each time openshift-node is
45
45
// started.
46
46
47
- // Default CNIServer unix domain socket path which the OpenShift SDN CNI
48
- // plugin uses to talk to the CNIServer
49
- const CNIServerSocketPath string = "/var/run/openshift-sdn/cni-server.sock"
47
+ // Default directory for CNIServer runtime files
48
+ const CNIServerRunDir string = "/var/run/openshift-sdn"
49
+
50
+ // CNIServer socket name, and default full path
51
+ const CNIServerSocketName string = "cni-server.sock"
52
+ const CNIServerSocketPath string = CNIServerRunDir + "/" + CNIServerSocketName
53
+
54
+ // Config file containing MTU, and default full path
55
+ const CNIServerConfigFileName string = "config.json"
56
+ const CNIServerConfigFilePath string = CNIServerRunDir + "/" + CNIServerConfigFileName
57
+
58
+ // Server-to-plugin config data
59
+ type Config struct {
60
+ MTU uint32 `json:"mtu"`
61
+ }
50
62
51
63
// Explicit type for CNI commands the server handles
52
64
type CNICommand string
@@ -76,6 +88,8 @@ type PodRequest struct {
76
88
SandboxID string
77
89
// kernel network namespace path
78
90
Netns string
91
+ // for an ADD request, the host side of the created veth
92
+ HostVeth string
79
93
// Channel for returning the operation result to the CNIServer
80
94
Result chan * PodResult
81
95
}
@@ -95,19 +109,20 @@ type cniRequestFunc func(request *PodRequest) ([]byte, error)
95
109
type CNIServer struct {
96
110
http.Server
97
111
requestFunc cniRequestFunc
98
- path string
112
+ rundir string
113
+ config * Config
99
114
}
100
115
101
- // Create and return a new CNIServer object which will listen on the given
102
- // socket path
103
- func NewCNIServer (socketPath string ) * CNIServer {
116
+ // Create and return a new CNIServer object which will listen on a socket in the given path
117
+ func NewCNIServer (rundir string , config * Config ) * CNIServer {
104
118
router := mux .NewRouter ()
105
119
106
120
s := & CNIServer {
107
121
Server : http.Server {
108
122
Handler : router ,
109
123
},
110
- path : socketPath ,
124
+ rundir : rundir ,
125
+ config : config ,
111
126
}
112
127
router .NotFoundHandler = http .HandlerFunc (http .NotFound )
113
128
router .HandleFunc ("/" , s .handleCNIRequest ).Methods ("POST" )
@@ -125,25 +140,36 @@ func (s *CNIServer) Start(requestFunc cniRequestFunc) error {
125
140
s .requestFunc = requestFunc
126
141
127
142
// Remove and re-create the socket directory with root-only permissions
128
- dirName := path .Dir (s .path )
129
- if err := os .RemoveAll (s .path ); err != nil && ! os .IsNotExist (err ) {
143
+ if err := os .RemoveAll (s .rundir ); err != nil && ! os .IsNotExist (err ) {
130
144
utilruntime .HandleError (fmt .Errorf ("failed to remove old pod info socket: %v" , err ))
131
145
}
132
- if err := os .RemoveAll (dirName ); err != nil && ! os .IsNotExist (err ) {
146
+ if err := os .RemoveAll (s . rundir ); err != nil && ! os .IsNotExist (err ) {
133
147
utilruntime .HandleError (fmt .Errorf ("failed to remove contents of socket directory: %v" , err ))
134
148
}
135
- if err := os .MkdirAll (dirName , 0700 ); err != nil {
149
+ if err := os .MkdirAll (s . rundir , 0700 ); err != nil {
136
150
return fmt .Errorf ("failed to create pod info socket directory: %v" , err )
137
151
}
138
152
153
+ // Write config file
154
+ config , err := json .Marshal (s .config )
155
+ if err != nil {
156
+ return fmt .Errorf ("could not marshal config data: %v" , err )
157
+ }
158
+ configPath := filepath .Join (s .rundir , CNIServerConfigFileName )
159
+ err = ioutil .WriteFile (configPath , config , os .FileMode (0444 ))
160
+ if err != nil {
161
+ return fmt .Errorf ("could not write config file %q: %v" , configPath , err )
162
+ }
163
+
139
164
// On Linux the socket is created with the permissions of the directory
140
165
// it is in, so as long as the directory is root-only we can avoid
141
166
// racy umask manipulation.
142
- l , err := net .Listen ("unix" , s .path )
167
+ socketPath := filepath .Join (s .rundir , CNIServerSocketName )
168
+ l , err := net .Listen ("unix" , socketPath )
143
169
if err != nil {
144
170
return fmt .Errorf ("failed to listen on pod info socket: %v" , err )
145
171
}
146
- if err := os .Chmod (s . path , 0600 ); err != nil {
172
+ if err := os .Chmod (socketPath , 0600 ); err != nil {
147
173
l .Close ()
148
174
return fmt .Errorf ("failed to set pod info socket mode: %v" , err )
149
175
}
@@ -157,6 +183,22 @@ func (s *CNIServer) Start(requestFunc cniRequestFunc) error {
157
183
return nil
158
184
}
159
185
186
+ func ReadConfig (configPath string ) (* Config , error ) {
187
+ bytes , err := ioutil .ReadFile (configPath )
188
+ if err != nil {
189
+ if os .IsNotExist (err ) {
190
+ return nil , fmt .Errorf ("OpenShift SDN network process is not (yet?) available" )
191
+ } else {
192
+ return nil , fmt .Errorf ("could not read config file %q: %v" , configPath , err )
193
+ }
194
+ }
195
+ var config Config
196
+ if err = json .Unmarshal (bytes , & config ); err != nil {
197
+ return nil , fmt .Errorf ("could not parse config file %q: %v" , configPath , err )
198
+ }
199
+ return & config , nil
200
+ }
201
+
160
202
// Split the "CNI_ARGS" environment variable's value into a map. CNI_ARGS
161
203
// contains arbitrary key/value pairs separated by ';' and is for runtime or
162
204
// plugin specific uses. Kubernetes passes the pod namespace and name in
@@ -204,6 +246,11 @@ func cniRequestToPodRequest(r *http.Request) (*PodRequest, error) {
204
246
return nil , fmt .Errorf ("missing CNI_NETNS" )
205
247
}
206
248
249
+ req .HostVeth , ok = cr .Env ["OSDN_HOSTVETH" ]
250
+ if ! ok && req .Command == CNI_ADD {
251
+ return nil , fmt .Errorf ("missing OSDN_HOSTVETH" )
252
+ }
253
+
207
254
cniArgs , err := gatherCNIArgs (cr .Env )
208
255
if err != nil {
209
256
return nil , err
0 commit comments