github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/client/allocdir/fs_linux_test.go (about)

     1  package allocdir
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  	"path/filepath"
     9  	"strings"
    10  	"testing"
    11  
    12  	"github.com/hashicorp/nomad/ci"
    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  	ci.Parallel(t)
    53  	if unix.Geteuid() != 0 {
    54  		t.Skip("Must be run as root")
    55  	}
    56  
    57  	secretsDir := filepath.Join(t.TempDir(), TaskSecrets)
    58  
    59  	// removing a nonexistent secrets dir should NOT error
    60  	if err := removeSecretDir(secretsDir); err != nil {
    61  		t.Fatalf("error removing nonexistent secrets dir %q: %v", secretsDir, err)
    62  	}
    63  	// run twice as it should be idempotent
    64  	if err := removeSecretDir(secretsDir); err != nil {
    65  		t.Fatalf("error removing nonexistent secrets dir %q: %v", secretsDir, err)
    66  	}
    67  
    68  	// creating a secrets dir should work
    69  	if err := createSecretDir(secretsDir); err != nil {
    70  		t.Fatalf("error creating secrets dir %q: %v", secretsDir, err)
    71  	}
    72  	// creating it again should be a noop (NO error)
    73  	if err := createSecretDir(secretsDir); err != nil {
    74  		t.Fatalf("error creating secrets dir %q: %v", secretsDir, err)
    75  	}
    76  
    77  	// ensure it exists and is a directory
    78  	fi, err := os.Lstat(secretsDir)
    79  	if err != nil {
    80  		t.Fatalf("error stat'ing secrets dir %q: %v", secretsDir, err)
    81  	}
    82  	if !fi.IsDir() {
    83  		t.Fatalf("secrets dir %q is not a directory and should be", secretsDir)
    84  	}
    85  	if err := isMount(secretsDir); err != nil {
    86  		t.Fatalf("secrets dir %q is not a mount: %v", secretsDir, err)
    87  	}
    88  
    89  	// now remove it
    90  	if err := removeSecretDir(secretsDir); err != nil {
    91  		t.Fatalf("error removing secrets dir %q: %v", secretsDir, err)
    92  	}
    93  
    94  	// make sure it's gone
    95  	if err := isMount(secretsDir); err != notFoundErr {
    96  		t.Fatalf("error ensuring secrets dir %q isn't mounted: %v", secretsDir, err)
    97  	}
    98  
    99  	// removing again should be a noop
   100  	if err := removeSecretDir(secretsDir); err != nil {
   101  		t.Fatalf("error removing nonexistent secrets dir %q: %v", secretsDir, err)
   102  	}
   103  }
   104  
   105  // TestLinuxUnprivilegedSecretDir asserts secret dir creation and removal are
   106  // idempotent.
   107  func TestLinuxUnprivilegedSecretDir(t *testing.T) {
   108  	ci.Parallel(t)
   109  	if unix.Geteuid() == 0 {
   110  		t.Skip("Must not be run as root")
   111  	}
   112  
   113  	secretsDir := filepath.Join(t.TempDir(), TaskSecrets)
   114  
   115  	// removing a nonexistent secrets dir should NOT error
   116  	if err := removeSecretDir(secretsDir); err != nil {
   117  		t.Fatalf("error removing nonexistent secrets dir %q: %v", secretsDir, err)
   118  	}
   119  	// run twice as it should be idempotent
   120  	if err := removeSecretDir(secretsDir); err != nil {
   121  		t.Fatalf("error removing nonexistent secrets dir %q: %v", secretsDir, err)
   122  	}
   123  
   124  	// creating a secrets dir should work
   125  	if err := createSecretDir(secretsDir); err != nil {
   126  		t.Fatalf("error creating secrets dir %q: %v", secretsDir, err)
   127  	}
   128  	// creating it again should be a noop (NO error)
   129  	if err := createSecretDir(secretsDir); err != nil {
   130  		t.Fatalf("error creating secrets dir %q: %v", secretsDir, err)
   131  	}
   132  
   133  	// ensure it exists and is a directory
   134  	fi, err := os.Lstat(secretsDir)
   135  	if err != nil {
   136  		t.Fatalf("error stat'ing secrets dir %q: %v", secretsDir, err)
   137  	}
   138  	if !fi.IsDir() {
   139  		t.Fatalf("secrets dir %q is not a directory and should be", secretsDir)
   140  	}
   141  	if err := isMount(secretsDir); err != notFoundErr {
   142  		t.Fatalf("error ensuring secrets dir %q isn't mounted: %v", secretsDir, err)
   143  	}
   144  
   145  	// now remove it
   146  	if err := removeSecretDir(secretsDir); err != nil {
   147  		t.Fatalf("error removing secrets dir %q: %v", secretsDir, err)
   148  	}
   149  
   150  	// make sure it's gone
   151  	if _, err := os.Lstat(secretsDir); err == nil {
   152  		t.Fatalf("expected secrets dir %q to be gone but it was found", secretsDir)
   153  	}
   154  
   155  	// removing again should be a noop
   156  	if err := removeSecretDir(secretsDir); err != nil {
   157  		t.Fatalf("error removing nonexistent secrets dir %q: %v", secretsDir, err)
   158  	}
   159  }