@@ -44,6 +44,16 @@ import (
44
44
"github.com/sirupsen/logrus"
45
45
)
46
46
47
+ const (
48
+ // NetworkNamespace is the network namespace path to be passed to the CNI plugins.
49
+ // When this annotation is set from the runtime spec.State payload, it takes
50
+ // precedence over the PID based resolution (/proc/<pid>/ns/net) where pid is
51
+ // spec.State.Pid.
52
+ // This is mostly used for VM based runtime, where the spec.State PID does not
53
+ // necessarily lives in the created container networking namespace.
54
+ NetworkNamespace = labels .Prefix + "network-namespace"
55
+ )
56
+
47
57
func Run (stdin io.Reader , stderr io.Writer , event , dataStore , cniPath , cniNetconfPath string ) error {
48
58
if stdin == nil || event == "" || dataStore == "" || cniPath == "" || cniNetconfPath == "" {
49
59
return errors .New ("got insufficient args" )
@@ -252,9 +262,21 @@ func loadSpec(bundle string) (*hookSpec, error) {
252
262
}
253
263
254
264
func getNetNSPath (state * specs.State ) (string , error ) {
255
- if state .Pid == 0 {
256
- return "" , errors .New ("state.Pid is unset" )
265
+ // If we have a network-namespace annotation we use it over the passed Pid.
266
+ netNsPath , netNsFound := state .Annotations [NetworkNamespace ]
267
+ if netNsFound {
268
+ if _ , err := os .Stat (netNsPath ); err != nil {
269
+ return "" , err
270
+ }
271
+
272
+ return netNsPath , nil
257
273
}
274
+
275
+ if state .Pid == 0 && ! netNsFound {
276
+ return "" , errors .New ("Both state.Pid and the netNs annotation are unset" )
277
+ }
278
+
279
+ // We dont't have a networking namespace annotation, but we have a PID.
258
280
s := fmt .Sprintf ("/proc/%d/ns/net" , state .Pid )
259
281
if _ , err := os .Stat (s ); err != nil {
260
282
return "" , err
0 commit comments