diff --git a/man/ocitools-validate.1.md b/man/ocitools-validate.1.md index 2f171cc4c..b054a10be 100644 --- a/man/ocitools-validate.1.md +++ b/man/ocitools-validate.1.md @@ -18,6 +18,9 @@ Validate an OCI bundle **--path=PATH Path to bundle +**--hooks** + Specify check hooks exists and executable on host, default is false. + # SEE ALSO **ocitools**(1) diff --git a/validate.go b/validate.go index f5a795958..108afa1ea 100644 --- a/validate.go +++ b/validate.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "path" + "path/filepath" "reflect" "regexp" "strings" @@ -16,6 +17,7 @@ import ( var bundleValidateFlags = []cli.Flag{ cli.StringFlag{Name: "path", Usage: "path to a bundle"}, + cli.BoolFlag{Name: "hooks", Usage: "Specify check hooks on host, default is false"}, } var ( @@ -72,18 +74,20 @@ var bundleValidateCommand = cli.Command{ logrus.Fatalf("Rootfs: %v is not a directory.", spec.Root.Path) } - bundleValidate(spec, rootfsPath) + hooksCheck := context.Bool("hooks") + bundleValidate(spec, rootfsPath, hooksCheck) logrus.Infof("Bundle validation succeeded.") }, } -func bundleValidate(spec rspec.Spec, rootfs string) { +func bundleValidate(spec rspec.Spec, rootfs string, hooksCheck bool) { checkMandatoryField(spec) checkSemVer(spec.Version) checkPlatform(spec.Platform) checkProcess(spec.Process, rootfs) checkMounts(spec.Mounts, rootfs) checkLinux(spec.Linux, rootfs) + checkHooks(spec.Hooks, hooksCheck) } func checkSemVer(version string) { @@ -128,6 +132,30 @@ func checkPlatform(platform rspec.Platform) { logrus.Fatalf("Operation system '%s' of the bundle is not supported yet.", platform.OS) } +func checkHooks(hooks rspec.Hooks, hooksCheck bool) { + checkEventHookPaths("pre-start", hooks.Prestart, hooksCheck) + checkEventHookPaths("post-start", hooks.Poststart, hooksCheck) + checkEventHookPaths("post-stop", hooks.Poststop, hooksCheck) +} + +func checkEventHookPaths(hookType string, hooks []rspec.Hook, hooksCheck bool) { + for _, hook := range hooks { + if !filepath.IsAbs(hook.Path) { + logrus.Fatalf("The %s hook %v: is not absolute path", hookType, hook.Path) + } + + if hooksCheck { + fi, err := os.Stat(hook.Path) + if err != nil { + logrus.Fatalf("Cannot find %s hook: %v", hookType, hook.Path) + } + if fi.Mode()&0111 == 0 { + logrus.Fatalf("The %s hook %v: is not executable", hookType, hook.Path) + } + } + } +} + func checkProcess(process rspec.Process, rootfs string) { for index := 0; index < len(process.Capabilities); index++ { capability := process.Capabilities[index]