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  }