@@ -309,31 +309,38 @@ func (v *Validator) CheckMounts() (msgs []string) {
309309func (v * Validator ) CheckLinux () (msgs []string ) {
310310 logrus .Debugf ("check linux" )
311311
312- utsExists := false
313- ipcExists := false
314- mountExists := false
315- netExists := false
316- userExists := false
312+ var typeList = map [rspec.NamespaceType ]struct {
313+ num int
314+ newExist bool
315+ }{
316+ rspec .PIDNamespace : {0 , false },
317+ rspec .NetworkNamespace : {0 , false },
318+ rspec .MountNamespace : {0 , false },
319+ rspec .IPCNamespace : {0 , false },
320+ rspec .UTSNamespace : {0 , false },
321+ rspec .UserNamespace : {0 , false },
322+ rspec .CgroupNamespace : {0 , false },
323+ }
317324
318325 for index := 0 ; index < len (v .spec .Linux .Namespaces ); index ++ {
319- if ! namespaceValid (v .spec .Linux .Namespaces [index ]) {
320- msgs = append (msgs , fmt .Sprintf ("namespace %v is invalid." , v .spec .Linux .Namespaces [index ]))
321- } else if len (v .spec .Linux .Namespaces [index ].Path ) == 0 {
322- if v .spec .Linux .Namespaces [index ].Type == rspec .UTSNamespace {
323- utsExists = true
324- } else if v .spec .Linux .Namespaces [index ].Type == rspec .IPCNamespace {
325- ipcExists = true
326- } else if v .spec .Linux .Namespaces [index ].Type == rspec .NetworkNamespace {
327- netExists = true
328- } else if v .spec .Linux .Namespaces [index ].Type == rspec .MountNamespace {
329- mountExists = true
330- } else if v .spec .Linux .Namespaces [index ].Type == rspec .UserNamespace {
331- userExists = true
332- }
326+ ns := v .spec .Linux .Namespaces [index ]
327+ if ! namespaceValid (ns ) {
328+ msgs = append (msgs , fmt .Sprintf ("namespace %v is invalid." , ns ))
329+ }
330+
331+ tmpItem := typeList [ns .Type ]
332+ tmpItem .num = tmpItem .num + 1
333+ if tmpItem .num > 1 {
334+ msgs = append (msgs , fmt .Sprintf ("duplicated namespace %q" , ns .Type ))
335+ }
336+
337+ if len (ns .Path ) == 0 {
338+ tmpItem .newExist = true
333339 }
340+ typeList [ns .Type ] = tmpItem
334341 }
335342
336- if (len (v .spec .Linux .UIDMappings ) > 0 || len (v .spec .Linux .GIDMappings ) > 0 ) && ! userExists {
343+ if (len (v .spec .Linux .UIDMappings ) > 0 || len (v .spec .Linux .GIDMappings ) > 0 ) && ! typeList [ rspec . UserNamespace ]. newExist {
337344 msgs = append (msgs , "UID/GID mappings requires a new User namespace to be specified as well" )
338345 } else if len (v .spec .Linux .UIDMappings ) > 5 {
339346 msgs = append (msgs , "Only 5 UID mappings are allowed (linux kernel restriction)." )
@@ -342,17 +349,17 @@ func (v *Validator) CheckLinux() (msgs []string) {
342349 }
343350
344351 for k := range v .spec .Linux .Sysctl {
345- if strings .HasPrefix (k , "net." ) && ! netExists {
352+ if strings .HasPrefix (k , "net." ) && ! typeList [ rspec . NetworkNamespace ]. newExist {
346353 msgs = append (msgs , fmt .Sprintf ("Sysctl %v requires a new Network namespace to be specified as well" , k ))
347354 }
348355 if strings .HasPrefix (k , "fs.mqueue." ) {
349- if ! mountExists || ! ipcExists {
356+ if ! typeList [ rspec . MountNamespace ]. newExist || ! typeList [ rspec . IPCNamespace ]. newExist {
350357 msgs = append (msgs , fmt .Sprintf ("Sysctl %v requires a new IPC namespace and Mount namespace to be specified as well" , k ))
351358 }
352359 }
353360 }
354361
355- if v .spec .Platform .OS == "linux" && ! utsExists && v .spec .Hostname != "" {
362+ if v .spec .Platform .OS == "linux" && ! typeList [ rspec . UTSNamespace ]. newExist && v .spec .Hostname != "" {
356363 msgs = append (msgs , fmt .Sprintf ("On Linux, hostname requires a new UTS namespace to be specified as well" ))
357364 }
358365
0 commit comments