Skip to content
This repository has been archived by the owner on Apr 21, 2021. It is now read-only.

Commit

Permalink
validation: add a new test for NSInheritWithoutType
Browse files Browse the repository at this point in the history
This test is to check for NSInheritWithoutType, i.e. "If a namespace
type is not specified in the namespaces array, the container MUST
inherit the runtime namespace of that type".

See also opencontainers#572

Signed-off-by: Dongsu Park <[email protected]>
  • Loading branch information
Dongsu Park committed Apr 17, 2018
1 parent 5ce0ff8 commit d7985e3
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 0 deletions.
8 changes: 8 additions & 0 deletions generate/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,14 @@ func (g *Generator) RemoveAnnotation(key string) {
delete(g.Config.Annotations, key)
}

// RemoveHostname removes g.Config.Hostname, setting it to an empty string.
func (g *Generator) RemoveHostname() {
if g.Config == nil {
return
}
g.Config.Hostname = ""
}

// SetProcessConsoleSize sets g.Config.Process.ConsoleSize.
func (g *Generator) SetProcessConsoleSize(width, height uint) {
g.initConfigProcessConsoleSize()
Expand Down
88 changes: 88 additions & 0 deletions validation/linux_ns_itype.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package main

import (
"fmt"
"os"
"path/filepath"
"runtime"

"github.com/mndrix/tap-go"
rspec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/specerror"
"github.com/opencontainers/runtime-tools/validation/util"
)

func testNamespaceInheritType(t *tap.T) error {
g, err := util.GetDefaultGenerator()
if err != nil {
return err
}

// Obtain a map for host (runtime) namespace, and remove every namespace
// from the generated config, to be able to see if each container namespace
// becomes inherited from its corresponding host namespace.
hostNsPath := fmt.Sprintf("/proc/%d/ns", os.Getpid())
hostNsInodes := map[string]string{}
for _, nsName := range util.ProcNamespaces {
nsInode, err := os.Readlink(filepath.Join(hostNsPath, nsName))
if err != nil {
return err
}
hostNsInodes[nsName] = nsInode

if err := g.RemoveLinuxNamespace(util.GetRuntimeToolsNamespace(nsName)); err != nil {
return err
}
}

// We need to remove hostname to avoid test failures when not creating UTS namespace
g.RemoveHostname()

err = util.RuntimeOutsideValidate(g, func(config *rspec.Spec, state *rspec.State) error {
containerNsPath := fmt.Sprintf("/proc/%d/ns", state.Pid)

for _, nsName := range util.ProcNamespaces {
nsInode, err := os.Readlink(filepath.Join(containerNsPath, nsName))
if err != nil {
return err
}

t.Ok(hostNsInodes[nsName] == nsInode, fmt.Sprintf("inherit namespace %s without type", nsName))
if hostNsInodes[nsName] != nsInode {
specErr := specerror.NewError(specerror.NSInheritWithoutType,
fmt.Errorf("namespace %s (inode %s) does not inherit runtime namespace %s", nsName, nsInode, hostNsInodes[nsName]),
rspec.Version)
diagnostic := map[string]interface{}{
"expected": hostNsInodes[nsName],
"actual": nsInode,
"namespace type": nsName,
"level": specErr.(*specerror.Error).Err.Level,
"reference": specErr.(*specerror.Error).Err.Reference,
}
t.YAML(diagnostic)

continue
}
}

return nil
})

return err
}

func main() {
t := tap.New()
t.Header(0)

if "linux" != runtime.GOOS {
t.Skip(1, fmt.Sprintf("linux-specific namespace test"))
}

err := testNamespaceInheritType(t)
if err != nil {
util.Fatal(err)
}

t.AutoPlan()
}
16 changes: 16 additions & 0 deletions validation/util/linux_namespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,19 @@ var ProcNamespaces = []string{
"user",
"uts",
}

// GetRuntimeToolsNamespace converts a namespace type string for /proc into
// a string for runtime-tools. It deals with exceptional cases of "net" and
// "mnt", because those strings cannot be recognized by mapStrToNamespace(),
// which actually expects "network" and "mount" respectively.
func GetRuntimeToolsNamespace(ns string) string {
switch ns {
case "net":
return "network"
case "mnt":
return "mount"
}

// In other cases, return just the original string
return ns
}

0 comments on commit d7985e3

Please sign in to comment.