github.com/hhrutter/nomad@v0.6.0-rc2.0.20170723054333-80c4b03f0705/client/allocdir/fs_linux_test.go (about) 1 package allocdir 2 3 import ( 4 "bufio" 5 "fmt" 6 "io" 7 "io/ioutil" 8 "os" 9 "path/filepath" 10 "strings" 11 "testing" 12 13 "golang.org/x/sys/unix" 14 ) 15 16 var notFoundErr = fmt.Errorf("not found") 17 18 func isMount(path string) error { 19 file, err := os.Open("/proc/self/mounts") 20 if err != nil { 21 return err 22 } 23 defer file.Close() 24 reader := bufio.NewReaderSize(file, 64*1024) 25 const max = 100000 26 for i := 0; i < max; i++ { 27 line, err := reader.ReadString('\n') 28 if err != nil { 29 if err == io.EOF { 30 return notFoundErr 31 } 32 return err 33 } 34 parts := strings.SplitN(line, " ", 3) 35 if len(parts) != 3 { 36 return fmt.Errorf("unexpected line: %q", line) 37 } 38 if parts[1] == path { 39 // Found it! Make sure it's a tmpfs 40 if parts[0] != "tmpfs" { 41 return fmt.Errorf("unexpected fs: %q", parts[1]) 42 } 43 return nil 44 } 45 } 46 return fmt.Errorf("exceeded max mount entries (%d)", max) 47 } 48 49 // TestLinuxRootSecretDir asserts secret dir creation and removal are 50 // idempotent. 51 func TestLinuxRootSecretDir(t *testing.T) { 52 if unix.Geteuid() != 0 { 53 t.Skip("Must be run as root") 54 } 55 tmpdir, err := ioutil.TempDir("", "nomadtest-rootsecretdir") 56 if err != nil { 57 t.Fatalf("unable to create tempdir for test: %v", err) 58 } 59 defer os.RemoveAll(tmpdir) 60 61 secretsDir := filepath.Join(tmpdir, TaskSecrets) 62 63 // removing a nonexistent secrets dir should NOT error 64 if err := removeSecretDir(secretsDir); err != nil { 65 t.Fatalf("error removing nonexistent secrets dir %q: %v", secretsDir, err) 66 } 67 // run twice as it should be idemptotent 68 if err := removeSecretDir(secretsDir); err != nil { 69 t.Fatalf("error removing nonexistent secrets dir %q: %v", secretsDir, err) 70 } 71 72 // creating a secrets dir should work 73 if err := createSecretDir(secretsDir); err != nil { 74 t.Fatalf("error creating secrets dir %q: %v", secretsDir, err) 75 } 76 // creating it again should be a noop (NO error) 77 if err := createSecretDir(secretsDir); err != nil { 78 t.Fatalf("error creating secrets dir %q: %v", secretsDir, err) 79 } 80 81 // ensure it exists and is a directory 82 fi, err := os.Lstat(secretsDir) 83 if err != nil { 84 t.Fatalf("error stat'ing secrets dir %q: %v", secretsDir, err) 85 } 86 if !fi.IsDir() { 87 t.Fatalf("secrets dir %q is not a directory and should be", secretsDir) 88 } 89 if err := isMount(secretsDir); err != nil { 90 t.Fatalf("secrets dir %q is not a mount: %v", secretsDir, err) 91 } 92 93 // now remove it 94 if err := removeSecretDir(secretsDir); err != nil { 95 t.Fatalf("error removing secrets dir %q: %v", secretsDir, err) 96 } 97 98 // make sure it's gone 99 if err := isMount(secretsDir); err != notFoundErr { 100 t.Fatalf("error ensuring secrets dir %q isn't mounted: %v", secretsDir, err) 101 } 102 103 // removing again should be a noop 104 if err := removeSecretDir(secretsDir); err != nil { 105 t.Fatalf("error removing nonexistent secrets dir %q: %v", secretsDir, err) 106 } 107 } 108 109 // TestLinuxUnprivilegedSecretDir asserts secret dir creation and removal are 110 // idempotent. 111 func TestLinuxUnprivilegedSecretDir(t *testing.T) { 112 if unix.Geteuid() == 0 { 113 t.Skip("Must not be run as root") 114 } 115 tmpdir, err := ioutil.TempDir("", "nomadtest-secretdir") 116 if err != nil { 117 t.Fatalf("unable to create tempdir for test: %s", err) 118 } 119 defer os.RemoveAll(tmpdir) 120 121 secretsDir := filepath.Join(tmpdir, TaskSecrets) 122 123 // removing a nonexistent secrets dir should NOT error 124 if err := removeSecretDir(secretsDir); err != nil { 125 t.Fatalf("error removing nonexistent secrets dir %q: %v", secretsDir, err) 126 } 127 // run twice as it should be idemptotent 128 if err := removeSecretDir(secretsDir); err != nil { 129 t.Fatalf("error removing nonexistent secrets dir %q: %v", secretsDir, err) 130 } 131 132 // creating a secrets dir should work 133 if err := createSecretDir(secretsDir); err != nil { 134 t.Fatalf("error creating secrets dir %q: %v", secretsDir, err) 135 } 136 // creating it again should be a noop (NO error) 137 if err := createSecretDir(secretsDir); err != nil { 138 t.Fatalf("error creating secrets dir %q: %v", secretsDir, err) 139 } 140 141 // ensure it exists and is a directory 142 fi, err := os.Lstat(secretsDir) 143 if err != nil { 144 t.Fatalf("error stat'ing secrets dir %q: %v", secretsDir, err) 145 } 146 if !fi.IsDir() { 147 t.Fatalf("secrets dir %q is not a directory and should be", secretsDir) 148 } 149 if err := isMount(secretsDir); err != notFoundErr { 150 t.Fatalf("error ensuring secrets dir %q isn't mounted: %v", secretsDir, err) 151 } 152 153 // now remove it 154 if err := removeSecretDir(secretsDir); err != nil { 155 t.Fatalf("error removing secrets dir %q: %v", secretsDir, err) 156 } 157 158 // make sure it's gone 159 if _, err := os.Lstat(secretsDir); err == nil { 160 t.Fatalf("expected secrets dir %q to be gone but it was found", secretsDir) 161 } 162 163 // removing again should be a noop 164 if err := removeSecretDir(secretsDir); err != nil { 165 t.Fatalf("error removing nonexistent secrets dir %q: %v", secretsDir, err) 166 } 167 }