@@ -13,7 +13,6 @@ import (
1313 "regexp"
1414 "runtime"
1515 "strings"
16- "syscall"
1716 "unicode"
1817 "unicode/utf8"
1918
@@ -590,189 +589,6 @@ func (v *Validator) CheckPlatform() (errs error) {
590589 return
591590}
592591
593- // CheckLinux checks v.spec.Linux
594- func (v * Validator ) CheckLinux () (errs error ) {
595- logrus .Debugf ("check linux" )
596-
597- if v .spec .Linux == nil {
598- return
599- }
600-
601- var nsTypeList = map [rspec.LinuxNamespaceType ]struct {
602- num int
603- newExist bool
604- }{
605- rspec .PIDNamespace : {0 , false },
606- rspec .NetworkNamespace : {0 , false },
607- rspec .MountNamespace : {0 , false },
608- rspec .IPCNamespace : {0 , false },
609- rspec .UTSNamespace : {0 , false },
610- rspec .UserNamespace : {0 , false },
611- rspec .CgroupNamespace : {0 , false },
612- }
613-
614- for index := 0 ; index < len (v .spec .Linux .Namespaces ); index ++ {
615- ns := v .spec .Linux .Namespaces [index ]
616- if ns .Path != "" && ! osFilepath .IsAbs (v .platform , ns .Path ) {
617- errs = multierror .Append (errs , specerror .NewError (specerror .NSPathAbs , fmt .Errorf ("namespace.path %q is not an absolute path" , ns .Path ), rspec .Version ))
618- }
619-
620- tmpItem := nsTypeList [ns .Type ]
621- tmpItem .num = tmpItem .num + 1
622- if tmpItem .num > 1 {
623- errs = multierror .Append (errs , specerror .NewError (specerror .NSErrorOnDup , fmt .Errorf ("duplicated namespace %q" , ns .Type ), rspec .Version ))
624- }
625-
626- if len (ns .Path ) == 0 {
627- tmpItem .newExist = true
628- }
629- nsTypeList [ns .Type ] = tmpItem
630- }
631-
632- if (len (v .spec .Linux .UIDMappings ) > 0 || len (v .spec .Linux .GIDMappings ) > 0 ) && ! nsTypeList [rspec .UserNamespace ].newExist {
633- errs = multierror .Append (errs , errors .New ("the UID/GID mappings requires a new User namespace to be specified as well" ))
634- }
635-
636- for k := range v .spec .Linux .Sysctl {
637- if strings .HasPrefix (k , "net." ) && ! nsTypeList [rspec .NetworkNamespace ].newExist {
638- errs = multierror .Append (errs , fmt .Errorf ("sysctl %v requires a new Network namespace to be specified as well" , k ))
639- }
640- if strings .HasPrefix (k , "fs.mqueue." ) {
641- if ! nsTypeList [rspec .MountNamespace ].newExist || ! nsTypeList [rspec .IPCNamespace ].newExist {
642- errs = multierror .Append (errs , fmt .Errorf ("sysctl %v requires a new IPC namespace and Mount namespace to be specified as well" , k ))
643- }
644- }
645- }
646-
647- if v .platform == "linux" && ! nsTypeList [rspec .UTSNamespace ].newExist && v .spec .Hostname != "" {
648- errs = multierror .Append (errs , fmt .Errorf ("on Linux, hostname requires a new UTS namespace to be specified as well" ))
649- }
650-
651- // Linux devices validation
652- devList := make (map [string ]bool )
653- devTypeList := make (map [string ]bool )
654- for index := 0 ; index < len (v .spec .Linux .Devices ); index ++ {
655- device := v .spec .Linux .Devices [index ]
656- if ! deviceValid (device ) {
657- errs = multierror .Append (errs , fmt .Errorf ("device %v is invalid" , device ))
658- }
659-
660- if _ , exists := devList [device .Path ]; exists {
661- errs = multierror .Append (errs , fmt .Errorf ("device %s is duplicated" , device .Path ))
662- } else {
663- var rootfsPath string
664- if filepath .IsAbs (v .spec .Root .Path ) {
665- rootfsPath = v .spec .Root .Path
666- } else {
667- rootfsPath = filepath .Join (v .bundlePath , v .spec .Root .Path )
668- }
669- absPath := filepath .Join (rootfsPath , device .Path )
670- fi , err := os .Stat (absPath )
671- if os .IsNotExist (err ) {
672- devList [device .Path ] = true
673- } else if err != nil {
674- errs = multierror .Append (errs , err )
675- } else {
676- fStat , ok := fi .Sys ().(* syscall.Stat_t )
677- if ! ok {
678- errs = multierror .Append (errs , specerror .NewError (specerror .DevicesAvailable ,
679- fmt .Errorf ("cannot determine state for device %s" , device .Path ), rspec .Version ))
680- continue
681- }
682- var devType string
683- switch fStat .Mode & syscall .S_IFMT {
684- case syscall .S_IFCHR :
685- devType = "c"
686- case syscall .S_IFBLK :
687- devType = "b"
688- case syscall .S_IFIFO :
689- devType = "p"
690- default :
691- devType = "unmatched"
692- }
693- if devType != device .Type || (devType == "c" && device .Type == "u" ) {
694- errs = multierror .Append (errs , specerror .NewError (specerror .DevicesFileNotMatch ,
695- fmt .Errorf ("unmatched %s already exists in filesystem" , device .Path ), rspec .Version ))
696- continue
697- }
698- if devType != "p" {
699- dev := fStat .Rdev
700- major := (dev >> 8 ) & 0xfff
701- minor := (dev & 0xff ) | ((dev >> 12 ) & 0xfff00 )
702- if int64 (major ) != device .Major || int64 (minor ) != device .Minor {
703- errs = multierror .Append (errs , specerror .NewError (specerror .DevicesFileNotMatch ,
704- fmt .Errorf ("unmatched %s already exists in filesystem" , device .Path ), rspec .Version ))
705- continue
706- }
707- }
708- if device .FileMode != nil {
709- expectedPerm := * device .FileMode & os .ModePerm
710- actualPerm := fi .Mode () & os .ModePerm
711- if expectedPerm != actualPerm {
712- errs = multierror .Append (errs , specerror .NewError (specerror .DevicesFileNotMatch ,
713- fmt .Errorf ("unmatched %s already exists in filesystem" , device .Path ), rspec .Version ))
714- continue
715- }
716- }
717- if device .UID != nil {
718- if * device .UID != fStat .Uid {
719- errs = multierror .Append (errs , specerror .NewError (specerror .DevicesFileNotMatch ,
720- fmt .Errorf ("unmatched %s already exists in filesystem" , device .Path ), rspec .Version ))
721- continue
722- }
723- }
724- if device .GID != nil {
725- if * device .GID != fStat .Gid {
726- errs = multierror .Append (errs , specerror .NewError (specerror .DevicesFileNotMatch ,
727- fmt .Errorf ("unmatched %s already exists in filesystem" , device .Path ), rspec .Version ))
728- continue
729- }
730- }
731- }
732- }
733-
734- // unify u->c when comparing, they are synonyms
735- var devID string
736- if device .Type == "u" {
737- devID = fmt .Sprintf ("%s:%d:%d" , "c" , device .Major , device .Minor )
738- } else {
739- devID = fmt .Sprintf ("%s:%d:%d" , device .Type , device .Major , device .Minor )
740- }
741-
742- if _ , exists := devTypeList [devID ]; exists {
743- logrus .Warnf ("%v" , specerror .NewError (specerror .DevicesErrorOnDup , fmt .Errorf ("type:%s, major:%d and minor:%d for linux devices is duplicated" , device .Type , device .Major , device .Minor ), rspec .Version ))
744- } else {
745- devTypeList [devID ] = true
746- }
747- }
748-
749- if v .spec .Linux .Resources != nil {
750- errs = multierror .Append (errs , v .CheckLinuxResources ())
751- }
752-
753- for _ , maskedPath := range v .spec .Linux .MaskedPaths {
754- if ! strings .HasPrefix (maskedPath , "/" ) {
755- errs = multierror .Append (errs ,
756- specerror .NewError (
757- specerror .MaskedPathsAbs ,
758- fmt .Errorf ("maskedPath %v is not an absolute path" , maskedPath ),
759- rspec .Version ))
760- }
761- }
762-
763- for _ , readonlyPath := range v .spec .Linux .ReadonlyPaths {
764- if ! strings .HasPrefix (readonlyPath , "/" ) {
765- errs = multierror .Append (errs ,
766- specerror .NewError (
767- specerror .ReadonlyPathsAbs ,
768- fmt .Errorf ("readonlyPath %v is not an absolute path" , readonlyPath ),
769- rspec .Version ))
770- }
771- }
772-
773- return
774- }
775-
776592// CheckLinuxResources checks v.spec.Linux.Resources
777593func (v * Validator ) CheckLinuxResources () (errs error ) {
778594 logrus .Debugf ("check linux resources" )
0 commit comments