...

Source file src/k8s.io/kubernetes/test/images/agnhost/mounttest/mt.go

Documentation: k8s.io/kubernetes/test/images/agnhost/mounttest

     1  /*
     2  Copyright 2015 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package mounttest
    18  
    19  import (
    20  	"fmt"
    21  	"os"
    22  	"time"
    23  
    24  	"github.com/spf13/cobra"
    25  )
    26  
    27  // CmdMounttest is used by agnhost Cobra.
    28  var CmdMounttest = &cobra.Command{
    29  	Use:   "mounttest",
    30  	Short: "Creates files with given permissions and outputs FS type, owner, mode, permissions, contents of files",
    31  	Long:  "Creates files with specific file permissions, and outputs the filesystem type, owner, mode, permissions, content of the given files, if they exist.",
    32  	Args:  cobra.MaximumNArgs(0),
    33  	Run:   main,
    34  }
    35  
    36  var (
    37  	fsTypePath                = ""
    38  	fileModePath              = ""
    39  	filePermPath              = ""
    40  	fileOwnerPath             = ""
    41  	newFilePath0644           = ""
    42  	newFilePath0666           = ""
    43  	newFilePath0660           = ""
    44  	newFilePath0777           = ""
    45  	readFileContentPath       = ""
    46  	readFileContentInLoopPath = ""
    47  	retryDuration             = 180
    48  	breakOnExpectedContent    = true
    49  )
    50  
    51  func init() {
    52  	CmdMounttest.Flags().StringVar(&fsTypePath, "fs_type", "", "Path to print the fs type for")
    53  	CmdMounttest.Flags().StringVar(&fileModePath, "file_mode", "", "Path to print the mode bits of")
    54  	CmdMounttest.Flags().StringVar(&filePermPath, "file_perm", "", "Path to print the perms of")
    55  	CmdMounttest.Flags().StringVar(&fileOwnerPath, "file_owner", "", "Path to print the owning UID and GID of")
    56  	CmdMounttest.Flags().StringVar(&newFilePath0644, "new_file_0644", "", "Path to write to and read from with perm 0644")
    57  	CmdMounttest.Flags().StringVar(&newFilePath0666, "new_file_0666", "", "Path to write to and read from with perm 0666")
    58  	CmdMounttest.Flags().StringVar(&newFilePath0660, "new_file_0660", "", "Path to write to and read from with perm 0660")
    59  	CmdMounttest.Flags().StringVar(&newFilePath0777, "new_file_0777", "", "Path to write to and read from with perm 0777")
    60  	CmdMounttest.Flags().StringVar(&readFileContentPath, "file_content", "", "Path to read the file content from")
    61  	CmdMounttest.Flags().StringVar(&readFileContentInLoopPath, "file_content_in_loop", "", "Path to read the file content in loop from")
    62  	CmdMounttest.Flags().IntVar(&retryDuration, "retry_time", 180, "Retry time during the loop")
    63  	CmdMounttest.Flags().BoolVar(&breakOnExpectedContent, "break_on_expected_content", true, "Break out of loop on expected content, (use with --file_content_in_loop flag only)")
    64  }
    65  
    66  // This program performs some tests on the filesystem as dictated by the
    67  // flags passed by the user.
    68  func main(cmd *cobra.Command, args []string) {
    69  	var (
    70  		err  error
    71  		errs = []error{}
    72  	)
    73  
    74  	// Clear the umask so we can set any mode bits we want.
    75  	umask(0000)
    76  
    77  	// NOTE: the ordering of execution of the various command line
    78  	// flags is intentional and allows a single command to:
    79  	//
    80  	// 1.  Check the fstype of a path
    81  	// 2.  Write a new file within that path
    82  	// 3.  Check that the file's content can be read
    83  	//
    84  	// Changing the ordering of the following code will break tests.
    85  
    86  	err = fsType(fsTypePath)
    87  	if err != nil {
    88  		errs = append(errs, err)
    89  	}
    90  
    91  	err = readWriteNewFile(newFilePath0644, 0644)
    92  	if err != nil {
    93  		errs = append(errs, err)
    94  	}
    95  
    96  	err = readWriteNewFile(newFilePath0666, 0666)
    97  	if err != nil {
    98  		errs = append(errs, err)
    99  	}
   100  
   101  	err = readWriteNewFile(newFilePath0660, 0660)
   102  	if err != nil {
   103  		errs = append(errs, err)
   104  	}
   105  
   106  	err = readWriteNewFile(newFilePath0777, 0777)
   107  	if err != nil {
   108  		errs = append(errs, err)
   109  	}
   110  
   111  	err = fileMode(fileModePath)
   112  	if err != nil {
   113  		errs = append(errs, err)
   114  	}
   115  
   116  	err = filePerm(filePermPath)
   117  	if err != nil {
   118  		errs = append(errs, err)
   119  	}
   120  
   121  	err = fileOwner(fileOwnerPath)
   122  	if err != nil {
   123  		errs = append(errs, err)
   124  	}
   125  
   126  	err = readFileContent(readFileContentPath)
   127  	if err != nil {
   128  		errs = append(errs, err)
   129  	}
   130  
   131  	err = readFileContentInLoop(readFileContentInLoopPath, retryDuration, breakOnExpectedContent)
   132  	if err != nil {
   133  		errs = append(errs, err)
   134  	}
   135  
   136  	if len(errs) != 0 {
   137  		os.Exit(1)
   138  	}
   139  
   140  	os.Exit(0)
   141  }
   142  
   143  func readFileContent(path string) error {
   144  	if path == "" {
   145  		return nil
   146  	}
   147  
   148  	contentBytes, err := os.ReadFile(path)
   149  	if err != nil {
   150  		fmt.Printf("error reading file content for %q: %v\n", path, err)
   151  		return err
   152  	}
   153  
   154  	fmt.Printf("content of file %q: %v\n", path, string(contentBytes))
   155  
   156  	return nil
   157  }
   158  
   159  const initialContent string = "mount-tester new file\n"
   160  
   161  func readWriteNewFile(path string, perm os.FileMode) error {
   162  	if path == "" {
   163  		return nil
   164  	}
   165  
   166  	err := os.WriteFile(path, []byte(initialContent), perm)
   167  	if err != nil {
   168  		fmt.Printf("error writing new file %q: %v\n", path, err)
   169  		return err
   170  	}
   171  
   172  	return readFileContent(path)
   173  }
   174  
   175  func readFileContentInLoop(path string, retryDuration int, breakOnExpectedContent bool) error {
   176  	if path == "" {
   177  		return nil
   178  	}
   179  	return testFileContent(path, retryDuration, breakOnExpectedContent)
   180  }
   181  
   182  func testFileContent(filePath string, retryDuration int, breakOnExpectedContent bool) error {
   183  	var (
   184  		contentBytes []byte
   185  		err          error
   186  	)
   187  
   188  	retryTime := time.Second * time.Duration(retryDuration)
   189  	for start := time.Now(); time.Since(start) < retryTime; time.Sleep(2 * time.Second) {
   190  		contentBytes, err = os.ReadFile(filePath)
   191  		if err != nil {
   192  			fmt.Printf("Error reading file %s: %v, retrying\n", filePath, err)
   193  			continue
   194  		}
   195  		fmt.Printf("content of file %q: %v\n", filePath, string(contentBytes))
   196  		if breakOnExpectedContent {
   197  			if string(contentBytes) != initialContent {
   198  				fmt.Printf("Unexpected content. Expected: %s. Retrying\n", initialContent)
   199  				continue
   200  			}
   201  			break
   202  		}
   203  	}
   204  	return err
   205  }
   206  

View as plain text