@@ -577,113 +577,91 @@ func validateGIDMappings(spec *rspec.Spec) error {
577
577
return validateIDMappings (spec .Linux .GIDMappings , "/proc/self/gid_map" , "linux.gidMappings" )
578
578
}
579
579
580
- func mountMatch (configMount rspec.Mount , sysMount rspec.Mount ) error {
581
- if filepath .Clean (configMount .Destination ) != sysMount .Destination {
582
- return fmt .Errorf ("mount destination expected: %v, actual: %v" , configMount .Destination , sysMount .Destination )
580
+ func mountMatch (configMount rspec.Mount , sysMount * mount.Info ) error {
581
+ sys := rspec.Mount {
582
+ Destination : sysMount .Mountpoint ,
583
+ Type : sysMount .Fstype ,
584
+ Source : sysMount .Source ,
583
585
}
584
586
585
- if configMount .Type != sysMount . Type {
586
- return fmt .Errorf ("mount %v type expected: %v, actual: %v" , configMount .Destination , configMount . Type , sysMount . Type )
587
+ if filepath . Clean ( configMount .Destination ) != sys . Destination {
588
+ return fmt .Errorf ("mount destination expected: %v, actual: %v" , configMount .Destination , sys . Destination )
587
589
}
588
590
589
- if filepath .Clean (configMount .Source ) != sysMount .Source {
590
- return fmt .Errorf ("mount %v source expected: %v, actual: %v" , configMount .Destination , configMount .Source , sysMount .Source )
591
+ if configMount .Type != sys .Type {
592
+ return fmt .Errorf ("mount %v type expected: %v, actual: %v" , configMount .Destination , configMount .Type , sys .Type )
593
+ }
594
+
595
+ if filepath .Clean (configMount .Source ) != sys .Source {
596
+ return fmt .Errorf ("mount %v source expected: %v, actual: %v" , configMount .Destination , configMount .Source , sys .Source )
591
597
}
592
598
593
599
return nil
594
600
}
595
601
596
- func validateMountsExist (spec * rspec.Spec ) error {
602
+ func validateMounts (spec * rspec.Spec ) error {
603
+ if runtime .GOOS == "windows" {
604
+ logrus .Warnf ("mounts validation not yet implemented for OS %q" , runtime .GOOS )
605
+ return nil
606
+ }
607
+
597
608
mountInfos , err := mount .GetMounts ()
598
609
if err != nil {
599
610
return err
600
611
}
601
612
602
- mountsMap := make (map [string ][]rspec.Mount )
603
- for _ , mountInfo := range mountInfos {
604
- m := rspec.Mount {
605
- Destination : mountInfo .Mountpoint ,
606
- Type : mountInfo .Fstype ,
607
- Source : mountInfo .Source ,
608
- }
609
- mountsMap [mountInfo .Mountpoint ] = append (mountsMap [mountInfo .Mountpoint ], m )
610
- }
611
-
612
- for _ , configMount := range spec .Mounts {
613
+ var mountErrs error
614
+ var consumedSys = make (map [int ]bool )
615
+ highestMatchedConfig := - 1
616
+ highestMatchedSystem := - 1
617
+ var j = 0
618
+ for i , configMount := range spec .Mounts {
613
619
if configMount .Type == "bind" || configMount .Type == "rbind" {
614
620
// TODO: add bind or rbind check.
615
621
continue
616
622
}
617
623
618
624
found := false
619
- for _ , sysMount := range mountsMap [ filepath . Clean ( configMount . Destination ) ] {
625
+ for k , sysMount := range mountInfos [ j : ] {
620
626
if err := mountMatch (configMount , sysMount ); err == nil {
621
627
found = true
628
+ j += k + 1
629
+ consumedSys [j - 1 ] = true
630
+ if j > highestMatchedSystem {
631
+ highestMatchedSystem = j - 1
632
+ highestMatchedConfig = i
633
+ }
622
634
break
623
635
}
624
636
}
625
637
if ! found {
626
- return fmt .Errorf ("Expected mount %v does not exist" , configMount )
627
- }
628
- }
629
-
630
- return nil
631
- }
632
-
633
- func validateMountsOrder (spec * rspec.Spec ) error {
634
- if runtime .GOOS == "windows" {
635
- logrus .Warnf ("mounts order validation not yet implemented for OS %q" , runtime .GOOS )
636
- return nil
637
- }
638
-
639
- mountInfos , err := mount .GetMounts ()
640
- if err != nil {
641
- return err
642
- }
643
-
644
- type mountOrder struct {
645
- Order int
646
- Root string
647
- Dest string
648
- Source string
649
- }
650
- mountsMap := make (map [string ][]mountOrder )
651
- for i , mountInfo := range mountInfos {
652
- m := mountOrder {
653
- Order : i ,
654
- Root : mountInfo .Root ,
655
- Dest : mountInfo .Mountpoint ,
656
- Source : mountInfo .Source ,
657
- }
658
- mountsMap [mountInfo .Mountpoint ] = append (mountsMap [mountInfo .Mountpoint ], m )
659
- }
660
- current := - 1
661
- for i , configMount := range spec .Mounts {
662
- mounts := mountsMap [configMount .Destination ]
663
- if len (mounts ) == 0 {
664
- return fmt .Errorf ("Mounts[%d] %s is not mounted in order" , i , configMount .Destination )
665
- }
666
- for j , mount := range mounts {
667
- source := mount .Source
668
- for _ , option := range configMount .Options {
669
- if option == "bind" || option == "rbind" {
670
- source = mount .Root
671
- break
638
+ if j > 0 {
639
+ for k , sysMount := range mountInfos [:j - 1 ] {
640
+ if _ , ok := consumedSys [k ]; ok {
641
+ continue
642
+ }
643
+ if err := mountMatch (configMount , sysMount ); err == nil {
644
+ found = true
645
+ break
646
+ }
672
647
}
673
648
}
674
- if source == configMount .Source {
675
- if current > mount .Order {
676
- return fmt .Errorf ("Mounts[%d] %s is not mounted in order" , i , configMount .Destination )
677
- }
678
- current = mount .Order
679
- // in order to deal with dup mount elements
680
- mountsMap [configMount .Destination ] = append (mountsMap [configMount .Destination ][:j ], mountsMap [configMount .Destination ][j + 1 :]... )
681
- break
649
+ if found {
650
+ mountErrs = multierror .Append (
651
+ mountErrs ,
652
+ fmt .Errorf (
653
+ "mounts[%d] %v mounted before mounts[%d] %v" ,
654
+ i ,
655
+ configMount ,
656
+ highestMatchedConfig ,
657
+ spec .Mounts [highestMatchedConfig ]))
658
+ } else {
659
+ mountErrs = multierror .Append (mountErrs , fmt .Errorf ("mounts[%d] %v does not exist" , i , configMount ))
682
660
}
683
661
}
684
662
}
685
663
686
- return nil
664
+ return mountErrs
687
665
}
688
666
689
667
func run (context * cli.Context ) error {
@@ -712,13 +690,9 @@ func run(context *cli.Context) error {
712
690
description : "hostname" ,
713
691
},
714
692
{
715
- test : validateMountsExist ,
693
+ test : validateMounts ,
716
694
description : "mounts" ,
717
695
},
718
- {
719
- test : validateMountsOrder ,
720
- description : "mounts order" ,
721
- },
722
696
}
723
697
724
698
linuxValidations := []validation {
0 commit comments