k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/test/images/agnhost/mounttest/mt.go (about) 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 }