@@ -372,31 +372,38 @@ func (v *Validator) CheckOS() (msgs []string) {
372372func (v * Validator ) CheckLinux () (msgs []string ) {
373373 logrus .Debugf ("check linux" )
374374
375- utsExists := false
376- ipcExists := false
377- mountExists := false
378- netExists := false
379- userExists := false
375+ var typeList = map [rspec.NamespaceType ]struct {
376+ num int
377+ newExist bool
378+ }{
379+ rspec .PIDNamespace : {0 , false },
380+ rspec .NetworkNamespace : {0 , false },
381+ rspec .MountNamespace : {0 , false },
382+ rspec .IPCNamespace : {0 , false },
383+ rspec .UTSNamespace : {0 , false },
384+ rspec .UserNamespace : {0 , false },
385+ rspec .CgroupNamespace : {0 , false },
386+ }
380387
381388 for index := 0 ; index < len (v .spec .Linux .Namespaces ); index ++ {
382- if ! namespaceValid (v .spec .Linux .Namespaces [index ]) {
383- msgs = append (msgs , fmt .Sprintf ("namespace %v is invalid." , v .spec .Linux .Namespaces [index ]))
384- } else if len (v .spec .Linux .Namespaces [index ].Path ) == 0 {
385- if v .spec .Linux .Namespaces [index ].Type == rspec .UTSNamespace {
386- utsExists = true
387- } else if v .spec .Linux .Namespaces [index ].Type == rspec .IPCNamespace {
388- ipcExists = true
389- } else if v .spec .Linux .Namespaces [index ].Type == rspec .NetworkNamespace {
390- netExists = true
391- } else if v .spec .Linux .Namespaces [index ].Type == rspec .MountNamespace {
392- mountExists = true
393- } else if v .spec .Linux .Namespaces [index ].Type == rspec .UserNamespace {
394- userExists = true
395- }
389+ ns := v .spec .Linux .Namespaces [index ]
390+ if ! namespaceValid (ns ) {
391+ msgs = append (msgs , fmt .Sprintf ("namespace %v is invalid." , ns ))
392+ }
393+
394+ tmpItem := typeList [ns .Type ]
395+ tmpItem .num = tmpItem .num + 1
396+ if tmpItem .num > 1 {
397+ msgs = append (msgs , fmt .Sprintf ("duplicated namespace %q" , ns .Type ))
398+ }
399+
400+ if len (ns .Path ) == 0 {
401+ tmpItem .newExist = true
396402 }
403+ typeList [ns .Type ] = tmpItem
397404 }
398405
399- if (len (v .spec .Linux .UIDMappings ) > 0 || len (v .spec .Linux .GIDMappings ) > 0 ) && ! userExists {
406+ if (len (v .spec .Linux .UIDMappings ) > 0 || len (v .spec .Linux .GIDMappings ) > 0 ) && ! typeList [ rspec . UserNamespace ]. newExist {
400407 msgs = append (msgs , "UID/GID mappings requires a new User namespace to be specified as well" )
401408 } else if len (v .spec .Linux .UIDMappings ) > 5 {
402409 msgs = append (msgs , "Only 5 UID mappings are allowed (linux kernel restriction)." )
@@ -405,17 +412,17 @@ func (v *Validator) CheckLinux() (msgs []string) {
405412 }
406413
407414 for k := range v .spec .Linux .Sysctl {
408- if strings .HasPrefix (k , "net." ) && ! netExists {
415+ if strings .HasPrefix (k , "net." ) && ! typeList [ rspec . NetworkNamespace ]. newExist {
409416 msgs = append (msgs , fmt .Sprintf ("Sysctl %v requires a new Network namespace to be specified as well" , k ))
410417 }
411418 if strings .HasPrefix (k , "fs.mqueue." ) {
412- if ! mountExists || ! ipcExists {
419+ if ! typeList [ rspec . MountNamespace ]. newExist || ! typeList [ rspec . IPCNamespace ]. newExist {
413420 msgs = append (msgs , fmt .Sprintf ("Sysctl %v requires a new IPC namespace and Mount namespace to be specified as well" , k ))
414421 }
415422 }
416423 }
417424
418- if v .spec .Platform .OS == "linux" && ! utsExists && v .spec .Hostname != "" {
425+ if v .spec .Platform .OS == "linux" && ! typeList [ rspec . UTSNamespace ]. newExist && v .spec .Hostname != "" {
419426 msgs = append (msgs , fmt .Sprintf ("On Linux, hostname requires a new UTS namespace to be specified as well" ))
420427 }
421428
0 commit comments