1
16
17 package mounttest
18
19 import (
20 "fmt"
21 "os"
22 "time"
23
24 "github.com/spf13/cobra"
25 )
26
27
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
67
68 func main(cmd *cobra.Command, args []string) {
69 var (
70 err error
71 errs = []error{}
72 )
73
74
75 umask(0000)
76
77
78
79
80
81
82
83
84
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