github.com/joelanford/operator-sdk@v0.8.2/internal/util/fileutil/file_util.go (about) 1 // Copyright 2018 The Operator-SDK Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Modified from github.com/kubernetes-sigs/controller-tools/pkg/util/util.go 16 17 package fileutil 18 19 import ( 20 "fmt" 21 "io" 22 "os" 23 "path/filepath" 24 "sync" 25 26 log "github.com/sirupsen/logrus" 27 "github.com/spf13/afero" 28 ) 29 30 const ( 31 // file modes 32 DefaultDirFileMode = 0750 33 DefaultFileMode = 0644 34 DefaultExecFileMode = 0755 35 36 DefaultFileFlags = os.O_WRONLY | os.O_CREATE 37 ) 38 39 // FileWriter is a io wrapper to write files 40 type FileWriter struct { 41 fs afero.Fs 42 once sync.Once 43 } 44 45 func NewFileWriterFS(fs afero.Fs) *FileWriter { 46 fw := &FileWriter{} 47 fw.once.Do(func() { 48 fw.fs = fs 49 }) 50 return fw 51 } 52 53 func (fw *FileWriter) GetFS() afero.Fs { 54 fw.once.Do(func() { 55 fw.fs = afero.NewOsFs() 56 }) 57 return fw.fs 58 } 59 60 // WriteCloser returns a WriteCloser to write to given path 61 func (fw *FileWriter) WriteCloser(path string, mode os.FileMode) (io.Writer, error) { 62 dir := filepath.Dir(path) 63 err := fw.GetFS().MkdirAll(dir, DefaultDirFileMode) 64 if err != nil { 65 return nil, err 66 } 67 68 fi, err := fw.GetFS().OpenFile(path, DefaultFileFlags, mode) 69 if err != nil { 70 return nil, err 71 } 72 73 return fi, nil 74 } 75 76 // WriteFile write given content to the file path 77 func (fw *FileWriter) WriteFile(filePath string, content []byte) error { 78 f, err := fw.WriteCloser(filePath, DefaultFileMode) 79 if err != nil { 80 return fmt.Errorf("failed to create %s: %v", filePath, err) 81 } 82 83 if c, ok := f.(io.Closer); ok { 84 defer func() { 85 if err := c.Close(); err != nil { 86 log.Fatal(err) 87 } 88 }() 89 } 90 91 _, err = f.Write(content) 92 if err != nil { 93 return fmt.Errorf("failed to write %s: %v", filePath, err) 94 } 95 96 return nil 97 } 98 99 func IsClosedError(e error) bool { 100 pathErr, ok := e.(*os.PathError) 101 if !ok { 102 return false 103 } 104 if pathErr.Err == os.ErrClosed { 105 return true 106 } 107 return false 108 }