1
16
17 package files
18
19 import (
20 "fmt"
21 "os"
22 "path/filepath"
23
24 utilfs "k8s.io/kubernetes/pkg/util/filesystem"
25 )
26
27 const (
28 defaultPerm = 0755
29 tmpTag = "tmp_"
30 )
31
32
33 func FileExists(fs utilfs.Filesystem, path string) (bool, error) {
34 if info, err := fs.Stat(path); err == nil {
35 if info.Mode().IsRegular() {
36 return true, nil
37 }
38 return false, fmt.Errorf("expected regular file at %q, but mode is %q", path, info.Mode().String())
39 } else if os.IsNotExist(err) {
40 return false, nil
41 } else {
42 return false, err
43 }
44 }
45
46
47
48 func EnsureFile(fs utilfs.Filesystem, path string) error {
49
50 if ok, err := FileExists(fs, path); ok || err != nil {
51 return err
52 }
53
54
55 err := fs.MkdirAll(filepath.Dir(path), defaultPerm)
56 if err != nil {
57 return err
58 }
59
60
61 file, err := fs.Create(path)
62 if err != nil {
63 return err
64 }
65
66 return file.Close()
67 }
68
69
70
71 func WriteTmpFile(fs utilfs.Filesystem, path string, data []byte) (tmpPath string, retErr error) {
72 dir := filepath.Dir(path)
73 prefix := tmpTag + filepath.Base(path)
74
75
76 tmpFile, err := fs.TempFile(dir, prefix)
77 if err != nil {
78 return "", err
79 }
80 defer func() {
81
82 if err := tmpFile.Close(); retErr == nil {
83 retErr = err
84 }
85
86 if retErr != nil {
87 if err := fs.Remove(tmpPath); err != nil {
88 retErr = fmt.Errorf("attempted to remove temporary file %q after error %v, but failed due to error: %v", tmpPath, retErr, err)
89 }
90 tmpPath = ""
91 }
92 }()
93
94
95
96 tmpPath = tmpFile.Name()
97
98
99 if _, err := tmpFile.Write(data); err != nil {
100 return tmpPath, err
101 }
102
103 return tmpPath, tmpFile.Sync()
104 }
105
106
107
108
109
110 func ReplaceFile(fs utilfs.Filesystem, path string, data []byte) error {
111
112 tmpPath, err := WriteTmpFile(fs, path, data)
113 if err != nil {
114 return err
115 }
116
117 return fs.Rename(tmpPath, path)
118 }
119
120
121 func DirExists(fs utilfs.Filesystem, path string) (bool, error) {
122 if info, err := fs.Stat(path); err == nil {
123 if info.IsDir() {
124 return true, nil
125 }
126 return false, fmt.Errorf("expected dir at %q, but mode is %q", path, info.Mode().String())
127 } else if os.IsNotExist(err) {
128 return false, nil
129 } else {
130 return false, err
131 }
132 }
133
134
135
136 func EnsureDir(fs utilfs.Filesystem, path string) error {
137
138 if ok, err := DirExists(fs, path); ok || err != nil {
139 return err
140 }
141
142
143 return fs.MkdirAll(path, defaultPerm)
144 }
145
146
147
148
149
150
151
152
153
154 func WriteTempDir(fs utilfs.Filesystem, path string, files map[string]string) (tmpPath string, retErr error) {
155
156 for name := range files {
157
158 if name == "" {
159 return "", fmt.Errorf("invalid file key: must not be empty: %q", name)
160 }
161
162 if name != filepath.Base(name) {
163 return "", fmt.Errorf("invalid file key %q, only base names are allowed", name)
164 }
165
166 if name == "." || name == ".." {
167 return "", fmt.Errorf("invalid file key, may not be '.' or '..'")
168 }
169
170 if len(name) > 255 {
171 return "", fmt.Errorf("invalid file key %q, must be less than 255 characters", name)
172 }
173 }
174
175
176 dir := filepath.Dir(path)
177 prefix := tmpTag + filepath.Base(path)
178
179
180 var err error
181 tmpPath, err = fs.TempDir(dir, prefix)
182 if err != nil {
183 return "", err
184 }
185
186 defer func() {
187 if retErr != nil {
188 if err := fs.RemoveAll(tmpPath); err != nil {
189 retErr = fmt.Errorf("attempted to remove temporary directory %q after error %v, but failed due to error: %v", tmpPath, retErr, err)
190 }
191 }
192 }()
193
194 for name, data := range files {
195
196 file, err := fs.Create(filepath.Join(tmpPath, name))
197 if err != nil {
198 return tmpPath, err
199 }
200
201 defer func() {
202
203 if err := file.Close(); retErr == nil {
204 retErr = err
205 }
206 }()
207
208 if _, err := file.Write([]byte(data)); err != nil {
209 return tmpPath, err
210 }
211
212 if err := file.Sync(); err != nil {
213 return tmpPath, err
214 }
215 }
216 return tmpPath, nil
217 }
218
219
220
221 func ReplaceDir(fs utilfs.Filesystem, path string, files map[string]string) error {
222
223 tmpPath, err := WriteTempDir(fs, path, files)
224 if err != nil {
225 return err
226 }
227
228 return fs.Rename(tmpPath, path)
229 }
230
View as plain text