Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions cmd/runtimetest/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -1091,14 +1091,32 @@ func mountMatch(configMount rspec.Mount, sysMount *mount.Info) error {
return fmt.Errorf("mount destination expected: %v, actual: %v", configMount.Destination, sys.Destination)
}

if configMount.Type != sys.Type {
isBind := false
for _, opt := range configMount.Options {
if opt == "bind" || opt == "rbind" {
isBind = true
break
}
}
// Type is an optional field in the spec: only check if it is set
if configMount.Type != "" && configMount.Type != sys.Type {
return fmt.Errorf("mount %v type expected: %v, actual: %v", configMount.Destination, configMount.Type, sys.Type)
}

if filepath.Clean(configMount.Source) != sys.Source {
return fmt.Errorf("mount %v source expected: %v, actual: %v", configMount.Destination, configMount.Source, sys.Source)
// For bind mounts, the source is not the block device but the path on the host that is being bind mounted.
// sysMount.Root is that path.
if isBind {
// Source is an optional field in the spec: only check if it is set
// We only test the base name here, in case the tests are being run in a chroot environment
if configMount.Source != "" && filepath.Base(configMount.Source) != filepath.Base(sysMount.Root) {
return fmt.Errorf("mount %v source expected: %v, actual: %v", configMount.Destination, filepath.Base(configMount.Source), filepath.Base(sysMount.Root))
}
} else {
// Source is an optional field in the spec: only check if it is set
if configMount.Source != "" && filepath.Clean(configMount.Source) != sys.Source {
return fmt.Errorf("mount %v source expected: %v, actual: %v", configMount.Destination, configMount.Source, sys.Source)
}
}

return nil
}

Expand Down
85 changes: 74 additions & 11 deletions validation/mounts/mounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,85 @@ import (
)

func main() {
defaultOptions := []string{
"nosuid",
"strictatime",
"mode=755",
"size=1k",
}

// Different combinations of mount types, mount options, mount propagation modes
mounts := []rspec.Mount{
rspec.Mount{
Destination: "/tmp/test-shared",
Type: "tmpfs",
Source: "tmpfs",
Options: []string{"shared"},
},
rspec.Mount{
Destination: "/tmp/test-slave",
Type: "tmpfs",
Source: "tmpfs",
Options: []string{"slave"},
},
rspec.Mount{
Destination: "/tmp/test-private",
Type: "tmpfs",
Source: "tmpfs",
Options: []string{"private"},
},
rspec.Mount{
Destination: "/mnt/etc-shared",
Source: "/etc",
Options: []string{"bind", "shared"},
},
rspec.Mount{
Destination: "/mnt/etc-rshared",
Source: "/etc",
Options: []string{"rbind", "rshared"},
},
rspec.Mount{
Destination: "/mnt/etc-slave",
Source: "/etc",
Options: []string{"bind", "slave"},
},
rspec.Mount{
Destination: "/mnt/etc-rslave",
Source: "/etc",
Options: []string{"rbind", "rslave"},
},
rspec.Mount{
Destination: "/mnt/etc-private",
Source: "/etc",
Options: []string{"bind", "private"},
},
rspec.Mount{
Destination: "/mnt/etc-rprivate",
Source: "/etc",
Options: []string{"rbind", "rprivate"},
},
rspec.Mount{
Destination: "/mnt/etc-unbindable",
Source: "/etc",
Options: []string{"bind", "unbindable"},
},
rspec.Mount{
Destination: "/mnt/etc-runbindable",
Source: "/etc",
Options: []string{"rbind", "runbindable"},
},
}

g, err := util.GetDefaultGenerator()
if err != nil {
util.Fatal(err)
}
mount := rspec.Mount{
Destination: "/tmp",
Type: "tmpfs",
Source: "tmpfs",
Options: []string{
"nosuid",
"strictatime",
"mode=755",
"size=1k",
},

for _, m := range mounts {
m.Options = append(defaultOptions, m.Options...)

g.AddMount(m)
}
g.AddMount(mount)
err = util.RuntimeInsideValidate(g, nil, nil)
if err != nil {
util.Fatal(err)
Expand Down