Skip to content

Commit f1ff4d0

Browse files
author
Ma Shimiao
committed
validate: add mount type check
Signed-off-by: Ma Shimiao <mashimiao.fnst@cn.fujitsu.com>
1 parent aa9cba2 commit f1ff4d0

3 files changed

Lines changed: 80 additions & 14 deletions

File tree

completions/bash/ocitools

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ _ocitools_validate() {
253253

254254
case "$cur" in
255255
-*)
256-
COMPREPLY=( $( compgen -W "--hooks --path --help" -- "$cur" ) )
256+
COMPREPLY=( $( compgen -W "--host-specific --path --help" -- "$cur" ) )
257257
;;
258258
esac
259259

man/ocitools-validate.1.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,15 @@ Validate an OCI bundle
1818
**--path=PATH
1919
Path to bundle
2020

21-
**--hooks**
22-
Check specified hooks exist and are executable on the host.
21+
**--host-specific**
22+
Check host specific configs.
23+
By default, validation only tests for compatibility with a hypothetical host.
24+
With this flag, validation will also run more specific tests to see whether
25+
the current host is capable of launching a container from the configuration.
26+
For example, validating a compliant Windows configuration on a Linux machine
27+
will pass without this flag ("there may be a Windows host capable of
28+
launching this container"), but will fail with it ("this host is not capable
29+
of launching this container").
2330

2431
# SEE ALSO
2532
**ocitools**(1)

validate.go

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"bufio"
45
"encoding/json"
56
"fmt"
67
"io/ioutil"
@@ -20,7 +21,7 @@ import (
2021

2122
var bundleValidateFlags = []cli.Flag{
2223
cli.StringFlag{Name: "path", Value: ".", Usage: "path to a bundle"},
23-
cli.BoolFlag{Name: "hooks", Usage: "Check specified hooks exist and are executable on the host."},
24+
cli.BoolFlag{Name: "host-specific", Usage: "Check host specific configs."},
2425
}
2526

2627
var (
@@ -79,20 +80,21 @@ var bundleValidateCommand = cli.Command{
7980
return fmt.Errorf("The root path %q is not a directory.", rootfsPath)
8081
}
8182

82-
hooksCheck := context.Bool("hooks")
83-
bundleValidate(spec, rootfsPath, hooksCheck)
83+
hostCheck := context.Bool("host-specific")
84+
bundleValidate(spec, rootfsPath, hostCheck)
8485
logrus.Infof("Bundle validation succeeded.")
8586
return nil
8687
},
8788
}
8889

89-
func bundleValidate(spec rspec.Spec, rootfs string, hooksCheck bool) {
90+
func bundleValidate(spec rspec.Spec, rootfs string, hostCheck bool) {
9091
checkMandatoryField(spec)
9192
checkSemVer(spec.Version)
9293
checkPlatform(spec.Platform)
9394
checkProcess(spec.Process, rootfs)
95+
checkMounts(spec, hostCheck)
9496
checkLinux(spec)
95-
checkHooks(spec.Hooks, hooksCheck)
97+
checkHooks(spec.Hooks, hostCheck)
9698
}
9799

98100
func checkSemVer(version string) {
@@ -129,19 +131,19 @@ func checkPlatform(platform rspec.Platform) {
129131
logrus.Fatalf("Operation system %q of the bundle is not supported yet.", platform.OS)
130132
}
131133

132-
func checkHooks(hooks rspec.Hooks, hooksCheck bool) {
133-
checkEventHooks("pre-start", hooks.Prestart, hooksCheck)
134-
checkEventHooks("post-start", hooks.Poststart, hooksCheck)
135-
checkEventHooks("post-stop", hooks.Poststop, hooksCheck)
134+
func checkHooks(hooks rspec.Hooks, hostCheck bool) {
135+
checkEventHooks("pre-start", hooks.Prestart, hostCheck)
136+
checkEventHooks("post-start", hooks.Poststart, hostCheck)
137+
checkEventHooks("post-stop", hooks.Poststop, hostCheck)
136138
}
137139

138-
func checkEventHooks(hookType string, hooks []rspec.Hook, hooksCheck bool) {
140+
func checkEventHooks(hookType string, hooks []rspec.Hook, hostCheck bool) {
139141
for _, hook := range hooks {
140142
if !filepath.IsAbs(hook.Path) {
141143
logrus.Fatalf("The %s hook %v: is not absolute path", hookType, hook.Path)
142144
}
143145

144-
if hooksCheck {
146+
if hostCheck {
145147
fi, err := os.Stat(hook.Path)
146148
if err != nil {
147149
logrus.Fatalf("Cannot find %s hook: %v", hookType, hook.Path)
@@ -192,6 +194,63 @@ func checkProcess(process rspec.Process, rootfs string) {
192194
}
193195
}
194196

197+
func supportedMountTypes(OS string, hostCheck bool) (map[string]bool, error) {
198+
supportedTypes := make(map[string]bool)
199+
200+
if OS != "linux" && OS != "windows" {
201+
logrus.Warnf("%v is not supported to check mount type", OS)
202+
return nil, nil
203+
} else if OS == "windows" {
204+
supportedTypes["ntfs"] = true
205+
return supportedTypes, nil
206+
}
207+
208+
if hostCheck {
209+
f, err := os.Open("/proc/filesystems")
210+
if err != nil {
211+
return nil, err
212+
}
213+
defer f.Close()
214+
215+
s := bufio.NewScanner(f)
216+
for s.Scan() {
217+
if err := s.Err(); err != nil {
218+
return supportedTypes, err
219+
}
220+
221+
text := s.Text()
222+
parts := strings.Split(text, "\t")
223+
if len(parts) > 1 {
224+
supportedTypes[parts[1]] = true
225+
} else {
226+
supportedTypes[parts[0]] = true
227+
}
228+
}
229+
230+
supportedTypes["bind"] = true
231+
232+
return supportedTypes, nil
233+
} else {
234+
logrus.Warn("Checking linux mount types without --host-specific is not supported yet")
235+
return nil, nil
236+
}
237+
}
238+
239+
func checkMounts(spec rspec.Spec, hostCheck bool) {
240+
supportedTypes, err := supportedMountTypes(spec.Platform.OS, hostCheck)
241+
if err != nil {
242+
logrus.Fatal(err)
243+
}
244+
245+
if supportedTypes != nil {
246+
for _, mount := range spec.Mounts {
247+
if !supportedTypes[mount.Type] {
248+
logrus.Fatalf("Unsupported mount type %q", mount.Type)
249+
}
250+
}
251+
}
252+
}
253+
195254
//Linux only
196255
func checkLinux(spec rspec.Spec) {
197256
utsExists := false

0 commit comments

Comments
 (0)