github.com/NeowayLabs/nash@v0.2.2-0.20200127205349-a227041ffd50/internal/sh/shell_linux_test.go (about) 1 // +build linux 2 3 package sh_test 4 5 import ( 6 "bytes" 7 "fmt" 8 "io/ioutil" 9 "os" 10 "os/exec" 11 "strings" 12 "testing" 13 ) 14 15 var ( 16 enableUserNS bool 17 ) 18 19 func init() { 20 const usernsOk = "1" 21 const kernelcfg = "CONFIG_USER_NS" 22 23 logUsernsDetection := func(err error) { 24 if enableUserNS { 25 fmt.Printf("Linux user namespaces enabled!") 26 return 27 } 28 29 fmt.Printf("Warning: Impossible to know if kernel support USER namespace.\n") 30 fmt.Printf("Warning: USER namespace tests will not run.\n") 31 if err != nil { 32 fmt.Printf("ERROR: %s\n", err) 33 } 34 } 35 36 usernsCfg := "/proc/sys/kernel/unprivileged_userns_clone" 37 val, permerr := ioutil.ReadFile(usernsCfg) 38 39 // Travis build doesn't support /proc/config.gz but kernel has userns 40 if os.Getenv("TRAVIS_BUILD") == "1" { 41 enableUserNS = permerr == nil && string(val) == usernsOk 42 logUsernsDetection(permerr) 43 return 44 } 45 46 if permerr == nil { 47 enableUserNS = string(val) == usernsOk 48 logUsernsDetection(permerr) 49 return 50 } 51 52 // old kernels dont have sysctl configurations 53 // than just checking the /proc/config suffices 54 usernsCmd := exec.Command("zgrep", kernelcfg, "/proc/config.gz") 55 56 content, err := usernsCmd.CombinedOutput() 57 if err != nil { 58 enableUserNS = false 59 logUsernsDetection(fmt.Errorf("Failed to get kernel config: %s", err)) 60 return 61 } 62 63 cfgVal := strings.Trim(string(content), "\n\t ") 64 enableUserNS = cfgVal == kernelcfg+"=y" 65 logUsernsDetection(fmt.Errorf("%s not enabled in kernel config", kernelcfg)) 66 } 67 68 func TestExecuteRforkUserNS(t *testing.T) { 69 if !enableUserNS { 70 t.Skip("User namespace not enabled") 71 return 72 } 73 74 f, teardown := setup(t) 75 defer teardown() 76 77 err := f.shell.Exec("rfork test", ` 78 rfork u { 79 id -u 80 } 81 `) 82 83 if err != nil { 84 t.Error(err) 85 return 86 } 87 88 if string(f.shellOut.Bytes()) != "0\n" { 89 t.Errorf("User namespace not supported in your kernel: %s", string(f.shellOut.Bytes())) 90 return 91 } 92 } 93 94 func TestExecuteRforkEnvVars(t *testing.T) { 95 if !enableUserNS { 96 t.Skip("User namespace not enabled") 97 return 98 } 99 100 f, teardown := setup(t) 101 defer teardown() 102 103 sh := f.shell 104 105 err := sh.Exec("test env", `var abra = "cadabra" 106 setenv abra 107 rfork up { 108 echo $abra 109 }`) 110 111 if err != nil { 112 t.Error(err) 113 return 114 } 115 } 116 117 func TestExecuteRforkUserNSNested(t *testing.T) { 118 if !enableUserNS { 119 t.Skip("User namespace not enabled") 120 return 121 } 122 123 var out bytes.Buffer 124 f, teardown := setup(t) 125 defer teardown() 126 127 sh := f.shell 128 129 sh.SetStdout(&out) 130 131 err := sh.Exec("rfork userns nested", ` 132 rfork u { 133 id -u 134 rfork u { 135 id -u 136 } 137 } 138 `) 139 140 if err != nil { 141 t.Error(err) 142 return 143 } 144 145 if string(out.Bytes()) != "0\n0\n" { 146 t.Errorf("User namespace not supported in your kernel") 147 return 148 } 149 }