@@ -576,17 +576,17 @@ func validateGIDMappings(spec *rspec.Spec) error {
576
576
return validateIDMappings (spec .Linux .GIDMappings , "/proc/self/gid_map" , "linux.gidMappings" )
577
577
}
578
578
579
- func mountMatch (specMount rspec.Mount , sysMount rspec.Mount ) error {
580
- if filepath .Clean (specMount .Destination ) != sysMount .Destination {
581
- return fmt .Errorf ("mount destination expected: %v, actual: %v" , specMount .Destination , sysMount .Destination )
579
+ func mountMatch (configMount rspec.Mount , sysMount rspec.Mount ) error {
580
+ if filepath .Clean (configMount .Destination ) != sysMount .Destination {
581
+ return fmt .Errorf ("mount destination expected: %v, actual: %v" , configMount .Destination , sysMount .Destination )
582
582
}
583
583
584
- if specMount .Type != sysMount .Type {
585
- return fmt .Errorf ("mount %v type expected: %v, actual: %v" , specMount .Destination , specMount .Type , sysMount .Type )
584
+ if configMount .Type != sysMount .Type {
585
+ return fmt .Errorf ("mount %v type expected: %v, actual: %v" , configMount .Destination , configMount .Type , sysMount .Type )
586
586
}
587
587
588
- if filepath .Clean (specMount .Source ) != sysMount .Source {
589
- return fmt .Errorf ("mount %v source expected: %v, actual: %v" , specMount .Destination , specMount .Source , sysMount .Source )
588
+ if filepath .Clean (configMount .Source ) != sysMount .Source {
589
+ return fmt .Errorf ("mount %v source expected: %v, actual: %v" , configMount .Destination , configMount .Source , sysMount .Source )
590
590
}
591
591
592
592
return nil
@@ -608,21 +608,77 @@ func validateMountsExist(spec *rspec.Spec) error {
608
608
mountsMap [mountInfo .Mountpoint ] = append (mountsMap [mountInfo .Mountpoint ], m )
609
609
}
610
610
611
- for _ , specMount := range spec .Mounts {
612
- if specMount .Type == "bind" || specMount .Type == "rbind" {
611
+ for _ , configMount := range spec .Mounts {
612
+ if configMount .Type == "bind" || configMount .Type == "rbind" {
613
613
// TODO: add bind or rbind check.
614
614
continue
615
615
}
616
616
617
617
found := false
618
- for _ , sysMount := range mountsMap [filepath .Clean (specMount .Destination )] {
619
- if err := mountMatch (specMount , sysMount ); err == nil {
618
+ for _ , sysMount := range mountsMap [filepath .Clean (configMount .Destination )] {
619
+ if err := mountMatch (configMount , sysMount ); err == nil {
620
620
found = true
621
621
break
622
622
}
623
623
}
624
624
if ! found {
625
- return fmt .Errorf ("Expected mount %v does not exist" , specMount )
625
+ return fmt .Errorf ("Expected mount %v does not exist" , configMount )
626
+ }
627
+ }
628
+
629
+ return nil
630
+ }
631
+
632
+ func validateMountsOrder (spec * rspec.Spec ) error {
633
+ if runtime .GOOS == "windows" {
634
+ logrus .Warnf ("mounts order validation not yet implemented for OS %q" , runtime .GOOS )
635
+ return nil
636
+ }
637
+
638
+ mountInfos , err := mount .GetMounts ()
639
+ if err != nil {
640
+ return err
641
+ }
642
+
643
+ type mountOrder struct {
644
+ Order int
645
+ Root string
646
+ Dest string
647
+ Source string
648
+ }
649
+ mountsMap := make (map [string ][]mountOrder )
650
+ for i , mountInfo := range mountInfos {
651
+ m := mountOrder {
652
+ Order : i ,
653
+ Root : mountInfo .Root ,
654
+ Dest : mountInfo .Mountpoint ,
655
+ Source : mountInfo .Source ,
656
+ }
657
+ mountsMap [mountInfo .Mountpoint ] = append (mountsMap [mountInfo .Mountpoint ], m )
658
+ }
659
+ current := - 1
660
+ for i , configMount := range spec .Mounts {
661
+ mounts := mountsMap [configMount .Destination ]
662
+ if len (mounts ) == 0 {
663
+ return fmt .Errorf ("Mounts[%d] %s is not mounted in order" , i , configMount .Destination )
664
+ }
665
+ for j , mount := range mounts {
666
+ source := mount .Source
667
+ for _ , option := range configMount .Options {
668
+ if option == "bind" || option == "rbind" {
669
+ source = mount .Root
670
+ break
671
+ }
672
+ }
673
+ if source == configMount .Source {
674
+ if current > mount .Order {
675
+ return fmt .Errorf ("Mounts[%d] %s is not mounted in order" , i , configMount .Destination )
676
+ }
677
+ current = mount .Order
678
+ // in order to deal with dup mount elements
679
+ mountsMap [configMount .Destination ] = append (mountsMap [configMount .Destination ][:j ], mountsMap [configMount .Destination ][j + 1 :]... )
680
+ break
681
+ }
626
682
}
627
683
}
628
684
@@ -658,6 +714,10 @@ func run(context *cli.Context) error {
658
714
test : validateMountsExist ,
659
715
description : "mounts" ,
660
716
},
717
+ {
718
+ test : validateMountsOrder ,
719
+ description : "mounts order" ,
720
+ },
661
721
}
662
722
663
723
linuxValidations := []validation {
0 commit comments